1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: transfer.cxx,v $
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"
34 #include <tools/prewin.h>
36 #pragma warning(push, 1)
37 #pragma warning(disable: 4917)
43 #include <tools/postwin.h>
45 #include <vos/mutex.hxx>
46 #include <rtl/memory.h>
49 #include <tools/debug.hxx>
52 #include <tools/urlobj.hxx>
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>
73 #ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPE_HPP_
74 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
76 #include <com/sun/star/frame/XDesktop.hpp>
77 #include <com/sun/star/lang/XInitialization.hpp>
80 #include "inetimg.hxx"
81 #include <svtools/wmf.hxx>
82 #include <svtools/imap.hxx>
83 #include <svtools/transfer.hxx>
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
;
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;
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
;
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
);
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
;
174 if( rObjDesc
.maTypeName
.Len() )
176 aParams
+= ::rtl::OUString::createFromAscii( ";typename=\"" );
177 aParams
+= rObjDesc
.maTypeName
;
181 if( rObjDesc
.maDisplayName
.Len() )
183 aParams
+= ::rtl::OUString::createFromAscii( ";displayname=\"" );
184 aParams
+= rObjDesc
.maDisplayName
;
188 aParams
+= ::rtl::OUString::createFromAscii( ";viewaspect=\"" );
189 aParams
+= ::rtl::OUString::valueOf( static_cast< sal_Int32
>( rObjDesc
.mnViewAspect
) );
192 aParams
+= ::rtl::OUString::createFromAscii( ";width=\"" );
193 aParams
+= ::rtl::OUString::valueOf( rObjDesc
.maSize
.Width() );
196 aParams
+= ::rtl::OUString::createFromAscii( ";height=\"" );
197 aParams
+= ::rtl::OUString::valueOf( rObjDesc
.maSize
.Height() );
200 aParams
+= ::rtl::OUString::createFromAscii( ";posx=\"" );
201 aParams
+= ::rtl::OUString::valueOf( rObjDesc
.maDragStartPos
.X() );
204 aParams
+= ::rtl::OUString::createFromAscii( ";posy=\"" );
205 aParams
+= ::rtl::OUString::valueOf( rObjDesc
.maDragStartPos
.X() );
211 // -----------------------------------------------------------------------------
213 static void ImplSetParameterString( TransferableObjectDescriptor
& rObjDesc
, const DataFlavorEx
& rFlavorEx
)
215 Reference
< XMultiServiceFactory
> xFact( ::comphelper::getProcessServiceFactory() );
216 Reference
< XMimeContentTypeFactory
> xMimeFact
;
222 xMimeFact
= Reference
< XMimeContentTypeFactory
>( xFact
->createInstance( ::rtl::OUString::createFromAscii(
223 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
229 Reference
< XMimeContentType
> xMimeType( xMimeFact
->createMimeContentType( rFlavorEx
.MimeType
) );
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
),
333 // -----------------------------------------------------------------------------
335 TransferableHelper::~TransferableHelper()
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
;
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
);
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
;
387 SvMemoryStream
* pSrcStm
= new SvMemoryStream( (char*) aSeq
.getConstArray(), aSeq
.getLength(), STREAM_WRITE
| STREAM_TRUNC
);
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
) ) );
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
;
417 SvMemoryStream
* pSrcStm
= new SvMemoryStream( (char*) aSeq
.getConstArray(), aSeq
.getLength(), STREAM_WRITE
| STREAM_TRUNC
);
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
) ) );
436 // reset Any if substitute doesn't work
437 if( !bDone
&& maAny
.hasValue() )
440 // if any is not yet filled, use standard format
441 if( !maAny
.hasValue() )
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() );
449 catch( const ::com::sun::star::uno::Exception
& )
453 if( !maAny
.hasValue() )
454 throw UnsupportedFlavorException();
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
++;
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
) )
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() );
533 Reference
< XDesktop
> xDesktop( xFact
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY
);
536 xDesktop
->removeTerminateListener( mxTerminateListener
);
539 mxTerminateListener
= Reference
< XTerminateListener
>();
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
);
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
)
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));
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
)
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
);
666 fprintf( stderr
, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
667 ByteString( String( aIter
->MimeType
), RTL_TEXTENCODING_ASCII_US
).GetBuffer() );
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
)
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();
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
)
754 // -----------------------------------------------------------------------------
756 void TransferableHelper::ClearFormats()
762 // -----------------------------------------------------------------------------
764 sal_Bool
TransferableHelper::SetAny( const Any
& rAny
, const DataFlavor
& )
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;
791 return( maAny
.hasValue() );
794 // -----------------------------------------------------------------------------
796 sal_Bool
TransferableHelper::SetBitmap( const Bitmap
& rBitmap
, const DataFlavor
& )
798 if( !rBitmap
.IsEmpty() )
800 SvMemoryStream
aMemStm( 65535, 65535 );
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
);
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
& )
861 SvMemoryStream
aMemStm( 1024, 1024 );
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() );
893 case( FORMAT_STRING
):
894 maAny
<<= ::rtl::OUString( rBmk
.GetURL() );
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() );
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() );
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 ];
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 );
936 strcpy( rFDesc1
.cFileName
, aStr
.GetBuffer() );
942 case SOT_FORMATSTR_ID_FILECONTENT
:
944 String
aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
945 maAny
<<= ::rtl::OUString( aStr
+= rBmk
.GetURL() );
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
);
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
& )
1025 return( maAny
.hasValue() );
1028 // -----------------------------------------------------------------------------
1030 sal_Bool
TransferableHelper::WriteObject( SotStorageStreamRef
&, void*, sal_uInt32
, const DataFlavor
& )
1032 DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
1036 // -----------------------------------------------------------------------------
1038 void TransferableHelper::DragFinished( sal_Int8
)
1042 // -----------------------------------------------------------------------------
1044 void TransferableHelper::ObjectReleased()
1048 // -----------------------------------------------------------------------------
1050 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor
& rObjDesc
)
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
;
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() );
1083 Reference
< XDesktop
> xDesktop( xFact
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY
);
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
;
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() );
1120 Reference
< XDesktop
> xDesktop( xFact
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY
);
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
1160 #if !defined(QUARTZ)
1161 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
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
);
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();
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
);
1220 rtl_createUuid( reinterpret_cast< sal_uInt8
* >( aSeq
.getArray() ), 0, sal_True
);
1227 // ---------------------------------
1228 // - TransferableClipboardNotifier -
1229 // ---------------------------------
1231 class TransferableClipboardNotifier
: public ::cppu::WeakImplHelper1
< XClipboardListener
>
1234 ::osl::Mutex
& mrMutex
;
1235 Reference
< XClipboardNotifier
> mxNotifier
;
1236 TransferableDataHelper
* mpListener
;
1239 // XClipboardListener
1240 virtual void SAL_CALL
changedContents( const clipboard::ClipboardEvent
& event
) throw (RuntimeException
);
1243 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
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
1258 // -----------------------------------------------------------------------------
1260 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference
< XClipboard
>& _rxClipboard
, TransferableDataHelper
& _rListener
, ::osl::Mutex
& _rMutex
)
1262 ,mxNotifier( _rxClipboard
, UNO_QUERY
)
1263 ,mpListener( &_rListener
)
1265 osl_incrementInterlockedCount( &m_refCount
);
1267 if ( mxNotifier
.is() )
1268 mxNotifier
->addClipboardListener( this );
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
);
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.
1298 // -----------------------------------------------------------------------------
1300 void TransferableClipboardNotifier::dispose()
1302 ::osl::MutexGuard
aGuard( mrMutex
);
1304 Reference
< XClipboardListener
> xKeepMeAlive( this );
1306 if ( mxNotifier
.is() )
1307 mxNotifier
->removeClipboardListener( this );
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
)
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();
1386 // -----------------------------------------------------------------------------
1388 TransferableDataHelper::~TransferableDataHelper()
1390 StopClipboardListening( );
1392 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1393 delete mpFormats
, mpFormats
= NULL
;
1394 delete mpObjDesc
, mpObjDesc
= NULL
;
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" ) );
1412 xMimeFact
= Reference
< XMimeContentTypeFactory
>( xFact
->createInstance( ::rtl::OUString::createFromAscii(
1413 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
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
);
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
);
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
)
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
++ ) )
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" );
1598 if( nFormat
< mpFormats
->size() )
1599 aRet
= (*mpFormats
)[ nFormat
];
1604 // -----------------------------------------------------------------------------
1606 Reference
< XTransferable
> TransferableDataHelper::GetXTransferable() const
1608 Reference
< XTransferable
> xRet
;
1610 if( mxTransfer
.is() )
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
>();
1629 // -----------------------------------------------------------------------------
1631 Any
TransferableDataHelper::GetAny( SotFormatStringId nFormat
) const
1636 if ( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) )
1637 aReturn
= GetAny( aFlavor
);
1643 // -----------------------------------------------------------------------------
1645 Any
TransferableDataHelper::GetAny( const DataFlavor
& rFlavor
) const
1647 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
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() )
1672 if( !aRet
.hasValue() )
1673 aRet
= mxTransfer
->getTransferData( rFlavor
);
1676 catch( const ::com::sun::star::uno::Exception
& )
1683 // -----------------------------------------------------------------------------
1685 sal_Bool
TransferableDataHelper::GetString( SotFormatStringId nFormat
, String
& rStr
)
1687 ::rtl::OUString aOUString
;
1688 sal_Bool bRet
= GetString( nFormat
, aOUString
);
1695 // -----------------------------------------------------------------------------
1697 sal_Bool
TransferableDataHelper::GetString( const DataFlavor
& rFlavor
, String
& rStr
)
1699 ::rtl::OUString aOUString
;
1700 sal_Bool bRet
= GetString( rFlavor
, aOUString
);
1707 // -----------------------------------------------------------------------------
1709 sal_Bool
TransferableDataHelper::GetString( SotFormatStringId nFormat
, ::rtl::OUString
& rStr
)
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
)
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 ) ) )
1743 rStr
= ::rtl::OUString( pChars
, nLen
, gsl_getSystemTextEncoding() );
1751 // -----------------------------------------------------------------------------
1753 sal_Bool
TransferableDataHelper::GetBitmap( SotFormatStringId nFormat
, Bitmap
& rBmp
)
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
);
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
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
);
1794 HasFormat( SOT_FORMATSTR_ID_BMP
) &&
1795 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP
, aSubstFlavor
) &&
1796 GetSotStorageStream( aSubstFlavor
, xStm
) )
1800 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1806 // -----------------------------------------------------------------------------
1808 sal_Bool
TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat
, GDIMetaFile
& rMtf
)
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
) )
1825 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1829 HasFormat( SOT_FORMATSTR_ID_EMF
) &&
1830 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF
, aSubstFlavor
) &&
1831 GetSotStorageStream( aSubstFlavor
, xStm
) )
1835 if( GraphicConverter::Import( *xStm
, aGraphic
) == ERRCODE_NONE
)
1837 rMtf
= aGraphic
.GetGDIMetaFile();
1843 HasFormat( SOT_FORMATSTR_ID_WMF
) &&
1844 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF
, aSubstFlavor
) &&
1845 GetSotStorageStream( aSubstFlavor
, xStm
) )
1849 if( GraphicConverter::Import( *xStm
, aGraphic
) == ERRCODE_NONE
)
1851 rMtf
= aGraphic
.GetGDIMetaFile();
1859 // -----------------------------------------------------------------------------
1861 sal_Bool
TransferableDataHelper::GetGraphic( SotFormatStringId nFormat
, Graphic
& rGraphic
)
1864 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetGraphic( aFlavor
, rGraphic
) );
1867 // -----------------------------------------------------------------------------
1869 sal_Bool
TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
, Graphic
& rGraphic
)
1872 sal_Bool bRet
= sal_False
;
1874 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP
, aFlavor
) &&
1875 TransferableDataHelper::IsEqual( aFlavor
, rFlavor
) )
1879 if( ( bRet
= GetBitmap( aFlavor
, aBmp
) ) == sal_True
)
1882 else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE
, aFlavor
) &&
1883 TransferableDataHelper::IsEqual( aFlavor
, rFlavor
) )
1887 if( ( bRet
= GetGDIMetaFile( aFlavor
, aMtf
) ) == sal_True
)
1892 SotStorageStreamRef xStm
;
1894 if( GetSotStorageStream( rFlavor
, xStm
) )
1897 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1904 // -----------------------------------------------------------------------------
1906 sal_Bool
TransferableDataHelper::GetImageMap( SotFormatStringId nFormat
, ImageMap
& rIMap
)
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
);
1921 rIMap
.Read( *xStm
, String() );
1922 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1928 // -----------------------------------------------------------------------------
1930 sal_Bool
TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat
, TransferableObjectDescriptor
& rDesc
)
1933 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetTransferableObjectDescriptor( aFlavor
, rDesc
) );
1936 // -----------------------------------------------------------------------------
1938 sal_Bool
TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor
&, TransferableObjectDescriptor
& rDesc
)
1944 // -----------------------------------------------------------------------------
1946 sal_Bool
TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat
, INetBookmark
& rBmk
)
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
);
1962 case( SOT_FORMATSTR_ID_SOLK
):
1963 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
):
1966 if( GetString( rFlavor
, aString
) )
1968 if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
== nFormat
)
1970 rBmk
= INetBookmark( aString
, aString
);
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
);
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() ) );
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
),
2041 if( !pStream
|| pStream
->GetError() )
2043 DataFlavor aFileContentFlavor
;
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
);
2060 sal_Bool bSttFnd
= sal_False
;
2062 while( pStream
->ReadLine( aLine
) )
2064 if( aLine
.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
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
) );
2089 // -----------------------------------------------------------------------------
2091 sal_Bool
TransferableDataHelper::GetINetImage( SotFormatStringId nFormat
,
2092 INetImage
& rINtImg
)
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
);
2108 bRet
= rINtImg
.Read( *xStm
, SotExchange::GetFormat( rFlavor
) );
2112 // -----------------------------------------------------------------------------
2114 sal_Bool
TransferableDataHelper::GetFileList( SotFormatStringId nFormat
,
2115 FileList
& rFileList
)
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
) );
2149 bRet
= ( ( *xStm
>> rFileList
).GetError() == ERRCODE_NONE
);
2157 // -----------------------------------------------------------------------------
2159 sal_Bool
TransferableDataHelper::GetSequence( SotFormatStringId nFormat
, Sequence
< sal_Int8
>& rSeq
)
2162 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetSequence( aFlavor
, rSeq
) );
2165 // -----------------------------------------------------------------------------
2167 sal_Bool
TransferableDataHelper::GetSequence( const DataFlavor
& rFlavor
, Sequence
< sal_Int8
>& rSeq
)
2170 fprintf( stderr
, "TransferableDataHelper requests sequence of data\n" );
2173 const Any
aAny( GetAny( rFlavor
) );
2174 return( aAny
.hasValue() && ( aAny
>>= rSeq
) );
2177 // -----------------------------------------------------------------------------
2179 sal_Bool
TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat
, SotStorageStreamRef
& rxStream
)
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
);
2194 rxStream
= new SotStorageStream( String() );
2195 rxStream
->Write( aSeq
.getConstArray(), aSeq
.getLength() );
2196 rxStream
->Seek( 0 );
2202 sal_Bool
TransferableDataHelper::GetInputStream( SotFormatStringId nFormat
, Reference
< XInputStream
>& rxStream
)
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
);
2216 rxStream
= new ::comphelper::SequenceInputStream( aSeq
);
2221 // -----------------------------------------------------------------------------
2224 sal_Bool
TransferableDataHelper::GetInterface( SotFormatStringId nFormat
, Reference
< XInterface
>& rIf
)
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
;
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
;
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
& )
2308 // -----------------------------------------------------------------------------
2310 TransferableDataHelper
TransferableDataHelper::CreateFromSelection( Window
* pWindow
)
2312 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
2314 Reference
< XClipboard
> xSelection
;
2315 TransferableDataHelper aRet
;
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
);
2344 // -----------------------------------------------------------------------------
2345 sal_Bool
TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor
& rInternalFlavor
,
2346 const ::com::sun::star::datatransfer::DataFlavor
& rRequestFlavor
,
2349 Reference
< XMultiServiceFactory
> xFact( ::comphelper::getProcessServiceFactory() );
2350 Reference
< XMimeContentTypeFactory
> xMimeFact
;
2351 sal_Bool bRet
= sal_False
;
2356 xMimeFact
= Reference
< XMimeContentTypeFactory
>( xFact
->createInstance( ::rtl::OUString::createFromAscii(
2357 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
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" ) ) )
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
) ) )
2399 catch( const ::com::sun::star::uno::Exception
& )
2401 bRet
= rInternalFlavor
.MimeType
.equalsIgnoreAsciiCase( rRequestFlavor
.MimeType
);