1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #include <osl/mutex.hxx>
26 #include <rtl/uri.hxx>
27 #include <tools/debug.hxx>
28 #include <tools/urlobj.hxx>
29 #include <unotools/ucbstreamhelper.hxx>
30 #include <sot/exchange.hxx>
31 #include <sot/storage.hxx>
32 #include <vcl/bitmap.hxx>
33 #include <vcl/gdimtf.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/cvtgrf.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/window.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/servicehelper.hxx>
40 #include <sot/filelist.hxx>
41 #include <cppuhelper/implbase1.hxx>
43 #include <comphelper/seqstream.hxx>
44 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
45 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
46 #include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp>
47 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
48 #include <com/sun/star/frame/Desktop.hpp>
49 #include <com/sun/star/lang/XInitialization.hpp>
51 #include "svl/urlbmk.hxx"
52 #include "inetimg.hxx"
53 #include <vcl/wmf.hxx>
54 #include <svtools/imap.hxx>
55 #include <svtools/transfer.hxx>
56 #include <rtl/strbuf.hxx>
63 using namespace ::com::sun::star::uno
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::frame
;
66 using namespace ::com::sun::star::io
;
67 using namespace ::com::sun::star::datatransfer
;
68 using namespace ::com::sun::star::datatransfer::clipboard
;
69 using namespace ::com::sun::star::datatransfer::dnd
;
71 // --------------------------------
72 // - TransferableObjectDescriptor -
73 // --------------------------------
75 #define TOD_SIG1 0x01234567
76 #define TOD_SIG2 0x89abcdef
78 SvStream
& operator>>( SvStream
& rIStm
, TransferableObjectDescriptor
& rObjDesc
)
80 sal_uInt32 nSize
, nViewAspect
, nSig1
, nSig2
;
81 //#fdo39428 Remove SvStream operator>>(long&)
85 rIStm
>> rObjDesc
.maClassName
;
88 rObjDesc
.maSize
.Width() = nTmp
;
90 rObjDesc
.maSize
.Height() = nTmp
;
92 rObjDesc
.maDragStartPos
.X() = nTmp
;
94 rObjDesc
.maDragStartPos
.Y() = nTmp
;
95 rObjDesc
.maTypeName
= rIStm
.ReadUniOrByteString(osl_getThreadTextEncoding());
96 rObjDesc
.maDisplayName
= rIStm
.ReadUniOrByteString(osl_getThreadTextEncoding());
98 rIStm
>> nSig1
>> nSig2
;
100 rObjDesc
.mnViewAspect
= static_cast< sal_uInt16
>( nViewAspect
);
102 // don't use width/height info from external objects
103 if( ( TOD_SIG1
!= nSig1
) || ( TOD_SIG2
!= nSig2
) )
105 rObjDesc
.maSize
.Width() = 0;
106 rObjDesc
.maSize
.Height() = 0;
112 // -----------------------------------------------------------------------------
114 SvStream
& operator<<( SvStream
& rOStm
, const TransferableObjectDescriptor
& rObjDesc
)
116 const sal_uInt32 nFirstPos
= rOStm
.Tell(), nViewAspect
= rObjDesc
.mnViewAspect
;
117 const sal_uInt32 nSig1
= TOD_SIG1
, nSig2
= TOD_SIG2
;
120 rOStm
<< rObjDesc
.maClassName
;
121 rOStm
<< nViewAspect
;
122 //#fdo39428 Remove SvStream operator<<(long)
123 rOStm
<< sal::static_int_cast
<sal_Int32
>(rObjDesc
.maSize
.Width());
124 rOStm
<< sal::static_int_cast
<sal_Int32
>(rObjDesc
.maSize
.Height());
125 rOStm
<< sal::static_int_cast
<sal_Int32
>(rObjDesc
.maDragStartPos
.X());
126 rOStm
<< sal::static_int_cast
<sal_Int32
>(rObjDesc
.maDragStartPos
.Y());
127 rOStm
.WriteUniOrByteString( rObjDesc
.maTypeName
, osl_getThreadTextEncoding() );
128 rOStm
.WriteUniOrByteString( rObjDesc
.maDisplayName
, osl_getThreadTextEncoding() );
129 rOStm
<< nSig1
<< nSig2
;
131 const sal_uInt32 nLastPos
= rOStm
.Tell();
133 rOStm
.Seek( nFirstPos
);
134 rOStm
<< ( nLastPos
- nFirstPos
);
135 rOStm
.Seek( nLastPos
);
140 // -----------------------------------------------------------------------------
141 // the reading of the parameter is done using the special service ::com::sun::star::datatransfer::MimeContentType,
142 // a similar approach should be implemented for creation of the mimetype string;
143 // for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype
145 static OUString
ImplGetParameterString( const TransferableObjectDescriptor
& rObjDesc
)
147 const OUString
aChar( "\"" );
148 const OUString
aClassName( rObjDesc
.maClassName
.GetHexName() );
151 if( !aClassName
.isEmpty() )
153 aParams
+= OUString( ";classname=\"" );
154 aParams
+= aClassName
;
158 if( !rObjDesc
.maTypeName
.isEmpty() )
160 aParams
+= OUString( ";typename=\"" );
161 aParams
+= rObjDesc
.maTypeName
;
165 if( !rObjDesc
.maDisplayName
.isEmpty() )
167 // the display name might contain unacceptable characters, encode all of them
168 // this seems to be the only parameter currently that might contain such characters
169 sal_Bool pToAccept
[128];
170 for ( sal_Int32 nBInd
= 0; nBInd
< 128; nBInd
++ )
171 pToAccept
[nBInd
] = sal_False
;
173 const char aQuotedParamChars
[] =
174 "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. ";
176 for ( sal_Int32 nInd
= 0; nInd
< RTL_CONSTASCII_LENGTH(aQuotedParamChars
); ++nInd
)
178 sal_Unicode nChar
= aQuotedParamChars
[nInd
];
180 pToAccept
[nChar
] = sal_True
;
183 aParams
+= OUString( ";displayname=\"" );
184 aParams
+= ::rtl::Uri::encode( rObjDesc
.maDisplayName
, pToAccept
, rtl_UriEncodeIgnoreEscapes
, RTL_TEXTENCODING_UTF8
);
188 aParams
+= OUString( ";viewaspect=\"" );
189 aParams
+= OUString::number( rObjDesc
.mnViewAspect
);
192 aParams
+= OUString( ";width=\"" );
193 aParams
+= OUString::valueOf( rObjDesc
.maSize
.Width() );
196 aParams
+= OUString( ";height=\"" );
197 aParams
+= OUString::valueOf( rObjDesc
.maSize
.Height() );
200 aParams
+= OUString( ";posx=\"" );
201 aParams
+= OUString::valueOf( rObjDesc
.maDragStartPos
.X() );
204 aParams
+= OUString( ";posy=\"" );
205 aParams
+= OUString::valueOf( rObjDesc
.maDragStartPos
.X() );
211 // -----------------------------------------------------------------------------
213 static void ImplSetParameterString( TransferableObjectDescriptor
& rObjDesc
, const DataFlavorEx
& rFlavorEx
)
215 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
219 Reference
< XMimeContentTypeFactory
> xMimeFact
= MimeContentTypeFactory::create( xContext
);
221 Reference
< XMimeContentType
> xMimeType( xMimeFact
->createMimeContentType( rFlavorEx
.MimeType
) );
225 const OUString
aClassNameString( "classname" );
226 const OUString
aTypeNameString( "typename" );
227 const OUString
aDisplayNameString( "displayname" );
228 const OUString
aViewAspectString( "viewaspect" );
229 const OUString
aWidthString( "width" );
230 const OUString
aHeightString( "height" );
231 const OUString
aPosXString( "posx" );
232 const OUString
aPosYString( "posy" );
234 if( xMimeType
->hasParameter( aClassNameString
) )
236 rObjDesc
.maClassName
.MakeId( xMimeType
->getParameterValue( aClassNameString
) );
239 if( xMimeType
->hasParameter( aTypeNameString
) )
241 rObjDesc
.maTypeName
= xMimeType
->getParameterValue( aTypeNameString
);
244 if( xMimeType
->hasParameter( aDisplayNameString
) )
246 // the display name might contain unacceptable characters, in this case they should be encoded
247 // this seems to be the only parameter currently that might contain such characters
248 rObjDesc
.maDisplayName
= ::rtl::Uri::decode( xMimeType
->getParameterValue( aDisplayNameString
), rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
251 if( xMimeType
->hasParameter( aViewAspectString
) )
253 rObjDesc
.mnViewAspect
= static_cast< sal_uInt16
>( xMimeType
->getParameterValue( aViewAspectString
).toInt32() );
256 if( xMimeType
->hasParameter( aWidthString
) )
258 rObjDesc
.maSize
.Width() = xMimeType
->getParameterValue( aWidthString
).toInt32();
261 if( xMimeType
->hasParameter( aHeightString
) )
263 rObjDesc
.maSize
.Height() = xMimeType
->getParameterValue( aHeightString
).toInt32();
266 if( xMimeType
->hasParameter( aPosXString
) )
268 rObjDesc
.maDragStartPos
.X() = xMimeType
->getParameterValue( aPosXString
).toInt32();
271 if( xMimeType
->hasParameter( aPosYString
) )
273 rObjDesc
.maDragStartPos
.Y() = xMimeType
->getParameterValue( aPosYString
).toInt32();
277 catch( const ::com::sun::star::uno::Exception
& )
282 // -----------------------------------------
283 // - TransferableHelper::TerminateListener -
284 // -----------------------------------------
286 TransferableHelper::TerminateListener::TerminateListener( TransferableHelper
& rTransferableHelper
) :
287 mrParent( rTransferableHelper
)
291 // -----------------------------------------------------------------------------
293 TransferableHelper::TerminateListener::~TerminateListener()
297 // -----------------------------------------------------------------------------
299 void SAL_CALL
TransferableHelper::TerminateListener::disposing( const EventObject
& ) throw( RuntimeException
)
303 // -----------------------------------------------------------------------------
305 void SAL_CALL
TransferableHelper::TerminateListener::queryTermination( const EventObject
& ) throw( TerminationVetoException
, RuntimeException
)
309 // -----------------------------------------------------------------------------
311 void SAL_CALL
TransferableHelper::TerminateListener::notifyTermination( const EventObject
& ) throw( RuntimeException
)
313 mrParent
.ImplFlush();
316 // ----------------------
317 // - TransferableHelper -
318 // ----------------------
320 TransferableHelper::TransferableHelper() :
321 mpFormats( new DataFlavorExVector
),
326 // -----------------------------------------------------------------------------
328 TransferableHelper::~TransferableHelper()
334 // -----------------------------------------------------------------------------
336 Any SAL_CALL
TransferableHelper::getTransferData( const DataFlavor
& rFlavor
) throw( UnsupportedFlavorException
, IOException
, RuntimeException
)
338 if( !maAny
.hasValue() || !mpFormats
->size() || ( maLastFormat
!= rFlavor
.MimeType
) )
340 const SolarMutexGuard aGuard
;
342 maLastFormat
= rFlavor
.MimeType
;
347 DataFlavor aSubstFlavor
;
348 sal_Bool bDone
= sal_False
;
350 // add formats if not already done
351 if( !mpFormats
->size() )
352 AddSupportedFormats();
354 // check alien formats first and try to get a substitution format
355 if( SotExchange::GetFormatDataFlavor( FORMAT_STRING
, aSubstFlavor
) &&
356 TransferableDataHelper::IsEqual( aSubstFlavor
, rFlavor
) )
358 GetData( aSubstFlavor
);
359 bDone
= maAny
.hasValue();
361 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP
, aSubstFlavor
) &&
362 TransferableDataHelper::IsEqual( aSubstFlavor
, rFlavor
) &&
363 SotExchange::GetFormatDataFlavor( FORMAT_BITMAP
, aSubstFlavor
) )
365 GetData( aSubstFlavor
);
368 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF
, aSubstFlavor
) &&
369 TransferableDataHelper::IsEqual( aSubstFlavor
, rFlavor
) &&
370 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE
, aSubstFlavor
) )
372 GetData( aSubstFlavor
);
374 if( maAny
.hasValue() )
376 Sequence
< sal_Int8
> aSeq
;
380 SvMemoryStream
* pSrcStm
= new SvMemoryStream( (char*) aSeq
.getConstArray(), aSeq
.getLength(), STREAM_WRITE
| STREAM_TRUNC
);
386 Graphic
aGraphic( aMtf
);
387 SvMemoryStream
aDstStm( 65535, 65535 );
389 if( GraphicConverter::Export( aDstStm
, aGraphic
, CVT_EMF
) == ERRCODE_NONE
)
391 maAny
<<= ( aSeq
= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aDstStm
.GetData() ),
392 aDstStm
.Seek( STREAM_SEEK_TO_END
) ) );
398 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF
, aSubstFlavor
) &&
399 TransferableDataHelper::IsEqual( aSubstFlavor
, rFlavor
) &&
400 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE
, aSubstFlavor
) )
402 GetData( aSubstFlavor
);
404 if( maAny
.hasValue() )
406 Sequence
< sal_Int8
> aSeq
;
410 SvMemoryStream
* pSrcStm
= new SvMemoryStream( (char*) aSeq
.getConstArray(), aSeq
.getLength(), STREAM_WRITE
| STREAM_TRUNC
);
416 SvMemoryStream
aDstStm( 65535, 65535 );
418 // taking wmf without file header
419 if ( ConvertGDIMetaFileToWMF( aMtf
, aDstStm
, NULL
, sal_False
) )
421 maAny
<<= ( aSeq
= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aDstStm
.GetData() ),
422 aDstStm
.Seek( STREAM_SEEK_TO_END
) ) );
429 // reset Any if substitute doesn't work
430 if( !bDone
&& maAny
.hasValue() )
433 // if any is not yet filled, use standard format
434 if( !maAny
.hasValue() )
438 if( maAny
.hasValue() && ::com::sun::star::uno::TypeClass_STRING
!= maAny
.getValueType().getTypeClass() )
439 fprintf( stderr
, "TransferableHelper delivers sequence of data [ %s ]\n", OUStringToOString(rFlavor
.MimeType
, RTL_TEXTENCODING_ASCII_US
).getStr() );
442 catch( const ::com::sun::star::uno::Exception
& )
446 if( !maAny
.hasValue() )
447 throw UnsupportedFlavorException();
453 // -----------------------------------------------------------------------------
455 Sequence
< DataFlavor
> SAL_CALL
TransferableHelper::getTransferDataFlavors() throw( RuntimeException
)
457 const SolarMutexGuard aGuard
;
461 if( !mpFormats
->size() )
462 AddSupportedFormats();
464 catch( const ::com::sun::star::uno::Exception
& )
468 Sequence
< DataFlavor
> aRet( mpFormats
->size() );
469 DataFlavorExVector::iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() );
470 sal_uInt32 nCurPos
= 0;
472 while( aIter
!= aEnd
)
474 aRet
[ nCurPos
++ ] = *aIter
++;
480 // -----------------------------------------------------------------------------
482 sal_Bool SAL_CALL
TransferableHelper::isDataFlavorSupported( const DataFlavor
& rFlavor
) throw( RuntimeException
)
484 const SolarMutexGuard aGuard
;
485 sal_Bool bRet
= sal_False
;
489 if( !mpFormats
->size() )
490 AddSupportedFormats();
492 catch( const ::com::sun::star::uno::Exception
& )
496 for (DataFlavorExVector::const_iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() ); aIter
!= aEnd
; ++aIter
)
498 if( TransferableDataHelper::IsEqual( *aIter
, rFlavor
) )
508 // -----------------------------------------------------------------------------
510 void SAL_CALL
TransferableHelper::lostOwnership( const Reference
< XClipboard
>&, const Reference
< XTransferable
>& ) throw( RuntimeException
)
512 const SolarMutexGuard aGuard
;
516 if( mxTerminateListener
.is() )
518 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
519 xDesktop
->removeTerminateListener( mxTerminateListener
);
521 mxTerminateListener
= Reference
< XTerminateListener
>();
526 catch( const ::com::sun::star::uno::Exception
& )
531 // -----------------------------------------------------------------------------
533 void SAL_CALL
TransferableHelper::disposing( const EventObject
& ) throw( RuntimeException
)
537 // -----------------------------------------------------------------------------
539 void SAL_CALL
TransferableHelper::dragDropEnd( const DragSourceDropEvent
& rDSDE
) throw( RuntimeException
)
541 const SolarMutexGuard aGuard
;
545 DragFinished( rDSDE
.DropSuccess
? ( rDSDE
.DropAction
& ~DNDConstants::ACTION_DEFAULT
) : DNDConstants::ACTION_NONE
);
548 catch( const ::com::sun::star::uno::Exception
& )
553 // -----------------------------------------------------------------------------
555 void SAL_CALL
TransferableHelper::dragEnter( const DragSourceDragEvent
& ) throw( RuntimeException
)
559 // -----------------------------------------------------------------------------
561 void SAL_CALL
TransferableHelper::dragExit( const DragSourceEvent
& ) throw( RuntimeException
)
565 // -----------------------------------------------------------------------------
567 void SAL_CALL
TransferableHelper::dragOver( const DragSourceDragEvent
& ) throw( RuntimeException
)
571 // -----------------------------------------------------------------------------
573 void SAL_CALL
TransferableHelper::dropActionChanged( const DragSourceDragEvent
& ) throw( RuntimeException
)
577 // -----------------------------------------------------------------------------
579 sal_Int64 SAL_CALL
TransferableHelper::getSomething( const Sequence
< sal_Int8
>& rId
) throw( RuntimeException
)
583 if( ( rId
.getLength() == 16 ) &&
584 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId
.getConstArray(), 16 ) ) )
586 nRet
= sal::static_int_cast
<sal_Int64
>(reinterpret_cast<sal_IntPtr
>(this));
594 // -----------------------------------------------------------------------------
596 void TransferableHelper::ImplFlush()
598 if( mxClipboard
.is() )
600 Reference
< XFlushableClipboard
> xFlushableClipboard( mxClipboard
, UNO_QUERY
);
601 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
605 if( xFlushableClipboard
.is() )
606 xFlushableClipboard
->flushClipboard();
608 catch( const ::com::sun::star::uno::Exception
& )
610 OSL_FAIL( "Could not flush clipboard" );
613 Application::AcquireSolarMutex( nRef
);
617 // -----------------------------------------------------------------------------
619 void TransferableHelper::AddFormat( SotFormatStringId nFormat
)
623 if( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) )
624 AddFormat( aFlavor
);
627 // -----------------------------------------------------------------------------
629 void TransferableHelper::AddFormat( const DataFlavor
& rFlavor
)
631 sal_Bool bAdd
= sal_True
;
633 for (DataFlavorExVector::iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() ); aIter
!= aEnd
; ++aIter
)
635 if( TransferableDataHelper::IsEqual( *aIter
, rFlavor
) )
637 // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
638 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
== aIter
->mnSotId
) && mpObjDesc
)
640 DataFlavor aObjDescFlavor
;
642 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDescFlavor
);
643 aIter
->MimeType
= aObjDescFlavor
.MimeType
;
644 aIter
->MimeType
+= ::ImplGetParameterString( *mpObjDesc
);
647 fprintf( stderr
, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
648 OUStringToOString(aIter
->MimeType
, RTL_TEXTENCODING_ASCII_US
).getStr() );
659 DataFlavorEx aFlavorEx
;
660 DataFlavor aObjDescFlavor
;
662 aFlavorEx
.MimeType
= rFlavor
.MimeType
;
663 aFlavorEx
.HumanPresentableName
= rFlavor
.HumanPresentableName
;
664 aFlavorEx
.DataType
= rFlavor
.DataType
;
665 aFlavorEx
.mnSotId
= SotExchange::RegisterFormat( rFlavor
);
667 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
== aFlavorEx
.mnSotId
) && mpObjDesc
)
668 aFlavorEx
.MimeType
+= ::ImplGetParameterString( *mpObjDesc
);
670 mpFormats
->push_back( aFlavorEx
);
672 if( FORMAT_BITMAP
== aFlavorEx
.mnSotId
)
674 AddFormat( SOT_FORMATSTR_ID_BMP
);
676 else if( FORMAT_GDIMETAFILE
== aFlavorEx
.mnSotId
)
678 AddFormat( SOT_FORMATSTR_ID_EMF
);
679 AddFormat( SOT_FORMATSTR_ID_WMF
);
684 // -----------------------------------------------------------------------------
686 void TransferableHelper::RemoveFormat( SotFormatStringId nFormat
)
690 if( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) )
691 RemoveFormat( aFlavor
);
694 // -----------------------------------------------------------------------------
696 void TransferableHelper::RemoveFormat( const DataFlavor
& rFlavor
)
698 DataFlavorExVector::iterator
aIter( mpFormats
->begin() );
700 while (aIter
!= mpFormats
->end())
702 if( TransferableDataHelper::IsEqual( *aIter
, rFlavor
) )
703 aIter
= mpFormats
->erase( aIter
);
709 // -----------------------------------------------------------------------------
711 sal_Bool
TransferableHelper::HasFormat( SotFormatStringId nFormat
)
713 sal_Bool bRet
= sal_False
;
715 for (DataFlavorExVector::const_iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() ); aIter
!= aEnd
; ++aIter
)
717 if( nFormat
== (*aIter
).mnSotId
)
727 // -----------------------------------------------------------------------------
729 void TransferableHelper::ClearFormats()
735 // -----------------------------------------------------------------------------
737 sal_Bool
TransferableHelper::SetAny( const Any
& rAny
, const DataFlavor
& )
740 return( maAny
.hasValue() );
743 // -----------------------------------------------------------------------------
745 sal_Bool
TransferableHelper::SetString( const OUString
& rString
, const DataFlavor
& rFlavor
)
747 DataFlavor aFileFlavor
;
749 if( !rString
.isEmpty() &&
750 SotExchange::GetFormatDataFlavor( FORMAT_FILE
, aFileFlavor
) &&
751 TransferableDataHelper::IsEqual( aFileFlavor
, rFlavor
) )
753 const OString
aByteStr(OUStringToOString(rString
, osl_getThreadTextEncoding()));
754 Sequence
< sal_Int8
> aSeq( aByteStr
.getLength() + 1 );
756 memcpy( aSeq
.getArray(), aByteStr
.getStr(), aByteStr
.getLength() );
757 aSeq
[ aByteStr
.getLength() ] = 0;
763 return( maAny
.hasValue() );
766 // -----------------------------------------------------------------------------
768 sal_Bool
TransferableHelper::SetBitmap( const Bitmap
& rBitmap
, const DataFlavor
& )
770 if( !rBitmap
.IsEmpty() )
772 SvMemoryStream
aMemStm( 65535, 65535 );
775 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Seek( STREAM_SEEK_TO_END
) );
778 return( maAny
.hasValue() );
781 // -----------------------------------------------------------------------------
783 sal_Bool
TransferableHelper::SetGDIMetaFile( const GDIMetaFile
& rMtf
, const DataFlavor
& )
785 if( rMtf
.GetActionSize() )
787 SvMemoryStream
aMemStm( 65535, 65535 );
789 ( (GDIMetaFile
&) rMtf
).Write( aMemStm
);
790 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Seek( STREAM_SEEK_TO_END
) );
793 return( maAny
.hasValue() );
796 // -----------------------------------------------------------------------------
798 sal_Bool
TransferableHelper::SetGraphic( const Graphic
& rGraphic
, const DataFlavor
& )
800 if( rGraphic
.GetType() != GRAPHIC_NONE
)
802 SvMemoryStream
aMemStm( 65535, 65535 );
804 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_50
);
805 aMemStm
.SetCompressMode( COMPRESSMODE_NATIVE
);
807 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Seek( STREAM_SEEK_TO_END
) );
810 return( maAny
.hasValue() );
813 // -----------------------------------------------------------------------------
815 sal_Bool
TransferableHelper::SetImageMap( const ImageMap
& rIMap
, const ::com::sun::star::datatransfer::DataFlavor
& )
817 SvMemoryStream
aMemStm( 8192, 8192 );
819 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_50
);
820 rIMap
.Write( aMemStm
, String() );
821 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Seek( STREAM_SEEK_TO_END
) );
823 return( maAny
.hasValue() );
826 // -----------------------------------------------------------------------------
828 sal_Bool
TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor
& rDesc
,
829 const ::com::sun::star::datatransfer::DataFlavor
& )
833 SvMemoryStream
aMemStm( 1024, 1024 );
836 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Tell() );
838 return( maAny
.hasValue() );
841 // -----------------------------------------------------------------------------
843 sal_Bool
TransferableHelper::SetINetBookmark( const INetBookmark
& rBmk
,
844 const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
)
846 rtl_TextEncoding eSysCSet
= osl_getThreadTextEncoding();
848 switch( SotExchange::GetFormat( rFlavor
) )
850 case( SOT_FORMATSTR_ID_SOLK
):
852 OString
sURL(OUStringToOString(rBmk
.GetURL(), eSysCSet
));
853 OString
sDesc(OUStringToOString(rBmk
.GetDescription(), eSysCSet
));
855 sOut
.append(sURL
.getLength());
856 sOut
.append('@').append(sURL
);
857 sOut
.append(sDesc
.getLength());
858 sOut
.append('@').append(sDesc
);
860 Sequence
< sal_Int8
> aSeq(sOut
.getLength());
861 memcpy(aSeq
.getArray(), sOut
.getStr(), sOut
.getLength());
866 case( FORMAT_STRING
):
867 maAny
<<= OUString( rBmk
.GetURL() );
870 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
):
872 OString
sURL(OUStringToOString(rBmk
.GetURL(), eSysCSet
));
873 Sequence
< sal_Int8
> aSeq( sURL
.getLength() );
874 memcpy( aSeq
.getArray(), sURL
.getStr(), sURL
.getLength() );
879 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
):
881 Sequence
< sal_Int8
> aSeq( 2048 );
883 memset( aSeq
.getArray(), 0, 2048 );
884 strcpy( reinterpret_cast< char* >( aSeq
.getArray() ), OUStringToOString(rBmk
.GetURL(), eSysCSet
).getStr() );
885 strcpy( reinterpret_cast< char* >( aSeq
.getArray() ) + 1024, OUStringToOString(rBmk
.GetDescription(), eSysCSet
).getStr() );
892 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
:
894 Sequence
< sal_Int8
> aSeq( sizeof( FILEGROUPDESCRIPTOR
) );
895 FILEGROUPDESCRIPTOR
* pFDesc
= (FILEGROUPDESCRIPTOR
*) aSeq
.getArray();
896 FILEDESCRIPTOR
& rFDesc1
= pFDesc
->fgd
[ 0 ];
899 memset( &rFDesc1
, 0, sizeof( FILEDESCRIPTOR
) );
900 rFDesc1
.dwFlags
= FD_LINKUI
;
902 OStringBuffer
aStr(OUStringToOString(
903 rBmk
.GetDescription(), eSysCSet
));
904 for( sal_uInt16 nChar
= 0; nChar
< aStr
.getLength(); ++nChar
)
905 if( strchr( "\\/:*?\"<>|", aStr
[nChar
] ) )
906 aStr
.remove(nChar
--, 1);
908 aStr
.insert(0, RTL_CONSTASCII_STRINGPARAM("Shortcut to "));
909 aStr
.append(RTL_CONSTASCII_STRINGPARAM(".URL"));
910 strcpy( rFDesc1
.cFileName
, aStr
.getStr() );
916 case SOT_FORMATSTR_ID_FILECONTENT
:
918 String
aStr( RTL_CONSTASCII_USTRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
919 maAny
<<= OUString( aStr
+= rBmk
.GetURL() );
928 return( maAny
.hasValue() );
931 // -----------------------------------------------------------------------------
933 sal_Bool
TransferableHelper::SetINetImage( const INetImage
& rINtImg
,
934 const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
)
936 SvMemoryStream
aMemStm( 1024, 1024 );
938 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_50
);
939 rINtImg
.Write( aMemStm
, SotExchange::GetFormat( rFlavor
) );
941 maAny
<<= Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ), aMemStm
.Seek( STREAM_SEEK_TO_END
) );
943 return( maAny
.hasValue() );
946 // -----------------------------------------------------------------------------
948 sal_Bool
TransferableHelper::SetObject( void* pUserObject
, sal_uInt32 nUserObjectId
, const DataFlavor
& rFlavor
)
950 SotStorageStreamRef
xStm( new SotStorageStream( String() ) );
952 xStm
->SetVersion( SOFFICE_FILEFORMAT_50
);
954 if( pUserObject
&& WriteObject( xStm
, pUserObject
, nUserObjectId
, rFlavor
) )
956 const sal_uInt32 nLen
= xStm
->Seek( STREAM_SEEK_TO_END
);
957 Sequence
< sal_Int8
> aSeq( nLen
);
959 xStm
->Seek( STREAM_SEEK_TO_BEGIN
);
960 xStm
->Read( aSeq
.getArray(), nLen
);
962 if( nLen
&& ( SotExchange::GetFormat( rFlavor
) == SOT_FORMAT_STRING
) )
964 //JP 24.7.2001: as I know was this only for the writer application and this
965 // writes now UTF16 format into the stream
966 //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
967 // little / big endians! - Bug 88121
968 maAny
<<= OUString( reinterpret_cast< const sal_Char
* >( aSeq
.getConstArray() ), nLen
- 1, RTL_TEXTENCODING_UTF8
);
974 return( maAny
.hasValue() );
977 // -----------------------------------------------------------------------------
979 sal_Bool
TransferableHelper::WriteObject( SotStorageStreamRef
&, void*, sal_uInt32
, const DataFlavor
& )
981 OSL_FAIL( "TransferableHelper::WriteObject( ... ) not implemented" );
985 // -----------------------------------------------------------------------------
987 void TransferableHelper::DragFinished( sal_Int8
)
991 // -----------------------------------------------------------------------------
993 void TransferableHelper::ObjectReleased()
997 // -----------------------------------------------------------------------------
999 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor
& rObjDesc
)
1002 mpObjDesc
= new TransferableObjectDescriptor( rObjDesc
);
1004 if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
) )
1005 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
);
1008 // -----------------------------------------------------------------------------
1010 void TransferableHelper::CopyToClipboard( Window
*pWindow
) const
1012 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
1013 Reference
< XClipboard
> xClipboard
;
1016 xClipboard
= pWindow
->GetClipboard();
1018 if( xClipboard
.is() )
1019 mxClipboard
= xClipboard
;
1021 if( mxClipboard
.is() && !mxTerminateListener
.is() )
1023 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1027 TransferableHelper
* pThis
= const_cast< TransferableHelper
* >( this );
1028 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
1029 xDesktop
->addTerminateListener( pThis
->mxTerminateListener
= new TerminateListener( *pThis
) );
1031 mxClipboard
->setContents( pThis
, pThis
);
1033 catch( const ::com::sun::star::uno::Exception
& )
1037 Application::AcquireSolarMutex( nRef
);
1041 // -----------------------------------------------------------------------------
1043 void TransferableHelper::CopyToSelection( Window
*pWindow
) const
1045 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
1046 Reference
< XClipboard
> xSelection
;
1049 xSelection
= pWindow
->GetPrimarySelection();
1051 if( xSelection
.is() && !mxTerminateListener
.is() )
1053 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1057 TransferableHelper
* pThis
= const_cast< TransferableHelper
* >( this );
1058 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
1059 xDesktop
->addTerminateListener( pThis
->mxTerminateListener
= new TerminateListener( *pThis
) );
1061 xSelection
->setContents( pThis
, pThis
);
1063 catch( const ::com::sun::star::uno::Exception
& )
1067 Application::AcquireSolarMutex( nRef
);
1071 // -----------------------------------------------------------------------------
1073 void TransferableHelper::StartDrag( Window
* pWindow
, sal_Int8 nDnDSourceActions
,
1074 sal_Int32 nDnDPointer
, sal_Int32 nDnDImage
)
1077 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
1078 Reference
< XDragSource
> xDragSource( pWindow
->GetDragSource() );
1080 if( xDragSource
.is() )
1083 * #96792# release mouse before actually starting DnD.
1084 * This is necessary for the X11 DnD implementation to work.
1086 if( pWindow
->IsMouseCaptured() )
1087 pWindow
->ReleaseMouse();
1089 const Point
aPt( pWindow
->GetPointerPosPixel() );
1091 // On Mac OS X we are forced to execute 'startDrag' synchronously
1092 // contrary to the XDragSource interface specification because
1093 // we can receive drag events from the system only in the main
1095 #if !defined(MACOSX)
1096 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1101 DragGestureEvent aEvt
;
1102 aEvt
.DragAction
= DNDConstants::ACTION_COPY
;
1103 aEvt
.DragOriginX
= aPt
.X();
1104 aEvt
.DragOriginY
= aPt
.Y();
1105 aEvt
.DragSource
= xDragSource
;
1107 xDragSource
->startDrag( aEvt
, nDnDSourceActions
, nDnDPointer
, nDnDImage
, this, this );
1109 catch( const ::com::sun::star::uno::Exception
& )
1113 // See above for the reason of this define
1114 #if !defined(MACOSX)
1115 Application::AcquireSolarMutex( nRef
);
1120 // -----------------------------------------------------------------------------
1122 void TransferableHelper::ClearSelection( Window
*pWindow
)
1124 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
1125 Reference
< XClipboard
> xSelection( pWindow
->GetPrimarySelection() );
1127 if( xSelection
.is() )
1128 xSelection
->setContents( NULL
, NULL
);
1131 // -----------------------------------------------------------------------------
1133 Reference
< XClipboard
> TransferableHelper::GetSystemClipboard()
1135 Window
*pFocusWindow
= Application::GetFocusWindow();
1138 return pFocusWindow
->GetClipboard();
1140 return Reference
< XClipboard
> ();
1145 class theTransferableHelperUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theTransferableHelperUnoTunnelId
> {};
1148 const Sequence
< sal_Int8
>& TransferableHelper::getUnoTunnelId()
1150 return theTransferableHelperUnoTunnelId::get().getSeq();
1153 // ---------------------------------
1154 // - TransferableClipboardNotifier -
1155 // ---------------------------------
1157 class TransferableClipboardNotifier
: public ::cppu::WeakImplHelper1
< XClipboardListener
>
1160 ::osl::Mutex
& mrMutex
;
1161 Reference
< XClipboardNotifier
> mxNotifier
;
1162 TransferableDataHelper
* mpListener
;
1165 // XClipboardListener
1166 virtual void SAL_CALL
changedContents( const clipboard::ClipboardEvent
& event
) throw (RuntimeException
);
1169 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
1172 TransferableClipboardNotifier( const Reference
< XClipboard
>& _rxClipboard
, TransferableDataHelper
& _rListener
, ::osl::Mutex
& _rMutex
);
1174 /// determines whether we're currently listening
1175 inline bool isListening() const { return !isDisposed(); }
1177 /// determines whether the instance is disposed
1178 inline bool isDisposed() const { return mpListener
== NULL
; }
1180 /// makes the instance non-functional
1184 // -----------------------------------------------------------------------------
1186 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference
< XClipboard
>& _rxClipboard
, TransferableDataHelper
& _rListener
, ::osl::Mutex
& _rMutex
)
1188 ,mxNotifier( _rxClipboard
, UNO_QUERY
)
1189 ,mpListener( &_rListener
)
1191 osl_atomic_increment( &m_refCount
);
1193 if ( mxNotifier
.is() )
1194 mxNotifier
->addClipboardListener( this );
1199 osl_atomic_decrement( &m_refCount
);
1202 // -----------------------------------------------------------------------------
1204 void SAL_CALL
TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent
& event
) throw (RuntimeException
)
1206 SolarMutexGuard aSolarGuard
;
1207 // the SolarMutex here is necessary, since
1208 // - we cannot call mpListener without our own mutex locked
1209 // - Rebind respectively InitFormats (called by Rebind) will
1210 // try to lock the SolarMutex, too
1211 ::osl::MutexGuard
aGuard( mrMutex
);
1213 mpListener
->Rebind( event
.Contents
);
1216 // -----------------------------------------------------------------------------
1218 void SAL_CALL
TransferableClipboardNotifier::disposing( const EventObject
& ) throw (RuntimeException
)
1220 // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1224 // -----------------------------------------------------------------------------
1226 void TransferableClipboardNotifier::dispose()
1228 ::osl::MutexGuard
aGuard( mrMutex
);
1230 Reference
< XClipboardListener
> xKeepMeAlive( this );
1232 if ( mxNotifier
.is() )
1233 mxNotifier
->removeClipboardListener( this );
1239 // -------------------------------
1240 // - TransferableDataHelper_Impl -
1241 // -------------------------------
1243 struct TransferableDataHelper_Impl
1245 ::osl::Mutex maMutex
;
1246 TransferableClipboardNotifier
* mpClipboardListener
;
1248 TransferableDataHelper_Impl()
1249 :mpClipboardListener( NULL
)
1254 // --------------------------
1255 // - TransferableDataHelper -
1256 // --------------------------
1258 TransferableDataHelper::TransferableDataHelper() :
1259 mpFormats( new DataFlavorExVector
),
1260 mpObjDesc( new TransferableObjectDescriptor
),
1261 mpImpl( new TransferableDataHelper_Impl
)
1265 // -----------------------------------------------------------------------------
1267 TransferableDataHelper::TransferableDataHelper( const Reference
< ::com::sun::star::datatransfer::XTransferable
>& rxTransferable
) :
1268 mxTransfer( rxTransferable
),
1269 mpFormats( new DataFlavorExVector
),
1270 mpObjDesc( new TransferableObjectDescriptor
),
1271 mpImpl( new TransferableDataHelper_Impl
)
1276 // -----------------------------------------------------------------------------
1278 TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper
& rDataHelper
) :
1279 mxTransfer( rDataHelper
.mxTransfer
),
1280 mxClipboard( rDataHelper
.mxClipboard
),
1281 mpFormats( new DataFlavorExVector( *rDataHelper
.mpFormats
) ),
1282 mpObjDesc( new TransferableObjectDescriptor( *rDataHelper
.mpObjDesc
) ),
1283 mpImpl( new TransferableDataHelper_Impl
)
1287 // -----------------------------------------------------------------------------
1289 TransferableDataHelper
& TransferableDataHelper::operator=( const TransferableDataHelper
& rDataHelper
)
1291 if ( this != &rDataHelper
)
1293 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1295 bool bWasClipboardListening
= ( NULL
!= mpImpl
->mpClipboardListener
);
1297 if ( bWasClipboardListening
)
1298 StopClipboardListening();
1300 mxTransfer
= rDataHelper
.mxTransfer
;
1301 delete mpFormats
, mpFormats
= new DataFlavorExVector( *rDataHelper
.mpFormats
);
1302 delete mpObjDesc
, mpObjDesc
= new TransferableObjectDescriptor( *rDataHelper
.mpObjDesc
);
1303 mxClipboard
= rDataHelper
.mxClipboard
;
1305 if ( bWasClipboardListening
)
1306 StartClipboardListening();
1312 // -----------------------------------------------------------------------------
1314 TransferableDataHelper::~TransferableDataHelper()
1316 StopClipboardListening( );
1318 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1319 delete mpFormats
, mpFormats
= NULL
;
1320 delete mpObjDesc
, mpObjDesc
= NULL
;
1325 // -----------------------------------------------------------------------------
1327 void TransferableDataHelper::FillDataFlavorExVector( const Sequence
< DataFlavor
>& rDataFlavorSeq
,
1328 DataFlavorExVector
& rDataFlavorExVector
)
1332 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
1333 Reference
< XMimeContentTypeFactory
> xMimeFact
= MimeContentTypeFactory::create( xContext
);
1334 DataFlavorEx aFlavorEx
;
1335 const OUString
aCharsetStr( "charset" );
1338 for( sal_Int32 i
= 0; i
< rDataFlavorSeq
.getLength(); i
++ )
1340 const DataFlavor
& rFlavor
= rDataFlavorSeq
[ i
];
1341 Reference
< XMimeContentType
> xMimeType
;
1345 if( !rFlavor
.MimeType
.isEmpty() )
1346 xMimeType
= xMimeFact
->createMimeContentType( rFlavor
.MimeType
);
1348 catch( const ::com::sun::star::uno::Exception
& )
1353 aFlavorEx
.MimeType
= rFlavor
.MimeType
;
1354 aFlavorEx
.HumanPresentableName
= rFlavor
.HumanPresentableName
;
1355 aFlavorEx
.DataType
= rFlavor
.DataType
;
1356 aFlavorEx
.mnSotId
= SotExchange::RegisterFormat( rFlavor
);
1358 rDataFlavorExVector
.push_back( aFlavorEx
);
1360 // add additional formats for special mime types
1361 if( SOT_FORMATSTR_ID_BMP
== aFlavorEx
.mnSotId
)
1363 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP
, aFlavorEx
) )
1365 aFlavorEx
.mnSotId
= SOT_FORMAT_BITMAP
;
1366 rDataFlavorExVector
.push_back( aFlavorEx
);
1369 else if( SOT_FORMATSTR_ID_WMF
== aFlavorEx
.mnSotId
|| SOT_FORMATSTR_ID_EMF
== aFlavorEx
.mnSotId
)
1371 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE
, aFlavorEx
) )
1373 aFlavorEx
.mnSotId
= SOT_FORMAT_GDIMETAFILE
;
1374 rDataFlavorExVector
.push_back( aFlavorEx
);
1377 else if ( SOT_FORMATSTR_ID_HTML_SIMPLE
== aFlavorEx
.mnSotId
)
1379 // #104735# HTML_SIMPLE may also be inserted without comments
1380 aFlavorEx
.mnSotId
= SOT_FORMATSTR_ID_HTML_NO_COMMENT
;
1381 rDataFlavorExVector
.push_back( aFlavorEx
);
1383 else if( xMimeType
.is() && xMimeType
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/plain" ) ) )
1385 // add, if it is a UTF-8 byte buffer
1386 if( xMimeType
->hasParameter( aCharsetStr
) )
1388 if( xMimeType
->getParameterValue( aCharsetStr
).equalsIgnoreAsciiCase( OUString( "unicode" ) ) ||
1389 xMimeType
->getParameterValue( aCharsetStr
).equalsIgnoreAsciiCase( OUString( "utf-16" ) ) )
1391 rDataFlavorExVector
[ rDataFlavorExVector
.size() - 1 ].mnSotId
= FORMAT_STRING
;
1396 else if( xMimeType
.is() && xMimeType
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/rtf" ) ) )
1398 rDataFlavorExVector
[ rDataFlavorExVector
.size() - 1 ].mnSotId
= FORMAT_RTF
;
1400 else if( xMimeType
.is() && xMimeType
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/html" ) ) )
1403 rDataFlavorExVector
[ rDataFlavorExVector
.size() - 1 ].mnSotId
= SOT_FORMATSTR_ID_HTML
;
1405 else if( xMimeType
.is() && xMimeType
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/uri-list" ) ) )
1407 rDataFlavorExVector
[ rDataFlavorExVector
.size() - 1 ].mnSotId
= SOT_FORMAT_FILE_LIST
;
1409 else if( xMimeType
.is() && xMimeType
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "application/x-openoffice-objectdescriptor-xml" ) ) )
1411 rDataFlavorExVector
[ rDataFlavorExVector
.size() - 1 ].mnSotId
= SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
;
1415 catch( const ::com::sun::star::uno::Exception
& )
1420 // -----------------------------------------------------------------------------
1422 void TransferableDataHelper::InitFormats()
1424 SolarMutexGuard aSolarGuard
;
1425 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1428 delete mpObjDesc
, mpObjDesc
= new TransferableObjectDescriptor
;
1430 if( mxTransfer
.is() )
1432 TransferableDataHelper::FillDataFlavorExVector( mxTransfer
->getTransferDataFlavors(), *mpFormats
);
1434 for (DataFlavorExVector::const_iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() ); aIter
!= aEnd
; ++aIter
)
1436 if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
== aIter
->mnSotId
)
1438 ImplSetParameterString( *mpObjDesc
, *aIter
);
1445 // -----------------------------------------------------------------------------
1447 sal_Bool
TransferableDataHelper::HasFormat( SotFormatStringId nFormat
) const
1449 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1451 DataFlavorExVector::iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() );
1452 sal_Bool bRet
= sal_False
;
1454 while( aIter
!= aEnd
)
1456 if( nFormat
== (*aIter
++).mnSotId
)
1466 // -----------------------------------------------------------------------------
1468 sal_Bool
TransferableDataHelper::HasFormat( const DataFlavor
& rFlavor
) const
1470 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1472 DataFlavorExVector::iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() );
1473 sal_Bool bRet
= sal_False
;
1475 while( aIter
!= aEnd
)
1477 if( TransferableDataHelper::IsEqual( rFlavor
, *aIter
++ ) )
1487 // -----------------------------------------------------------------------------
1489 sal_uInt32
TransferableDataHelper::GetFormatCount() const
1491 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1492 return mpFormats
->size();
1495 // -----------------------------------------------------------------------------
1498 SotFormatStringId
TransferableDataHelper::GetFormat( sal_uInt32 nFormat
) const
1500 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1501 DBG_ASSERT( nFormat
< mpFormats
->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1502 return( ( nFormat
< mpFormats
->size() ) ? (*mpFormats
)[ nFormat
].mnSotId
: 0 );
1505 // -----------------------------------------------------------------------------
1507 DataFlavor
TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat
) const
1509 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1510 DBG_ASSERT( nFormat
< mpFormats
->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1514 if( nFormat
< mpFormats
->size() )
1515 aRet
= (*mpFormats
)[ nFormat
];
1520 // -----------------------------------------------------------------------------
1522 Reference
< XTransferable
> TransferableDataHelper::GetXTransferable() const
1524 Reference
< XTransferable
> xRet
;
1526 if( mxTransfer
.is() )
1532 // do a dummy call to check, if this interface is valid (nasty)
1533 Sequence
< DataFlavor
> aTestSeq( xRet
->getTransferDataFlavors() );
1536 catch( const ::com::sun::star::uno::Exception
& )
1538 xRet
= Reference
< XTransferable
>();
1545 // -----------------------------------------------------------------------------
1547 Any
TransferableDataHelper::GetAny( SotFormatStringId nFormat
) const
1552 if ( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) )
1553 aReturn
= GetAny( aFlavor
);
1559 // -----------------------------------------------------------------------------
1561 Any
TransferableDataHelper::GetAny( const DataFlavor
& rFlavor
) const
1563 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
1568 if( mxTransfer
.is() )
1570 const SotFormatStringId nRequestFormat
= SotExchange::GetFormat( rFlavor
);
1572 if( nRequestFormat
)
1574 // try to get alien format first
1575 for (DataFlavorExVector::const_iterator
aIter( mpFormats
->begin() ), aEnd( mpFormats
->end() ); aIter
!= aEnd
; ++aIter
)
1577 if( ( nRequestFormat
== (*aIter
).mnSotId
) && !rFlavor
.MimeType
.equalsIgnoreAsciiCase( (*aIter
).MimeType
) )
1578 aRet
= mxTransfer
->getTransferData( *aIter
);
1580 if( aRet
.hasValue() )
1585 if( !aRet
.hasValue() )
1586 aRet
= mxTransfer
->getTransferData( rFlavor
);
1589 catch( const ::com::sun::star::uno::Exception
& )
1596 // -----------------------------------------------------------------------------
1598 sal_Bool
TransferableDataHelper::GetString( SotFormatStringId nFormat
, String
& rStr
)
1601 sal_Bool bRet
= GetString( nFormat
, aOUString
);
1608 // -----------------------------------------------------------------------------
1610 sal_Bool
TransferableDataHelper::GetString( const DataFlavor
& rFlavor
, String
& rStr
)
1613 sal_Bool bRet
= GetString( rFlavor
, aOUString
);
1620 // -----------------------------------------------------------------------------
1622 sal_Bool
TransferableDataHelper::GetString( SotFormatStringId nFormat
, OUString
& rStr
)
1625 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetString( aFlavor
, rStr
) );
1628 // -----------------------------------------------------------------------------
1630 sal_Bool
TransferableDataHelper::GetString( const DataFlavor
& rFlavor
, OUString
& rStr
)
1632 Any
aAny( GetAny( rFlavor
) );
1633 sal_Bool bRet
= sal_False
;
1635 if( aAny
.hasValue() )
1638 Sequence
< sal_Int8
> aSeq
;
1640 if( aAny
>>= aOUString
)
1645 else if( aAny
>>= aSeq
)
1648 const sal_Char
* pChars
= reinterpret_cast< const sal_Char
* >( aSeq
.getConstArray() );
1649 sal_Int32 nLen
= aSeq
.getLength();
1651 //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1652 //DVO 2002-05-27: strip _all_ trailing zeros
1653 while( nLen
&& ( 0 == *( pChars
+ nLen
- 1 ) ) )
1656 rStr
= OUString( pChars
, nLen
, osl_getThreadTextEncoding() );
1664 // -----------------------------------------------------------------------------
1666 sal_Bool
TransferableDataHelper::GetBitmap( SotFormatStringId nFormat
, Bitmap
& rBmp
)
1669 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetBitmap( aFlavor
, rBmp
) );
1672 // -----------------------------------------------------------------------------
1674 sal_Bool
TransferableDataHelper::GetBitmap( const DataFlavor
& rFlavor
, Bitmap
& rBmp
)
1676 SotStorageStreamRef xStm
;
1677 DataFlavor aSubstFlavor
;
1678 sal_Bool bRet
= GetSotStorageStream( rFlavor
, xStm
);
1683 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1685 /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1686 problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1687 and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1688 Due to this reason the following code assumes that bitmaps with a logical size
1689 greater than 50 cm aren't having the correct mapmode set.
1691 The following code should be removed if DDBs and DIBs are supported via clipboard
1696 MapMode aMapMode
= rBmp
.GetPrefMapMode();
1697 if ( aMapMode
.GetMapUnit() != MAP_PIXEL
)
1699 Size aSize
= OutputDevice::LogicToLogic( rBmp
.GetPrefSize(), aMapMode
, MAP_100TH_MM
);
1700 if ( ( aSize
.Width() > 5000 ) || ( aSize
.Height() > 5000 ) )
1701 rBmp
.SetPrefMapMode( MAP_PIXEL
);
1707 HasFormat( SOT_FORMATSTR_ID_BMP
) &&
1708 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP
, aSubstFlavor
) &&
1709 GetSotStorageStream( aSubstFlavor
, xStm
) )
1713 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1719 // -----------------------------------------------------------------------------
1721 sal_Bool
TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat
, GDIMetaFile
& rMtf
)
1724 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetGDIMetaFile( aFlavor
, rMtf
) );
1727 // -----------------------------------------------------------------------------
1729 sal_Bool
TransferableDataHelper::GetGDIMetaFile( const DataFlavor
& rFlavor
, GDIMetaFile
& rMtf
)
1731 SotStorageStreamRef xStm
;
1732 DataFlavor aSubstFlavor
;
1733 sal_Bool bRet
= sal_False
;
1735 if( GetSotStorageStream( rFlavor
, xStm
) )
1738 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1742 HasFormat( SOT_FORMATSTR_ID_EMF
) &&
1743 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF
, aSubstFlavor
) &&
1744 GetSotStorageStream( aSubstFlavor
, xStm
) )
1748 if( GraphicConverter::Import( *xStm
, aGraphic
) == ERRCODE_NONE
)
1750 rMtf
= aGraphic
.GetGDIMetaFile();
1756 HasFormat( SOT_FORMATSTR_ID_WMF
) &&
1757 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF
, aSubstFlavor
) &&
1758 GetSotStorageStream( aSubstFlavor
, xStm
) )
1762 if( GraphicConverter::Import( *xStm
, aGraphic
) == ERRCODE_NONE
)
1764 rMtf
= aGraphic
.GetGDIMetaFile();
1772 // -----------------------------------------------------------------------------
1774 sal_Bool
TransferableDataHelper::GetGraphic( SotFormatStringId nFormat
, Graphic
& rGraphic
)
1777 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetGraphic( aFlavor
, rGraphic
) );
1780 // -----------------------------------------------------------------------------
1782 sal_Bool
TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
, Graphic
& rGraphic
)
1785 sal_Bool bRet
= sal_False
;
1787 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP
, aFlavor
) &&
1788 TransferableDataHelper::IsEqual( aFlavor
, rFlavor
) )
1792 if( ( bRet
= GetBitmap( aFlavor
, aBmp
) ) == sal_True
)
1795 else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE
, aFlavor
) &&
1796 TransferableDataHelper::IsEqual( aFlavor
, rFlavor
) )
1800 if( ( bRet
= GetGDIMetaFile( aFlavor
, aMtf
) ) == sal_True
)
1805 SotStorageStreamRef xStm
;
1807 if( GetSotStorageStream( rFlavor
, xStm
) )
1810 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1817 // -----------------------------------------------------------------------------
1819 sal_Bool
TransferableDataHelper::GetImageMap( SotFormatStringId nFormat
, ImageMap
& rIMap
)
1822 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetImageMap( aFlavor
, rIMap
) );
1825 // -----------------------------------------------------------------------------
1827 sal_Bool
TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
, ImageMap
& rIMap
)
1829 SotStorageStreamRef xStm
;
1830 sal_Bool bRet
= GetSotStorageStream( rFlavor
, xStm
);
1834 rIMap
.Read( *xStm
, String() );
1835 bRet
= ( xStm
->GetError() == ERRCODE_NONE
);
1841 // -----------------------------------------------------------------------------
1843 sal_Bool
TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat
, TransferableObjectDescriptor
& rDesc
)
1846 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetTransferableObjectDescriptor( aFlavor
, rDesc
) );
1849 // -----------------------------------------------------------------------------
1851 sal_Bool
TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor
&, TransferableObjectDescriptor
& rDesc
)
1857 // -----------------------------------------------------------------------------
1859 sal_Bool
TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat
, INetBookmark
& rBmk
)
1862 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetINetBookmark( aFlavor
, rBmk
) );
1865 // -----------------------------------------------------------------------------
1867 sal_Bool
TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
, INetBookmark
& rBmk
)
1869 sal_Bool bRet
= sal_False
;
1870 if( HasFormat( rFlavor
))
1872 const SotFormatStringId nFormat
= SotExchange::GetFormat( rFlavor
);
1875 case( SOT_FORMATSTR_ID_SOLK
):
1876 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
):
1879 if( GetString( rFlavor
, aString
) )
1881 if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
== nFormat
)
1883 rBmk
= INetBookmark( aString
, aString
);
1889 sal_uInt16 nStart
= aString
.Search( '@' ), nLen
= (sal_uInt16
) aString
.ToInt32();
1891 if( !nLen
&& aString
.GetChar( 0 ) != '0' )
1893 DBG_WARNING( "SOLK: 1. len=0" );
1895 if( nStart
== STRING_NOTFOUND
|| nLen
> aString
.Len() - nStart
- 3 )
1897 DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
1899 aURL
= aString
.Copy( nStart
+ 1, nLen
);
1901 aString
.Erase( 0, nStart
+ 1 + nLen
);
1902 nStart
= aString
.Search( '@' );
1903 nLen
= (sal_uInt16
) aString
.ToInt32();
1905 if( !nLen
&& aString
.GetChar( 0 ) != '0' )
1907 DBG_WARNING( "SOLK: 2. len=0" );
1909 if( nStart
== STRING_NOTFOUND
|| nLen
> aString
.Len() - nStart
- 1 )
1911 DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
1913 aDesc
= aString
.Copy( nStart
+1, nLen
);
1915 rBmk
= INetBookmark( aURL
, aDesc
);
1922 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
):
1924 Sequence
< sal_Int8
> aSeq
;
1926 if( GetSequence( rFlavor
, aSeq
) && ( 2048 == aSeq
.getLength() ) )
1928 rBmk
= INetBookmark( String( reinterpret_cast< const sal_Char
* >( aSeq
.getConstArray() ), osl_getThreadTextEncoding() ),
1929 String( reinterpret_cast< const sal_Char
* >( aSeq
.getConstArray() ) + 1024, osl_getThreadTextEncoding() ) );
1936 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
:
1938 Sequence
< sal_Int8
> aSeq
;
1940 if( GetSequence( rFlavor
, aSeq
) && aSeq
.getLength() )
1942 FILEGROUPDESCRIPTOR
* pFDesc
= (FILEGROUPDESCRIPTOR
*) aSeq
.getConstArray();
1944 if( pFDesc
->cItems
)
1946 OString
aDesc( pFDesc
->fgd
[ 0 ].cFileName
);
1947 rtl_TextEncoding eTextEncoding
= osl_getThreadTextEncoding();
1949 if( ( aDesc
.getLength() > 4 ) && aDesc
.copy(aDesc
.getLength() - 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM(".URL")) )
1951 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( INetURLObject( OStringToOUString(aDesc
, eTextEncoding
) ).GetMainURL( INetURLObject::NO_DECODE
),
1954 if( !pStream
|| pStream
->GetError() )
1956 DataFlavor aFileContentFlavor
;
1961 if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT
, aFileContentFlavor
) &&
1962 GetSequence( aFileContentFlavor
, aSeq
) && aSeq
.getLength() )
1964 pStream
= new SvMemoryStream( (sal_Char
*) aSeq
.getConstArray(), aSeq
.getLength(), STREAM_STD_READ
);
1973 sal_Bool bSttFnd
= sal_False
;
1975 while( pStream
->ReadLine( aLine
) )
1977 if (aLine
.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("[InternetShortcut]")))
1979 else if (bSttFnd
&& aLine
.copy(0, 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("URL=")))
1981 rBmk
= INetBookmark( OStringToOUString(aLine
.copy(4), eTextEncoding
),
1982 OStringToOUString(aDesc
.copy(0, aDesc
.getLength() - 4), eTextEncoding
) );
2002 // -----------------------------------------------------------------------------
2004 sal_Bool
TransferableDataHelper::GetINetImage( SotFormatStringId nFormat
,
2005 INetImage
& rINtImg
)
2008 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetINetImage( aFlavor
, rINtImg
) );
2011 // -----------------------------------------------------------------------------
2013 sal_Bool
TransferableDataHelper::GetINetImage(
2014 const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
,
2015 INetImage
& rINtImg
)
2017 SotStorageStreamRef xStm
;
2018 sal_Bool bRet
= GetSotStorageStream( rFlavor
, xStm
);
2021 bRet
= rINtImg
.Read( *xStm
, SotExchange::GetFormat( rFlavor
) );
2025 // -----------------------------------------------------------------------------
2027 sal_Bool
TransferableDataHelper::GetFileList( SotFormatStringId nFormat
,
2028 FileList
& rFileList
)
2031 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetFileList( aFlavor
, rFileList
) );
2034 // -----------------------------------------------------------------------------
2036 sal_Bool
TransferableDataHelper::GetFileList(
2037 const ::com::sun::star::datatransfer::DataFlavor
&,
2038 FileList
& rFileList
)
2040 SotStorageStreamRef xStm
;
2041 sal_Bool bRet
= sal_False
;
2043 for( sal_uInt32 i
= 0, nFormatCount
= GetFormatCount(); ( i
< nFormatCount
) && !bRet
; ++i
)
2045 if( SOT_FORMAT_FILE_LIST
== GetFormat( i
) )
2047 const DataFlavor
aFlavor( GetFormatDataFlavor( i
) );
2049 if( GetSotStorageStream( aFlavor
, xStm
) )
2051 if( aFlavor
.MimeType
.indexOf( "text/uri-list" ) > -1 )
2053 OString aDiskString
;
2055 while( xStm
->ReadLine( aDiskString
) )
2056 if( !aDiskString
.isEmpty() && aDiskString
[0] != '#' )
2057 rFileList
.AppendFile( OStringToOUString(aDiskString
, RTL_TEXTENCODING_UTF8
) );
2062 bRet
= ( ( *xStm
>> rFileList
).GetError() == ERRCODE_NONE
);
2070 // -----------------------------------------------------------------------------
2072 sal_Bool
TransferableDataHelper::GetSequence( SotFormatStringId nFormat
, Sequence
< sal_Int8
>& rSeq
)
2075 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetSequence( aFlavor
, rSeq
) );
2078 // -----------------------------------------------------------------------------
2080 sal_Bool
TransferableDataHelper::GetSequence( const DataFlavor
& rFlavor
, Sequence
< sal_Int8
>& rSeq
)
2083 fprintf( stderr
, "TransferableDataHelper requests sequence of data\n" );
2086 const Any
aAny( GetAny( rFlavor
) );
2087 return( aAny
.hasValue() && ( aAny
>>= rSeq
) );
2090 // -----------------------------------------------------------------------------
2092 sal_Bool
TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat
, SotStorageStreamRef
& rxStream
)
2095 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetSotStorageStream( aFlavor
, rxStream
) );
2098 // -----------------------------------------------------------------------------
2100 sal_Bool
TransferableDataHelper::GetSotStorageStream( const DataFlavor
& rFlavor
, SotStorageStreamRef
& rxStream
)
2102 Sequence
< sal_Int8
> aSeq
;
2103 sal_Bool bRet
= GetSequence( rFlavor
, aSeq
);
2107 rxStream
= new SotStorageStream( String() );
2108 rxStream
->Write( aSeq
.getConstArray(), aSeq
.getLength() );
2109 rxStream
->Seek( 0 );
2115 sal_Bool
TransferableDataHelper::GetInputStream( SotFormatStringId nFormat
, Reference
< XInputStream
>& rxStream
)
2118 return( SotExchange::GetFormatDataFlavor( nFormat
, aFlavor
) && GetInputStream( aFlavor
, rxStream
) );
2121 // -----------------------------------------------------------------------------
2123 sal_Bool
TransferableDataHelper::GetInputStream( const DataFlavor
& rFlavor
, Reference
< XInputStream
>& rxStream
)
2125 Sequence
< sal_Int8
> aSeq
;
2126 sal_Bool bRet
= GetSequence( rFlavor
, aSeq
);
2129 rxStream
= new ::comphelper::SequenceInputStream( aSeq
);
2134 // -----------------------------------------------------------------------------
2136 void TransferableDataHelper::Rebind( const Reference
< XTransferable
>& _rxNewContent
)
2138 mxTransfer
= _rxNewContent
;
2142 // -----------------------------------------------------------------------------
2144 sal_Bool
TransferableDataHelper::StartClipboardListening( )
2146 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
2148 StopClipboardListening( );
2150 mpImpl
->mpClipboardListener
= new TransferableClipboardNotifier( mxClipboard
, *this, mpImpl
->maMutex
);
2151 mpImpl
->mpClipboardListener
->acquire();
2153 return mpImpl
->mpClipboardListener
->isListening();
2156 // -----------------------------------------------------------------------------
2158 void TransferableDataHelper::StopClipboardListening( )
2160 ::osl::MutexGuard
aGuard( mpImpl
->maMutex
);
2162 if ( mpImpl
->mpClipboardListener
)
2164 mpImpl
->mpClipboardListener
->dispose();
2165 mpImpl
->mpClipboardListener
->release();
2166 mpImpl
->mpClipboardListener
= NULL
;
2170 // -----------------------------------------------------------------------------
2172 TransferableDataHelper
TransferableDataHelper::CreateFromSystemClipboard( Window
* pWindow
)
2174 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
2176 Reference
< XClipboard
> xClipboard
;
2177 TransferableDataHelper aRet
;
2180 xClipboard
= pWindow
->GetClipboard();
2182 if( xClipboard
.is() )
2186 Reference
< XTransferable
> xTransferable( xClipboard
->getContents() );
2188 if( xTransferable
.is() )
2190 aRet
= TransferableDataHelper( xTransferable
);
2191 // also copy the clipboard
2192 aRet
.mxClipboard
= xClipboard
;
2195 catch( const ::com::sun::star::uno::Exception
& )
2204 // -----------------------------------------------------------------------------
2206 TransferableDataHelper
TransferableDataHelper::CreateFromSelection( Window
* pWindow
)
2208 DBG_ASSERT( pWindow
, "Window pointer is NULL" );
2210 Reference
< XClipboard
> xSelection
;
2211 TransferableDataHelper aRet
;
2214 xSelection
= pWindow
->GetPrimarySelection();
2216 if( xSelection
.is() )
2218 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
2222 Reference
< XTransferable
> xTransferable( xSelection
->getContents() );
2224 if( xTransferable
.is() )
2226 aRet
= TransferableDataHelper( xTransferable
);
2227 aRet
.mxClipboard
= xSelection
;
2230 catch( const ::com::sun::star::uno::Exception
& )
2234 Application::AcquireSolarMutex( nRef
);
2240 // -----------------------------------------------------------------------------
2241 sal_Bool
TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor
& rInternalFlavor
,
2242 const ::com::sun::star::datatransfer::DataFlavor
& rRequestFlavor
,
2245 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
2246 sal_Bool bRet
= sal_False
;
2250 Reference
< XMimeContentTypeFactory
> xMimeFact
= MimeContentTypeFactory::create( xContext
);
2252 Reference
< XMimeContentType
> xRequestType1( xMimeFact
->createMimeContentType( rInternalFlavor
.MimeType
) );
2253 Reference
< XMimeContentType
> xRequestType2( xMimeFact
->createMimeContentType( rRequestFlavor
.MimeType
) );
2255 if( xRequestType1
.is() && xRequestType2
.is() )
2257 if( xRequestType1
->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2
->getFullMediaType() ) )
2259 if( xRequestType1
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/plain" ) ) )
2261 // special handling for text/plain media types
2262 const OUString
aCharsetString( "charset" );
2264 if( !xRequestType2
->hasParameter( aCharsetString
) ||
2265 xRequestType2
->getParameterValue( aCharsetString
).equalsIgnoreAsciiCase( OUString( "utf-16" ) ) ||
2266 xRequestType2
->getParameterValue( aCharsetString
).equalsIgnoreAsciiCase( OUString( "unicode" ) ) )
2271 else if( xRequestType1
->getFullMediaType().equalsIgnoreAsciiCase( OUString( "application/x-openoffice" ) ) )
2273 // special handling for application/x-openoffice media types
2274 const OUString
aFormatString( "windows_formatname" );
2276 if( xRequestType1
->hasParameter( aFormatString
) &&
2277 xRequestType2
->hasParameter( aFormatString
) &&
2278 xRequestType1
->getParameterValue( aFormatString
).equalsIgnoreAsciiCase( xRequestType2
->getParameterValue( aFormatString
) ) )
2288 catch( const ::com::sun::star::uno::Exception
& )
2290 bRet
= rInternalFlavor
.MimeType
.equalsIgnoreAsciiCase( rRequestFlavor
.MimeType
);
2296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */