Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  transfer2.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <config_vclplug.h>

#include <osl/mutex.hxx>
#include <sot/exchange.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#include <com/sun/star/uno/DeploymentException.hpp>
#include <svl/urlbmk.hxx>
#include <vcl/transfer.hxx>

#include <svdata.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::datatransfer::clipboard;
using namespace ::com::sun::star::datatransfer::dnd;


DragSourceHelper::DragGestureListener::DragGestureListener( DragSourceHelper& rDragSourceHelper ) :
    mrParent( rDragSourceHelper )
{
}


DragSourceHelper::DragGestureListener::~DragGestureListener()
{
}


void SAL_CALL DragSourceHelper::DragGestureListener::disposing( const EventObject&&nbsp;)
{
}


void SAL_CALL DragSourceHelper::DragGestureListener::dragGestureRecognized( const DragGestureEvent& rDGE )
{
    const SolarMutexGuard aGuard;

    const Point aPtPixel( rDGE.DragOriginX, rDGE.DragOriginY );
    mrParent.StartDrag( rDGE.DragAction, aPtPixel );
}


DragSourceHelper::DragSourceHelper( vcl::Window* pWindow ) :
    mxDragGestureRecognizer( pWindow->GetDragGestureRecognizer() )
{
    if( mxDragGestureRecognizer.is() )
    {
        mxDragGestureListener = new DragSourceHelper::DragGestureListener( *this );
        mxDragGestureRecognizer->addDragGestureListener( mxDragGestureListener );
    }
}


void DragSourceHelper::dispose()
{
    Reference<XDragGestureRecognizer> xTmp;
    {
        std::scoped_lock aGuard( maMutex );
        xTmp = std::move(mxDragGestureRecognizer);
    }
    if( xTmp.is()  )
        xTmp->removeDragGestureListener( mxDragGestureListener );
}

DragSourceHelper::~DragSourceHelper()
{
    dispose();
}


void DragSourceHelper::StartDrag( sal_Int8, const Point& )
{
}


DropTargetHelper::DropTargetListener::DropTargetListener( DropTargetHelper& rDropTargetHelper ) :
    mrParent( rDropTargetHelper )
{
}


DropTargetHelper::DropTargetListener::~DropTargetListener()
{
}


void SAL_CALL DropTargetHelper::DropTargetListener::disposing( const EventObject& ;)
{
}


void SAL_CALL DropTargetHelper::DropTargetListener::drop( const DropTargetDropEvent&&nbsp;rDTDE )
{
    const SolarMutexGuard aGuard;

    try
    {
        AcceptDropEvent  aAcceptEvent;
        ExecuteDropEvent aExecuteEvt( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );

        aExecuteEvt.mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );

        // in case of a default action, call ::AcceptDrop first and use the returned
        // accepted action as the execute action in the call to ::ExecuteDrop
        aAcceptEvent.mnAction = aExecuteEvt.mnAction;
        aAcceptEvent.maPosPixel = aExecuteEvt.maPosPixel;
        static_cast<DropTargetEvent&>(const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent )) = rDTDE;
        const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).DropAction = rDTDE.DropAction;
        const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).LocationX = rDTDE.LocationX;
        const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).LocationY = rDTDE.LocationY;
        const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).SourceActions = rDTDE.SourceActions;
        aAcceptEvent.mbLeaving = false;
        aAcceptEvent.mbDefault = aExecuteEvt.mbDefault;

        sal_Int8 nRet = mrParent.AcceptDrop( aAcceptEvent );

        if( DNDConstants::ACTION_NONE != nRet )
        {
            rDTDE.Context->acceptDrop( nRet );

            if( aExecuteEvt.mbDefault )
                aExecuteEvt.mnAction = nRet;

            nRet = mrParent.ExecuteDrop( aExecuteEvt );
        }

        rDTDE.Context->dropComplete( DNDConstants::ACTION_NONE != nRet );

        mpLastDragOverEvent.reset();
    }
    catchconst css::uno::Exception& )
    {
    }
}


void SAL_CALL DropTargetHelper::DropTargetListener::dragEnter( const DropTargetDragEnterEvent& rDTDEE )
{
    const SolarMutexGuard aGuard;

    try
    {
        mrParent.ImplBeginDrag( rDTDEE.SupportedDataFlavors );
    }
    catchconst css::uno::Exception& )
    {
    }

    dragOver( rDTDEE );
}


