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