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