void SAL_CALL DropTargetHelper::DropTargetListener::dragOver( const DropTargetDragEvent& rDTDE )
{
    const SolarMutexGuard aGuard;

    try
    {
        mpLastDragOverEvent.reset( new AcceptDropEvent( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE ) );
        mpLastDragOverEvent->mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );

        const sal_Int8 nRet = mrParent.AcceptDrop( *mpLastDragOverEvent );

        if( DNDConstants::ACTION_NONE == nRet )
            rDTDE.Context->rejectDrag();
        else
            rDTDE.Context->acceptDrag( nRet );
    }
    catchconst css::uno::Exception& )
    {
    }
}


void SAL_CALL DropTargetHelper::DropTargetListener::dragExit( const DropTargetEvent&&nbsp;)
{
    const SolarMutexGuard aGuard;

    try
    {
        if( mpLastDragOverEvent )
        {
            mpLastDragOverEvent->mbLeaving = true;
            mrParent.AcceptDrop( *mpLastDragOverEvent );
            mpLastDragOverEvent.reset();
        }

        mrParent.ImplEndDrag();
    }
    catchconst css::uno::Exception& )
    {
    }
}


void SAL_CALL DropTargetHelper::DropTargetListener::dropActionChanged( const DropTargetDragEvent& )
{
}


DropTargetHelper::DropTargetHelper( vcl::Window* pWindow ) :
    mxDropTarget( pWindow->GetDropTarget() )
{
    ImplConstruct();
}


DropTargetHelper::DropTargetHelper( const Reference< XDropTarget >& rxDropTarget ) :
    mxDropTarget( rxDropTarget )
{
    ImplConstruct();
}


void DropTargetHelper::dispose()
{
    Reference< XDropTarget >  xTmp;
    {
        std::scoped_lock aGuard( maMutex );
        xTmp = std::move(mxDropTarget);
    }
    if( xTmp.is() )
        xTmp->removeDropTargetListener( mxDropTargetListener );
}

DropTargetHelper::~DropTargetHelper()
{
    dispose();
}


void DropTargetHelper::ImplConstruct()
{
    if( mxDropTarget.is() )
    {
        mxDropTargetListener = new DropTargetHelper::DropTargetListener( *this );
        mxDropTarget->addDropTargetListener( mxDropTargetListener );
        mxDropTarget->setActive( true );
    }
}


void DropTargetHelper::ImplBeginDrag( const Sequence< DataFlavor >& rSupportedDataFlavors )
{
    maFormats.clear();
    TransferableDataHelper::FillDataFlavorExVector( rSupportedDataFlavors, maFormats );
}


void DropTargetHelper::ImplEndDrag()
{
    maFormats.clear();
}


sal_Int8 DropTargetHelper::AcceptDrop( const AcceptDropEvent& )
{
    return DNDConstants::ACTION_NONE;
}


sal_Int8 DropTargetHelper::ExecuteDrop( const ExecuteDropEvent& )
{
    return DNDConstants::ACTION_NONE;
}


bool DropTargetHelper::IsDropFormatSupported(SotClipboardFormatId nFormat) const
{
    return std::any_of(maFormats.begin(), maFormats.end(),
           [&](const DataFlavorEx& data) { return data.mnSotId == nFormat; });
}


// TransferDataContainer

namespace {

struct TDataCntnrEntry_Impl
{
    css::uno::Any aAny;
    SotClipboardFormatId nId;
};

}

struct TransferDataContainer_Impl
{
    std::vector< TDataCntnrEntry_Impl > aFmtList;
    Link<sal_Int8,void> aFinishedLnk;
    std::optional<INetBookmark> moBookmk;

    TransferDataContainer_Impl()
    {
    }
};


TransferDataContainer::TransferDataContainer()
    : pImpl( new TransferDataContainer_Impl )
{
}


TransferDataContainer::~TransferDataContainer()
{
}


void TransferDataContainer::AddSupportedFormats()
{
}


bool TransferDataContainer::GetData(
    const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
{
    bool bFnd = false;
    SotClipboardFormatId nFmtId = SotExchange::GetFormat( rFlavor );

    // test first the list
    for (auto const& format : pImpl->aFmtList)
    {
        if( nFmtId == format.nId )
        {
            bFnd = SetAny( format.aAny );
            break;
        }
    }

    // test second the bookmark pointer
    if( !bFnd )
        switch( nFmtId )
        {
         case SotClipboardFormatId::STRING:
         case SotClipboardFormatId::SOLK:
         case SotClipboardFormatId::NETSCAPE_BOOKMARK:
         case SotClipboardFormatId::FILECONTENT:
         case SotClipboardFormatId::FILEGRPDESCRIPTOR:
         case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
            if( pImpl->moBookmk )
                bFnd = SetINetBookmark( *pImpl->moBookmk, rFlavor );
            break;

        defaultbreak;
        }

    return bFnd;
}


void TransferDataContainer::CopyINetBookmark( const INetBookmark& rBkmk )
{
    pImpl->moBookmk = rBkmk;

    AddFormat( SotClipboardFormatId::STRING );
    AddFormat( SotClipboardFormatId::SOLK );
    AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
    AddFormat( SotClipboardFormatId::FILECONTENT );
    AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
    AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
}


void TransferDataContainer::CopyAnyData( SotClipboardFormatId nFormatId,
                                        const char* pData, sal_uLong nLen )
{
    if( nLen )
    {
        TDataCntnrEntry_Impl aEntry;
        aEntry.nId = nFormatId;

        Sequence< sal_Int8 > aSeq( nLen  );
        memcpy( aSeq.getArray(), pData, nLen );
        aEntry.aAny <<= aSeq;
        pImpl->aFmtList.push_back( aEntry );
        AddFormat( nFormatId );
    }
}


void TransferDataContainer::CopyByteString( SotClipboardFormatId nFormatId,
                                            const OString& rStr )
{
    CopyAnyData( nFormatId, rStr.getStr(), rStr.getLength() );
}


void TransferDataContainer::CopyString( SotClipboardFormatId nFmt, const OUString& ;rStr )
{
    if( !rStr.isEmpty() )
    {
        TDataCntnrEntry_Impl aEntry;
        aEntry.nId = nFmt;
        aEntry.aAny <<= rStr;
        pImpl->aFmtList.push_back( aEntry );
        AddFormat( aEntry.nId );
    }
}


void TransferDataContainer::CopyString( const OUString& rStr )
{
    CopyString( SotClipboardFormatId::STRING, rStr );
}


bool TransferDataContainer::HasAnyData() const
{
    return !pImpl->aFmtList.empty() ||
            pImpl->moBookmk.has_value();
}


void TransferDataContainer::StartDrag(
        vcl::Window* pWindow, sal_Int8 nDragSourceActions,
        const Link<sal_Int8,void>& rLnk )
{
    pImpl->aFinishedLnk = rLnk;
    TransferableHelper::StartDrag( pWindow, nDragSourceActions );
}


void TransferDataContainer::DragFinished( sal_Int8 nDropAction )
{
    pImpl->aFinishedLnk.Call( nDropAction );
}

Reference<XClipboard> GetSystemClipboard()
{
    // On Windows, the css.datatransfer.clipboard.SystemClipboard UNO service is implemented as a
    // single-instance service (dtrans_CWinClipboard_get_implementation in
    // vcl/win/dtrans/WinClipboard.cxx) that needs timely disposing to join a spawned thread
    // (done in DeInitVCL, vcl/source/app/svmain.cxx), while on other platforms it is implemented as
    // a multi-instance service (ClipboardFactory, vcl/source/components/dtranscomp.cxx) so we
    // should not hold on to a single instance here:
#if defined _WIN32
    DBG_TESTSOLARMUTEX();
    auto const data = ImplGetSVData();
    if (!data->m_xSystemClipboard.is())
    {
        try
        {
            data->m_xSystemClipboard = css::datatransfer::clipboard::SystemClipboard::create(
                comphelper::getProcessComponentContext());
        }
        catch (DeploymentException const &) {}
    }
    return data->m_xSystemClipboard;
#else
    Reference<XClipboard> xClipboard;
    try
    {
#ifdef IOS
        if (false)
            ;
#else
        if (comphelper::LibreOfficeKit::isActive())
        {
            xClipboard = css::datatransfer::clipboard::LokClipboard::create(
                    comphelper::getProcessComponentContext());
        }
#endif
        else
        {
            xClipboard = css::datatransfer::clipboard::SystemClipboard::create(
                comphelper::getProcessComponentContext());
        }
    }
    catch (DeploymentException const &) {}
    return xClipboard;
#endif
}

Reference<XClipboard> GetSystemPrimarySelection()
{
    Reference<XClipboard> xSelection;
    try
    {
        const Reference<XComponentContext>& xContext(comphelper::getProcessComponentContext());
#if USING_X11
        // A hack, making the primary selection available as an instance
        // of the SystemClipboard service on X11:
        Sequence< Any > args{ Any(u"PRIMARY"_ustr) };
        xSelection.set(xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
            u"com.sun.star.datatransfer.clipboard.SystemClipboard"_ustr, args, xContext), UNO_QUERY_THROW);
#else
        static Reference< XClipboard > s_xSelection(
            xContext->getServiceManager()->createInstanceWithContext(
                "com.sun.star.datatransfer.clipboard.GenericClipboard", xContext), UNO_QUERY);
        xSelection = s_xSelection;
#endif
    }
    catch (RuntimeException const &) {}
    return xSelection;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge