merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / misc / transfer.cxx
blob38d9cdecf1987a14c9e781e8c0689b0976c8e7c7
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: transfer.cxx,v $
10 * $Revision: 1.81 $
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 #ifdef WNT
34 #include <tools/prewin.h>
35 #if defined _MSC_VER
36 #pragma warning(push, 1)
37 #pragma warning(disable: 4917)
38 #endif
39 #include <shlobj.h>
40 #if defined _MSC_VER
41 #pragma warning(pop)
42 #endif
43 #include <tools/postwin.h>
44 #endif
45 #include <vos/mutex.hxx>
46 #include <rtl/memory.h>
47 #include <rtl/uuid.h>
48 #ifndef DEBUG_HXX
49 #include <tools/debug.hxx>
50 #endif
51 #ifndef URLOBJ_HXX
52 #include <tools/urlobj.hxx>
53 #endif
54 #include <unotools/ucbstreamhelper.hxx>
55 #include <sot/exchange.hxx>
56 #include <sot/storage.hxx>
57 #include <vcl/bitmap.hxx>
58 #include <vcl/gdimtf.hxx>
59 #include <vcl/graph.hxx>
60 #include <vcl/cvtgrf.hxx>
61 #include <vcl/svapp.hxx>
62 #include <vcl/window.hxx>
63 #include <comphelper/processfactory.hxx>
64 #include <sot/filelist.hxx>
65 #include <cppuhelper/implbase1.hxx>
67 #include <comphelper/seqstream.hxx>
68 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
69 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
70 #ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPEFACTORY_HPP_
71 #include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
72 #endif
73 #ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPE_HPP_
74 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
75 #endif
76 #include <com/sun/star/frame/XDesktop.hpp>
77 #include <com/sun/star/lang/XInitialization.hpp>
79 #include "urlbmk.hxx"
80 #include "inetimg.hxx"
81 #include <svtools/wmf.hxx>
82 #include <svtools/imap.hxx>
83 #include <svtools/transfer.hxx>
84 #include <cstdio>
86 // --------------
87 // - Namespaces -
88 // --------------
90 using namespace ::com::sun::star::uno;
91 using namespace ::com::sun::star::lang;
92 using namespace ::com::sun::star::frame;
93 using namespace ::com::sun::star::io;
94 using namespace ::com::sun::star::datatransfer;
95 using namespace ::com::sun::star::datatransfer::clipboard;
96 using namespace ::com::sun::star::datatransfer::dnd;
98 // --------------------------------
99 // - TransferableObjectDescriptor -
100 // --------------------------------
102 #define TOD_SIG1 0x01234567
103 #define TOD_SIG2 0x89abcdef
105 SvStream& operator>>( SvStream& rIStm, TransferableObjectDescriptor& rObjDesc )
107 sal_uInt32 nSize, nViewAspect, nSig1, nSig2;
109 rIStm >> nSize;
110 rIStm >> rObjDesc.maClassName;
111 rIStm >> nViewAspect;
112 rIStm >> rObjDesc.maSize.Width();
113 rIStm >> rObjDesc.maSize.Height();
114 rIStm >> rObjDesc.maDragStartPos.X();
115 rIStm >> rObjDesc.maDragStartPos.Y();
116 rIStm.ReadByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
117 rIStm.ReadByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
118 rIStm >> nSig1 >> nSig2;
120 rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( nViewAspect );
122 // don't use width/height info from external objects
123 if( ( TOD_SIG1 != nSig1 ) || ( TOD_SIG2 != nSig2 ) )
125 rObjDesc.maSize.Width() = 0;
126 rObjDesc.maSize.Height() = 0;
129 return rIStm;
132 // -----------------------------------------------------------------------------
134 SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc )
136 const sal_uInt32 nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect;
137 const sal_uInt32 nSig1 = TOD_SIG1, nSig2 = TOD_SIG2;
139 rOStm.SeekRel( 4 );
140 rOStm << rObjDesc.maClassName;
141 rOStm << nViewAspect;
142 rOStm << rObjDesc.maSize.Width();
143 rOStm << rObjDesc.maSize.Height();
144 rOStm << rObjDesc.maDragStartPos.X();
145 rOStm << rObjDesc.maDragStartPos.Y();
146 rOStm.WriteByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
147 rOStm.WriteByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
148 rOStm << nSig1 << nSig2;
150 const sal_uInt32 nLastPos = rOStm.Tell();
152 rOStm.Seek( nFirstPos );
153 rOStm << ( nLastPos - nFirstPos );
154 rOStm.Seek( nLastPos );
156 return rOStm;
159 // -----------------------------------------------------------------------------
161 static ::rtl::OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc )
163 const ::rtl::OUString aChar( ::rtl::OUString::createFromAscii( "\"" ) );
164 const ::rtl::OUString aClassName( rObjDesc.maClassName.GetHexName() );
165 ::rtl::OUString aParams;
167 if( aClassName.getLength() )
169 aParams += ::rtl::OUString::createFromAscii( ";classname=\"" );
170 aParams += aClassName;
171 aParams += aChar;
174 if( rObjDesc.maTypeName.Len() )
176 aParams += ::rtl::OUString::createFromAscii( ";typename=\"" );
177 aParams += rObjDesc.maTypeName;
178 aParams += aChar;
181 if( rObjDesc.maDisplayName.Len() )
183 aParams += ::rtl::OUString::createFromAscii( ";displayname=\"" );
184 aParams += rObjDesc.maDisplayName;
185 aParams += aChar;
188 aParams += ::rtl::OUString::createFromAscii( ";viewaspect=\"" );
189 aParams += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rObjDesc.mnViewAspect ) );
190 aParams += aChar;
192 aParams += ::rtl::OUString::createFromAscii( ";width=\"" );
193 aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Width() );
194 aParams += aChar;
196 aParams += ::rtl::OUString::createFromAscii( ";height=\"" );
197 aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Height() );
198 aParams += aChar;
200 aParams += ::rtl::OUString::createFromAscii( ";posx=\"" );
201 aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
202 aParams += aChar;
204 aParams += ::rtl::OUString::createFromAscii( ";posy=\"" );
205 aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
206 aParams += aChar;
208 return aParams;
211 // -----------------------------------------------------------------------------
213 static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, const DataFlavorEx& rFlavorEx )
215 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
216 Reference< XMimeContentTypeFactory > xMimeFact;
220 if( xFact.is() )
222 xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
223 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
224 UNO_QUERY );
227 if( xMimeFact.is() )
229 Reference< XMimeContentType > xMimeType( xMimeFact->createMimeContentType( rFlavorEx.MimeType ) );
231 if( xMimeType.is() )
233 const ::rtl::OUString aClassNameString( ::rtl::OUString::createFromAscii( "classname" ) );
234 const ::rtl::OUString aTypeNameString( ::rtl::OUString::createFromAscii( "typename" ) );
235 const ::rtl::OUString aDisplayNameString( ::rtl::OUString::createFromAscii( "displayname" ) );
236 const ::rtl::OUString aViewAspectString( ::rtl::OUString::createFromAscii( "viewaspect" ) );
237 const ::rtl::OUString aWidthString( ::rtl::OUString::createFromAscii( "width" ) );
238 const ::rtl::OUString aHeightString( ::rtl::OUString::createFromAscii( "height" ) );
239 const ::rtl::OUString aPosXString( ::rtl::OUString::createFromAscii( "posx" ) );
240 const ::rtl::OUString aPosYString( ::rtl::OUString::createFromAscii( "posy" ) );
242 if( xMimeType->hasParameter( aClassNameString ) )
244 rObjDesc.maClassName.MakeId( xMimeType->getParameterValue( aClassNameString ) );
247 if( xMimeType->hasParameter( aTypeNameString ) )
249 rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString );
252 if( xMimeType->hasParameter( aDisplayNameString ) )
254 rObjDesc.maDisplayName = xMimeType->getParameterValue( aDisplayNameString );
257 if( xMimeType->hasParameter( aViewAspectString ) )
259 rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( xMimeType->getParameterValue( aViewAspectString ).toInt32() );
262 if( xMimeType->hasParameter( aWidthString ) )
264 rObjDesc.maSize.Width() = xMimeType->getParameterValue( aWidthString ).toInt32();
267 if( xMimeType->hasParameter( aHeightString ) )
269 rObjDesc.maSize.Height() = xMimeType->getParameterValue( aHeightString ).toInt32();
272 if( xMimeType->hasParameter( aPosXString ) )
274 rObjDesc.maDragStartPos.X() = xMimeType->getParameterValue( aPosXString ).toInt32();
277 if( xMimeType->hasParameter( aPosYString ) )
279 rObjDesc.maDragStartPos.Y() = xMimeType->getParameterValue( aPosYString ).toInt32();
284 catch( const ::com::sun::star::uno::Exception& )
289 // -----------------------------------------
290 // - TransferableHelper::TerminateListener -
291 // -----------------------------------------
293 TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
294 mrParent( rTransferableHelper )
298 // -----------------------------------------------------------------------------
300 TransferableHelper::TerminateListener::~TerminateListener()
304 // -----------------------------------------------------------------------------
306 void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
310 // -----------------------------------------------------------------------------
312 void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
316 // -----------------------------------------------------------------------------
318 void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
320 mrParent.ImplFlush();
323 // ----------------------
324 // - TransferableHelper -
325 // ----------------------
327 TransferableHelper::TransferableHelper() :
328 mpFormats( new DataFlavorExVector ),
329 mpObjDesc( NULL )
333 // -----------------------------------------------------------------------------
335 TransferableHelper::~TransferableHelper()
337 delete mpObjDesc;
338 delete mpFormats;
341 // -----------------------------------------------------------------------------
343 Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) throw( UnsupportedFlavorException, IOException, RuntimeException )
345 if( !maAny.hasValue() || !mpFormats->size() || ( maLastFormat != rFlavor.MimeType ) )
347 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
349 maLastFormat = rFlavor.MimeType;
350 maAny = Any();
354 DataFlavor aSubstFlavor;
355 sal_Bool bDone = sal_False;
357 // add formats if not already done
358 if( !mpFormats->size() )
359 AddSupportedFormats();
361 // check alien formats first and try to get a substitution format
362 if( SotExchange::GetFormatDataFlavor( FORMAT_STRING, aSubstFlavor ) &&
363 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) )
365 GetData( aSubstFlavor );
366 bDone = maAny.hasValue();
368 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
369 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
370 SotExchange::GetFormatDataFlavor( FORMAT_BITMAP, aSubstFlavor ) )
372 GetData( aSubstFlavor );
373 bDone = sal_True;
375 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
376 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
377 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
379 GetData( aSubstFlavor );
381 if( maAny.hasValue() )
383 Sequence< sal_Int8 > aSeq;
385 if( maAny >>= aSeq )
387 SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
388 GDIMetaFile aMtf;
390 *pSrcStm >> aMtf;
391 delete pSrcStm;
393 Graphic aGraphic( aMtf );
394 SvMemoryStream aDstStm( 65535, 65535 );
396 if( GraphicConverter::Export( aDstStm, aGraphic, CVT_EMF ) == ERRCODE_NONE )
398 maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
399 aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
400 bDone = sal_True;
405 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
406 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
407 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
409 GetData( aSubstFlavor );
411 if( maAny.hasValue() )
413 Sequence< sal_Int8 > aSeq;
415 if( maAny >>= aSeq )
417 SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
418 GDIMetaFile aMtf;
420 *pSrcStm >> aMtf;
421 delete pSrcStm;
423 SvMemoryStream aDstStm( 65535, 65535 );
425 // taking wmf without file header
426 if ( ConvertGDIMetaFileToWMF( aMtf, aDstStm, NULL, FALSE ) )
428 maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
429 aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
430 bDone = sal_True;
436 // reset Any if substitute doesn't work
437 if( !bDone && maAny.hasValue() )
438 maAny = Any();
440 // if any is not yet filled, use standard format
441 if( !maAny.hasValue() )
442 GetData( rFlavor );
444 #ifdef DEBUG
445 if( maAny.hasValue() && ::com::sun::star::uno::TypeClass_STRING != maAny.getValueType().getTypeClass() )
446 fprintf( stderr, "TransferableHelper delivers sequence of data [ %s ]\n", ByteString( String( rFlavor.MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
447 #endif
449 catch( const ::com::sun::star::uno::Exception& )
453 if( !maAny.hasValue() )
454 throw UnsupportedFlavorException();
457 return maAny;
460 // -----------------------------------------------------------------------------
462 Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() throw( RuntimeException )
464 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
468 if( !mpFormats->size() )
469 AddSupportedFormats();
471 catch( const ::com::sun::star::uno::Exception& )
475 Sequence< DataFlavor > aRet( mpFormats->size() );
476 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
477 sal_uInt32 nCurPos = 0;
479 while( aIter != aEnd )
481 aRet[ nCurPos++ ] = *aIter++;
484 return aRet;
487 // -----------------------------------------------------------------------------
489 sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) throw( RuntimeException )
491 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
492 sal_Bool bRet = sal_False;
496 if( !mpFormats->size() )
497 AddSupportedFormats();
499 catch( const ::com::sun::star::uno::Exception& )
503 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
505 while( aIter != aEnd )
507 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
509 aIter = aEnd;
510 bRet = sal_True;
512 else
513 aIter++;
516 return bRet;
519 // -----------------------------------------------------------------------------
521 void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) throw( RuntimeException )
523 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
527 if( mxTerminateListener.is() )
529 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
531 if( xFact.is() )
533 Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
535 if( xDesktop.is() )
536 xDesktop->removeTerminateListener( mxTerminateListener );
539 mxTerminateListener = Reference< XTerminateListener >();
542 ObjectReleased();
544 catch( const ::com::sun::star::uno::Exception& )
549 // -----------------------------------------------------------------------------
551 void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
555 // -----------------------------------------------------------------------------
557 void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
559 const ::vos::OGuard aGuard( Application::GetSolarMutex() );
563 DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
564 ObjectReleased();
566 catch( const ::com::sun::star::uno::Exception& )
571 // -----------------------------------------------------------------------------
573 void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
577 // -----------------------------------------------------------------------------
579 void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
583 // -----------------------------------------------------------------------------
585 void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
589 // -----------------------------------------------------------------------------
591 void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
595 // -----------------------------------------------------------------------------
597 sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
599 sal_Int64 nRet;
601 if( ( rId.getLength() == 16 ) &&
602 ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
604 nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
606 else
607 nRet = 0;
609 return nRet;
612 // -----------------------------------------------------------------------------
614 void TransferableHelper::ImplFlush()
616 if( mxClipboard.is() )
618 Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY );
619 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
623 if( xFlushableClipboard.is() )
624 xFlushableClipboard->flushClipboard();
626 catch( const ::com::sun::star::uno::Exception& )
628 DBG_ERROR( "Could not flush clipboard" );
631 Application::AcquireSolarMutex( nRef );
635 // -----------------------------------------------------------------------------
637 void TransferableHelper::AddFormat( SotFormatStringId nFormat )
639 DataFlavor aFlavor;
641 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
642 AddFormat( aFlavor );
645 // -----------------------------------------------------------------------------
647 void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
649 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
650 sal_Bool bAdd = sal_True;
652 while( aIter != aEnd )
654 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
656 // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
657 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId ) && mpObjDesc )
659 DataFlavor aObjDescFlavor;
661 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDescFlavor );
662 aIter->MimeType = aObjDescFlavor.MimeType;
663 aIter->MimeType += ::ImplGetParameterString( *mpObjDesc );
665 #ifdef DEBUG
666 fprintf( stderr, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
667 ByteString( String( aIter->MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
668 #endif
671 aIter = aEnd;
672 bAdd = sal_False;
674 else
675 aIter++;
678 if( bAdd )
680 DataFlavorEx aFlavorEx;
681 DataFlavor aObjDescFlavor;
683 aFlavorEx.MimeType = rFlavor.MimeType;
684 aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
685 aFlavorEx.DataType = rFlavor.DataType;
686 aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
688 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aFlavorEx.mnSotId ) && mpObjDesc )
689 aFlavorEx.MimeType += ::ImplGetParameterString( *mpObjDesc );
691 mpFormats->push_back( aFlavorEx );
693 if( FORMAT_BITMAP == aFlavorEx.mnSotId )
695 AddFormat( SOT_FORMATSTR_ID_BMP );
697 else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
699 AddFormat( SOT_FORMATSTR_ID_EMF );
700 AddFormat( SOT_FORMATSTR_ID_WMF );
705 // -----------------------------------------------------------------------------
707 void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
709 DataFlavor aFlavor;
711 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
712 RemoveFormat( aFlavor );
715 // -----------------------------------------------------------------------------
717 void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
719 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
721 while( aIter != aEnd )
723 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
725 aIter = mpFormats->erase( aIter );
726 aEnd = mpFormats->end();
728 else
729 ++aIter;
733 // -----------------------------------------------------------------------------
735 sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
737 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
738 sal_Bool bRet = sal_False;
740 while( aIter != aEnd )
742 if( nFormat == (*aIter).mnSotId )
744 aIter = aEnd;
745 bRet = sal_True;
747 else
748 ++aIter;
751 return bRet;
754 // -----------------------------------------------------------------------------
756 void TransferableHelper::ClearFormats()
758 mpFormats->clear();
759 maAny.clear();
762 // -----------------------------------------------------------------------------
764 sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
766 maAny = rAny;
767 return( maAny.hasValue() );
770 // -----------------------------------------------------------------------------
772 sal_Bool TransferableHelper::SetString( const ::rtl::OUString& rString, const DataFlavor& rFlavor )
774 DataFlavor aFileFlavor;
776 if( rString.getLength() &&
777 SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
778 TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
780 const String aString( rString );
781 const ByteString aByteStr( aString, gsl_getSystemTextEncoding() );
782 Sequence< sal_Int8 > aSeq( aByteStr.Len() + 1 );
784 rtl_copyMemory( aSeq.getArray(), aByteStr.GetBuffer(), aByteStr.Len() );
785 aSeq[ aByteStr.Len() ] = 0;
786 maAny <<= aSeq;
788 else
789 maAny <<= rString;
791 return( maAny.hasValue() );
794 // -----------------------------------------------------------------------------
796 sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& )
798 if( !rBitmap.IsEmpty() )
800 SvMemoryStream aMemStm( 65535, 65535 );
802 aMemStm << rBitmap;
803 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
806 return( maAny.hasValue() );
809 // -----------------------------------------------------------------------------
811 sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
813 if( rMtf.GetActionCount() )
815 SvMemoryStream aMemStm( 65535, 65535 );
817 ( (GDIMetaFile&) rMtf ).Write( aMemStm );
818 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
821 return( maAny.hasValue() );
824 // -----------------------------------------------------------------------------
826 sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
828 if( rGraphic.GetType() != GRAPHIC_NONE )
830 SvMemoryStream aMemStm( 65535, 65535 );
832 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
833 aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
834 aMemStm << rGraphic;
835 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
838 return( maAny.hasValue() );
841 // -----------------------------------------------------------------------------
843 sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
845 SvMemoryStream aMemStm( 8192, 8192 );
847 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
848 rIMap.Write( aMemStm, String() );
849 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
851 return( maAny.hasValue() );
854 // -----------------------------------------------------------------------------
856 sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
857 const ::com::sun::star::datatransfer::DataFlavor& )
859 PrepareOLE( rDesc );
861 SvMemoryStream aMemStm( 1024, 1024 );
863 aMemStm << rDesc;
864 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
866 return( maAny.hasValue() );
869 // -----------------------------------------------------------------------------
871 sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
872 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
874 rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
876 switch( SotExchange::GetFormat( rFlavor ) )
878 case( SOT_FORMATSTR_ID_SOLK ):
880 ByteString sURL( rBmk.GetURL(), eSysCSet ),
881 sDesc( rBmk.GetDescription(), eSysCSet );
882 ByteString sOut( ByteString::CreateFromInt32( sURL.Len() ));
883 ( sOut += '@' ) += sURL;
884 sOut += ByteString::CreateFromInt32( sDesc.Len() );
885 ( sOut += '@' ) += sDesc;
887 Sequence< sal_Int8 > aSeq( sOut.Len() );
888 memcpy( aSeq.getArray(), sOut.GetBuffer(), sOut.Len() );
889 maAny <<= aSeq;
891 break;
893 case( FORMAT_STRING ):
894 maAny <<= ::rtl::OUString( rBmk.GetURL() );
895 break;
897 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
899 ByteString sURL( rBmk.GetURL(), eSysCSet );
900 Sequence< sal_Int8 > aSeq( sURL.Len() );
901 memcpy( aSeq.getArray(), sURL.GetBuffer(), sURL.Len() );
902 maAny <<= aSeq;
904 break;
906 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
908 Sequence< sal_Int8 > aSeq( 2048 );
910 memset( aSeq.getArray(), 0, 2048 );
911 strcpy( reinterpret_cast< char* >( aSeq.getArray() ), ByteString( rBmk.GetURL(), eSysCSet).GetBuffer() );
912 strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, ByteString( rBmk.GetDescription(), eSysCSet ).GetBuffer() );
914 maAny <<= aSeq;
916 break;
918 #ifdef WNT
919 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
921 Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
922 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
923 FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
925 pFDesc->cItems = 1;
926 memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
927 rFDesc1.dwFlags = FD_LINKUI;
929 ByteString aStr( rBmk.GetDescription(), eSysCSet );
930 for( USHORT nChar = 0; nChar < aStr.Len(); ++nChar )
931 if( strchr( "\\/:*?\"<>|", aStr.GetChar( nChar ) ) )
932 aStr.Erase( nChar--, 1 );
934 aStr.Insert( "Shortcut to ", 0 );
935 aStr += ".URL";
936 strcpy( rFDesc1.cFileName, aStr.GetBuffer() );
938 maAny <<= aSeq;
940 break;
942 case SOT_FORMATSTR_ID_FILECONTENT:
944 String aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
945 maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
947 break;
948 #endif
950 default:
951 break;
954 return( maAny.hasValue() );
957 // -----------------------------------------------------------------------------
959 sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
960 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
962 SvMemoryStream aMemStm( 1024, 1024 );
964 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
965 rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
967 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
969 return( maAny.hasValue() );
972 // -----------------------------------------------------------------------------
974 sal_Bool TransferableHelper::SetFileList( const FileList& rFileList,
975 const ::com::sun::star::datatransfer::DataFlavor& )
977 SvMemoryStream aMemStm( 4096, 4096 );
979 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
980 aMemStm << rFileList;
982 maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
983 aMemStm.Seek( STREAM_SEEK_TO_END ) );
985 return( maAny.hasValue() );
988 // -----------------------------------------------------------------------------
990 sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
992 SotStorageStreamRef xStm( new SotStorageStream( String() ) );
994 xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
996 if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
998 const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
999 Sequence< sal_Int8 > aSeq( nLen );
1001 xStm->Seek( STREAM_SEEK_TO_BEGIN );
1002 xStm->Read( aSeq.getArray(), nLen );
1004 if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
1006 //JP 24.7.2001: as I know was this only for the writer application and this
1007 // writes now UTF16 format into the stream
1008 //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
1009 // little / big endians! - Bug 88121
1010 maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
1012 else
1013 maAny <<= aSeq;
1016 return( maAny.hasValue() );
1019 // -----------------------------------------------------------------------------
1021 sal_Bool TransferableHelper::SetInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rIf,
1022 const ::com::sun::star::datatransfer::DataFlavor& )
1024 maAny <<= rIf;
1025 return( maAny.hasValue() );
1028 // -----------------------------------------------------------------------------
1030 sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
1032 DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
1033 return sal_False;
1036 // -----------------------------------------------------------------------------
1038 void TransferableHelper::DragFinished( sal_Int8 )
1042 // -----------------------------------------------------------------------------
1044 void TransferableHelper::ObjectReleased()
1048 // -----------------------------------------------------------------------------
1050 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
1052 delete mpObjDesc;
1053 mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
1055 if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
1056 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
1059 // -----------------------------------------------------------------------------
1061 void TransferableHelper::CopyToClipboard( Window *pWindow ) const
1063 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1064 Reference< XClipboard > xClipboard;
1066 if( pWindow )
1067 xClipboard = pWindow->GetClipboard();
1069 if( xClipboard.is() )
1070 mxClipboard = xClipboard;
1072 if( mxClipboard.is() && !mxTerminateListener.is() )
1074 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1078 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1079 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1081 if( xFact.is() )
1083 Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1085 if( xDesktop.is() )
1086 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1089 mxClipboard->setContents( pThis, pThis );
1091 catch( const ::com::sun::star::uno::Exception& )
1095 Application::AcquireSolarMutex( nRef );
1099 // -----------------------------------------------------------------------------
1101 void TransferableHelper::CopyToSelection( Window *pWindow ) const
1103 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1104 Reference< XClipboard > xSelection;
1106 if( pWindow )
1107 xSelection = pWindow->GetPrimarySelection();
1109 if( xSelection.is() && !mxTerminateListener.is() )
1111 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1115 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1116 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1118 if( xFact.is() )
1120 Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1122 if( xDesktop.is() )
1123 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1126 xSelection->setContents( pThis, pThis );
1128 catch( const ::com::sun::star::uno::Exception& )
1132 Application::AcquireSolarMutex( nRef );
1136 // -----------------------------------------------------------------------------
1138 void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
1139 sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
1142 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1143 Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
1145 if( xDragSource.is() )
1148 * #96792# release mouse before actually starting DnD.
1149 * This is necessary for the X11 DnD implementation to work.
1151 if( pWindow->IsMouseCaptured() )
1152 pWindow->ReleaseMouse();
1154 const Point aPt( pWindow->GetPointerPosPixel() );
1156 // On Mac OS X we are forced to execute 'startDrag' synchronously
1157 // contrary to the XDragSource interface specification because
1158 // we can receive drag events from the system only in the main
1159 // thread
1160 #if !defined(QUARTZ)
1161 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1162 #endif
1166 DragGestureEvent aEvt;
1167 aEvt.DragAction = DNDConstants::ACTION_COPY;
1168 aEvt.DragOriginX = aPt.X();
1169 aEvt.DragOriginY = aPt.Y();
1170 aEvt.DragSource = xDragSource;
1172 xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
1174 catch( const ::com::sun::star::uno::Exception& )
1178 // See above for the reason of this define
1179 #if !defined(QUARTZ)
1180 Application::AcquireSolarMutex( nRef );
1181 #endif
1185 // -----------------------------------------------------------------------------
1187 void TransferableHelper::ClearSelection( Window *pWindow )
1189 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1190 Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
1192 if( xSelection.is() )
1193 xSelection->setContents( NULL, NULL );
1196 // -----------------------------------------------------------------------------
1198 Reference< XClipboard> TransferableHelper::GetSystemClipboard()
1200 Window *pFocusWindow = Application::GetFocusWindow();
1202 if( pFocusWindow )
1203 return pFocusWindow->GetClipboard();
1205 return Reference< XClipboard > ();
1208 // -----------------------------------------------------------------------------
1210 const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
1212 static Sequence< sal_Int8 > aSeq;
1214 if( !aSeq.getLength() )
1216 static osl::Mutex aCreateMutex;
1217 osl::Guard< osl::Mutex > aGuard( aCreateMutex );
1219 aSeq.realloc( 16 );
1220 rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
1224 return aSeq;
1227 // ---------------------------------
1228 // - TransferableClipboardNotifier -
1229 // ---------------------------------
1231 class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
1233 private:
1234 ::osl::Mutex& mrMutex;
1235 Reference< XClipboardNotifier > mxNotifier;
1236 TransferableDataHelper* mpListener;
1238 protected:
1239 // XClipboardListener
1240 virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
1242 // XEventListener
1243 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
1245 public:
1246 TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
1248 /// determines whether we're currently listening
1249 inline bool isListening() const { return !isDisposed(); }
1251 /// determines whether the instance is disposed
1252 inline bool isDisposed() const { return mpListener == NULL; }
1254 /// makes the instance non-functional
1255 void dispose();
1258 // -----------------------------------------------------------------------------
1260 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
1261 :mrMutex( _rMutex )
1262 ,mxNotifier( _rxClipboard, UNO_QUERY )
1263 ,mpListener( &_rListener )
1265 osl_incrementInterlockedCount( &m_refCount );
1267 if ( mxNotifier.is() )
1268 mxNotifier->addClipboardListener( this );
1269 else
1270 // born dead
1271 mpListener = NULL;
1273 osl_decrementInterlockedCount( &m_refCount );
1276 // -----------------------------------------------------------------------------
1278 void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
1280 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1281 // the SolarMutex here is necessary, since
1282 // - we cannot call mpListener without our own mutex locked
1283 // - Rebind respectively InitFormats (called by Rebind) will
1284 // try to lock the SolarMutex, too
1285 ::osl::MutexGuard aGuard( mrMutex );
1286 if( mpListener )
1287 mpListener->Rebind( event.Contents );
1290 // -----------------------------------------------------------------------------
1292 void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
1294 // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1295 dispose();
1298 // -----------------------------------------------------------------------------
1300 void TransferableClipboardNotifier::dispose()
1302 ::osl::MutexGuard aGuard( mrMutex );
1304 Reference< XClipboardListener > xKeepMeAlive( this );
1306 if ( mxNotifier.is() )
1307 mxNotifier->removeClipboardListener( this );
1308 mxNotifier.clear();
1310 mpListener = NULL;
1313 // -------------------------------
1314 // - TransferableDataHelper_Impl -
1315 // -------------------------------
1317 struct TransferableDataHelper_Impl
1319 ::osl::Mutex maMutex;
1320 TransferableClipboardNotifier* mpClipboardListener;
1322 TransferableDataHelper_Impl()
1323 :mpClipboardListener( NULL )
1328 // --------------------------
1329 // - TransferableDataHelper -
1330 // --------------------------
1332 TransferableDataHelper::TransferableDataHelper() :
1333 mpFormats( new DataFlavorExVector ),
1334 mpObjDesc( new TransferableObjectDescriptor ),
1335 mpImpl( new TransferableDataHelper_Impl )
1339 // -----------------------------------------------------------------------------
1341 TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
1342 mxTransfer( rxTransferable ),
1343 mpFormats( new DataFlavorExVector ),
1344 mpObjDesc( new TransferableObjectDescriptor ),
1345 mpImpl( new TransferableDataHelper_Impl )
1347 InitFormats();
1350 // -----------------------------------------------------------------------------
1352 TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
1353 mxTransfer( rDataHelper.mxTransfer ),
1354 mxClipboard( rDataHelper.mxClipboard ),
1355 mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
1356 mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
1357 mpImpl( new TransferableDataHelper_Impl )
1361 // -----------------------------------------------------------------------------
1363 TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
1365 if ( this != &rDataHelper )
1367 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1369 bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
1371 if ( bWasClipboardListening )
1372 StopClipboardListening();
1374 mxTransfer = rDataHelper.mxTransfer;
1375 delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
1376 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
1377 mxClipboard = rDataHelper.mxClipboard;
1379 if ( bWasClipboardListening )
1380 StartClipboardListening();
1383 return *this;
1386 // -----------------------------------------------------------------------------
1388 TransferableDataHelper::~TransferableDataHelper()
1390 StopClipboardListening( );
1392 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1393 delete mpFormats, mpFormats = NULL;
1394 delete mpObjDesc, mpObjDesc = NULL;
1396 delete mpImpl;
1399 // -----------------------------------------------------------------------------
1401 void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
1402 DataFlavorExVector& rDataFlavorExVector )
1406 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1407 Reference< XMimeContentTypeFactory > xMimeFact;
1408 DataFlavorEx aFlavorEx;
1409 const ::rtl::OUString aCharsetStr( ::rtl::OUString::createFromAscii( "charset" ) );
1411 if( xFact.is() )
1412 xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
1413 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
1414 UNO_QUERY );
1416 for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
1418 const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
1419 Reference< XMimeContentType > xMimeType;
1423 if( xMimeFact.is() && rFlavor.MimeType.getLength() )
1424 xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
1426 catch( const ::com::sun::star::uno::Exception& )
1431 aFlavorEx.MimeType = rFlavor.MimeType;
1432 aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
1433 aFlavorEx.DataType = rFlavor.DataType;
1434 aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
1436 rDataFlavorExVector.push_back( aFlavorEx );
1438 // add additional formats for special mime types
1439 if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId )
1441 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
1443 aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
1444 rDataFlavorExVector.push_back( aFlavorEx );
1447 else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
1449 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
1451 aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
1452 rDataFlavorExVector.push_back( aFlavorEx );
1455 else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
1457 // #104735# HTML_SIMPLE may also be inserted without comments
1458 aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
1459 rDataFlavorExVector.push_back( aFlavorEx );
1461 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
1463 // add, if it is a UTF-8 byte buffer
1464 if( xMimeType->hasParameter( aCharsetStr ) )
1466 const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
1468 if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) ||
1469 xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) )
1471 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
1476 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/rtf" ) ) )
1478 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
1480 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/html" ) ) )
1483 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
1485 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) )
1487 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
1489 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice-objectdescriptor-xml" ) ) )
1491 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
1495 catch( const ::com::sun::star::uno::Exception& )
1500 // -----------------------------------------------------------------------------
1502 void TransferableDataHelper::InitFormats()
1504 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1505 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1507 mpFormats->clear();
1508 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
1510 if( mxTransfer.is() )
1512 TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
1514 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1516 while( aIter != aEnd )
1518 if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
1520 ImplSetParameterString( *mpObjDesc, *aIter );
1521 aIter = aEnd;
1523 else
1524 ++aIter;
1529 // -----------------------------------------------------------------------------
1531 sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
1533 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1535 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1536 sal_Bool bRet = sal_False;
1538 while( aIter != aEnd )
1540 if( nFormat == (*aIter++).mnSotId )
1542 aIter = aEnd;
1543 bRet = sal_True;
1547 return bRet;
1550 // -----------------------------------------------------------------------------
1552 sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
1554 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1556 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1557 sal_Bool bRet = sal_False;
1559 while( aIter != aEnd )
1561 if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
1563 aIter = aEnd;
1564 bRet = sal_True;
1568 return bRet;
1571 // -----------------------------------------------------------------------------
1573 sal_uInt32 TransferableDataHelper::GetFormatCount() const
1575 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1576 return mpFormats->size();
1579 // -----------------------------------------------------------------------------
1582 SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
1584 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1585 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1586 return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
1589 // -----------------------------------------------------------------------------
1591 DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
1593 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1594 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1596 DataFlavor aRet;
1598 if( nFormat < mpFormats->size() )
1599 aRet = (*mpFormats)[ nFormat ];
1601 return aRet;
1604 // -----------------------------------------------------------------------------
1606 Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
1608 Reference< XTransferable > xRet;
1610 if( mxTransfer.is() )
1614 xRet = mxTransfer;
1616 // do a dummy call to check, if this interface is valid (nasty)
1617 Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
1620 catch( const ::com::sun::star::uno::Exception& )
1622 xRet = Reference< XTransferable >();
1626 return xRet;
1629 // -----------------------------------------------------------------------------
1631 Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
1633 Any aReturn;
1635 DataFlavor aFlavor;
1636 if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
1637 aReturn = GetAny( aFlavor );
1639 return aReturn;
1643 // -----------------------------------------------------------------------------
1645 Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
1647 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1648 Any aRet;
1652 if( mxTransfer.is() )
1654 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1655 const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
1657 if( nRequestFormat )
1659 // try to get alien format first
1660 while( aIter != aEnd )
1662 if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
1663 aRet = mxTransfer->getTransferData( *aIter );
1665 if( aRet.hasValue() )
1666 aIter = aEnd;
1667 else
1668 aIter++;
1672 if( !aRet.hasValue() )
1673 aRet = mxTransfer->getTransferData( rFlavor );
1676 catch( const ::com::sun::star::uno::Exception& )
1680 return aRet;
1683 // -----------------------------------------------------------------------------
1685 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
1687 ::rtl::OUString aOUString;
1688 sal_Bool bRet = GetString( nFormat, aOUString );
1690 rStr = aOUString;
1692 return bRet;
1695 // -----------------------------------------------------------------------------
1697 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
1699 ::rtl::OUString aOUString;
1700 sal_Bool bRet = GetString( rFlavor, aOUString );
1702 rStr = aOUString;
1704 return bRet;
1707 // -----------------------------------------------------------------------------
1709 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
1711 DataFlavor aFlavor;
1712 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
1715 // -----------------------------------------------------------------------------
1717 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
1719 Any aAny( GetAny( rFlavor ) );
1720 sal_Bool bRet = sal_False;
1722 if( aAny.hasValue() )
1724 ::rtl::OUString aOUString;
1725 Sequence< sal_Int8 > aSeq;
1727 if( aAny >>= aOUString )
1729 rStr = aOUString;
1730 bRet = sal_True;
1732 else if( aAny >>= aSeq )
1735 const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
1736 sal_Int32 nLen = aSeq.getLength();
1738 //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1739 //DVO 2002-05-27: strip _all_ trailing zeros
1740 while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
1741 --nLen;
1743 rStr = ::rtl::OUString( pChars, nLen, gsl_getSystemTextEncoding() );
1744 bRet = sal_True;
1748 return bRet;
1751 // -----------------------------------------------------------------------------
1753 sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp )
1755 DataFlavor aFlavor;
1756 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) );
1759 // -----------------------------------------------------------------------------
1761 sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp )
1763 SotStorageStreamRef xStm;
1764 DataFlavor aSubstFlavor;
1765 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1767 if( bRet )
1769 *xStm >> rBmp;
1770 bRet = ( xStm->GetError() == ERRCODE_NONE );
1772 /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1773 problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1774 and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1775 Due to this reason the following code assumes that bitmaps with a logical size
1776 greater than 50 cm aren't having the correct mapmode set.
1778 The following code should be removed if DDBs and DIBs are supported via clipboard
1779 properly.
1781 if ( bRet )
1783 MapMode aMapMode = rBmp.GetPrefMapMode();
1784 if ( aMapMode.GetMapUnit() != MAP_PIXEL )
1786 Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM );
1787 if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) )
1788 rBmp.SetPrefMapMode( MAP_PIXEL );
1793 if( !bRet &&
1794 HasFormat( SOT_FORMATSTR_ID_BMP ) &&
1795 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
1796 GetSotStorageStream( aSubstFlavor, xStm ) )
1798 xStm->ResetError();
1799 *xStm >> rBmp;
1800 bRet = ( xStm->GetError() == ERRCODE_NONE );
1803 return bRet;
1806 // -----------------------------------------------------------------------------
1808 sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
1810 DataFlavor aFlavor;
1811 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
1814 // -----------------------------------------------------------------------------
1816 sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
1818 SotStorageStreamRef xStm;
1819 DataFlavor aSubstFlavor;
1820 sal_Bool bRet = sal_False;
1822 if( GetSotStorageStream( rFlavor, xStm ) )
1824 *xStm >> rMtf;
1825 bRet = ( xStm->GetError() == ERRCODE_NONE );
1828 if( !bRet &&
1829 HasFormat( SOT_FORMATSTR_ID_EMF ) &&
1830 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
1831 GetSotStorageStream( aSubstFlavor, xStm ) )
1833 Graphic aGraphic;
1835 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1837 rMtf = aGraphic.GetGDIMetaFile();
1838 bRet = TRUE;
1842 if( !bRet &&
1843 HasFormat( SOT_FORMATSTR_ID_WMF ) &&
1844 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
1845 GetSotStorageStream( aSubstFlavor, xStm ) )
1847 Graphic aGraphic;
1849 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1851 rMtf = aGraphic.GetGDIMetaFile();
1852 bRet = TRUE;
1856 return bRet;
1859 // -----------------------------------------------------------------------------
1861 sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
1863 DataFlavor aFlavor;
1864 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
1867 // -----------------------------------------------------------------------------
1869 sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
1871 DataFlavor aFlavor;
1872 sal_Bool bRet = sal_False;
1874 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
1875 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1877 Bitmap aBmp;
1879 if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True )
1880 rGraphic = aBmp;
1882 else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
1883 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1885 GDIMetaFile aMtf;
1887 if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
1888 rGraphic = aMtf;
1890 else
1892 SotStorageStreamRef xStm;
1894 if( GetSotStorageStream( rFlavor, xStm ) )
1896 *xStm >> rGraphic;
1897 bRet = ( xStm->GetError() == ERRCODE_NONE );
1901 return bRet;
1904 // -----------------------------------------------------------------------------
1906 sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
1908 DataFlavor aFlavor;
1909 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
1912 // -----------------------------------------------------------------------------
1914 sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
1916 SotStorageStreamRef xStm;
1917 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1919 if( bRet )
1921 rIMap.Read( *xStm, String() );
1922 bRet = ( xStm->GetError() == ERRCODE_NONE );
1925 return bRet;
1928 // -----------------------------------------------------------------------------
1930 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
1932 DataFlavor aFlavor;
1933 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
1936 // -----------------------------------------------------------------------------
1938 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
1940 rDesc = *mpObjDesc;
1941 return true;
1944 // -----------------------------------------------------------------------------
1946 sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
1948 DataFlavor aFlavor;
1949 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
1952 // -----------------------------------------------------------------------------
1954 sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
1956 sal_Bool bRet = sal_False;
1957 if( HasFormat( rFlavor ))
1959 const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
1960 switch( nFormat )
1962 case( SOT_FORMATSTR_ID_SOLK ):
1963 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
1965 String aString;
1966 if( GetString( rFlavor, aString ) )
1968 if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
1970 rBmk = INetBookmark( aString, aString );
1971 bRet = sal_True;
1973 else
1975 String aURL, aDesc;
1976 sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
1978 if( !nLen && aString.GetChar( 0 ) != '0' )
1980 DBG_WARNING( "SOLK: 1. len=0" );
1982 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
1984 DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
1986 aURL = aString.Copy( nStart + 1, nLen );
1988 aString.Erase( 0, nStart + 1 + nLen );
1989 nStart = aString.Search( '@' );
1990 nLen = (sal_uInt16) aString.ToInt32();
1992 if( !nLen && aString.GetChar( 0 ) != '0' )
1994 DBG_WARNING( "SOLK: 2. len=0" );
1996 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
1998 DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
2000 aDesc = aString.Copy( nStart+1, nLen );
2002 rBmk = INetBookmark( aURL, aDesc );
2003 bRet = sal_True;
2007 break;
2009 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
2011 Sequence< sal_Int8 > aSeq;
2013 if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
2015 rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), gsl_getSystemTextEncoding() ),
2016 String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, gsl_getSystemTextEncoding() ) );
2017 bRet = sal_True;
2020 break;
2022 #ifdef WNT
2023 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
2025 Sequence< sal_Int8 > aSeq;
2027 if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
2029 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
2031 if( pFDesc->cItems )
2033 ByteString aDesc( pFDesc->fgd[ 0 ].cFileName );
2034 rtl_TextEncoding eTextEncoding = gsl_getSystemTextEncoding();
2036 if( ( aDesc.Len() > 4 ) && aDesc.Copy( aDesc.Len() - 4 ).EqualsIgnoreCaseAscii( ".URL" ) )
2038 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( String( aDesc, eTextEncoding ) ).GetMainURL( INetURLObject::NO_DECODE ),
2039 STREAM_STD_READ );
2041 if( !pStream || pStream->GetError() )
2043 DataFlavor aFileContentFlavor;
2045 aSeq.realloc( 0 );
2046 delete pStream;
2048 if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
2049 GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
2051 pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
2053 else
2054 pStream = NULL;
2057 if( pStream )
2059 ByteString aLine;
2060 sal_Bool bSttFnd = sal_False;
2062 while( pStream->ReadLine( aLine ) )
2064 if( aLine.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
2065 bSttFnd = sal_True;
2066 else if( bSttFnd && aLine.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "URL=" ) )
2068 rBmk = INetBookmark( String( aLine.Erase( 0, 4 ), eTextEncoding ),
2069 String( aDesc.Erase( aDesc.Len() - 4 ), eTextEncoding ) );
2070 bRet = sal_True;
2071 break;
2075 delete pStream;
2081 break;
2082 #endif
2086 return bRet;
2089 // -----------------------------------------------------------------------------
2091 sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
2092 INetImage& rINtImg )
2094 DataFlavor aFlavor;
2095 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
2098 // -----------------------------------------------------------------------------
2100 sal_Bool TransferableDataHelper::GetINetImage(
2101 const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
2102 INetImage& rINtImg )
2104 SotStorageStreamRef xStm;
2105 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2107 if( bRet )
2108 bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
2109 return bRet;
2112 // -----------------------------------------------------------------------------
2114 sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
2115 FileList& rFileList )
2117 DataFlavor aFlavor;
2118 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
2121 // -----------------------------------------------------------------------------
2123 sal_Bool TransferableDataHelper::GetFileList(
2124 const ::com::sun::star::datatransfer::DataFlavor&,
2125 FileList& rFileList )
2127 SotStorageStreamRef xStm;
2128 sal_Bool bRet = sal_False;
2130 for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
2132 if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
2134 const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
2136 if( GetSotStorageStream( aFlavor, xStm ) )
2138 if( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) > -1 )
2140 ByteString aByteString;
2142 while( xStm->ReadLine( aByteString ) )
2143 if( aByteString.Len() && aByteString.GetChar( 0 ) != '#' )
2144 rFileList.AppendFile( String( aByteString, RTL_TEXTENCODING_UTF8 ) );
2146 bRet = sal_True;
2148 else
2149 bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
2154 return bRet;
2157 // -----------------------------------------------------------------------------
2159 sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
2161 DataFlavor aFlavor;
2162 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
2165 // -----------------------------------------------------------------------------
2167 sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
2169 #ifdef DEBUG
2170 fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
2171 #endif
2173 const Any aAny( GetAny( rFlavor ) );
2174 return( aAny.hasValue() && ( aAny >>= rSeq ) );
2177 // -----------------------------------------------------------------------------
2179 sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
2181 DataFlavor aFlavor;
2182 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
2185 // -----------------------------------------------------------------------------
2187 sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
2189 Sequence< sal_Int8 > aSeq;
2190 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2192 if( bRet )
2194 rxStream = new SotStorageStream( String() );
2195 rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
2196 rxStream->Seek( 0 );
2199 return bRet;
2202 sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
2204 DataFlavor aFlavor;
2205 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
2208 // -----------------------------------------------------------------------------
2210 sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
2212 Sequence< sal_Int8 > aSeq;
2213 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2215 if( bRet )
2216 rxStream = new ::comphelper::SequenceInputStream( aSeq );
2218 return bRet;
2221 // -----------------------------------------------------------------------------
2224 sal_Bool TransferableDataHelper::GetInterface( SotFormatStringId nFormat, Reference< XInterface >& rIf )
2226 DataFlavor aFlavor;
2227 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInterface( aFlavor, rIf ) );
2230 // -----------------------------------------------------------------------------
2232 sal_Bool TransferableDataHelper::GetInterface( const DataFlavor& rFlavor, Reference< XInterface >& rIf )
2234 const Any aAny( GetAny( rFlavor ) );
2235 return( aAny.hasValue() && ( aAny >>= rIf ) );
2238 // -----------------------------------------------------------------------------
2239 void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
2241 mxTransfer = _rxNewContent;
2242 InitFormats();
2245 // -----------------------------------------------------------------------------
2247 sal_Bool TransferableDataHelper::StartClipboardListening( )
2249 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2251 StopClipboardListening( );
2253 mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
2254 mpImpl->mpClipboardListener->acquire();
2256 return mpImpl->mpClipboardListener->isListening();
2259 // -----------------------------------------------------------------------------
2261 void TransferableDataHelper::StopClipboardListening( )
2263 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2265 if ( mpImpl->mpClipboardListener )
2267 mpImpl->mpClipboardListener->dispose();
2268 mpImpl->mpClipboardListener->release();
2269 mpImpl->mpClipboardListener = NULL;
2273 // -----------------------------------------------------------------------------
2275 TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
2277 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2279 Reference< XClipboard > xClipboard;
2280 TransferableDataHelper aRet;
2282 if( pWindow )
2283 xClipboard = pWindow->GetClipboard();
2285 if( xClipboard.is() )
2290 Reference< XTransferable > xTransferable( xClipboard->getContents() );
2292 if( xTransferable.is() )
2294 aRet = TransferableDataHelper( xTransferable );
2295 aRet.mxClipboard = xClipboard;
2296 // also copy the clipboard - 99030 - 23.05.2002 - fs@openoffice.org
2299 catch( const ::com::sun::star::uno::Exception& )
2304 return aRet;
2308 // -----------------------------------------------------------------------------
2310 TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
2312 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2314 Reference< XClipboard > xSelection;
2315 TransferableDataHelper aRet;
2317 if( pWindow )
2318 xSelection = pWindow->GetPrimarySelection();
2320 if( xSelection.is() )
2322 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2326 Reference< XTransferable > xTransferable( xSelection->getContents() );
2328 if( xTransferable.is() )
2330 aRet = TransferableDataHelper( xTransferable );
2331 aRet.mxClipboard = xSelection;
2334 catch( const ::com::sun::star::uno::Exception& )
2338 Application::AcquireSolarMutex( nRef );
2341 return aRet;
2344 // -----------------------------------------------------------------------------
2345 sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
2346 const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
2347 sal_Bool )
2349 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
2350 Reference< XMimeContentTypeFactory > xMimeFact;
2351 sal_Bool bRet = sal_False;
2355 if( xFact.is() )
2356 xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
2357 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
2358 UNO_QUERY );
2360 if( xMimeFact.is() )
2362 Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
2363 Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2365 if( xRequestType1.is() && xRequestType2.is() )
2367 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2369 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
2371 // special handling for text/plain media types
2372 const ::rtl::OUString aCharsetString( ::rtl::OUString::createFromAscii( "charset" ) );
2374 if( !xRequestType2->hasParameter( aCharsetString ) ||
2375 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) ||
2376 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) )
2378 bRet = sal_True;
2381 else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice" ) ) )
2383 // special handling for application/x-openoffice media types
2384 const ::rtl::OUString aFormatString( ::rtl::OUString::createFromAscii( "windows_formatname" ) );
2386 if( xRequestType1->hasParameter( aFormatString ) &&
2387 xRequestType2->hasParameter( aFormatString ) &&
2388 xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
2390 bRet = sal_True;
2393 else
2394 bRet = sal_True;
2399 catch( const ::com::sun::star::uno::Exception& )
2401 bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
2404 return bRet;