Bump version to 5.0-14
[LibreOffice.git] / svtools / source / misc / transfer2.cxx
blobd0bb2cd9a12c952383ccc6a0aaf3779c7bb5cb16
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/mutex.hxx>
21 #include <unotools/ucbstreamhelper.hxx>
22 #include <sot/exchange.hxx>
23 #include <sot/storage.hxx>
24 #include <vcl/bitmap.hxx>
25 #include <vcl/gdimtf.hxx>
26 #include <vcl/graph.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/window.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
31 #include <svl/urlbmk.hxx>
32 #include <svtools/inetimg.hxx>
33 #include <svtools/imap.hxx>
34 #include <svtools/transfer.hxx>
37 // - Namespaces -
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::lang;
42 using namespace ::com::sun::star::io;
43 using namespace ::com::sun::star::datatransfer;
44 using namespace ::com::sun::star::datatransfer::clipboard;
45 using namespace ::com::sun::star::datatransfer::dnd;
48 // - DragSourceHelper::DragGestureListener -
51 DragSourceHelper::DragGestureListener::DragGestureListener( DragSourceHelper& rDragSourceHelper ) :
52 mrParent( rDragSourceHelper )
58 DragSourceHelper::DragGestureListener::~DragGestureListener()
64 void SAL_CALL DragSourceHelper::DragGestureListener::disposing( const EventObject& ) throw( RuntimeException, std::exception )
70 void SAL_CALL DragSourceHelper::DragGestureListener::dragGestureRecognized( const DragGestureEvent& rDGE ) throw( RuntimeException, std::exception )
72 const SolarMutexGuard aGuard;
74 const Point aPtPixel( rDGE.DragOriginX, rDGE.DragOriginY );
75 mrParent.StartDrag( rDGE.DragAction, aPtPixel );
79 // - DragSourceHelper -
82 DragSourceHelper::DragSourceHelper( vcl::Window* pWindow ) :
83 mxDragGestureRecognizer( pWindow->GetDragGestureRecognizer() )
85 if( mxDragGestureRecognizer.is() )
87 mxDragGestureListener = new DragSourceHelper::DragGestureListener( *this );
88 mxDragGestureRecognizer->addDragGestureListener( mxDragGestureListener );
94 DragSourceHelper::~DragSourceHelper()
96 if( mxDragGestureRecognizer.is() )
97 mxDragGestureRecognizer->removeDragGestureListener( mxDragGestureListener );
102 void DragSourceHelper::StartDrag( sal_Int8, const Point& )
107 // - DropTargetHelper::DropTargetListener -
110 DropTargetHelper::DropTargetListener::DropTargetListener( DropTargetHelper& rDropTargetHelper ) :
111 mrParent( rDropTargetHelper ),
112 mpLastDragOverEvent( NULL )
118 DropTargetHelper::DropTargetListener::~DropTargetListener()
120 delete mpLastDragOverEvent;
125 void SAL_CALL DropTargetHelper::DropTargetListener::disposing( const EventObject& ) throw( RuntimeException, std::exception )
131 void SAL_CALL DropTargetHelper::DropTargetListener::drop( const DropTargetDropEvent& rDTDE ) throw( RuntimeException, std::exception )
133 const SolarMutexGuard aGuard;
137 AcceptDropEvent aAcceptEvent;
138 ExecuteDropEvent aExecuteEvt( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
140 aExecuteEvt.mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
142 // in case of a default action, call ::AcceptDrop first and use the returned
143 // accepted action as the execute action in the call to ::ExecuteDrop
144 aAcceptEvent.mnAction = aExecuteEvt.mnAction;
145 aAcceptEvent.maPosPixel = aExecuteEvt.maPosPixel;
146 (DropTargetEvent&)( aAcceptEvent.maDragEvent ) = (DropTargetEvent&) rDTDE;
147 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).DropAction = rDTDE.DropAction;
148 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationX = rDTDE.LocationX;
149 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationY = rDTDE.LocationY;
150 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).SourceActions = rDTDE.SourceActions;
151 aAcceptEvent.mbLeaving = false;
152 aAcceptEvent.mbDefault = aExecuteEvt.mbDefault;
154 sal_Int8 nRet = mrParent.AcceptDrop( aAcceptEvent );
156 if( DNDConstants::ACTION_NONE != nRet )
158 rDTDE.Context->acceptDrop( nRet );
160 if( aExecuteEvt.mbDefault )
161 aExecuteEvt.mnAction = nRet;
163 nRet = mrParent.ExecuteDrop( aExecuteEvt );
166 rDTDE.Context->dropComplete( DNDConstants::ACTION_NONE != nRet );
168 if( mpLastDragOverEvent )
170 delete mpLastDragOverEvent;
171 mpLastDragOverEvent = NULL;
174 catch( const ::com::sun::star::uno::Exception& )
181 void SAL_CALL DropTargetHelper::DropTargetListener::dragEnter( const DropTargetDragEnterEvent& rDTDEE ) throw( RuntimeException, std::exception )
183 const SolarMutexGuard aGuard;
187 mrParent.ImplBeginDrag( rDTDEE.SupportedDataFlavors );
189 catch( const ::com::sun::star::uno::Exception& )
193 dragOver( rDTDEE );
198 void SAL_CALL DropTargetHelper::DropTargetListener::dragOver( const DropTargetDragEvent& rDTDE ) throw( RuntimeException, std::exception )
200 const SolarMutexGuard aGuard;
204 if( mpLastDragOverEvent )
205 delete mpLastDragOverEvent;
207 mpLastDragOverEvent = new AcceptDropEvent( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
208 mpLastDragOverEvent->mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
210 const sal_Int8 nRet = mrParent.AcceptDrop( *mpLastDragOverEvent );
212 if( DNDConstants::ACTION_NONE == nRet )
213 rDTDE.Context->rejectDrag();
214 else
215 rDTDE.Context->acceptDrag( nRet );
217 catch( const ::com::sun::star::uno::Exception& )
224 void SAL_CALL DropTargetHelper::DropTargetListener::dragExit( const DropTargetEvent& ) throw( RuntimeException, std::exception )
226 const SolarMutexGuard aGuard;
230 if( mpLastDragOverEvent )
232 mpLastDragOverEvent->mbLeaving = true;
233 mrParent.AcceptDrop( *mpLastDragOverEvent );
234 delete mpLastDragOverEvent;
235 mpLastDragOverEvent = NULL;
238 mrParent.ImplEndDrag();
240 catch( const ::com::sun::star::uno::Exception& )
248 void SAL_CALL DropTargetHelper::DropTargetListener::dropActionChanged( const DropTargetDragEvent& ) throw( RuntimeException, std::exception )
253 // - DropTargetHelper -
256 DropTargetHelper::DropTargetHelper( vcl::Window* pWindow ) :
257 mxDropTarget( pWindow->GetDropTarget() ),
258 mpFormats( new DataFlavorExVector )
260 ImplConstruct();
265 DropTargetHelper::DropTargetHelper( const Reference< XDropTarget >& rxDropTarget ) :
266 mxDropTarget( rxDropTarget ),
267 mpFormats( new DataFlavorExVector )
269 ImplConstruct();
274 DropTargetHelper::~DropTargetHelper()
276 if( mxDropTarget.is() )
277 mxDropTarget->removeDropTargetListener( mxDropTargetListener );
279 delete mpFormats;
284 void DropTargetHelper::ImplConstruct()
286 if( mxDropTarget.is() )
288 mxDropTargetListener = new DropTargetHelper::DropTargetListener( *this );
289 mxDropTarget->addDropTargetListener( mxDropTargetListener );
290 mxDropTarget->setActive( sal_True );
296 void DropTargetHelper::ImplBeginDrag( const Sequence< DataFlavor >& rSupportedDataFlavors )
298 mpFormats->clear();
299 TransferableDataHelper::FillDataFlavorExVector( rSupportedDataFlavors, *mpFormats );
304 void DropTargetHelper::ImplEndDrag()
306 mpFormats->clear();
311 sal_Int8 DropTargetHelper::AcceptDrop( const AcceptDropEvent& )
313 return( DNDConstants::ACTION_NONE );
318 sal_Int8 DropTargetHelper::ExecuteDrop( const ExecuteDropEvent& )
320 return( DNDConstants::ACTION_NONE );
325 bool DropTargetHelper::IsDropFormatSupported( SotClipboardFormatId nFormat )
327 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
328 bool bRet = false;
330 while( aIter != aEnd )
332 if( nFormat == (*aIter++).mnSotId )
334 bRet = true;
335 aIter = aEnd;
339 return bRet;
344 bool DropTargetHelper::IsDropFormatSupported( const DataFlavor& rFlavor )
346 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
347 bool bRet = false;
349 while( aIter != aEnd )
351 if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
353 bRet = true;
354 aIter = aEnd;
358 return bRet;
362 // TransferDataContainer
365 struct TDataCntnrEntry_Impl
367 ::com::sun::star::uno::Any aAny;
368 SotClipboardFormatId nId;
373 typedef ::std::list< TDataCntnrEntry_Impl > TDataCntnrEntryList;
377 struct TransferDataContainer_Impl
379 TDataCntnrEntryList aFmtList;
380 Link<> aFinshedLnk;
381 INetBookmark* pBookmk;
382 Graphic* pGrf;
384 TransferDataContainer_Impl()
385 : pBookmk( 0 ), pGrf( 0 )
389 ~TransferDataContainer_Impl()
391 delete pBookmk;
392 delete pGrf;
398 TransferDataContainer::TransferDataContainer()
399 : pImpl( new TransferDataContainer_Impl )
405 TransferDataContainer::~TransferDataContainer()
407 delete pImpl;
412 void TransferDataContainer::AddSupportedFormats()
418 bool TransferDataContainer::GetData(
419 const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
421 TDataCntnrEntryList::iterator aIter( pImpl->aFmtList.begin() ),
422 aEnd( pImpl->aFmtList.end() );
423 bool bFnd = false;
424 SotClipboardFormatId nFmtId = SotExchange::GetFormat( rFlavor );
426 // test first the list
427 for( ; aIter != aEnd; ++aIter )
429 TDataCntnrEntry_Impl& rEntry = (TDataCntnrEntry_Impl&)*aIter;
430 if( nFmtId == rEntry.nId )
432 bFnd = SetAny( rEntry.aAny, rFlavor );
433 break;
437 // test second the bookmark pointer
438 if( !bFnd )
439 switch( nFmtId )
441 case SotClipboardFormatId::STRING:
442 case SotClipboardFormatId::SOLK:
443 case SotClipboardFormatId::NETSCAPE_BOOKMARK:
444 case SotClipboardFormatId::FILECONTENT:
445 case SotClipboardFormatId::FILEGRPDESCRIPTOR:
446 case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
447 if( pImpl->pBookmk )
448 bFnd = SetINetBookmark( *pImpl->pBookmk, rFlavor );
449 break;
451 case SotClipboardFormatId::SVXB:
452 case SotClipboardFormatId::PNG:
453 case SotClipboardFormatId::BITMAP:
454 case SotClipboardFormatId::GDIMETAFILE:
455 if( pImpl->pGrf )
456 bFnd = SetGraphic( *pImpl->pGrf, rFlavor );
457 break;
458 default: break;
461 return bFnd;
466 void TransferDataContainer::CopyINetBookmark( const INetBookmark& rBkmk )
468 if( !pImpl->pBookmk )
469 pImpl->pBookmk = new INetBookmark( rBkmk );
470 else
471 *pImpl->pBookmk = rBkmk;
473 AddFormat( SotClipboardFormatId::STRING );
474 AddFormat( SotClipboardFormatId::SOLK );
475 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
476 AddFormat( SotClipboardFormatId::FILECONTENT );
477 AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
478 AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
483 void TransferDataContainer::CopyAnyData( SotClipboardFormatId nFormatId,
484 const sal_Char* pData, sal_uLong nLen )
486 if( nLen )
488 TDataCntnrEntry_Impl aEntry;
489 aEntry.nId = nFormatId;
491 Sequence< sal_Int8 > aSeq( nLen );
492 memcpy( aSeq.getArray(), pData, nLen );
493 aEntry.aAny <<= aSeq;
494 pImpl->aFmtList.push_back( aEntry );
495 AddFormat( nFormatId );
501 void TransferDataContainer::CopyByteString( SotClipboardFormatId nFormatId,
502 const OString& rStr )
504 CopyAnyData( nFormatId, rStr.getStr(), rStr.getLength() );
509 void TransferDataContainer::CopyINetImage( const INetImage& rINtImg )
511 SvMemoryStream aMemStm( 1024, 1024 );
512 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
513 rINtImg.Write( aMemStm, SotClipboardFormatId::INET_IMAGE );
514 CopyAnyData( SotClipboardFormatId::INET_IMAGE, static_cast<sal_Char const *>(aMemStm.GetData()),
515 aMemStm.Seek( STREAM_SEEK_TO_END ) );
520 void TransferDataContainer::CopyImageMap( const ImageMap& rImgMap )
522 SvMemoryStream aMemStm( 8192, 8192 );
523 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
524 rImgMap.Write( aMemStm, OUString() );
525 CopyAnyData( SotClipboardFormatId::SVIM, static_cast<sal_Char const *>(aMemStm.GetData()),
526 aMemStm.Seek( STREAM_SEEK_TO_END ) );
531 void TransferDataContainer::CopyGraphic( const Graphic& rGrf )
533 GraphicType nType = rGrf.GetType();
534 if( GRAPHIC_NONE != nType )
536 if( !pImpl->pGrf )
537 pImpl->pGrf = new Graphic( rGrf );
538 else
539 *pImpl->pGrf = rGrf;
541 AddFormat( SotClipboardFormatId::SVXB );
543 if( GRAPHIC_BITMAP == nType )
545 AddFormat( SotClipboardFormatId::PNG );
546 AddFormat( SotClipboardFormatId::BITMAP );
548 else if( GRAPHIC_GDIMETAFILE == nType )
550 AddFormat( SotClipboardFormatId::GDIMETAFILE );
557 void TransferDataContainer::CopyString( SotClipboardFormatId nFmt, const OUString& rStr )
559 if( !rStr.isEmpty() )
561 TDataCntnrEntry_Impl aEntry;
562 aEntry.nId = nFmt;
563 OUString aStr( rStr );
564 aEntry.aAny <<= aStr;
565 pImpl->aFmtList.push_back( aEntry );
566 AddFormat( aEntry.nId );
572 void TransferDataContainer::CopyString( const OUString& rStr )
574 CopyString( SotClipboardFormatId::STRING, rStr );
579 void TransferDataContainer::CopyAny( SotClipboardFormatId nFmt,
580 const ::com::sun::star::uno::Any& rAny )
582 TDataCntnrEntry_Impl aEntry;
583 aEntry.nId = nFmt;
584 aEntry.aAny = rAny;
585 pImpl->aFmtList.push_back( aEntry );
586 AddFormat( aEntry.nId );
591 bool TransferDataContainer::HasAnyData() const
593 return pImpl->aFmtList.begin() != pImpl->aFmtList.end() ||
594 0 != pImpl->pBookmk;
599 void TransferDataContainer::StartDrag(
600 vcl::Window* pWindow, sal_Int8 nDragSourceActions,
601 const Link<>& rLnk, sal_Int32 nDragPointer, sal_Int32 nDragImage )
603 pImpl->aFinshedLnk = rLnk;
604 TransferableHelper::StartDrag( pWindow, nDragSourceActions,
605 nDragPointer, nDragImage );
610 void TransferDataContainer::DragFinished( sal_Int8 nDropAction )
612 if( pImpl->aFinshedLnk.IsSet() )
613 pImpl->aFinshedLnk.Call( &nDropAction );
616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */