Update ooo320-m1
[ooovba.git] / svtools / source / misc / transfer2.cxx
blob8ed3d16225de0d358f6242028a5cbfca1660b132
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: transfer2.cxx,v $
10 * $Revision: 1.21 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <vos/mutex.hxx>
34 #ifndef DEBUG_HXX
35 #include <tools/debug.hxx>
36 #endif
37 #ifndef URLOBJ_HXX
38 #include <tools/urlobj.hxx>
39 #endif
40 #include <unotools/ucbstreamhelper.hxx>
41 #include <sot/exchange.hxx>
42 #include <sot/storage.hxx>
43 #include <vcl/bitmap.hxx>
44 #include <vcl/gdimtf.hxx>
45 #include <vcl/graph.hxx>
46 #include <vcl/svapp.hxx>
47 #include <vcl/window.hxx>
48 #include <comphelper/processfactory.hxx>
49 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_DROPTARGETDRAGCONTEXT_HPP_
50 #include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
51 #endif
53 #include "urlbmk.hxx"
54 #include "inetimg.hxx"
55 #include <svtools/imap.hxx>
56 #include <svtools/transfer.hxx>
58 // --------------
59 // - Namespaces -
60 // --------------
62 using namespace ::com::sun::star::uno;
63 using namespace ::com::sun::star::lang;
64 using namespace ::com::sun::star::io;
65 using namespace ::com::sun::star::datatransfer;
66 using namespace ::com::sun::star::datatransfer::clipboard;
67 using namespace ::com::sun::star::datatransfer::dnd;
69 // -----------------------------------------
70 // - DragSourceHelper::DragGestureListener -
71 // -----------------------------------------
73 DragSourceHelper::DragGestureListener::DragGestureListener( DragSourceHelper& rDragSourceHelper ) :
74 mrParent( rDragSourceHelper )
78 // -----------------------------------------------------------------------------
80 DragSourceHelper::DragGestureListener::~DragGestureListener()
84 // -----------------------------------------------------------------------------
86 void SAL_CALL DragSourceHelper::DragGestureListener::disposing( const EventObject& ) throw( RuntimeException )
90 // -----------------------------------------------------------------------------
92 void SAL_CALL DragSourceHelper::DragGestureListener::dragGestureRecognized( const DragGestureEvent& rDGE ) throw( RuntimeException )
94 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
96 const Point aPtPixel( rDGE.DragOriginX, rDGE.DragOriginY );
97 mrParent.StartDrag( rDGE.DragAction, aPtPixel );
100 // --------------------
101 // - DragSourceHelper -
102 // --------------------
104 DragSourceHelper::DragSourceHelper( Window* pWindow ) :
105 mxDragGestureRecognizer( pWindow->GetDragGestureRecognizer() )
107 if( mxDragGestureRecognizer.is() )
109 mxDragGestureListener = new DragSourceHelper::DragGestureListener( *this );
110 mxDragGestureRecognizer->addDragGestureListener( mxDragGestureListener );
114 // -----------------------------------------------------------------------------
116 DragSourceHelper::~DragSourceHelper()
118 if( mxDragGestureRecognizer.is() )
119 mxDragGestureRecognizer->removeDragGestureListener( mxDragGestureListener );
122 // -----------------------------------------------------------------------------
124 void DragSourceHelper::StartDrag( sal_Int8, const Point& )
128 // ----------------------------------------
129 // - DropTargetHelper::DropTargetListener -
130 // ----------------------------------------
132 DropTargetHelper::DropTargetListener::DropTargetListener( DropTargetHelper& rDropTargetHelper ) :
133 mrParent( rDropTargetHelper ),
134 mpLastDragOverEvent( NULL )
138 // -----------------------------------------------------------------------------
140 DropTargetHelper::DropTargetListener::~DropTargetListener()
142 delete mpLastDragOverEvent;
145 // -----------------------------------------------------------------------------
147 void SAL_CALL DropTargetHelper::DropTargetListener::disposing( const EventObject& ) throw( RuntimeException )
151 // -----------------------------------------------------------------------------
153 void SAL_CALL DropTargetHelper::DropTargetListener::drop( const DropTargetDropEvent& rDTDE ) throw( RuntimeException )
155 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
159 AcceptDropEvent aAcceptEvent;
160 ExecuteDropEvent aExecuteEvt( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
161 sal_Int8 nRet = DNDConstants::ACTION_NONE;
163 aExecuteEvt.mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
165 // in case of a default action, call ::AcceptDrop first and use the returned
166 // accepted action as the execute action in the call to ::ExecuteDrop
167 aAcceptEvent.mnAction = aExecuteEvt.mnAction;
168 aAcceptEvent.maPosPixel = aExecuteEvt.maPosPixel;
169 (DropTargetEvent&)( aAcceptEvent.maDragEvent ) = (DropTargetEvent&) rDTDE;
170 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).DropAction = rDTDE.DropAction;
171 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationX = rDTDE.LocationX;
172 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).LocationY = rDTDE.LocationY;
173 ( (DropTargetDragEvent&)( aAcceptEvent.maDragEvent ) ).SourceActions = rDTDE.SourceActions;
174 aAcceptEvent.mbLeaving = sal_False;
175 aAcceptEvent.mbDefault = aExecuteEvt.mbDefault;
177 nRet = mrParent.AcceptDrop( aAcceptEvent );
179 if( DNDConstants::ACTION_NONE != nRet )
181 rDTDE.Context->acceptDrop( nRet );
183 if( aExecuteEvt.mbDefault )
184 aExecuteEvt.mnAction = nRet;
186 nRet = mrParent.ExecuteDrop( aExecuteEvt );
189 rDTDE.Context->dropComplete( DNDConstants::ACTION_NONE != nRet );
191 if( mpLastDragOverEvent )
193 delete mpLastDragOverEvent;
194 mpLastDragOverEvent = NULL;
197 catch( const ::com::sun::star::uno::Exception& )
202 // -----------------------------------------------------------------------------
204 void SAL_CALL DropTargetHelper::DropTargetListener::dragEnter( const DropTargetDragEnterEvent& rDTDEE ) throw( RuntimeException )
206 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
210 mrParent.ImplBeginDrag( rDTDEE.SupportedDataFlavors );
212 catch( const ::com::sun::star::uno::Exception& )
216 dragOver( rDTDEE );
219 // -----------------------------------------------------------------------------
221 void SAL_CALL DropTargetHelper::DropTargetListener::dragOver( const DropTargetDragEvent& rDTDE ) throw( RuntimeException )
223 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
227 if( mpLastDragOverEvent )
228 delete mpLastDragOverEvent;
230 mpLastDragOverEvent = new AcceptDropEvent( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE );
231 mpLastDragOverEvent->mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 );
233 const sal_Int8 nRet = mrParent.AcceptDrop( *mpLastDragOverEvent );
235 if( DNDConstants::ACTION_NONE == nRet )
236 rDTDE.Context->rejectDrag();
237 else
238 rDTDE.Context->acceptDrag( nRet );
240 catch( const ::com::sun::star::uno::Exception& )
245 // -----------------------------------------------------------------------------
247 void SAL_CALL DropTargetHelper::DropTargetListener::dragExit( const DropTargetEvent& ) throw( RuntimeException )
249 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
253 if( mpLastDragOverEvent )
255 mpLastDragOverEvent->mbLeaving = sal_True;
256 mrParent.AcceptDrop( *mpLastDragOverEvent );
257 delete mpLastDragOverEvent;
258 mpLastDragOverEvent = NULL;
261 mrParent.ImplEndDrag();
263 catch( const ::com::sun::star::uno::Exception& )
269 // -----------------------------------------------------------------------------
271 void SAL_CALL DropTargetHelper::DropTargetListener::dropActionChanged( const DropTargetDragEvent& ) throw( RuntimeException )
275 // --------------------
276 // - DropTargetHelper -
277 // --------------------
279 DropTargetHelper::DropTargetHelper( Window* pWindow ) :
280 mxDropTarget( pWindow->GetDropTarget() ),
281 mpFormats( new DataFlavorExVector )
283 ImplConstruct();
286 // -----------------------------------------------------------------------------
288 DropTargetHelper::DropTargetHelper( const Reference< XDropTarget >& rxDropTarget ) :
289 mxDropTarget( rxDropTarget ),
290 mpFormats( new DataFlavorExVector )
292 ImplConstruct();
295 // -----------------------------------------------------------------------------
297 DropTargetHelper::~DropTargetHelper()
299 if( mxDropTarget.is() )
300 mxDropTarget->removeDropTargetListener( mxDropTargetListener );
302 delete mpFormats;
305 // -----------------------------------------------------------------------------
307 void DropTargetHelper::ImplConstruct()
309 if( mxDropTarget.is() )
311 mxDropTargetListener = new DropTargetHelper::DropTargetListener( *this );
312 mxDropTarget->addDropTargetListener( mxDropTargetListener );
313 mxDropTarget->setActive( sal_True );
317 // -----------------------------------------------------------------------------
319 void DropTargetHelper::ImplBeginDrag( const Sequence< DataFlavor >& rSupportedDataFlavors )
321 mpFormats->clear();
322 TransferableDataHelper::FillDataFlavorExVector( rSupportedDataFlavors, *mpFormats );
325 // -----------------------------------------------------------------------------
327 void DropTargetHelper::ImplEndDrag()
329 mpFormats->clear();
332 // -----------------------------------------------------------------------------
334 sal_Int8 DropTargetHelper::AcceptDrop( const AcceptDropEvent& )
336 return( DNDConstants::ACTION_NONE );
339 // -----------------------------------------------------------------------------
341 sal_Int8 DropTargetHelper::ExecuteDrop( const ExecuteDropEvent& )
343 return( DNDConstants::ACTION_NONE );
346 // -----------------------------------------------------------------------------
348 sal_Bool DropTargetHelper::IsDropFormatSupported( SotFormatStringId nFormat )
350 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
351 sal_Bool bRet = sal_False;
353 while( aIter != aEnd )
355 if( nFormat == (*aIter++).mnSotId )
357 bRet = sal_True;
358 aIter = aEnd;
362 return bRet;
365 // -----------------------------------------------------------------------------
367 sal_Bool DropTargetHelper::IsDropFormatSupported( const DataFlavor& rFlavor )
369 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
370 sal_Bool bRet = sal_False;
372 while( aIter != aEnd )
374 if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
376 bRet = sal_True;
377 aIter = aEnd;
381 return bRet;
384 // -----------------------------------------------------------------------------
385 // TransferDataContainer
386 // -----------------------------------------------------------------------------
388 struct TDataCntnrEntry_Impl
390 ::com::sun::star::uno::Any aAny;
391 SotFormatStringId nId;
394 // -----------------------------------------------------------------------------
396 typedef ::std::list< TDataCntnrEntry_Impl > TDataCntnrEntryList;
398 // -----------------------------------------------------------------------------
400 struct TransferDataContainer_Impl
402 TDataCntnrEntryList aFmtList;
403 Link aFinshedLnk;
404 INetBookmark* pBookmk;
405 Graphic* pGrf;
407 TransferDataContainer_Impl()
408 : pBookmk( 0 ), pGrf( 0 )
412 ~TransferDataContainer_Impl()
414 delete pBookmk;
415 delete pGrf;
419 // -----------------------------------------------------------------------------
421 TransferDataContainer::TransferDataContainer()
422 : pImpl( new TransferDataContainer_Impl )
426 // -----------------------------------------------------------------------------
428 TransferDataContainer::~TransferDataContainer()
430 delete pImpl;
433 // -----------------------------------------------------------------------------
435 void TransferDataContainer::AddSupportedFormats()
439 // -----------------------------------------------------------------------------
441 sal_Bool TransferDataContainer::GetData( const
442 ::com::sun::star::datatransfer::DataFlavor& rFlavor )
444 TDataCntnrEntryList::iterator aIter( pImpl->aFmtList.begin() ),
445 aEnd( pImpl->aFmtList.end() );
446 sal_Bool bFnd = sal_False;
447 ULONG nFmtId = SotExchange::GetFormat( rFlavor );
449 // test first the list
450 for( ; aIter != aEnd; ++aIter )
452 TDataCntnrEntry_Impl& rEntry = (TDataCntnrEntry_Impl&)*aIter;
453 if( nFmtId == rEntry.nId )
455 bFnd = SetAny( rEntry.aAny, rFlavor );
456 break;
460 // test second the bookmark pointer
461 if( !bFnd )
462 switch( nFmtId )
464 case SOT_FORMAT_STRING:
465 case SOT_FORMATSTR_ID_SOLK:
466 case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK:
467 case SOT_FORMATSTR_ID_FILECONTENT:
468 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
469 case SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR:
470 if( pImpl->pBookmk )
471 bFnd = SetINetBookmark( *pImpl->pBookmk, rFlavor );
472 break;
474 case SOT_FORMATSTR_ID_SVXB:
475 case SOT_FORMAT_BITMAP:
476 case SOT_FORMAT_GDIMETAFILE:
477 if( pImpl->pGrf )
478 bFnd = SetGraphic( *pImpl->pGrf, rFlavor );
479 break;
482 return bFnd;
485 // -----------------------------------------------------------------------------
487 void TransferDataContainer::ClearData()
489 delete pImpl;
490 pImpl = new TransferDataContainer_Impl;
491 ClearFormats();
494 // -----------------------------------------------------------------------------
496 void TransferDataContainer::CopyINetBookmark( const INetBookmark& rBkmk )
498 if( !pImpl->pBookmk )
499 pImpl->pBookmk = new INetBookmark( rBkmk );
500 else
501 *pImpl->pBookmk = rBkmk;
503 AddFormat( SOT_FORMAT_STRING );
504 AddFormat( SOT_FORMATSTR_ID_SOLK );
505 AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK );
506 AddFormat( SOT_FORMATSTR_ID_FILECONTENT );
507 AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR );
508 AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR );
511 // -----------------------------------------------------------------------------
513 void TransferDataContainer::CopyAnyData( ULONG nFormatId,
514 const sal_Char* pData, ULONG nLen )
516 if( nLen )
518 TDataCntnrEntry_Impl aEntry;
519 aEntry.nId = nFormatId;
521 Sequence< sal_Int8 > aSeq( nLen );
522 memcpy( aSeq.getArray(), pData, nLen );
523 aEntry.aAny <<= aSeq;
524 pImpl->aFmtList.push_back( aEntry );
525 AddFormat( nFormatId );
529 // -----------------------------------------------------------------------------
531 void TransferDataContainer::CopyByteString( ULONG nFormatId,
532 const ByteString& rStr )
534 CopyAnyData( nFormatId, rStr.GetBuffer(), rStr.Len() );
537 // -----------------------------------------------------------------------------
539 void TransferDataContainer::CopyINetImage( const INetImage& rINtImg )
541 SvMemoryStream aMemStm( 1024, 1024 );
542 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
543 rINtImg.Write( aMemStm, SOT_FORMATSTR_ID_INET_IMAGE );
544 CopyAnyData( SOT_FORMATSTR_ID_INET_IMAGE, (sal_Char*)aMemStm.GetData(),
545 aMemStm.Seek( STREAM_SEEK_TO_END ) );
548 // -----------------------------------------------------------------------------
550 void TransferDataContainer::CopyImageMap( const ImageMap& rImgMap )
552 SvMemoryStream aMemStm( 8192, 8192 );
553 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
554 rImgMap.Write( aMemStm, String() );
555 CopyAnyData( SOT_FORMATSTR_ID_SVIM, (sal_Char*)aMemStm.GetData(),
556 aMemStm.Seek( STREAM_SEEK_TO_END ) );
559 // -----------------------------------------------------------------------------
561 void TransferDataContainer::CopyGraphic( const Graphic& rGrf )
563 GraphicType nType = rGrf.GetType();
564 if( GRAPHIC_NONE != nType )
566 if( !pImpl->pGrf )
567 pImpl->pGrf = new Graphic( rGrf );
568 else
569 *pImpl->pGrf = rGrf;
571 AddFormat( SOT_FORMATSTR_ID_SVXB );
572 if( GRAPHIC_BITMAP == nType )
573 AddFormat( SOT_FORMAT_BITMAP );
574 else if( GRAPHIC_GDIMETAFILE == nType )
575 AddFormat( SOT_FORMAT_GDIMETAFILE );
579 // -----------------------------------------------------------------------------
581 void TransferDataContainer::CopyString( USHORT nFmt, const String& rStr )
583 if( rStr.Len() )
585 TDataCntnrEntry_Impl aEntry;
586 aEntry.nId = nFmt;
587 rtl::OUString aStr( rStr );
588 aEntry.aAny <<= aStr;
589 pImpl->aFmtList.push_back( aEntry );
590 AddFormat( aEntry.nId );
594 // -----------------------------------------------------------------------------
596 void TransferDataContainer::CopyString( const String& rStr )
598 CopyString( SOT_FORMAT_STRING, rStr );
601 // -----------------------------------------------------------------------------
603 void TransferDataContainer::CopyAny( USHORT nFmt,
604 const ::com::sun::star::uno::Any& rAny )
606 TDataCntnrEntry_Impl aEntry;
607 aEntry.nId = nFmt;
608 aEntry.aAny = rAny;
609 pImpl->aFmtList.push_back( aEntry );
610 AddFormat( aEntry.nId );
613 // -----------------------------------------------------------------------------
615 sal_Bool TransferDataContainer::HasAnyData() const
617 return pImpl->aFmtList.begin() != pImpl->aFmtList.end() ||
618 0 != pImpl->pBookmk;
621 // -----------------------------------------------------------------------------
623 void TransferDataContainer::StartDrag(
624 Window* pWindow, sal_Int8 nDragSourceActions,
625 const Link& rLnk, sal_Int32 nDragPointer, sal_Int32 nDragImage )
627 pImpl->aFinshedLnk = rLnk;
628 TransferableHelper::StartDrag( pWindow, nDragSourceActions,
629 nDragPointer, nDragImage );
632 // -----------------------------------------------------------------------------
634 void TransferDataContainer::DragFinished( sal_Int8 nDropAction )
636 if( pImpl->aFinshedLnk.IsSet() )
637 pImpl->aFinshedLnk.Call( &nDropAction );