xref: /aoo42x/main/svtools/source/misc/transfer.cxx (revision ad6faf97)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svtools.hxx"
24 #ifdef WNT
25 #include <tools/prewin.h>
26 #if defined _MSC_VER
27 #pragma warning(push, 1)
28 #pragma warning(disable: 4917)
29 #endif
30 #include <shlobj.h>
31 #if defined _MSC_VER
32 #pragma warning(pop)
33 #endif
34 #include <tools/postwin.h>
35 #endif
36 #include <vos/mutex.hxx>
37 #include <rtl/memory.h>
38 #include <rtl/uuid.h>
39 #include <rtl/uri.hxx>
40 #include <tools/debug.hxx>
41 #include <tools/urlobj.hxx>
42 #include <unotools/ucbstreamhelper.hxx>
43 #include <sot/exchange.hxx>
44 #include <sot/storage.hxx>
45 #include <vcl/bitmap.hxx>
46 #include <vcl/gdimtf.hxx>
47 #include <vcl/graph.hxx>
48 #include <vcl/cvtgrf.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/window.hxx>
51 #include <comphelper/processfactory.hxx>
52 #include <sot/filelist.hxx>
53 #include <cppuhelper/implbase1.hxx>
54 
55 #include <comphelper/seqstream.hxx>
56 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
57 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
58 #include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
59 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
60 #include <com/sun/star/frame/XDesktop.hpp>
61 #include <com/sun/star/lang/XInitialization.hpp>
62 
63 #include "svl/urlbmk.hxx"
64 #include "inetimg.hxx"
65 #include <svtools/wmf.hxx>
66 #include <svtools/imap.hxx>
67 #include <svtools/transfer.hxx>
68 #include <cstdio>
69 #include <vcl/dibtools.hxx>
70 #include <vcl/pngread.hxx>
71 #include <vcl/pngwrite.hxx>
72 
73 // --------------
74 // - Namespaces -
75 // --------------
76 
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::frame;
80 using namespace ::com::sun::star::io;
81 using namespace ::com::sun::star::datatransfer;
82 using namespace ::com::sun::star::datatransfer::clipboard;
83 using namespace ::com::sun::star::datatransfer::dnd;
84 
85 // --------------------------------
86 // - TransferableObjectDescriptor -
87 // --------------------------------
88 
89 #define TOD_SIG1 0x01234567
90 #define TOD_SIG2 0x89abcdef
91 
92 SvStream& operator>>( SvStream& rIStm, TransferableObjectDescriptor& rObjDesc )
93 {
94 	sal_uInt32  nSize, nViewAspect, nSig1, nSig2;
95 
96 	rIStm >> nSize;
97 	rIStm >> rObjDesc.maClassName;
98 	rIStm >> nViewAspect;
99 	rIStm >> rObjDesc.maSize.Width();
100     rIStm >> rObjDesc.maSize.Height();
101 	rIStm >> rObjDesc.maDragStartPos.X();
102 	rIStm >> rObjDesc.maDragStartPos.Y();
103 	rIStm.ReadByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
104 	rIStm.ReadByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
105     rIStm >> nSig1 >> nSig2;
106 
107     rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( nViewAspect );
108 
109     // don't use width/height info from external objects
110     if( ( TOD_SIG1 != nSig1 ) || ( TOD_SIG2 != nSig2 ) )
111     {
112         rObjDesc.maSize.Width() = 0;
113         rObjDesc.maSize.Height() = 0;
114     }
115 
116 	return rIStm;
117 }
118 
119 // -----------------------------------------------------------------------------
120 
121 SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc )
122 {
123 	const sal_uInt32    nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect;
124 	const sal_uInt32    nSig1 = TOD_SIG1, nSig2 = TOD_SIG2;
125 
126 	rOStm.SeekRel( 4 );
127 	rOStm << rObjDesc.maClassName;
128 	rOStm << nViewAspect;
129 	rOStm << rObjDesc.maSize.Width();
130 	rOStm << rObjDesc.maSize.Height();
131 	rOStm << rObjDesc.maDragStartPos.X();
132 	rOStm << rObjDesc.maDragStartPos.Y();
133 	rOStm.WriteByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
134 	rOStm.WriteByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
135 	rOStm << nSig1 << nSig2;
136 
137 	const sal_uInt32 nLastPos = rOStm.Tell();
138 
139 	rOStm.Seek( nFirstPos );
140 	rOStm << ( nLastPos - nFirstPos );
141 	rOStm.Seek( nLastPos );
142 
143 	return rOStm;
144 }
145 
146 // -----------------------------------------------------------------------------
147 // the reading of the parameter is done using the special service ::com::sun::star::datatransfer::MimeContentType,
148 // a similar approach should be implemented for creation of the mimetype string;
149 // for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype
150 const ::rtl::OUString aQuotedParamChars = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. " ) );
151 
152 static ::rtl::OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc )
153 {
154     const ::rtl::OUString   aChar( ::rtl::OUString::createFromAscii( "\"" ) );
155     const ::rtl::OUString   aClassName( rObjDesc.maClassName.GetHexName() );
156     ::rtl::OUString         aParams;
157 
158     if( aClassName.getLength() )
159     {
160         aParams += ::rtl::OUString::createFromAscii( ";classname=\"" );
161         aParams += aClassName;
162         aParams += aChar;
163     }
164 
165     if( rObjDesc.maTypeName.Len() )
166     {
167         aParams += ::rtl::OUString::createFromAscii( ";typename=\"" );
168         aParams += rObjDesc.maTypeName;
169         aParams += aChar;
170     }
171 
172     if( rObjDesc.maDisplayName.Len() )
173     {
174         // the display name might contain unacceptable characters, encode all of them
175         // this seems to be the only parameter currently that might contain such characters
176         sal_Bool pToAccept[128];
177         for ( sal_Int32 nBInd = 0; nBInd < 128; nBInd++ )
178             pToAccept[nBInd] = sal_False;
179 
180         for ( sal_Int32 nInd = 0; nInd < aQuotedParamChars.getLength(); nInd++ )
181         {
182             sal_Unicode nChar = aQuotedParamChars.getStr()[nInd];
183             if ( nChar < 128 )
184                 pToAccept[nChar] = sal_True;
185         }
186 
187         aParams += ::rtl::OUString::createFromAscii( ";displayname=\"" );
188         aParams += ::rtl::Uri::encode( rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
189         aParams += aChar;
190     }
191 
192     aParams += ::rtl::OUString::createFromAscii( ";viewaspect=\"" );
193     aParams += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rObjDesc.mnViewAspect ) );
194     aParams += aChar;
195 
196     aParams += ::rtl::OUString::createFromAscii( ";width=\"" );
197     aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Width() );
198     aParams += aChar;
199 
200     aParams += ::rtl::OUString::createFromAscii( ";height=\"" );
201     aParams += ::rtl::OUString::valueOf( rObjDesc.maSize.Height() );
202     aParams += aChar;
203 
204     aParams += ::rtl::OUString::createFromAscii( ";posx=\"" );
205     aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
206     aParams += aChar;
207 
208     aParams += ::rtl::OUString::createFromAscii( ";posy=\"" );
209     aParams += ::rtl::OUString::valueOf( rObjDesc.maDragStartPos.X() );
210     aParams += aChar;
211 
212     return aParams;
213 }
214 
215 // -----------------------------------------------------------------------------
216 
217 static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, const DataFlavorEx& rFlavorEx )
218 {
219     Reference< XMultiServiceFactory >       xFact( ::comphelper::getProcessServiceFactory() );
220     Reference< XMimeContentTypeFactory >    xMimeFact;
221 
222     try
223     {
224         if( xFact.is() )
225         {
226             xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
227                                                               "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
228                                                               UNO_QUERY );
229         }
230 
231         if( xMimeFact.is() )
232         {
233             Reference< XMimeContentType > xMimeType( xMimeFact->createMimeContentType( rFlavorEx.MimeType ) );
234 
235             if( xMimeType.is() )
236             {
237                 const ::rtl::OUString aClassNameString( ::rtl::OUString::createFromAscii( "classname" ) );
238                 const ::rtl::OUString aTypeNameString( ::rtl::OUString::createFromAscii( "typename" ) );
239                 const ::rtl::OUString aDisplayNameString( ::rtl::OUString::createFromAscii( "displayname" ) );
240                 const ::rtl::OUString aViewAspectString( ::rtl::OUString::createFromAscii( "viewaspect" ) );
241                 const ::rtl::OUString aWidthString( ::rtl::OUString::createFromAscii( "width" ) );
242                 const ::rtl::OUString aHeightString( ::rtl::OUString::createFromAscii( "height" ) );
243                 const ::rtl::OUString aPosXString( ::rtl::OUString::createFromAscii( "posx" ) );
244                 const ::rtl::OUString aPosYString( ::rtl::OUString::createFromAscii( "posy" ) );
245 
246                 if( xMimeType->hasParameter( aClassNameString ) )
247                 {
248                     rObjDesc.maClassName.MakeId( xMimeType->getParameterValue( aClassNameString ) );
249                 }
250 
251                 if( xMimeType->hasParameter( aTypeNameString ) )
252                 {
253                     rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString );
254                 }
255 
256                 if( xMimeType->hasParameter( aDisplayNameString ) )
257                 {
258                     // the display name might contain unacceptable characters, in this case they should be encoded
259                     // this seems to be the only parameter currently that might contain such characters
260                     rObjDesc.maDisplayName = ::rtl::Uri::decode( xMimeType->getParameterValue( aDisplayNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
261                 }
262 
263                 if( xMimeType->hasParameter( aViewAspectString ) )
264                 {
265                     rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( xMimeType->getParameterValue( aViewAspectString ).toInt32() );
266                 }
267 
268                 if( xMimeType->hasParameter( aWidthString ) )
269                 {
270                     rObjDesc.maSize.Width() = xMimeType->getParameterValue( aWidthString ).toInt32();
271                 }
272 
273                 if( xMimeType->hasParameter( aHeightString ) )
274                 {
275                     rObjDesc.maSize.Height() = xMimeType->getParameterValue( aHeightString ).toInt32();
276                 }
277 
278                 if( xMimeType->hasParameter( aPosXString ) )
279                 {
280                     rObjDesc.maDragStartPos.X() = xMimeType->getParameterValue( aPosXString ).toInt32();
281                 }
282 
283                 if( xMimeType->hasParameter( aPosYString ) )
284                 {
285                     rObjDesc.maDragStartPos.Y() = xMimeType->getParameterValue( aPosYString ).toInt32();
286                 }
287             }
288         }
289     }
290     catch( const ::com::sun::star::uno::Exception& )
291     {
292     }
293 }
294 
295 // -----------------------------------------
296 // - TransferableHelper::TerminateListener -
297 // -----------------------------------------
298 
299 TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
300 	mrParent( rTransferableHelper )
301 {
302 }
303 
304 // -----------------------------------------------------------------------------
305 
306 TransferableHelper::TerminateListener::~TerminateListener()
307 {
308 }
309 
310 // -----------------------------------------------------------------------------
311 
312 void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
313 {
314 }
315 
316 // -----------------------------------------------------------------------------
317 
318 void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
319 {
320 }
321 
322 // -----------------------------------------------------------------------------
323 
324 void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
325 {
326 	mrParent.ImplFlush();
327 }
328 
329 // ----------------------
330 // - TransferableHelper -
331 // ----------------------
332 
333 TransferableHelper::TransferableHelper() :
334 	mpFormats( new DataFlavorExVector ),
335     mpObjDesc( NULL )
336 {
337 }
338 
339 // -----------------------------------------------------------------------------
340 
341 TransferableHelper::~TransferableHelper()
342 {
343     delete mpObjDesc;
344 	delete mpFormats;
345 }
346 
347 // -----------------------------------------------------------------------------
348 
349 Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) throw( UnsupportedFlavorException, IOException, RuntimeException )
350 {
351 	if( !maAny.hasValue() || !mpFormats->size() || ( maLastFormat != rFlavor.MimeType ) )
352 	{
353 		const ::vos::OGuard aGuard( Application::GetSolarMutex() );
354 
355 		maLastFormat = rFlavor.MimeType;
356 		maAny = Any();
357 
358 		try
359 		{
360     	    DataFlavor  aSubstFlavor;
361             sal_Bool    bDone = sal_False;
362 
363 			// add formats if not already done
364             if( !mpFormats->size() )
365 				AddSupportedFormats();
366 
367 	        // check alien formats first and try to get a substitution format
368             if( SotExchange::GetFormatDataFlavor( FORMAT_STRING, aSubstFlavor ) &&
369                 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) )
370             {
371 			    GetData( aSubstFlavor );
372                 bDone = maAny.hasValue();
373             }
374             else if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_BMP, aSubstFlavor )
375                 && TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor )
376                 && SotExchange::GetFormatDataFlavor(FORMAT_BITMAP, aSubstFlavor))
377             {
378 			    GetData( aSubstFlavor );
379                 bDone = sal_True;
380             }
381             else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
382                      TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
383                      SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
384             {
385 			    GetData( aSubstFlavor );
386 
387 			    if( maAny.hasValue() )
388 			    {
389 				    Sequence< sal_Int8 > aSeq;
390 
391 				    if( maAny >>= aSeq )
392 				    {
393 					    SvMemoryStream*	pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
394 					    GDIMetaFile		aMtf;
395 
396 					    *pSrcStm >> aMtf;
397 					    delete pSrcStm;
398 
399 					    Graphic			aGraphic( aMtf );
400 					    SvMemoryStream	aDstStm( 65535, 65535 );
401 
402 					    if( GraphicConverter::Export( aDstStm, aGraphic, CVT_EMF ) == ERRCODE_NONE )
403                         {
404 						    maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
405                                                                      aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
406                             bDone = sal_True;
407                         }
408 				    }
409 			    }
410             }
411             else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
412                      TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
413                      SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
414             {
415 			    GetData( aSubstFlavor );
416 
417 			    if( maAny.hasValue() )
418 			    {
419 				    Sequence< sal_Int8 > aSeq;
420 
421 				    if( maAny >>= aSeq )
422 				    {
423 					    SvMemoryStream*	pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
424 					    GDIMetaFile		aMtf;
425 
426 					    *pSrcStm >> aMtf;
427 					    delete pSrcStm;
428 
429 					    SvMemoryStream	aDstStm( 65535, 65535 );
430 
431 						// taking wmf without file header
432 						if ( ConvertGDIMetaFileToWMF( aMtf, aDstStm, NULL, sal_False ) )
433                         {
434 						    maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
435                                                                      aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
436                             bDone = sal_True;
437                         }
438 				    }
439 			    }
440             }
441             else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_SVG, aSubstFlavor ) &&
442                      TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
443                      SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
444             {
445                 GetData( aSubstFlavor );
446 
447                 if( maAny.hasValue() )
448                 {
449                     Sequence< sal_Int8 > aSeq;
450 
451                     if( maAny >>= aSeq )
452                     {
453                         SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
454                         GDIMetaFile     aMtf;
455 
456                         *pSrcStm >> aMtf;
457                         delete pSrcStm;
458 
459                         Graphic         aGraphic( aMtf );
460                         SvMemoryStream  aDstStm( 65535, 65535 );
461 
462                         if( GraphicConverter::Export( aDstStm, aGraphic, CVT_SVG ) == ERRCODE_NONE )
463                         {
464                             maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
465                                                                      aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
466                             bDone = sal_True;
467                         }
468                     }
469                 }
470             }
471 
472             // reset Any if substitute doesn't work
473             if( !bDone && maAny.hasValue() )
474                 maAny = Any();
475 
476             // if any is not yet filled, use standard format
477             if( !maAny.hasValue() )
478                 GetData( rFlavor );
479 
480 #ifdef DEBUG
481             if( maAny.hasValue() && ::com::sun::star::uno::TypeClass_STRING != maAny.getValueType().getTypeClass() )
482                 fprintf( stderr, "TransferableHelper delivers sequence of data [ %s ]\n", ByteString( String( rFlavor.MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
483 #endif
484         }
485 		catch( const ::com::sun::star::uno::Exception& )
486 		{
487 		}
488 
489 		if( !maAny.hasValue() )
490 			throw UnsupportedFlavorException();
491 	}
492 
493 	return maAny;
494 }
495 
496 // -----------------------------------------------------------------------------
497 
498 Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() throw( RuntimeException )
499 {
500 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
501 
502 	try
503 	{
504 		if( !mpFormats->size() )
505 			AddSupportedFormats();
506 	}
507 	catch( const ::com::sun::star::uno::Exception& )
508 	{
509 	}
510 
511 	Sequence< DataFlavor >			aRet( mpFormats->size() );
512 	DataFlavorExVector::iterator	aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
513 	sal_uInt32						nCurPos = 0;
514 
515     while( aIter != aEnd )
516     {
517     	aRet[ nCurPos++ ] = *aIter++;
518     }
519 
520 	return aRet;
521 }
522 
523 // -----------------------------------------------------------------------------
524 
525 sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) throw( RuntimeException )
526 {
527 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
528 	sal_Bool			bRet = sal_False;
529 
530 	try
531 	{
532 		if( !mpFormats->size() )
533 			AddSupportedFormats();
534 	}
535 	catch( const ::com::sun::star::uno::Exception& )
536 	{
537 	}
538 
539 	DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
540 
541 	while( aIter != aEnd )
542 	{
543         if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
544         {
545             aIter = aEnd;
546             bRet = sal_True;
547         }
548         else
549             aIter++;
550     }
551 
552 	return bRet;
553 }
554 
555 // -----------------------------------------------------------------------------
556 
557 void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) throw( RuntimeException )
558 {
559 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
560 
561 	try
562 	{
563 		if( mxTerminateListener.is() )
564 		{
565 			Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
566 
567 			if( xFact.is() )
568 			{
569 				Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
570 
571 				if( xDesktop.is() )
572 					xDesktop->removeTerminateListener( mxTerminateListener );
573 			}
574 
575 			mxTerminateListener = Reference< XTerminateListener >();
576 		}
577 
578 		ObjectReleased();
579 	}
580 	catch( const ::com::sun::star::uno::Exception& )
581 	{
582 	}
583 }
584 
585 // -----------------------------------------------------------------------------
586 
587 void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
588 {
589 }
590 
591 // -----------------------------------------------------------------------------
592 
593 void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
594 {
595 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
596 
597 	try
598 	{
599 		DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
600 		ObjectReleased();
601 	}
602 	catch( const ::com::sun::star::uno::Exception& )
603 	{
604 	}
605 }
606 
607 // -----------------------------------------------------------------------------
608 
609 void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
610 {
611 }
612 
613 // -----------------------------------------------------------------------------
614 
615 void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
616 {
617 }
618 
619 // -----------------------------------------------------------------------------
620 
621 void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
622 {
623 }
624 
625 // -----------------------------------------------------------------------------
626 
627 void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
628 {
629 }
630 
631 // -----------------------------------------------------------------------------
632 
633 sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
634 {
635     sal_Int64 nRet;
636 
637     if( ( rId.getLength() == 16 ) &&
638         ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
639     {
640         nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
641     }
642     else
643         nRet = 0;
644 
645 	return nRet;
646 }
647 
648 // -----------------------------------------------------------------------------
649 
650 void TransferableHelper::ImplFlush()
651 {
652 	if( mxClipboard.is() )
653 	{
654 		Reference< XFlushableClipboard >	xFlushableClipboard( mxClipboard, UNO_QUERY );
655 		const sal_uInt32					nRef = Application::ReleaseSolarMutex();
656 
657 		try
658 		{
659 			if( xFlushableClipboard.is() )
660 			 	xFlushableClipboard->flushClipboard();
661 		}
662 		catch( const ::com::sun::star::uno::Exception& )
663 		{
664 			DBG_ERROR( "Could not flush clipboard" );
665 		}
666 
667 		Application::AcquireSolarMutex( nRef );
668 	}
669 }
670 
671 // -----------------------------------------------------------------------------
672 
673 void TransferableHelper::AddFormat( SotFormatStringId nFormat )
674 {
675     DataFlavor aFlavor;
676 
677     if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
678         AddFormat( aFlavor );
679 }
680 
681 // -----------------------------------------------------------------------------
682 
683 void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
684 {
685 	DataFlavorExVector::iterator    aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
686     sal_Bool                        bAdd = sal_True;
687 
688 	while( aIter != aEnd )
689 	{
690         if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
691         {
692             // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
693             if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId ) && mpObjDesc )
694             {
695                 DataFlavor aObjDescFlavor;
696 
697                 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDescFlavor );
698                 aIter->MimeType = aObjDescFlavor.MimeType;
699                 aIter->MimeType += ::ImplGetParameterString( *mpObjDesc );
700 
701 #ifdef DEBUG
702                 fprintf( stderr, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
703                          ByteString( String( aIter->MimeType), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
704 #endif
705             }
706 
707             aIter = aEnd;
708             bAdd = sal_False;
709         }
710         else
711             aIter++;
712     }
713 
714     if( bAdd )
715     {
716     	DataFlavorEx   aFlavorEx;
717         DataFlavor     aObjDescFlavor;
718 
719 		aFlavorEx.MimeType = rFlavor.MimeType;
720 		aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
721 		aFlavorEx.DataType = rFlavor.DataType;
722 		aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
723 
724         if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aFlavorEx.mnSotId ) && mpObjDesc )
725             aFlavorEx.MimeType += ::ImplGetParameterString( *mpObjDesc );
726 
727 		mpFormats->push_back( aFlavorEx );
728 
729 		if( FORMAT_BITMAP == aFlavorEx.mnSotId )
730 		{
731 			AddFormat( SOT_FORMATSTR_ID_PNG );
732 			AddFormat( SOT_FORMATSTR_ID_BMP );
733 		}
734 		else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
735 		{
736 			AddFormat( SOT_FORMATSTR_ID_EMF );
737 			AddFormat( SOT_FORMATSTR_ID_WMF );
738 			AddFormat( SOT_FORMATSTR_ID_SVG );
739 		}
740     }
741 }
742 
743 // -----------------------------------------------------------------------------
744 
745 void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
746 {
747     DataFlavor aFlavor;
748 
749     if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
750         RemoveFormat( aFlavor );
751 }
752 
753 // -----------------------------------------------------------------------------
754 
755 void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
756 {
757 	DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
758 
759 	while( aIter != aEnd )
760 	{
761 		if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
762 		{
763 			aIter = mpFormats->erase( aIter );
764 			aEnd = mpFormats->end();
765 		}
766 		else
767 			++aIter;
768 	}
769 }
770 
771 // -----------------------------------------------------------------------------
772 
773 sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
774 {
775 	DataFlavorExVector::iterator	aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
776 	sal_Bool						bRet = sal_False;
777 
778 	while( aIter != aEnd )
779 	{
780 		if( nFormat == (*aIter).mnSotId )
781 		{
782 			aIter = aEnd;
783 			bRet = sal_True;
784 		}
785 		else
786 			++aIter;
787 	}
788 
789 	return bRet;
790 }
791 
792 // -----------------------------------------------------------------------------
793 
794 void TransferableHelper::ClearFormats()
795 {
796 	mpFormats->clear();
797     maAny.clear();
798 }
799 
800 // -----------------------------------------------------------------------------
801 
802 sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
803 {
804 	maAny = rAny;
805 	return( maAny.hasValue() );
806 }
807 
808 // -----------------------------------------------------------------------------
809 
810 sal_Bool TransferableHelper::SetString( const ::rtl::OUString& rString, const DataFlavor& rFlavor )
811 {
812 	DataFlavor aFileFlavor;
813 
814 	if( rString.getLength() &&
815 		SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
816 		TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
817 	{
818 		const String			aString( rString );
819 		const ByteString		aByteStr( aString, gsl_getSystemTextEncoding() );
820 		Sequence< sal_Int8 >	aSeq( aByteStr.Len() + 1 );
821 
822 		rtl_copyMemory( aSeq.getArray(), aByteStr.GetBuffer(), aByteStr.Len() );
823 		aSeq[ aByteStr.Len() ] = 0;
824 		maAny <<= aSeq;
825 	}
826 	else
827 		maAny <<= rString;
828 
829 	return( maAny.hasValue() );
830 }
831 
832 // -----------------------------------------------------------------------------
833 
834 sal_Bool TransferableHelper::SetBitmapEx( const BitmapEx& rBitmapEx, const DataFlavor& rFlavor )
835 {
836 	if( !rBitmapEx.IsEmpty() )
837 	{
838         SvMemoryStream aMemStm( 65535, 65535 );
839 
840         if(rFlavor.MimeType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("image/png")))
841         {
842             // write a PNG
843             ::vcl::PNGWriter aPNGWriter(rBitmapEx);
844 
845             aPNGWriter.Write(aMemStm);
846         }
847         else
848         {
849             const Bitmap aBitmap(rBitmapEx.GetBitmap());
850 
851             // #124085# take out DIBV5 for writing to the clipboard
852             //if(rBitmapEx.IsTransparent())
853             //{
854             //    const Bitmap aMask(rBitmapEx.GetAlpha().GetBitmap());
855             //
856             //    // explicitly use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True
857             //    WriteDIBV5(aBitmap, aMask, aMemStm);
858             //}
859             //else
860             //{
861                 // explicitly use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True
862                 WriteDIB(aBitmap, aMemStm, false, true);
863             //}
864         }
865 
866         maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
867 	}
868 
869 	return( maAny.hasValue() );
870 }
871 
872 // -----------------------------------------------------------------------------
873 
874 sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
875 {
876 	if( rMtf.GetActionCount() )
877 	{
878 		SvMemoryStream aMemStm( 65535, 65535 );
879 
880 		( (GDIMetaFile&) rMtf ).Write( aMemStm );
881 		maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
882 	}
883 
884 	return( maAny.hasValue() );
885 }
886 
887 // -----------------------------------------------------------------------------
888 
889 sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
890 {
891 	if( rGraphic.GetType() != GRAPHIC_NONE )
892 	{
893 		SvMemoryStream aMemStm( 65535, 65535 );
894 
895         aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
896         aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
897 		aMemStm << rGraphic;
898 		maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
899 	}
900 
901 	return( maAny.hasValue() );
902 }
903 
904 // -----------------------------------------------------------------------------
905 
906 sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
907 {
908 	SvMemoryStream aMemStm( 8192, 8192 );
909 
910     aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
911     rIMap.Write( aMemStm, String() );
912 	maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
913 
914 	return( maAny.hasValue() );
915 }
916 
917 // -----------------------------------------------------------------------------
918 
919 sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
920 															  const ::com::sun::star::datatransfer::DataFlavor& )
921 {
922     PrepareOLE( rDesc );
923 
924 	SvMemoryStream aMemStm( 1024, 1024 );
925 
926 	aMemStm << rDesc;
927 	maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
928 
929 	return( maAny.hasValue() );
930  }
931 
932 // -----------------------------------------------------------------------------
933 
934 sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
935 											  const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
936 {
937 	rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
938 
939 	switch( SotExchange::GetFormat( rFlavor ) )
940 	{
941 		case( SOT_FORMATSTR_ID_SOLK ):
942 		{
943 			ByteString sURL( rBmk.GetURL(), eSysCSet ),
944 					   sDesc( rBmk.GetDescription(), eSysCSet );
945 			ByteString sOut( ByteString::CreateFromInt32( sURL.Len() ));
946 			( sOut += '@' ) += sURL;
947 			sOut += ByteString::CreateFromInt32( sDesc.Len() );
948 			( sOut += '@' ) += sDesc;
949 
950 			Sequence< sal_Int8 > aSeq( sOut.Len() );
951 			memcpy( aSeq.getArray(), sOut.GetBuffer(), sOut.Len() );
952 			maAny <<= aSeq;
953 		}
954 		break;
955 
956 		case( FORMAT_STRING ):
957 			maAny <<= ::rtl::OUString( rBmk.GetURL() );
958 			break;
959 
960 		case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
961 		{
962 			ByteString sURL( rBmk.GetURL(), eSysCSet );
963 			Sequence< sal_Int8 > aSeq( sURL.Len() );
964 			memcpy( aSeq.getArray(), sURL.GetBuffer(), sURL.Len() );
965 			maAny <<= aSeq;
966 		}
967 		break;
968 
969 		case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
970 		{
971 			Sequence< sal_Int8 > aSeq( 2048 );
972 
973 			memset( aSeq.getArray(), 0, 2048 );
974 			strcpy( reinterpret_cast< char* >( aSeq.getArray() ), ByteString( rBmk.GetURL(), eSysCSet).GetBuffer() );
975 			strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, ByteString( rBmk.GetDescription(), eSysCSet ).GetBuffer() );
976 
977 			maAny <<= aSeq;
978 		}
979 		break;
980 
981 #ifdef WNT
982 		case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
983 		{
984 			Sequence< sal_Int8 >	aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
985 			FILEGROUPDESCRIPTOR*	pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
986 			FILEDESCRIPTOR&			rFDesc1 = pFDesc->fgd[ 0 ];
987 
988 			pFDesc->cItems = 1;
989 			memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
990 			rFDesc1.dwFlags = FD_LINKUI;
991 
992 			ByteString aStr( rBmk.GetDescription(), eSysCSet );
993 			for( sal_uInt16 nChar = 0; nChar < aStr.Len(); ++nChar )
994 				if( strchr( "\\/:*?\"<>|", aStr.GetChar( nChar ) ) )
995 					aStr.Erase( nChar--, 1 );
996 
997 			aStr.Insert( "Shortcut to ", 0 );
998 			aStr += ".URL";
999 			strcpy( rFDesc1.cFileName, aStr.GetBuffer() );
1000 
1001 			maAny <<= aSeq;
1002 		}
1003 		break;
1004 
1005 		case SOT_FORMATSTR_ID_FILECONTENT:
1006 		{
1007 			String aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
1008 			maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
1009 		}
1010 		break;
1011 #endif
1012 
1013 		default:
1014 		break;
1015 	}
1016 
1017 	return( maAny.hasValue() );
1018 }
1019 
1020 // -----------------------------------------------------------------------------
1021 
1022 sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
1023 										   const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
1024 {
1025 	SvMemoryStream aMemStm( 1024, 1024 );
1026 
1027     aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
1028 	rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
1029 
1030 	maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
1031 
1032 	return( maAny.hasValue() );
1033 }
1034 
1035 // -----------------------------------------------------------------------------
1036 
1037 sal_Bool TransferableHelper::SetFileList( const FileList& rFileList,
1038 										  const ::com::sun::star::datatransfer::DataFlavor& )
1039 {
1040 	SvMemoryStream aMemStm( 4096, 4096 );
1041 
1042     aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
1043 	aMemStm << rFileList;
1044 
1045 	maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
1046                                        aMemStm.Seek( STREAM_SEEK_TO_END ) );
1047 
1048 	return( maAny.hasValue() );
1049 }
1050 
1051 // -----------------------------------------------------------------------------
1052 
1053 sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
1054 {
1055 	SotStorageStreamRef xStm( new SotStorageStream( String() ) );
1056 
1057     xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1058 
1059 	if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
1060 	{
1061 		const sal_uInt32		nLen = xStm->Seek( STREAM_SEEK_TO_END );
1062 		Sequence< sal_Int8 >	aSeq( nLen );
1063 
1064 		xStm->Seek( STREAM_SEEK_TO_BEGIN );
1065 		xStm->Read( aSeq.getArray(),  nLen );
1066 
1067 		if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
1068         {
1069             //JP 24.7.2001: as I know was this only for the writer application and this
1070             //		        writes now UTF16 format into the stream
1071             //JP 6.8.2001:  and now it writes UTF8 because then exist no problem with
1072             //		        little / big endians! - Bug 88121
1073 			maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
1074         }
1075 		else
1076 			maAny <<= aSeq;
1077 	}
1078 
1079 	return( maAny.hasValue() );
1080 }
1081 
1082 // -----------------------------------------------------------------------------
1083 
1084 sal_Bool TransferableHelper::SetInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rIf,
1085 										   const ::com::sun::star::datatransfer::DataFlavor& )
1086 {
1087 	maAny <<= rIf;
1088 	return( maAny.hasValue() );
1089 }
1090 
1091 // -----------------------------------------------------------------------------
1092 
1093 sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
1094 {
1095 	DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
1096 	return sal_False;
1097 }
1098 
1099 // -----------------------------------------------------------------------------
1100 
1101 void TransferableHelper::DragFinished( sal_Int8 )
1102 {
1103 }
1104 
1105 // -----------------------------------------------------------------------------
1106 
1107 void TransferableHelper::ObjectReleased()
1108 {
1109 }
1110 
1111 // -----------------------------------------------------------------------------
1112 
1113 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
1114 {
1115     delete mpObjDesc;
1116     mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
1117 
1118     if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
1119         AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
1120 }
1121 
1122 // -----------------------------------------------------------------------------
1123 
1124 void TransferableHelper::CopyToClipboard( Window *pWindow ) const
1125 {
1126 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
1127     Reference< XClipboard > xClipboard;
1128 
1129     if( pWindow )
1130         xClipboard = pWindow->GetClipboard();
1131 
1132     if( xClipboard.is() )
1133         mxClipboard = xClipboard;
1134 
1135 	if( mxClipboard.is() && !mxTerminateListener.is() )
1136 	{
1137 		const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1138 
1139 		try
1140 		{
1141             TransferableHelper*                 pThis = const_cast< TransferableHelper* >( this );
1142 			Reference< XMultiServiceFactory >   xFact( ::comphelper::getProcessServiceFactory() );
1143 
1144 			if( xFact.is() )
1145 			{
1146 				Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1147 
1148 				if( xDesktop.is() )
1149 					xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1150 			}
1151 
1152 			mxClipboard->setContents( pThis, pThis );
1153 		}
1154 		catch( const ::com::sun::star::uno::Exception& )
1155 		{
1156 		}
1157 
1158 		Application::AcquireSolarMutex( nRef );
1159 	}
1160 }
1161 
1162 // -----------------------------------------------------------------------------
1163 
1164 void TransferableHelper::CopyToSelection( Window *pWindow ) const
1165 {
1166 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
1167     Reference< XClipboard > xSelection;
1168 
1169     if( pWindow )
1170         xSelection = pWindow->GetPrimarySelection();
1171 
1172 	if( xSelection.is() && !mxTerminateListener.is() )
1173 	{
1174 		const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1175 
1176 		try
1177 		{
1178             TransferableHelper*                 pThis = const_cast< TransferableHelper* >( this );
1179 			Reference< XMultiServiceFactory >   xFact( ::comphelper::getProcessServiceFactory() );
1180 
1181 			if( xFact.is() )
1182 			{
1183 				Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1184 
1185 				if( xDesktop.is() )
1186 					xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1187 			}
1188 
1189 			xSelection->setContents( pThis, pThis );
1190 		}
1191 		catch( const ::com::sun::star::uno::Exception& )
1192 		{
1193 		}
1194 
1195 		Application::AcquireSolarMutex( nRef );
1196 	}
1197 }
1198 
1199 // -----------------------------------------------------------------------------
1200 
1201 void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
1202 									sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
1203 
1204 {
1205 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
1206     Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
1207 
1208 	if( xDragSource.is() )
1209 	{
1210         /*
1211          *    #96792# release mouse before actually starting DnD.
1212          *    This is necessary for the X11 DnD implementation to work.
1213          */
1214         if( pWindow->IsMouseCaptured() )
1215             pWindow->ReleaseMouse();
1216 
1217         const Point	aPt( pWindow->GetPointerPosPixel() );
1218 
1219 		// On Mac OS X we are forced to execute 'startDrag' synchronously
1220 		// contrary to the XDragSource interface specification because
1221 		// we can receive drag events from the system only in the main
1222 		// thread
1223 #if !defined(QUARTZ)
1224 		const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1225 #endif
1226 
1227 		try
1228 		{
1229 			DragGestureEvent	aEvt;
1230 			aEvt.DragAction = DNDConstants::ACTION_COPY;
1231 			aEvt.DragOriginX = aPt.X();
1232 			aEvt.DragOriginY = aPt.Y();
1233 			aEvt.DragSource = xDragSource;
1234 
1235 			xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
1236 		}
1237 		catch( const ::com::sun::star::uno::Exception& )
1238 		{
1239 		}
1240 
1241 		// See above for the reason of this define
1242 #if !defined(QUARTZ)
1243 		Application::AcquireSolarMutex( nRef );
1244 #endif
1245 	}
1246 }
1247 
1248 // -----------------------------------------------------------------------------
1249 
1250 void TransferableHelper::ClearSelection( Window *pWindow )
1251 {
1252 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
1253     Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
1254 
1255 	if( xSelection.is() )
1256         xSelection->setContents( NULL, NULL );
1257 }
1258 
1259 // -----------------------------------------------------------------------------
1260 
1261 Reference< XClipboard> TransferableHelper::GetSystemClipboard()
1262 {
1263     Window *pFocusWindow = Application::GetFocusWindow();
1264 
1265     if( pFocusWindow )
1266         return pFocusWindow->GetClipboard();
1267 
1268 	return 	Reference< XClipboard > ();
1269 }
1270 
1271 // -----------------------------------------------------------------------------
1272 
1273 const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
1274 {
1275     static Sequence< sal_Int8 > aSeq;
1276 
1277 	if( !aSeq.getLength() )
1278 	{
1279 		static osl::Mutex           aCreateMutex;
1280     	osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
1281 
1282 		aSeq.realloc( 16 );
1283     	rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
1284 	}
1285 
1286 
1287     return aSeq;
1288 }
1289 
1290 // ---------------------------------
1291 // - TransferableClipboardNotifier -
1292 // ---------------------------------
1293 
1294 class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
1295 {
1296 private:
1297     ::osl::Mutex&                   mrMutex;
1298     Reference< XClipboardNotifier > mxNotifier;
1299 	TransferableDataHelper*		    mpListener;
1300 
1301 protected:
1302 	// XClipboardListener
1303     virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
1304 
1305     // XEventListener
1306     virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
1307 
1308 public:
1309     TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
1310 
1311     /// determines whether we're currently listening
1312     inline bool isListening() const { return !isDisposed(); }
1313 
1314     /// determines whether the instance is disposed
1315     inline bool isDisposed() const { return mpListener == NULL; }
1316 
1317     /// makes the instance non-functional
1318     void    dispose();
1319 };
1320 
1321 // -----------------------------------------------------------------------------
1322 
1323 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
1324     :mrMutex( _rMutex )
1325     ,mxNotifier( _rxClipboard, UNO_QUERY )
1326     ,mpListener( &_rListener )
1327 {
1328     osl_incrementInterlockedCount( &m_refCount );
1329     {
1330         if ( mxNotifier.is() )
1331 		    mxNotifier->addClipboardListener( this );
1332         else
1333             // born dead
1334             mpListener = NULL;
1335     }
1336     osl_decrementInterlockedCount( &m_refCount );
1337 }
1338 
1339 // -----------------------------------------------------------------------------
1340 
1341 void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
1342 {
1343 	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1344         // the SolarMutex here is necessary, since
1345         // - we cannot call mpListener without our own mutex locked
1346         // - Rebind respectively InitFormats (called by Rebind) will
1347         // try to lock the SolarMutex, too
1348     ::osl::MutexGuard aGuard( mrMutex );
1349 	if( mpListener )
1350 		mpListener->Rebind( event.Contents );
1351 }
1352 
1353 // -----------------------------------------------------------------------------
1354 
1355 void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
1356 {
1357     // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1358 	dispose();
1359 }
1360 
1361 // -----------------------------------------------------------------------------
1362 
1363 void TransferableClipboardNotifier::dispose()
1364 {
1365     ::osl::MutexGuard aGuard( mrMutex );
1366 
1367     Reference< XClipboardListener > xKeepMeAlive( this );
1368 
1369     if ( mxNotifier.is() )
1370 		mxNotifier->removeClipboardListener( this );
1371     mxNotifier.clear();
1372 
1373     mpListener = NULL;
1374 }
1375 
1376 // -------------------------------
1377 // - TransferableDataHelper_Impl -
1378 // -------------------------------
1379 
1380 struct TransferableDataHelper_Impl
1381 {
1382     ::osl::Mutex                    maMutex;
1383     TransferableClipboardNotifier*  mpClipboardListener;
1384 
1385     TransferableDataHelper_Impl()
1386         :mpClipboardListener( NULL )
1387     {
1388     }
1389 };
1390 
1391 // --------------------------
1392 // - TransferableDataHelper -
1393 // --------------------------
1394 
1395 TransferableDataHelper::TransferableDataHelper() :
1396     mpFormats( new DataFlavorExVector ),
1397     mpObjDesc( new TransferableObjectDescriptor ),
1398     mpImpl( new TransferableDataHelper_Impl )
1399 {
1400 }
1401 
1402 // -----------------------------------------------------------------------------
1403 
1404 TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
1405     mxTransfer( rxTransferable ),
1406     mpFormats( new DataFlavorExVector ),
1407     mpObjDesc( new TransferableObjectDescriptor ),
1408     mpImpl( new TransferableDataHelper_Impl )
1409 {
1410 	InitFormats();
1411 }
1412 
1413 // -----------------------------------------------------------------------------
1414 
1415 TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
1416     mxTransfer( rDataHelper.mxTransfer ),
1417     mxClipboard( rDataHelper.mxClipboard ),
1418 	mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
1419     mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
1420     mpImpl( new TransferableDataHelper_Impl )
1421 {
1422 }
1423 
1424 // -----------------------------------------------------------------------------
1425 
1426 TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
1427 {
1428 	if ( this != &rDataHelper )
1429 	{
1430         ::osl::MutexGuard aGuard( mpImpl->maMutex );
1431 
1432         bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
1433 
1434         if ( bWasClipboardListening )
1435             StopClipboardListening();
1436 
1437         mxTransfer = rDataHelper.mxTransfer;
1438 		delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
1439         delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
1440 		mxClipboard = rDataHelper.mxClipboard;
1441 
1442         if ( bWasClipboardListening )
1443             StartClipboardListening();
1444 	}
1445 
1446 	return *this;
1447 }
1448 
1449 // -----------------------------------------------------------------------------
1450 
1451 TransferableDataHelper::~TransferableDataHelper()
1452 {
1453 	StopClipboardListening( );
1454     {
1455         ::osl::MutexGuard aGuard( mpImpl->maMutex );
1456 	    delete mpFormats, mpFormats = NULL;
1457         delete mpObjDesc, mpObjDesc = NULL;
1458     }
1459     delete mpImpl;
1460 }
1461 
1462 // -----------------------------------------------------------------------------
1463 
1464 void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
1465                                                      DataFlavorExVector& rDataFlavorExVector )
1466 {
1467     try
1468     {
1469 	    Reference< XMultiServiceFactory >       xFact( ::comphelper::getProcessServiceFactory() );
1470         Reference< XMimeContentTypeFactory >    xMimeFact;
1471 	    DataFlavorEx		                    aFlavorEx;
1472         const ::rtl::OUString                   aCharsetStr( ::rtl::OUString::createFromAscii( "charset" ) );
1473 
1474 	    if( xFact.is() )
1475 		    xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
1476                                                               "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
1477                                                               UNO_QUERY );
1478 
1479 	    for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
1480 	    {
1481 		    const DataFlavor&	            rFlavor = rDataFlavorSeq[ i ];
1482             Reference< XMimeContentType >   xMimeType;
1483 
1484             try
1485             {
1486                 if( xMimeFact.is() && rFlavor.MimeType.getLength() )
1487                     xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
1488             }
1489             catch( const ::com::sun::star::uno::Exception& )
1490 	        {
1491 
1492 	        }
1493 
1494 		    aFlavorEx.MimeType = rFlavor.MimeType;
1495 		    aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
1496 		    aFlavorEx.DataType = rFlavor.DataType;
1497 		    aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
1498 
1499 		    rDataFlavorExVector.push_back( aFlavorEx );
1500 
1501             // add additional formats for special mime types
1502             if(SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_PNG == aFlavorEx.mnSotId)
1503 		    {
1504 			    if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
1505 			    {
1506 				    aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
1507 				    rDataFlavorExVector.push_back( aFlavorEx );
1508 			    }
1509 		    }
1510             else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_SVG == aFlavorEx.mnSotId )
1511 		    {
1512 			    if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
1513 			    {
1514 				    aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
1515 				    rDataFlavorExVector.push_back( aFlavorEx );
1516 			    }
1517 		    }
1518             else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId  )
1519             {
1520                 // #104735# HTML_SIMPLE may also be inserted without comments
1521                 aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
1522                 rDataFlavorExVector.push_back( aFlavorEx );
1523             }
1524             else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
1525             {
1526                 // add, if it is a UTF-8 byte buffer
1527                 if( xMimeType->hasParameter( aCharsetStr ) )
1528                 {
1529                     const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
1530 
1531                     if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) ||
1532 					    xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) )
1533                     {
1534                         rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
1535 
1536                     }
1537                 }
1538             }
1539             else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/rtf" ) ) )
1540             {
1541                 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
1542             }
1543             else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/html" ) ) )
1544 
1545             {
1546                 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
1547             }
1548             else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) )
1549             {
1550                 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
1551             }
1552             else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice-objectdescriptor-xml" ) ) )
1553             {
1554                 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
1555             }
1556 	    }
1557     }
1558 	catch( const ::com::sun::star::uno::Exception& )
1559 	{
1560 	}
1561 }
1562 
1563 // -----------------------------------------------------------------------------
1564 
1565 void TransferableDataHelper::InitFormats()
1566 {
1567 	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1568     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1569 
1570     mpFormats->clear();
1571     delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
1572 
1573     if( mxTransfer.is() )
1574     {
1575         TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
1576 
1577         DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1578 
1579         while( aIter != aEnd )
1580         {
1581             if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
1582             {
1583                 ImplSetParameterString( *mpObjDesc, *aIter );
1584                 aIter = aEnd;
1585             }
1586             else
1587                 ++aIter;
1588         }
1589     }
1590 }
1591 
1592 // -----------------------------------------------------------------------------
1593 
1594 sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
1595 {
1596     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1597 
1598 	DataFlavorExVector::iterator	aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1599 	sal_Bool						bRet = sal_False;
1600 
1601 	while( aIter != aEnd )
1602 	{
1603 		if( nFormat == (*aIter++).mnSotId )
1604 		{
1605 			aIter = aEnd;
1606 			bRet = sal_True;
1607 		}
1608 	}
1609 
1610 	return bRet;
1611 }
1612 
1613 // -----------------------------------------------------------------------------
1614 
1615 sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
1616 {
1617     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1618 
1619     DataFlavorExVector::iterator	aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1620 	sal_Bool						bRet = sal_False;
1621 
1622 	while( aIter != aEnd )
1623 	{
1624 		if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
1625 		{
1626 			aIter = aEnd;
1627 			bRet = sal_True;
1628 		}
1629 	}
1630 
1631 	return bRet;
1632 }
1633 
1634 // -----------------------------------------------------------------------------
1635 
1636 sal_uInt32 TransferableDataHelper::GetFormatCount() const
1637 {
1638     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1639 	return mpFormats->size();
1640 }
1641 
1642 // -----------------------------------------------------------------------------
1643 
1644 
1645 SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
1646 {
1647     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1648 	DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1649 	return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
1650 }
1651 
1652 // -----------------------------------------------------------------------------
1653 
1654 DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
1655 {
1656     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1657 	DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1658 
1659     DataFlavor aRet;
1660 
1661 	if( nFormat < mpFormats->size() )
1662 		aRet = (*mpFormats)[ nFormat ];
1663 
1664 	return aRet;
1665 }
1666 
1667 // -----------------------------------------------------------------------------
1668 
1669 Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
1670 {
1671 	Reference< XTransferable > xRet;
1672 
1673 	if( mxTransfer.is() )
1674 	{
1675 		try
1676 		{
1677 			xRet = mxTransfer;
1678 
1679 			// do a dummy call to check, if this interface is valid (nasty)
1680 			Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
1681 
1682 		}
1683 		catch( const ::com::sun::star::uno::Exception& )
1684 		{
1685 			xRet = Reference< XTransferable >();
1686 		}
1687 	}
1688 
1689 	return xRet;
1690 }
1691 
1692 // -----------------------------------------------------------------------------
1693 
1694 Any	TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
1695 {
1696 	Any aReturn;
1697 
1698 	DataFlavor aFlavor;
1699 	if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
1700 		aReturn = GetAny( aFlavor );
1701 
1702 	return aReturn;
1703 }
1704 
1705 
1706 // -----------------------------------------------------------------------------
1707 
1708 Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
1709 {
1710     ::osl::MutexGuard aGuard( mpImpl->maMutex );
1711 	Any aRet;
1712 
1713 	try
1714 	{
1715 		if( mxTransfer.is() )
1716         {
1717             DataFlavorExVector::iterator    aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1718             const SotFormatStringId         nRequestFormat = SotExchange::GetFormat( rFlavor );
1719 
1720             if( nRequestFormat )
1721             {
1722     	        // try to get alien format first
1723 	            while( aIter != aEnd )
1724 	            {
1725                     if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
1726             			aRet = mxTransfer->getTransferData( *aIter );
1727 
1728                     if( aRet.hasValue() )
1729                         aIter = aEnd;
1730                     else
1731                         aIter++;
1732 	            }
1733             }
1734 
1735             if( !aRet.hasValue() )
1736     			aRet = mxTransfer->getTransferData( rFlavor );
1737         }
1738 	}
1739 	catch( const ::com::sun::star::uno::Exception& )
1740 	{
1741 	}
1742 
1743 	return aRet;
1744 }
1745 
1746 // -----------------------------------------------------------------------------
1747 
1748 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
1749 {
1750     ::rtl::OUString aOUString;
1751     sal_Bool        bRet = GetString( nFormat, aOUString );
1752 
1753     rStr = aOUString;
1754 
1755     return bRet;
1756 }
1757 
1758 // -----------------------------------------------------------------------------
1759 
1760 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
1761 {
1762     ::rtl::OUString aOUString;
1763     sal_Bool        bRet = GetString( rFlavor, aOUString );
1764 
1765     rStr = aOUString;
1766 
1767     return bRet;
1768 }
1769 
1770 // -----------------------------------------------------------------------------
1771 
1772 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
1773 {
1774 	DataFlavor aFlavor;
1775 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
1776 }
1777 
1778 // -----------------------------------------------------------------------------
1779 
1780 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
1781 {
1782 	Any         aAny( GetAny( rFlavor ) );
1783     sal_Bool    bRet = sal_False;
1784 
1785     if( aAny.hasValue() )
1786 	{
1787 		::rtl::OUString         aOUString;
1788 		Sequence< sal_Int8 >    aSeq;
1789 
1790         if( aAny >>= aOUString )
1791         {
1792 			rStr = aOUString;
1793             bRet = sal_True;
1794         }
1795 		else if( aAny >>= aSeq )
1796 		{
1797 
1798 			const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
1799 			sal_Int32       nLen = aSeq.getLength();
1800 
1801             //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1802             //DVO 2002-05-27: strip _all_ trailing zeros
1803 			while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
1804 				--nLen;
1805 
1806 			rStr = ::rtl::OUString( pChars, nLen, gsl_getSystemTextEncoding() );
1807             bRet = sal_True;
1808 		}
1809 	}
1810 
1811     return bRet;
1812 }
1813 
1814 // -----------------------------------------------------------------------------
1815 
1816 sal_Bool TransferableDataHelper::GetBitmapEx( SotFormatStringId nFormat, BitmapEx& rBmpEx )
1817 {
1818     if(FORMAT_BITMAP == nFormat)
1819     {
1820         // try to get PNG first
1821         DataFlavor aFlavor;
1822 
1823         if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor))
1824         {
1825             if(GetBitmapEx(aFlavor, rBmpEx))
1826             {
1827                 return true;
1828             }
1829         }
1830     }
1831 
1832     DataFlavor aFlavor;
1833     return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmapEx( aFlavor, rBmpEx ) );
1834 }
1835 
1836 // -----------------------------------------------------------------------------
1837 
1838 sal_Bool TransferableDataHelper::GetBitmapEx( const DataFlavor& rFlavor, BitmapEx& rBmpEx )
1839 {
1840     SotStorageStreamRef xStm;
1841     DataFlavor aSubstFlavor;
1842     bool bRet(GetSotStorageStream(rFlavor, xStm));
1843     bool bSuppressPNG(false); // #122982# If PNG stream not accessed, but BMP one, suppress trying to load PNG
1844 
1845     if(!bRet && HasFormat(SOT_FORMATSTR_ID_PNG) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aSubstFlavor))
1846     {
1847         // when no direct success, try if PNG is available
1848         bRet = GetSotStorageStream(aSubstFlavor, xStm);
1849     }
1850 
1851     if(!bRet && HasFormat(SOT_FORMATSTR_ID_BMP) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_BMP, aSubstFlavor))
1852     {
1853         // when no direct success, try if BMP is available
1854         bRet = GetSotStorageStream(aSubstFlavor, xStm);
1855         bSuppressPNG = bRet;
1856     }
1857 
1858     if(bRet)
1859     {
1860         if(!bSuppressPNG && rFlavor.MimeType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("image/png")))
1861         {
1862             // it's a PNG, import to BitmapEx
1863             ::vcl::PNGReader aPNGReader(*xStm);
1864 
1865             rBmpEx = aPNGReader.Read();
1866         }
1867 
1868         if(rBmpEx.IsEmpty())
1869         {
1870             Bitmap aBitmap;
1871             Bitmap aMask;
1872 
1873             // explicitly use Bitmap::Read with bFileHeader = sal_True
1874             // #124085# keep DIBV5 for read from clipboard, but should not happen
1875             ReadDIBV5(aBitmap, aMask, *xStm);
1876 
1877             if(aMask.IsEmpty())
1878             {
1879                 rBmpEx = aBitmap;
1880             }
1881             else
1882             {
1883                 rBmpEx = BitmapEx(aBitmap, aMask);
1884             }
1885         }
1886 
1887         bRet = (ERRCODE_NONE == xStm->GetError() && !rBmpEx.IsEmpty());
1888 
1889         /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1890            problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1891            and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1892            Due to this reason the following code assumes that bitmaps with a logical size
1893            greater than 50 cm aren't having the correct mapmode set.
1894 
1895            The following code should be removed if DDBs and DIBs are supported via clipboard
1896            properly.
1897         */
1898         if(bRet)
1899         {
1900             const MapMode aMapMode(rBmpEx.GetPrefMapMode());
1901 
1902             if(MAP_PIXEL != aMapMode.GetMapUnit())
1903             {
1904                 const Size aSize(OutputDevice::LogicToLogic(rBmpEx.GetPrefSize(), aMapMode, MAP_100TH_MM));
1905 
1906                 // #122388# This wrongly corrects in the given case; changing from 5000 100th mm to
1907                 // the described 50 cm (which is 50000 100th mm)
1908                 if((aSize.Width() > 50000) || (aSize.Height() > 50000))
1909                 {
1910                     rBmpEx.SetPrefMapMode(MAP_PIXEL);
1911 
1912                     // #122388# also adapt size by applying the mew MapMode
1913                     const Size aNewSize(OutputDevice::LogicToLogic(aSize, MAP_100TH_MM, MAP_PIXEL));
1914                     rBmpEx.SetPrefSize(aNewSize);
1915                 }
1916             }
1917         }
1918     }
1919 
1920     return bRet;
1921 }
1922 
1923 // -----------------------------------------------------------------------------
1924 
1925 sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
1926 {
1927 	DataFlavor aFlavor;
1928 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
1929 }
1930 
1931 // -----------------------------------------------------------------------------
1932 
1933 sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
1934 {
1935 	SotStorageStreamRef xStm;
1936 	DataFlavor			aSubstFlavor;
1937 	sal_Bool			bRet = sal_False;
1938 
1939 	if( GetSotStorageStream( rFlavor, xStm ) )
1940 	{
1941 		*xStm >> rMtf;
1942 		bRet = ( xStm->GetError() == ERRCODE_NONE );
1943 	}
1944 
1945 	if( !bRet &&
1946 		HasFormat( SOT_FORMATSTR_ID_EMF ) &&
1947 		SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
1948 		GetSotStorageStream( aSubstFlavor, xStm ) )
1949 	{
1950 		Graphic aGraphic;
1951 
1952 		if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1953 		{
1954 			rMtf = aGraphic.GetGDIMetaFile();
1955 			bRet = sal_True;
1956 		}
1957 	}
1958 
1959 	if( !bRet &&
1960 		HasFormat( SOT_FORMATSTR_ID_WMF ) &&
1961 		SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
1962 		GetSotStorageStream( aSubstFlavor, xStm ) )
1963 	{
1964 		Graphic aGraphic;
1965 
1966 		if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1967 		{
1968 			rMtf = aGraphic.GetGDIMetaFile();
1969 			bRet = sal_True;
1970 		}
1971 	}
1972 
1973 	return bRet;
1974 }
1975 
1976 // -----------------------------------------------------------------------------
1977 
1978 sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
1979 {
1980     if(FORMAT_BITMAP == nFormat)
1981     {
1982         // try to get PNG first
1983         DataFlavor aFlavor;
1984 
1985         if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor))
1986         {
1987             if(GetGraphic(aFlavor, rGraphic))
1988             {
1989                 return true;
1990             }
1991         }
1992     }
1993 
1994     DataFlavor aFlavor;
1995     return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
1996 }
1997 
1998 // -----------------------------------------------------------------------------
1999 
2000 sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
2001 {
2002 	DataFlavor	aFlavor;
2003 	sal_Bool	bRet = sal_False;
2004 
2005     if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor) &&
2006         TransferableDataHelper::IsEqual(aFlavor, rFlavor))
2007 	{
2008         // try to get PNG first
2009 		BitmapEx aBmpEx;
2010 
2011 		if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True )
2012 			rGraphic = aBmpEx;
2013 	}
2014 	else if(SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
2015 		TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
2016 	{
2017 		BitmapEx aBmpEx;
2018 
2019 		if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True )
2020 			rGraphic = aBmpEx;
2021 	}
2022 	else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
2023 			 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
2024 	{
2025 		GDIMetaFile aMtf;
2026 
2027 		if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
2028 			rGraphic = aMtf;
2029 	}
2030 	else
2031 	{
2032 		SotStorageStreamRef xStm;
2033 
2034 		if( GetSotStorageStream( rFlavor, xStm ) )
2035 		{
2036 			*xStm >> rGraphic;
2037 			bRet = ( xStm->GetError() == ERRCODE_NONE );
2038 		}
2039 	}
2040 
2041 	return bRet;
2042 }
2043 
2044 // -----------------------------------------------------------------------------
2045 
2046 sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
2047 {
2048 	DataFlavor aFlavor;
2049     return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
2050 }
2051 
2052 // -----------------------------------------------------------------------------
2053 
2054 sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
2055 {
2056 	SotStorageStreamRef xStm;
2057 	sal_Bool			bRet = GetSotStorageStream( rFlavor, xStm );
2058 
2059 	if( bRet )
2060 	{
2061         rIMap.Read( *xStm, String() );
2062 		bRet = ( xStm->GetError() == ERRCODE_NONE );
2063 	}
2064 
2065 	return bRet;
2066 }
2067 
2068 // -----------------------------------------------------------------------------
2069 
2070 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
2071 {
2072 	DataFlavor aFlavor;
2073 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
2074 }
2075 
2076 // -----------------------------------------------------------------------------
2077 
2078 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
2079 {
2080     rDesc = *mpObjDesc;
2081     return true;
2082 }
2083 
2084 // -----------------------------------------------------------------------------
2085 
2086 sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
2087 {
2088 	DataFlavor aFlavor;
2089 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
2090 }
2091 
2092 // -----------------------------------------------------------------------------
2093 
2094 sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
2095 {
2096 	sal_Bool bRet = sal_False;
2097 	if( HasFormat( rFlavor ))
2098 	{
2099 	const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
2100 	switch( nFormat )
2101 	{
2102 		case( SOT_FORMATSTR_ID_SOLK ):
2103 		case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
2104 		{
2105 			String aString;
2106 			if( GetString( rFlavor, aString ) )
2107 			{
2108 				if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
2109 				{
2110 					rBmk = INetBookmark( aString, aString );
2111 					bRet = sal_True;
2112 				}
2113 				else
2114 				{
2115 					String		aURL, aDesc;
2116 					sal_uInt16	nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
2117 
2118 					if( !nLen && aString.GetChar( 0 ) != '0' )
2119 					{
2120 						DBG_WARNING( "SOLK: 1. len=0" );
2121 					}
2122 					if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
2123 					{
2124 						DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
2125 					}
2126 					aURL = aString.Copy( nStart + 1, nLen );
2127 
2128 					aString.Erase( 0, nStart + 1 + nLen );
2129 					nStart = aString.Search( '@' );
2130 					nLen = (sal_uInt16) aString.ToInt32();
2131 
2132 					if( !nLen && aString.GetChar( 0 ) != '0' )
2133 					{
2134 						DBG_WARNING( "SOLK: 2. len=0" );
2135 					}
2136 					if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
2137 					{
2138 						DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
2139 					}
2140 					aDesc = aString.Copy( nStart+1, nLen );
2141 
2142 					rBmk = INetBookmark( aURL, aDesc );
2143 					bRet = sal_True;
2144 				}
2145 			}
2146 		}
2147 		break;
2148 
2149 		case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
2150 		{
2151 			Sequence< sal_Int8 > aSeq;
2152 
2153 			if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
2154 			{
2155 				rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), gsl_getSystemTextEncoding() ),
2156 									 String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, gsl_getSystemTextEncoding() ) );
2157 				bRet = sal_True;
2158 			}
2159 		}
2160 		break;
2161 
2162 #ifdef WNT
2163 		case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
2164 		{
2165 			Sequence< sal_Int8 > aSeq;
2166 
2167 			if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
2168 			{
2169 				FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
2170 
2171 				if( pFDesc->cItems )
2172 				{
2173 					ByteString			aDesc( pFDesc->fgd[ 0 ].cFileName );
2174 					rtl_TextEncoding	eTextEncoding = gsl_getSystemTextEncoding();
2175 
2176 					if( ( aDesc.Len() > 4 ) && aDesc.Copy( aDesc.Len() - 4 ).EqualsIgnoreCaseAscii( ".URL" ) )
2177 					{
2178 						SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( String( aDesc, eTextEncoding ) ).GetMainURL( INetURLObject::NO_DECODE ),
2179                                                                                   STREAM_STD_READ );
2180 
2181 						if( !pStream || pStream->GetError() )
2182 						{
2183 							DataFlavor aFileContentFlavor;
2184 
2185 							aSeq.realloc( 0 );
2186 							delete pStream;
2187 
2188 							if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
2189 								GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
2190 							{
2191 								pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
2192 							}
2193 							else
2194 								pStream = NULL;
2195 						}
2196 
2197 						if( pStream )
2198 						{
2199 							ByteString	aLine;
2200 							sal_Bool	bSttFnd = sal_False;
2201 
2202 							while( pStream->ReadLine( aLine ) )
2203 							{
2204 								if( aLine.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
2205 									bSttFnd = sal_True;
2206 								else if( bSttFnd && aLine.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "URL=" ) )
2207 								{
2208 									rBmk = INetBookmark( String( aLine.Erase( 0, 4 ), eTextEncoding ),
2209 														 String( aDesc.Erase( aDesc.Len() - 4 ), eTextEncoding ) );
2210 									bRet = sal_True;
2211 									break;
2212 								}
2213 							}
2214 
2215 							delete pStream;
2216 						}
2217 					}
2218 				}
2219 			}
2220 		}
2221 		break;
2222 #endif
2223 
2224 	}
2225 	}
2226 	return bRet;
2227 }
2228 
2229 // -----------------------------------------------------------------------------
2230 
2231 sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
2232 												INetImage& rINtImg )
2233 {
2234 	DataFlavor aFlavor;
2235 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
2236 }
2237 
2238 // -----------------------------------------------------------------------------
2239 
2240 sal_Bool TransferableDataHelper::GetINetImage(
2241 		const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
2242 		INetImage& rINtImg )
2243 {
2244 	SotStorageStreamRef xStm;
2245 	sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2246 
2247 	if( bRet )
2248 		bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
2249 	return bRet;
2250 }
2251 
2252 // -----------------------------------------------------------------------------
2253 
2254 sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
2255 												FileList& rFileList )
2256 {
2257 	DataFlavor aFlavor;
2258 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
2259 }
2260 
2261 // -----------------------------------------------------------------------------
2262 
2263 sal_Bool TransferableDataHelper::GetFileList(
2264 			const ::com::sun::star::datatransfer::DataFlavor&,
2265 			FileList& rFileList )
2266 {
2267 	SotStorageStreamRef xStm;
2268     sal_Bool            bRet = sal_False;
2269 
2270     for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
2271     {
2272         if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
2273         {
2274             const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
2275 
2276             if( GetSotStorageStream( aFlavor, xStm ) )
2277             {
2278                 if( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) > -1 )
2279                 {
2280                     ByteString aByteString;
2281 
2282                     while( xStm->ReadLine( aByteString ) )
2283                         if( aByteString.Len() && aByteString.GetChar( 0 ) != '#' )
2284                             rFileList.AppendFile( String( aByteString, RTL_TEXTENCODING_UTF8 ) );
2285 
2286                     bRet = sal_True;
2287                  }
2288                  else
2289                     bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
2290             }
2291         }
2292     }
2293 
2294     return bRet;
2295 }
2296 
2297 // -----------------------------------------------------------------------------
2298 
2299 sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
2300 {
2301 	DataFlavor aFlavor;
2302 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
2303 }
2304 
2305 // -----------------------------------------------------------------------------
2306 
2307 sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
2308 {
2309 #ifdef DEBUG
2310     fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
2311 #endif
2312 
2313     const Any aAny( GetAny( rFlavor ) );
2314 	return( aAny.hasValue() && ( aAny >>= rSeq ) );
2315 }
2316 
2317 // -----------------------------------------------------------------------------
2318 
2319 sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
2320 {
2321     DataFlavor aFlavor;
2322 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
2323 }
2324 
2325 // -----------------------------------------------------------------------------
2326 
2327 sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
2328 {
2329 	Sequence< sal_Int8 >	aSeq;
2330 	sal_Bool				bRet = GetSequence( rFlavor, aSeq );
2331 
2332 	if( bRet )
2333 	{
2334 		rxStream = new SotStorageStream( String() );
2335 		rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
2336 		rxStream->Seek( 0 );
2337 	}
2338 
2339 	return bRet;
2340 }
2341 
2342 sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
2343 {
2344 	DataFlavor aFlavor;
2345     return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
2346 }
2347 
2348 // -----------------------------------------------------------------------------
2349 
2350 sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
2351 {
2352 	Sequence< sal_Int8 >	aSeq;
2353 	sal_Bool				bRet = GetSequence( rFlavor, aSeq );
2354 
2355 	if( bRet )
2356           rxStream = new ::comphelper::SequenceInputStream( aSeq );
2357 
2358 	return bRet;
2359 }
2360 
2361 // -----------------------------------------------------------------------------
2362 
2363 
2364 sal_Bool TransferableDataHelper::GetInterface( SotFormatStringId nFormat, Reference< XInterface >& rIf )
2365 {
2366 	DataFlavor aFlavor;
2367 	return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInterface( aFlavor, rIf ) );
2368 }
2369 
2370 // -----------------------------------------------------------------------------
2371 
2372 sal_Bool TransferableDataHelper::GetInterface( const DataFlavor& rFlavor, Reference< XInterface >& rIf )
2373 {
2374 	const Any aAny( GetAny( rFlavor ) );
2375 	return( aAny.hasValue() && ( aAny >>= rIf ) );
2376 }
2377 
2378 // -----------------------------------------------------------------------------
2379 void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
2380 {
2381 	mxTransfer = _rxNewContent;
2382 	InitFormats();
2383 }
2384 
2385 // -----------------------------------------------------------------------------
2386 
2387 sal_Bool TransferableDataHelper::StartClipboardListening( )
2388 {
2389     ::osl::MutexGuard aGuard( mpImpl->maMutex );
2390 
2391     StopClipboardListening( );
2392 
2393 	mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
2394     mpImpl->mpClipboardListener->acquire();
2395 
2396 	return mpImpl->mpClipboardListener->isListening();
2397 }
2398 
2399 // -----------------------------------------------------------------------------
2400 
2401 void TransferableDataHelper::StopClipboardListening( )
2402 {
2403     ::osl::MutexGuard aGuard( mpImpl->maMutex );
2404 
2405 	if ( mpImpl->mpClipboardListener )
2406     {
2407         mpImpl->mpClipboardListener->dispose();
2408         mpImpl->mpClipboardListener->release();
2409         mpImpl->mpClipboardListener = NULL;
2410     }
2411 }
2412 
2413 // -----------------------------------------------------------------------------
2414 
2415 TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
2416 {
2417 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
2418 
2419     Reference< XClipboard >	xClipboard;
2420    	TransferableDataHelper	aRet;
2421 
2422     if( pWindow )
2423         xClipboard = pWindow->GetClipboard();
2424 
2425     if( xClipboard.is() )
2426    	{
2427    		try
2428 
2429     	{
2430 	    	Reference< XTransferable > xTransferable( xClipboard->getContents() );
2431 
2432 		    if( xTransferable.is() )
2433 			{
2434     			aRet = TransferableDataHelper( xTransferable );
2435    				aRet.mxClipboard = xClipboard;
2436 					// also copy the clipboard - 99030 - 23.05.2002 - fs@openoffice.org
2437 			}
2438    		}
2439     	catch( const ::com::sun::star::uno::Exception& )
2440 	    {
2441    		}
2442     }
2443 
2444 	return aRet;
2445 }
2446 
2447 
2448 // -----------------------------------------------------------------------------
2449 
2450 TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
2451 {
2452 	DBG_ASSERT( pWindow, "Window pointer is NULL" );
2453 
2454     Reference< XClipboard >	xSelection;
2455    	TransferableDataHelper	aRet;
2456 
2457     if( pWindow )
2458         xSelection = pWindow->GetPrimarySelection();
2459 
2460     if( xSelection.is() )
2461    	{
2462         const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2463 
2464   		try
2465     	{
2466 	    	Reference< XTransferable > xTransferable( xSelection->getContents() );
2467 
2468 		    if( xTransferable.is() )
2469    			{
2470     			aRet = TransferableDataHelper( xTransferable );
2471    				aRet.mxClipboard = xSelection;
2472 		    }
2473    		}
2474     	catch( const ::com::sun::star::uno::Exception& )
2475 	    {
2476    		}
2477 
2478         Application::AcquireSolarMutex( nRef );
2479     }
2480 
2481 	return aRet;
2482 }
2483 
2484 // -----------------------------------------------------------------------------
2485 sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
2486 										  const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
2487                                           sal_Bool )
2488 {
2489     Reference< XMultiServiceFactory >       xFact( ::comphelper::getProcessServiceFactory() );
2490     Reference< XMimeContentTypeFactory >    xMimeFact;
2491 	sal_Bool								bRet = sal_False;
2492 
2493     try
2494     {
2495 		if( xFact.is() )
2496     	    xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
2497                                                               "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
2498                                                               UNO_QUERY );
2499 
2500         if( xMimeFact.is() )
2501 		{
2502             Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
2503             Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2504 
2505 			if( xRequestType1.is() && xRequestType2.is() )
2506             {
2507                 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2508 			    {
2509                     if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
2510                     {
2511                         // special handling for text/plain media types
2512                         const ::rtl::OUString aCharsetString( ::rtl::OUString::createFromAscii( "charset" ) );
2513 
2514                         if( !xRequestType2->hasParameter( aCharsetString ) ||
2515 						    xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) ||
2516 						    xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) )
2517                         {
2518                             bRet = sal_True;
2519                         }
2520                     }
2521                     else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice" ) ) )
2522                     {
2523                         // special handling for application/x-openoffice media types
2524                         const ::rtl::OUString aFormatString( ::rtl::OUString::createFromAscii( "windows_formatname" ) );
2525 
2526                         if( xRequestType1->hasParameter( aFormatString ) &&
2527                             xRequestType2->hasParameter( aFormatString ) &&
2528                             xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
2529                         {
2530                             bRet = sal_True;
2531                         }
2532                     }
2533                     else
2534                         bRet = sal_True;
2535 			    }
2536             }
2537 		}
2538     }
2539     catch( const ::com::sun::star::uno::Exception& )
2540 	{
2541         bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
2542 	}
2543 
2544     return bRet;
2545 }
2546