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