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
operator >>(SvStream & rIStm,TransferableObjectDescriptor & rObjDesc)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
operator <<(SvStream & rOStm,const TransferableObjectDescriptor & rObjDesc)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
ImplGetParameterString(const TransferableObjectDescriptor & rObjDesc)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
ImplSetParameterString(TransferableObjectDescriptor & rObjDesc,const DataFlavorEx & rFlavorEx)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
TerminateListener(TransferableHelper & rTransferableHelper)299 TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
300 mrParent( rTransferableHelper )
301 {
302 }
303
304 // -----------------------------------------------------------------------------
305
~TerminateListener()306 TransferableHelper::TerminateListener::~TerminateListener()
307 {
308 }
309
310 // -----------------------------------------------------------------------------
311
disposing(const EventObject &)312 void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
313 {
314 }
315
316 // -----------------------------------------------------------------------------
317
queryTermination(const EventObject &)318 void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
319 {
320 }
321
322 // -----------------------------------------------------------------------------
323
notifyTermination(const EventObject &)324 void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
325 {
326 mrParent.ImplFlush();
327 }
328
329 // ----------------------
330 // - TransferableHelper -
331 // ----------------------
332
TransferableHelper()333 TransferableHelper::TransferableHelper() :
334 mpFormats( new DataFlavorExVector ),
335 mpObjDesc( NULL )
336 {
337 }
338
339 // -----------------------------------------------------------------------------
340
~TransferableHelper()341 TransferableHelper::~TransferableHelper()
342 {
343 delete mpObjDesc;
344 delete mpFormats;
345 }
346
347 // -----------------------------------------------------------------------------
348
getTransferData(const DataFlavor & rFlavor)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
getTransferDataFlavors()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
isDataFlavorSupported(const DataFlavor & rFlavor)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
lostOwnership(const Reference<XClipboard> &,const Reference<XTransferable> &)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
disposing(const EventObject &)557 void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
558 {
559 }
560
561 // -----------------------------------------------------------------------------
562
dragDropEnd(const DragSourceDropEvent & rDSDE)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
dragEnter(const DragSourceDragEvent &)579 void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
580 {
581 }
582
583 // -----------------------------------------------------------------------------
584
dragExit(const DragSourceEvent &)585 void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
586 {
587 }
588
589 // -----------------------------------------------------------------------------
590
dragOver(const DragSourceDragEvent &)591 void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
592 {
593 }
594
595 // -----------------------------------------------------------------------------
596
dropActionChanged(const DragSourceDragEvent &)597 void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
598 {
599 }
600
601 // -----------------------------------------------------------------------------
602
getSomething(const Sequence<sal_Int8> & rId)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
ImplFlush()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
AddFormat(SotFormatStringId nFormat)643 void TransferableHelper::AddFormat( SotFormatStringId nFormat )
644 {
645 DataFlavor aFlavor;
646
647 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
648 AddFormat( aFlavor );
649 }
650
651 // -----------------------------------------------------------------------------
652
AddFormat(const DataFlavor & rFlavor)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_PNG );
702 AddFormat( SOT_FORMATSTR_ID_BMP );
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
RemoveFormat(SotFormatStringId nFormat)714 void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
715 {
716 DataFlavor aFlavor;
717
718 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
719 RemoveFormat( aFlavor );
720 }
721
722 // -----------------------------------------------------------------------------
723
RemoveFormat(const DataFlavor & rFlavor)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
HasFormat(SotFormatStringId nFormat)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
ClearFormats()763 void TransferableHelper::ClearFormats()
764 {
765 mpFormats->clear();
766 maAny.clear();
767 }
768
769 // -----------------------------------------------------------------------------
770
SetAny(const Any & rAny,const DataFlavor &)771 sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
772 {
773 maAny = rAny;
774 return( maAny.hasValue() );
775 }
776
777 // -----------------------------------------------------------------------------
778
SetString(const::rtl::OUString & rString,const DataFlavor & rFlavor)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
SetBitmapEx(const BitmapEx & rBitmapEx,const DataFlavor & rFlavor)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 // #124085# take out DIBV5 for writing to the clipboard
821 //if(rBitmapEx.IsTransparent())
822 //{
823 // const Bitmap aMask(rBitmapEx.GetAlpha().GetBitmap());
824 //
825 // // explicitely use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True
826 // WriteDIBV5(aBitmap, aMask, aMemStm);
827 //}
828 //else
829 //{
830 // explicitely use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True
831 WriteDIB(aBitmap, aMemStm, false, true);
832 //}
833 }
834
835 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
836 }
837
838 return( maAny.hasValue() );
839 }
840
841 // -----------------------------------------------------------------------------
842
SetGDIMetaFile(const GDIMetaFile & rMtf,const DataFlavor &)843 sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
844 {
845 if( rMtf.GetActionCount() )
846 {
847 SvMemoryStream aMemStm( 65535, 65535 );
848
849 ( (GDIMetaFile&) rMtf ).Write( aMemStm );
850 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
851 }
852
853 return( maAny.hasValue() );
854 }
855
856 // -----------------------------------------------------------------------------
857
SetGraphic(const Graphic & rGraphic,const DataFlavor &)858 sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
859 {
860 if( rGraphic.GetType() != GRAPHIC_NONE )
861 {
862 SvMemoryStream aMemStm( 65535, 65535 );
863
864 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
865 aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
866 aMemStm << rGraphic;
867 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
868 }
869
870 return( maAny.hasValue() );
871 }
872
873 // -----------------------------------------------------------------------------
874
SetImageMap(const ImageMap & rIMap,const::com::sun::star::datatransfer::DataFlavor &)875 sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
876 {
877 SvMemoryStream aMemStm( 8192, 8192 );
878
879 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
880 rIMap.Write( aMemStm, String() );
881 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
882
883 return( maAny.hasValue() );
884 }
885
886 // -----------------------------------------------------------------------------
887
SetTransferableObjectDescriptor(const TransferableObjectDescriptor & rDesc,const::com::sun::star::datatransfer::DataFlavor &)888 sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
889 const ::com::sun::star::datatransfer::DataFlavor& )
890 {
891 PrepareOLE( rDesc );
892
893 SvMemoryStream aMemStm( 1024, 1024 );
894
895 aMemStm << rDesc;
896 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
897
898 return( maAny.hasValue() );
899 }
900
901 // -----------------------------------------------------------------------------
902
SetINetBookmark(const INetBookmark & rBmk,const::com::sun::star::datatransfer::DataFlavor & rFlavor)903 sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
904 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
905 {
906 rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
907
908 switch( SotExchange::GetFormat( rFlavor ) )
909 {
910 case( SOT_FORMATSTR_ID_SOLK ):
911 {
912 ByteString sURL( rBmk.GetURL(), eSysCSet ),
913 sDesc( rBmk.GetDescription(), eSysCSet );
914 ByteString sOut( ByteString::CreateFromInt32( sURL.Len() ));
915 ( sOut += '@' ) += sURL;
916 sOut += ByteString::CreateFromInt32( sDesc.Len() );
917 ( sOut += '@' ) += sDesc;
918
919 Sequence< sal_Int8 > aSeq( sOut.Len() );
920 memcpy( aSeq.getArray(), sOut.GetBuffer(), sOut.Len() );
921 maAny <<= aSeq;
922 }
923 break;
924
925 case( FORMAT_STRING ):
926 maAny <<= ::rtl::OUString( rBmk.GetURL() );
927 break;
928
929 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
930 {
931 ByteString sURL( rBmk.GetURL(), eSysCSet );
932 Sequence< sal_Int8 > aSeq( sURL.Len() );
933 memcpy( aSeq.getArray(), sURL.GetBuffer(), sURL.Len() );
934 maAny <<= aSeq;
935 }
936 break;
937
938 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
939 {
940 Sequence< sal_Int8 > aSeq( 2048 );
941
942 memset( aSeq.getArray(), 0, 2048 );
943 strcpy( reinterpret_cast< char* >( aSeq.getArray() ), ByteString( rBmk.GetURL(), eSysCSet).GetBuffer() );
944 strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, ByteString( rBmk.GetDescription(), eSysCSet ).GetBuffer() );
945
946 maAny <<= aSeq;
947 }
948 break;
949
950 #ifdef WNT
951 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
952 {
953 Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
954 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
955 FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
956
957 pFDesc->cItems = 1;
958 memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
959 rFDesc1.dwFlags = FD_LINKUI;
960
961 ByteString aStr( rBmk.GetDescription(), eSysCSet );
962 for( sal_uInt16 nChar = 0; nChar < aStr.Len(); ++nChar )
963 if( strchr( "\\/:*?\"<>|", aStr.GetChar( nChar ) ) )
964 aStr.Erase( nChar--, 1 );
965
966 aStr.Insert( "Shortcut to ", 0 );
967 aStr += ".URL";
968 strcpy( rFDesc1.cFileName, aStr.GetBuffer() );
969
970 maAny <<= aSeq;
971 }
972 break;
973
974 case SOT_FORMATSTR_ID_FILECONTENT:
975 {
976 String aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
977 maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
978 }
979 break;
980 #endif
981
982 default:
983 break;
984 }
985
986 return( maAny.hasValue() );
987 }
988
989 // -----------------------------------------------------------------------------
990
SetINetImage(const INetImage & rINtImg,const::com::sun::star::datatransfer::DataFlavor & rFlavor)991 sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
992 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
993 {
994 SvMemoryStream aMemStm( 1024, 1024 );
995
996 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
997 rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
998
999 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
1000
1001 return( maAny.hasValue() );
1002 }
1003
1004 // -----------------------------------------------------------------------------
1005
SetFileList(const FileList & rFileList,const::com::sun::star::datatransfer::DataFlavor &)1006 sal_Bool TransferableHelper::SetFileList( const FileList& rFileList,
1007 const ::com::sun::star::datatransfer::DataFlavor& )
1008 {
1009 SvMemoryStream aMemStm( 4096, 4096 );
1010
1011 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
1012 aMemStm << rFileList;
1013
1014 maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ),
1015 aMemStm.Seek( STREAM_SEEK_TO_END ) );
1016
1017 return( maAny.hasValue() );
1018 }
1019
1020 // -----------------------------------------------------------------------------
1021
SetObject(void * pUserObject,sal_uInt32 nUserObjectId,const DataFlavor & rFlavor)1022 sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
1023 {
1024 SotStorageStreamRef xStm( new SotStorageStream( String() ) );
1025
1026 xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1027
1028 if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
1029 {
1030 const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
1031 Sequence< sal_Int8 > aSeq( nLen );
1032
1033 xStm->Seek( STREAM_SEEK_TO_BEGIN );
1034 xStm->Read( aSeq.getArray(), nLen );
1035
1036 if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
1037 {
1038 //JP 24.7.2001: as I know was this only for the writer application and this
1039 // writes now UTF16 format into the stream
1040 //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
1041 // little / big endians! - Bug 88121
1042 maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
1043 }
1044 else
1045 maAny <<= aSeq;
1046 }
1047
1048 return( maAny.hasValue() );
1049 }
1050
1051 // -----------------------------------------------------------------------------
1052
SetInterface(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rIf,const::com::sun::star::datatransfer::DataFlavor &)1053 sal_Bool TransferableHelper::SetInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rIf,
1054 const ::com::sun::star::datatransfer::DataFlavor& )
1055 {
1056 maAny <<= rIf;
1057 return( maAny.hasValue() );
1058 }
1059
1060 // -----------------------------------------------------------------------------
1061
WriteObject(SotStorageStreamRef &,void *,sal_uInt32,const DataFlavor &)1062 sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
1063 {
1064 DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
1065 return sal_False;
1066 }
1067
1068 // -----------------------------------------------------------------------------
1069
DragFinished(sal_Int8)1070 void TransferableHelper::DragFinished( sal_Int8 )
1071 {
1072 }
1073
1074 // -----------------------------------------------------------------------------
1075
ObjectReleased()1076 void TransferableHelper::ObjectReleased()
1077 {
1078 }
1079
1080 // -----------------------------------------------------------------------------
1081
PrepareOLE(const TransferableObjectDescriptor & rObjDesc)1082 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
1083 {
1084 delete mpObjDesc;
1085 mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
1086
1087 if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
1088 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
1089 }
1090
1091 // -----------------------------------------------------------------------------
1092
CopyToClipboard(Window * pWindow) const1093 void TransferableHelper::CopyToClipboard( Window *pWindow ) const
1094 {
1095 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1096 Reference< XClipboard > xClipboard;
1097
1098 if( pWindow )
1099 xClipboard = pWindow->GetClipboard();
1100
1101 if( xClipboard.is() )
1102 mxClipboard = xClipboard;
1103
1104 if( mxClipboard.is() && !mxTerminateListener.is() )
1105 {
1106 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1107
1108 try
1109 {
1110 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1111 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1112
1113 if( xFact.is() )
1114 {
1115 Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1116
1117 if( xDesktop.is() )
1118 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1119 }
1120
1121 mxClipboard->setContents( pThis, pThis );
1122 }
1123 catch( const ::com::sun::star::uno::Exception& )
1124 {
1125 }
1126
1127 Application::AcquireSolarMutex( nRef );
1128 }
1129 }
1130
1131 // -----------------------------------------------------------------------------
1132
CopyToSelection(Window * pWindow) const1133 void TransferableHelper::CopyToSelection( Window *pWindow ) const
1134 {
1135 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1136 Reference< XClipboard > xSelection;
1137
1138 if( pWindow )
1139 xSelection = pWindow->GetPrimarySelection();
1140
1141 if( xSelection.is() && !mxTerminateListener.is() )
1142 {
1143 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1144
1145 try
1146 {
1147 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1148 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1149
1150 if( xFact.is() )
1151 {
1152 Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1153
1154 if( xDesktop.is() )
1155 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1156 }
1157
1158 xSelection->setContents( pThis, pThis );
1159 }
1160 catch( const ::com::sun::star::uno::Exception& )
1161 {
1162 }
1163
1164 Application::AcquireSolarMutex( nRef );
1165 }
1166 }
1167
1168 // -----------------------------------------------------------------------------
1169
StartDrag(Window * pWindow,sal_Int8 nDnDSourceActions,sal_Int32 nDnDPointer,sal_Int32 nDnDImage)1170 void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
1171 sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
1172
1173 {
1174 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1175 Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
1176
1177 if( xDragSource.is() )
1178 {
1179 /*
1180 * #96792# release mouse before actually starting DnD.
1181 * This is necessary for the X11 DnD implementation to work.
1182 */
1183 if( pWindow->IsMouseCaptured() )
1184 pWindow->ReleaseMouse();
1185
1186 const Point aPt( pWindow->GetPointerPosPixel() );
1187
1188 // On Mac OS X we are forced to execute 'startDrag' synchronously
1189 // contrary to the XDragSource interface specification because
1190 // we can receive drag events from the system only in the main
1191 // thread
1192 #if !defined(QUARTZ)
1193 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1194 #endif
1195
1196 try
1197 {
1198 DragGestureEvent aEvt;
1199 aEvt.DragAction = DNDConstants::ACTION_COPY;
1200 aEvt.DragOriginX = aPt.X();
1201 aEvt.DragOriginY = aPt.Y();
1202 aEvt.DragSource = xDragSource;
1203
1204 xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
1205 }
1206 catch( const ::com::sun::star::uno::Exception& )
1207 {
1208 }
1209
1210 // See above for the reason of this define
1211 #if !defined(QUARTZ)
1212 Application::AcquireSolarMutex( nRef );
1213 #endif
1214 }
1215 }
1216
1217 // -----------------------------------------------------------------------------
1218
ClearSelection(Window * pWindow)1219 void TransferableHelper::ClearSelection( Window *pWindow )
1220 {
1221 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1222 Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
1223
1224 if( xSelection.is() )
1225 xSelection->setContents( NULL, NULL );
1226 }
1227
1228 // -----------------------------------------------------------------------------
1229
GetSystemClipboard()1230 Reference< XClipboard> TransferableHelper::GetSystemClipboard()
1231 {
1232 Window *pFocusWindow = Application::GetFocusWindow();
1233
1234 if( pFocusWindow )
1235 return pFocusWindow->GetClipboard();
1236
1237 return Reference< XClipboard > ();
1238 }
1239
1240 // -----------------------------------------------------------------------------
1241
getUnoTunnelId()1242 const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
1243 {
1244 static Sequence< sal_Int8 > aSeq;
1245
1246 if( !aSeq.getLength() )
1247 {
1248 static osl::Mutex aCreateMutex;
1249 osl::Guard< osl::Mutex > aGuard( aCreateMutex );
1250
1251 aSeq.realloc( 16 );
1252 rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
1253 }
1254
1255
1256 return aSeq;
1257 }
1258
1259 // ---------------------------------
1260 // - TransferableClipboardNotifier -
1261 // ---------------------------------
1262
1263 class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
1264 {
1265 private:
1266 ::osl::Mutex& mrMutex;
1267 Reference< XClipboardNotifier > mxNotifier;
1268 TransferableDataHelper* mpListener;
1269
1270 protected:
1271 // XClipboardListener
1272 virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
1273
1274 // XEventListener
1275 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
1276
1277 public:
1278 TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
1279
1280 /// determines whether we're currently listening
isListening() const1281 inline bool isListening() const { return !isDisposed(); }
1282
1283 /// determines whether the instance is disposed
isDisposed() const1284 inline bool isDisposed() const { return mpListener == NULL; }
1285
1286 /// makes the instance non-functional
1287 void dispose();
1288 };
1289
1290 // -----------------------------------------------------------------------------
1291
TransferableClipboardNotifier(const Reference<XClipboard> & _rxClipboard,TransferableDataHelper & _rListener,::osl::Mutex & _rMutex)1292 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
1293 :mrMutex( _rMutex )
1294 ,mxNotifier( _rxClipboard, UNO_QUERY )
1295 ,mpListener( &_rListener )
1296 {
1297 osl_incrementInterlockedCount( &m_refCount );
1298 {
1299 if ( mxNotifier.is() )
1300 mxNotifier->addClipboardListener( this );
1301 else
1302 // born dead
1303 mpListener = NULL;
1304 }
1305 osl_decrementInterlockedCount( &m_refCount );
1306 }
1307
1308 // -----------------------------------------------------------------------------
1309
changedContents(const clipboard::ClipboardEvent & event)1310 void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
1311 {
1312 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1313 // the SolarMutex here is necessary, since
1314 // - we cannot call mpListener without our own mutex locked
1315 // - Rebind respectively InitFormats (called by Rebind) will
1316 // try to lock the SolarMutex, too
1317 ::osl::MutexGuard aGuard( mrMutex );
1318 if( mpListener )
1319 mpListener->Rebind( event.Contents );
1320 }
1321
1322 // -----------------------------------------------------------------------------
1323
disposing(const EventObject &)1324 void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
1325 {
1326 // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1327 dispose();
1328 }
1329
1330 // -----------------------------------------------------------------------------
1331
dispose()1332 void TransferableClipboardNotifier::dispose()
1333 {
1334 ::osl::MutexGuard aGuard( mrMutex );
1335
1336 Reference< XClipboardListener > xKeepMeAlive( this );
1337
1338 if ( mxNotifier.is() )
1339 mxNotifier->removeClipboardListener( this );
1340 mxNotifier.clear();
1341
1342 mpListener = NULL;
1343 }
1344
1345 // -------------------------------
1346 // - TransferableDataHelper_Impl -
1347 // -------------------------------
1348
1349 struct TransferableDataHelper_Impl
1350 {
1351 ::osl::Mutex maMutex;
1352 TransferableClipboardNotifier* mpClipboardListener;
1353
TransferableDataHelper_ImplTransferableDataHelper_Impl1354 TransferableDataHelper_Impl()
1355 :mpClipboardListener( NULL )
1356 {
1357 }
1358 };
1359
1360 // --------------------------
1361 // - TransferableDataHelper -
1362 // --------------------------
1363
TransferableDataHelper()1364 TransferableDataHelper::TransferableDataHelper() :
1365 mpFormats( new DataFlavorExVector ),
1366 mpObjDesc( new TransferableObjectDescriptor ),
1367 mpImpl( new TransferableDataHelper_Impl )
1368 {
1369 }
1370
1371 // -----------------------------------------------------------------------------
1372
TransferableDataHelper(const Reference<::com::sun::star::datatransfer::XTransferable> & rxTransferable)1373 TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
1374 mxTransfer( rxTransferable ),
1375 mpFormats( new DataFlavorExVector ),
1376 mpObjDesc( new TransferableObjectDescriptor ),
1377 mpImpl( new TransferableDataHelper_Impl )
1378 {
1379 InitFormats();
1380 }
1381
1382 // -----------------------------------------------------------------------------
1383
TransferableDataHelper(const TransferableDataHelper & rDataHelper)1384 TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
1385 mxTransfer( rDataHelper.mxTransfer ),
1386 mxClipboard( rDataHelper.mxClipboard ),
1387 mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
1388 mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
1389 mpImpl( new TransferableDataHelper_Impl )
1390 {
1391 }
1392
1393 // -----------------------------------------------------------------------------
1394
operator =(const TransferableDataHelper & rDataHelper)1395 TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
1396 {
1397 if ( this != &rDataHelper )
1398 {
1399 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1400
1401 bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
1402
1403 if ( bWasClipboardListening )
1404 StopClipboardListening();
1405
1406 mxTransfer = rDataHelper.mxTransfer;
1407 delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
1408 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
1409 mxClipboard = rDataHelper.mxClipboard;
1410
1411 if ( bWasClipboardListening )
1412 StartClipboardListening();
1413 }
1414
1415 return *this;
1416 }
1417
1418 // -----------------------------------------------------------------------------
1419
~TransferableDataHelper()1420 TransferableDataHelper::~TransferableDataHelper()
1421 {
1422 StopClipboardListening( );
1423 {
1424 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1425 delete mpFormats, mpFormats = NULL;
1426 delete mpObjDesc, mpObjDesc = NULL;
1427 }
1428 delete mpImpl;
1429 }
1430
1431 // -----------------------------------------------------------------------------
1432
FillDataFlavorExVector(const Sequence<DataFlavor> & rDataFlavorSeq,DataFlavorExVector & rDataFlavorExVector)1433 void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
1434 DataFlavorExVector& rDataFlavorExVector )
1435 {
1436 try
1437 {
1438 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1439 Reference< XMimeContentTypeFactory > xMimeFact;
1440 DataFlavorEx aFlavorEx;
1441 const ::rtl::OUString aCharsetStr( ::rtl::OUString::createFromAscii( "charset" ) );
1442
1443 if( xFact.is() )
1444 xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
1445 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
1446 UNO_QUERY );
1447
1448 for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
1449 {
1450 const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
1451 Reference< XMimeContentType > xMimeType;
1452
1453 try
1454 {
1455 if( xMimeFact.is() && rFlavor.MimeType.getLength() )
1456 xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
1457 }
1458 catch( const ::com::sun::star::uno::Exception& )
1459 {
1460
1461 }
1462
1463 aFlavorEx.MimeType = rFlavor.MimeType;
1464 aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
1465 aFlavorEx.DataType = rFlavor.DataType;
1466 aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
1467
1468 rDataFlavorExVector.push_back( aFlavorEx );
1469
1470 // add additional formats for special mime types
1471 if(SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_PNG == aFlavorEx.mnSotId)
1472 {
1473 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
1474 {
1475 aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
1476 rDataFlavorExVector.push_back( aFlavorEx );
1477 }
1478 }
1479 else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
1480 {
1481 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
1482 {
1483 aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
1484 rDataFlavorExVector.push_back( aFlavorEx );
1485 }
1486 }
1487 else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
1488 {
1489 // #104735# HTML_SIMPLE may also be inserted without comments
1490 aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
1491 rDataFlavorExVector.push_back( aFlavorEx );
1492 }
1493 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
1494 {
1495 // add, if it is a UTF-8 byte buffer
1496 if( xMimeType->hasParameter( aCharsetStr ) )
1497 {
1498 const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
1499
1500 if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) ||
1501 xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) )
1502 {
1503 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
1504
1505 }
1506 }
1507 }
1508 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/rtf" ) ) )
1509 {
1510 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
1511 }
1512 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/html" ) ) )
1513
1514 {
1515 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
1516 }
1517 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) )
1518 {
1519 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
1520 }
1521 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice-objectdescriptor-xml" ) ) )
1522 {
1523 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
1524 }
1525 }
1526 }
1527 catch( const ::com::sun::star::uno::Exception& )
1528 {
1529 }
1530 }
1531
1532 // -----------------------------------------------------------------------------
1533
InitFormats()1534 void TransferableDataHelper::InitFormats()
1535 {
1536 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1537 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1538
1539 mpFormats->clear();
1540 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
1541
1542 if( mxTransfer.is() )
1543 {
1544 TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
1545
1546 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1547
1548 while( aIter != aEnd )
1549 {
1550 if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
1551 {
1552 ImplSetParameterString( *mpObjDesc, *aIter );
1553 aIter = aEnd;
1554 }
1555 else
1556 ++aIter;
1557 }
1558 }
1559 }
1560
1561 // -----------------------------------------------------------------------------
1562
HasFormat(SotFormatStringId nFormat) const1563 sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
1564 {
1565 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1566
1567 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1568 sal_Bool bRet = sal_False;
1569
1570 while( aIter != aEnd )
1571 {
1572 if( nFormat == (*aIter++).mnSotId )
1573 {
1574 aIter = aEnd;
1575 bRet = sal_True;
1576 }
1577 }
1578
1579 return bRet;
1580 }
1581
1582 // -----------------------------------------------------------------------------
1583
HasFormat(const DataFlavor & rFlavor) const1584 sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
1585 {
1586 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1587
1588 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1589 sal_Bool bRet = sal_False;
1590
1591 while( aIter != aEnd )
1592 {
1593 if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
1594 {
1595 aIter = aEnd;
1596 bRet = sal_True;
1597 }
1598 }
1599
1600 return bRet;
1601 }
1602
1603 // -----------------------------------------------------------------------------
1604
GetFormatCount() const1605 sal_uInt32 TransferableDataHelper::GetFormatCount() const
1606 {
1607 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1608 return mpFormats->size();
1609 }
1610
1611 // -----------------------------------------------------------------------------
1612
1613
GetFormat(sal_uInt32 nFormat) const1614 SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
1615 {
1616 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1617 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1618 return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
1619 }
1620
1621 // -----------------------------------------------------------------------------
1622
GetFormatDataFlavor(sal_uInt32 nFormat) const1623 DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
1624 {
1625 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1626 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1627
1628 DataFlavor aRet;
1629
1630 if( nFormat < mpFormats->size() )
1631 aRet = (*mpFormats)[ nFormat ];
1632
1633 return aRet;
1634 }
1635
1636 // -----------------------------------------------------------------------------
1637
GetXTransferable() const1638 Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
1639 {
1640 Reference< XTransferable > xRet;
1641
1642 if( mxTransfer.is() )
1643 {
1644 try
1645 {
1646 xRet = mxTransfer;
1647
1648 // do a dummy call to check, if this interface is valid (nasty)
1649 Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
1650
1651 }
1652 catch( const ::com::sun::star::uno::Exception& )
1653 {
1654 xRet = Reference< XTransferable >();
1655 }
1656 }
1657
1658 return xRet;
1659 }
1660
1661 // -----------------------------------------------------------------------------
1662
GetAny(SotFormatStringId nFormat) const1663 Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
1664 {
1665 Any aReturn;
1666
1667 DataFlavor aFlavor;
1668 if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
1669 aReturn = GetAny( aFlavor );
1670
1671 return aReturn;
1672 }
1673
1674
1675 // -----------------------------------------------------------------------------
1676
GetAny(const DataFlavor & rFlavor) const1677 Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
1678 {
1679 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1680 Any aRet;
1681
1682 try
1683 {
1684 if( mxTransfer.is() )
1685 {
1686 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1687 const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
1688
1689 if( nRequestFormat )
1690 {
1691 // try to get alien format first
1692 while( aIter != aEnd )
1693 {
1694 if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
1695 aRet = mxTransfer->getTransferData( *aIter );
1696
1697 if( aRet.hasValue() )
1698 aIter = aEnd;
1699 else
1700 aIter++;
1701 }
1702 }
1703
1704 if( !aRet.hasValue() )
1705 aRet = mxTransfer->getTransferData( rFlavor );
1706 }
1707 }
1708 catch( const ::com::sun::star::uno::Exception& )
1709 {
1710 }
1711
1712 return aRet;
1713 }
1714
1715 // -----------------------------------------------------------------------------
1716
GetString(SotFormatStringId nFormat,String & rStr)1717 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
1718 {
1719 ::rtl::OUString aOUString;
1720 sal_Bool bRet = GetString( nFormat, aOUString );
1721
1722 rStr = aOUString;
1723
1724 return bRet;
1725 }
1726
1727 // -----------------------------------------------------------------------------
1728
GetString(const DataFlavor & rFlavor,String & rStr)1729 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
1730 {
1731 ::rtl::OUString aOUString;
1732 sal_Bool bRet = GetString( rFlavor, aOUString );
1733
1734 rStr = aOUString;
1735
1736 return bRet;
1737 }
1738
1739 // -----------------------------------------------------------------------------
1740
GetString(SotFormatStringId nFormat,::rtl::OUString & rStr)1741 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
1742 {
1743 DataFlavor aFlavor;
1744 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
1745 }
1746
1747 // -----------------------------------------------------------------------------
1748
GetString(const DataFlavor & rFlavor,::rtl::OUString & rStr)1749 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
1750 {
1751 Any aAny( GetAny( rFlavor ) );
1752 sal_Bool bRet = sal_False;
1753
1754 if( aAny.hasValue() )
1755 {
1756 ::rtl::OUString aOUString;
1757 Sequence< sal_Int8 > aSeq;
1758
1759 if( aAny >>= aOUString )
1760 {
1761 rStr = aOUString;
1762 bRet = sal_True;
1763 }
1764 else if( aAny >>= aSeq )
1765 {
1766
1767 const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
1768 sal_Int32 nLen = aSeq.getLength();
1769
1770 //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1771 //DVO 2002-05-27: strip _all_ trailing zeros
1772 while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
1773 --nLen;
1774
1775 rStr = ::rtl::OUString( pChars, nLen, gsl_getSystemTextEncoding() );
1776 bRet = sal_True;
1777 }
1778 }
1779
1780 return bRet;
1781 }
1782
1783 // -----------------------------------------------------------------------------
1784
GetBitmapEx(SotFormatStringId nFormat,BitmapEx & rBmpEx)1785 sal_Bool TransferableDataHelper::GetBitmapEx( SotFormatStringId nFormat, BitmapEx& rBmpEx )
1786 {
1787 if(FORMAT_BITMAP == nFormat)
1788 {
1789 // try to get PNG first
1790 DataFlavor aFlavor;
1791
1792 if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor))
1793 {
1794 if(GetBitmapEx(aFlavor, rBmpEx))
1795 {
1796 return true;
1797 }
1798 }
1799 }
1800
1801 DataFlavor aFlavor;
1802 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmapEx( aFlavor, rBmpEx ) );
1803 }
1804
1805 // -----------------------------------------------------------------------------
1806
GetBitmapEx(const DataFlavor & rFlavor,BitmapEx & rBmpEx)1807 sal_Bool TransferableDataHelper::GetBitmapEx( const DataFlavor& rFlavor, BitmapEx& rBmpEx )
1808 {
1809 SotStorageStreamRef xStm;
1810 DataFlavor aSubstFlavor;
1811 bool bRet(GetSotStorageStream(rFlavor, xStm));
1812 bool bSuppressPNG(false); // #122982# If PNG stream not accessed, but BMP one, suppress trying to load PNG
1813
1814 if(!bRet && HasFormat(SOT_FORMATSTR_ID_PNG) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aSubstFlavor))
1815 {
1816 // when no direct success, try if PNG is available
1817 bRet = GetSotStorageStream(aSubstFlavor, xStm);
1818 }
1819
1820 if(!bRet && HasFormat(SOT_FORMATSTR_ID_BMP) && SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_BMP, aSubstFlavor))
1821 {
1822 // when no direct success, try if BMP is available
1823 bRet = GetSotStorageStream(aSubstFlavor, xStm);
1824 bSuppressPNG = bRet;
1825 }
1826
1827 if(bRet)
1828 {
1829 if(!bSuppressPNG && rFlavor.MimeType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("image/png")))
1830 {
1831 // it's a PNG, import to BitmapEx
1832 ::vcl::PNGReader aPNGReader(*xStm);
1833
1834 rBmpEx = aPNGReader.Read();
1835 }
1836
1837 if(rBmpEx.IsEmpty())
1838 {
1839 Bitmap aBitmap;
1840 Bitmap aMask;
1841
1842 // explicitely use Bitmap::Read with bFileHeader = sal_True
1843 // #124085# keep DIBV5 for read from clipboard, but should not happen
1844 ReadDIBV5(aBitmap, aMask, *xStm);
1845
1846 if(aMask.IsEmpty())
1847 {
1848 rBmpEx = aBitmap;
1849 }
1850 else
1851 {
1852 rBmpEx = BitmapEx(aBitmap, aMask);
1853 }
1854 }
1855
1856 bRet = (ERRCODE_NONE == xStm->GetError() && !rBmpEx.IsEmpty());
1857
1858 /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1859 problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1860 and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1861 Due to this reason the following code assumes that bitmaps with a logical size
1862 greater than 50 cm aren't having the correct mapmode set.
1863
1864 The following code should be removed if DDBs and DIBs are supported via clipboard
1865 properly.
1866 */
1867 if(bRet)
1868 {
1869 const MapMode aMapMode(rBmpEx.GetPrefMapMode());
1870
1871 if(MAP_PIXEL != aMapMode.GetMapUnit())
1872 {
1873 const Size aSize(OutputDevice::LogicToLogic(rBmpEx.GetPrefSize(), aMapMode, MAP_100TH_MM));
1874
1875 // #122388# This wrongly corrects in the given case; changing from 5000 100th mm to
1876 // the described 50 cm (which is 50000 100th mm)
1877 if((aSize.Width() > 50000) || (aSize.Height() > 50000))
1878 {
1879 rBmpEx.SetPrefMapMode(MAP_PIXEL);
1880
1881 // #122388# also adapt size by applying the mew MapMode
1882 const Size aNewSize(OutputDevice::LogicToLogic(aSize, MAP_100TH_MM, MAP_PIXEL));
1883 rBmpEx.SetPrefSize(aNewSize);
1884 }
1885 }
1886 }
1887 }
1888
1889 return bRet;
1890 }
1891
1892 // -----------------------------------------------------------------------------
1893
GetGDIMetaFile(SotFormatStringId nFormat,GDIMetaFile & rMtf)1894 sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
1895 {
1896 DataFlavor aFlavor;
1897 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
1898 }
1899
1900 // -----------------------------------------------------------------------------
1901
GetGDIMetaFile(const DataFlavor & rFlavor,GDIMetaFile & rMtf)1902 sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
1903 {
1904 SotStorageStreamRef xStm;
1905 DataFlavor aSubstFlavor;
1906 sal_Bool bRet = sal_False;
1907
1908 if( GetSotStorageStream( rFlavor, xStm ) )
1909 {
1910 *xStm >> rMtf;
1911 bRet = ( xStm->GetError() == ERRCODE_NONE );
1912 }
1913
1914 if( !bRet &&
1915 HasFormat( SOT_FORMATSTR_ID_EMF ) &&
1916 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
1917 GetSotStorageStream( aSubstFlavor, xStm ) )
1918 {
1919 Graphic aGraphic;
1920
1921 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1922 {
1923 rMtf = aGraphic.GetGDIMetaFile();
1924 bRet = sal_True;
1925 }
1926 }
1927
1928 if( !bRet &&
1929 HasFormat( SOT_FORMATSTR_ID_WMF ) &&
1930 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
1931 GetSotStorageStream( aSubstFlavor, xStm ) )
1932 {
1933 Graphic aGraphic;
1934
1935 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1936 {
1937 rMtf = aGraphic.GetGDIMetaFile();
1938 bRet = sal_True;
1939 }
1940 }
1941
1942 return bRet;
1943 }
1944
1945 // -----------------------------------------------------------------------------
1946
GetGraphic(SotFormatStringId nFormat,Graphic & rGraphic)1947 sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
1948 {
1949 if(FORMAT_BITMAP == nFormat)
1950 {
1951 // try to get PNG first
1952 DataFlavor aFlavor;
1953
1954 if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor))
1955 {
1956 if(GetGraphic(aFlavor, rGraphic))
1957 {
1958 return true;
1959 }
1960 }
1961 }
1962
1963 DataFlavor aFlavor;
1964 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
1965 }
1966
1967 // -----------------------------------------------------------------------------
1968
GetGraphic(const::com::sun::star::datatransfer::DataFlavor & rFlavor,Graphic & rGraphic)1969 sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
1970 {
1971 DataFlavor aFlavor;
1972 sal_Bool bRet = sal_False;
1973
1974 if(SotExchange::GetFormatDataFlavor(SOT_FORMATSTR_ID_PNG, aFlavor) &&
1975 TransferableDataHelper::IsEqual(aFlavor, rFlavor))
1976 {
1977 // try to get PNG first
1978 BitmapEx aBmpEx;
1979
1980 if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True )
1981 rGraphic = aBmpEx;
1982 }
1983 else if(SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
1984 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1985 {
1986 BitmapEx aBmpEx;
1987
1988 if( ( bRet = GetBitmapEx( aFlavor, aBmpEx ) ) == sal_True )
1989 rGraphic = aBmpEx;
1990 }
1991 else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
1992 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1993 {
1994 GDIMetaFile aMtf;
1995
1996 if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
1997 rGraphic = aMtf;
1998 }
1999 else
2000 {
2001 SotStorageStreamRef xStm;
2002
2003 if( GetSotStorageStream( rFlavor, xStm ) )
2004 {
2005 *xStm >> rGraphic;
2006 bRet = ( xStm->GetError() == ERRCODE_NONE );
2007 }
2008 }
2009
2010 return bRet;
2011 }
2012
2013 // -----------------------------------------------------------------------------
2014
GetImageMap(SotFormatStringId nFormat,ImageMap & rIMap)2015 sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
2016 {
2017 DataFlavor aFlavor;
2018 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
2019 }
2020
2021 // -----------------------------------------------------------------------------
2022
GetImageMap(const::com::sun::star::datatransfer::DataFlavor & rFlavor,ImageMap & rIMap)2023 sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
2024 {
2025 SotStorageStreamRef xStm;
2026 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2027
2028 if( bRet )
2029 {
2030 rIMap.Read( *xStm, String() );
2031 bRet = ( xStm->GetError() == ERRCODE_NONE );
2032 }
2033
2034 return bRet;
2035 }
2036
2037 // -----------------------------------------------------------------------------
2038
GetTransferableObjectDescriptor(SotFormatStringId nFormat,TransferableObjectDescriptor & rDesc)2039 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
2040 {
2041 DataFlavor aFlavor;
2042 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
2043 }
2044
2045 // -----------------------------------------------------------------------------
2046
GetTransferableObjectDescriptor(const::com::sun::star::datatransfer::DataFlavor &,TransferableObjectDescriptor & rDesc)2047 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
2048 {
2049 rDesc = *mpObjDesc;
2050 return true;
2051 }
2052
2053 // -----------------------------------------------------------------------------
2054
GetINetBookmark(SotFormatStringId nFormat,INetBookmark & rBmk)2055 sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
2056 {
2057 DataFlavor aFlavor;
2058 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
2059 }
2060
2061 // -----------------------------------------------------------------------------
2062
GetINetBookmark(const::com::sun::star::datatransfer::DataFlavor & rFlavor,INetBookmark & rBmk)2063 sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
2064 {
2065 sal_Bool bRet = sal_False;
2066 if( HasFormat( rFlavor ))
2067 {
2068 const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
2069 switch( nFormat )
2070 {
2071 case( SOT_FORMATSTR_ID_SOLK ):
2072 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
2073 {
2074 String aString;
2075 if( GetString( rFlavor, aString ) )
2076 {
2077 if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
2078 {
2079 rBmk = INetBookmark( aString, aString );
2080 bRet = sal_True;
2081 }
2082 else
2083 {
2084 String aURL, aDesc;
2085 sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
2086
2087 if( !nLen && aString.GetChar( 0 ) != '0' )
2088 {
2089 DBG_WARNING( "SOLK: 1. len=0" );
2090 }
2091 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
2092 {
2093 DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
2094 }
2095 aURL = aString.Copy( nStart + 1, nLen );
2096
2097 aString.Erase( 0, nStart + 1 + nLen );
2098 nStart = aString.Search( '@' );
2099 nLen = (sal_uInt16) aString.ToInt32();
2100
2101 if( !nLen && aString.GetChar( 0 ) != '0' )
2102 {
2103 DBG_WARNING( "SOLK: 2. len=0" );
2104 }
2105 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
2106 {
2107 DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
2108 }
2109 aDesc = aString.Copy( nStart+1, nLen );
2110
2111 rBmk = INetBookmark( aURL, aDesc );
2112 bRet = sal_True;
2113 }
2114 }
2115 }
2116 break;
2117
2118 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
2119 {
2120 Sequence< sal_Int8 > aSeq;
2121
2122 if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
2123 {
2124 rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), gsl_getSystemTextEncoding() ),
2125 String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, gsl_getSystemTextEncoding() ) );
2126 bRet = sal_True;
2127 }
2128 }
2129 break;
2130
2131 #ifdef WNT
2132 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
2133 {
2134 Sequence< sal_Int8 > aSeq;
2135
2136 if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
2137 {
2138 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
2139
2140 if( pFDesc->cItems )
2141 {
2142 ByteString aDesc( pFDesc->fgd[ 0 ].cFileName );
2143 rtl_TextEncoding eTextEncoding = gsl_getSystemTextEncoding();
2144
2145 if( ( aDesc.Len() > 4 ) && aDesc.Copy( aDesc.Len() - 4 ).EqualsIgnoreCaseAscii( ".URL" ) )
2146 {
2147 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( String( aDesc, eTextEncoding ) ).GetMainURL( INetURLObject::NO_DECODE ),
2148 STREAM_STD_READ );
2149
2150 if( !pStream || pStream->GetError() )
2151 {
2152 DataFlavor aFileContentFlavor;
2153
2154 aSeq.realloc( 0 );
2155 delete pStream;
2156
2157 if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
2158 GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
2159 {
2160 pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
2161 }
2162 else
2163 pStream = NULL;
2164 }
2165
2166 if( pStream )
2167 {
2168 ByteString aLine;
2169 sal_Bool bSttFnd = sal_False;
2170
2171 while( pStream->ReadLine( aLine ) )
2172 {
2173 if( aLine.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
2174 bSttFnd = sal_True;
2175 else if( bSttFnd && aLine.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "URL=" ) )
2176 {
2177 rBmk = INetBookmark( String( aLine.Erase( 0, 4 ), eTextEncoding ),
2178 String( aDesc.Erase( aDesc.Len() - 4 ), eTextEncoding ) );
2179 bRet = sal_True;
2180 break;
2181 }
2182 }
2183
2184 delete pStream;
2185 }
2186 }
2187 }
2188 }
2189 }
2190 break;
2191 #endif
2192
2193 }
2194 }
2195 return bRet;
2196 }
2197
2198 // -----------------------------------------------------------------------------
2199
GetINetImage(SotFormatStringId nFormat,INetImage & rINtImg)2200 sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
2201 INetImage& rINtImg )
2202 {
2203 DataFlavor aFlavor;
2204 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
2205 }
2206
2207 // -----------------------------------------------------------------------------
2208
GetINetImage(const::com::sun::star::datatransfer::DataFlavor & rFlavor,INetImage & rINtImg)2209 sal_Bool TransferableDataHelper::GetINetImage(
2210 const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
2211 INetImage& rINtImg )
2212 {
2213 SotStorageStreamRef xStm;
2214 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2215
2216 if( bRet )
2217 bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
2218 return bRet;
2219 }
2220
2221 // -----------------------------------------------------------------------------
2222
GetFileList(SotFormatStringId nFormat,FileList & rFileList)2223 sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
2224 FileList& rFileList )
2225 {
2226 DataFlavor aFlavor;
2227 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
2228 }
2229
2230 // -----------------------------------------------------------------------------
2231
GetFileList(const::com::sun::star::datatransfer::DataFlavor &,FileList & rFileList)2232 sal_Bool TransferableDataHelper::GetFileList(
2233 const ::com::sun::star::datatransfer::DataFlavor&,
2234 FileList& rFileList )
2235 {
2236 SotStorageStreamRef xStm;
2237 sal_Bool bRet = sal_False;
2238
2239 for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
2240 {
2241 if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
2242 {
2243 const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
2244
2245 if( GetSotStorageStream( aFlavor, xStm ) )
2246 {
2247 if( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) > -1 )
2248 {
2249 ByteString aByteString;
2250
2251 while( xStm->ReadLine( aByteString ) )
2252 if( aByteString.Len() && aByteString.GetChar( 0 ) != '#' )
2253 rFileList.AppendFile( String( aByteString, RTL_TEXTENCODING_UTF8 ) );
2254
2255 bRet = sal_True;
2256 }
2257 else
2258 bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
2259 }
2260 }
2261 }
2262
2263 return bRet;
2264 }
2265
2266 // -----------------------------------------------------------------------------
2267
GetSequence(SotFormatStringId nFormat,Sequence<sal_Int8> & rSeq)2268 sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
2269 {
2270 DataFlavor aFlavor;
2271 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
2272 }
2273
2274 // -----------------------------------------------------------------------------
2275
GetSequence(const DataFlavor & rFlavor,Sequence<sal_Int8> & rSeq)2276 sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
2277 {
2278 #ifdef DEBUG
2279 fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
2280 #endif
2281
2282 const Any aAny( GetAny( rFlavor ) );
2283 return( aAny.hasValue() && ( aAny >>= rSeq ) );
2284 }
2285
2286 // -----------------------------------------------------------------------------
2287
GetSotStorageStream(SotFormatStringId nFormat,SotStorageStreamRef & rxStream)2288 sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
2289 {
2290 DataFlavor aFlavor;
2291 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
2292 }
2293
2294 // -----------------------------------------------------------------------------
2295
GetSotStorageStream(const DataFlavor & rFlavor,SotStorageStreamRef & rxStream)2296 sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
2297 {
2298 Sequence< sal_Int8 > aSeq;
2299 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2300
2301 if( bRet )
2302 {
2303 rxStream = new SotStorageStream( String() );
2304 rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
2305 rxStream->Seek( 0 );
2306 }
2307
2308 return bRet;
2309 }
2310
GetInputStream(SotFormatStringId nFormat,Reference<XInputStream> & rxStream)2311 sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
2312 {
2313 DataFlavor aFlavor;
2314 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
2315 }
2316
2317 // -----------------------------------------------------------------------------
2318
GetInputStream(const DataFlavor & rFlavor,Reference<XInputStream> & rxStream)2319 sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
2320 {
2321 Sequence< sal_Int8 > aSeq;
2322 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2323
2324 if( bRet )
2325 rxStream = new ::comphelper::SequenceInputStream( aSeq );
2326
2327 return bRet;
2328 }
2329
2330 // -----------------------------------------------------------------------------
2331
2332
GetInterface(SotFormatStringId nFormat,Reference<XInterface> & rIf)2333 sal_Bool TransferableDataHelper::GetInterface( SotFormatStringId nFormat, Reference< XInterface >& rIf )
2334 {
2335 DataFlavor aFlavor;
2336 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInterface( aFlavor, rIf ) );
2337 }
2338
2339 // -----------------------------------------------------------------------------
2340
GetInterface(const DataFlavor & rFlavor,Reference<XInterface> & rIf)2341 sal_Bool TransferableDataHelper::GetInterface( const DataFlavor& rFlavor, Reference< XInterface >& rIf )
2342 {
2343 const Any aAny( GetAny( rFlavor ) );
2344 return( aAny.hasValue() && ( aAny >>= rIf ) );
2345 }
2346
2347 // -----------------------------------------------------------------------------
Rebind(const Reference<XTransferable> & _rxNewContent)2348 void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
2349 {
2350 mxTransfer = _rxNewContent;
2351 InitFormats();
2352 }
2353
2354 // -----------------------------------------------------------------------------
2355
StartClipboardListening()2356 sal_Bool TransferableDataHelper::StartClipboardListening( )
2357 {
2358 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2359
2360 StopClipboardListening( );
2361
2362 mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
2363 mpImpl->mpClipboardListener->acquire();
2364
2365 return mpImpl->mpClipboardListener->isListening();
2366 }
2367
2368 // -----------------------------------------------------------------------------
2369
StopClipboardListening()2370 void TransferableDataHelper::StopClipboardListening( )
2371 {
2372 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2373
2374 if ( mpImpl->mpClipboardListener )
2375 {
2376 mpImpl->mpClipboardListener->dispose();
2377 mpImpl->mpClipboardListener->release();
2378 mpImpl->mpClipboardListener = NULL;
2379 }
2380 }
2381
2382 // -----------------------------------------------------------------------------
2383
CreateFromSystemClipboard(Window * pWindow)2384 TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
2385 {
2386 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2387
2388 Reference< XClipboard > xClipboard;
2389 TransferableDataHelper aRet;
2390
2391 if( pWindow )
2392 xClipboard = pWindow->GetClipboard();
2393
2394 if( xClipboard.is() )
2395 {
2396 try
2397
2398 {
2399 Reference< XTransferable > xTransferable( xClipboard->getContents() );
2400
2401 if( xTransferable.is() )
2402 {
2403 aRet = TransferableDataHelper( xTransferable );
2404 aRet.mxClipboard = xClipboard;
2405 // also copy the clipboard - 99030 - 23.05.2002 - fs@openoffice.org
2406 }
2407 }
2408 catch( const ::com::sun::star::uno::Exception& )
2409 {
2410 }
2411 }
2412
2413 return aRet;
2414 }
2415
2416
2417 // -----------------------------------------------------------------------------
2418
CreateFromSelection(Window * pWindow)2419 TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
2420 {
2421 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2422
2423 Reference< XClipboard > xSelection;
2424 TransferableDataHelper aRet;
2425
2426 if( pWindow )
2427 xSelection = pWindow->GetPrimarySelection();
2428
2429 if( xSelection.is() )
2430 {
2431 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2432
2433 try
2434 {
2435 Reference< XTransferable > xTransferable( xSelection->getContents() );
2436
2437 if( xTransferable.is() )
2438 {
2439 aRet = TransferableDataHelper( xTransferable );
2440 aRet.mxClipboard = xSelection;
2441 }
2442 }
2443 catch( const ::com::sun::star::uno::Exception& )
2444 {
2445 }
2446
2447 Application::AcquireSolarMutex( nRef );
2448 }
2449
2450 return aRet;
2451 }
2452
2453 // -----------------------------------------------------------------------------
IsEqual(const::com::sun::star::datatransfer::DataFlavor & rInternalFlavor,const::com::sun::star::datatransfer::DataFlavor & rRequestFlavor,sal_Bool)2454 sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
2455 const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
2456 sal_Bool )
2457 {
2458 Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
2459 Reference< XMimeContentTypeFactory > xMimeFact;
2460 sal_Bool bRet = sal_False;
2461
2462 try
2463 {
2464 if( xFact.is() )
2465 xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
2466 "com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
2467 UNO_QUERY );
2468
2469 if( xMimeFact.is() )
2470 {
2471 Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
2472 Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2473
2474 if( xRequestType1.is() && xRequestType2.is() )
2475 {
2476 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2477 {
2478 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
2479 {
2480 // special handling for text/plain media types
2481 const ::rtl::OUString aCharsetString( ::rtl::OUString::createFromAscii( "charset" ) );
2482
2483 if( !xRequestType2->hasParameter( aCharsetString ) ||
2484 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) ||
2485 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) )
2486 {
2487 bRet = sal_True;
2488 }
2489 }
2490 else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice" ) ) )
2491 {
2492 // special handling for application/x-openoffice media types
2493 const ::rtl::OUString aFormatString( ::rtl::OUString::createFromAscii( "windows_formatname" ) );
2494
2495 if( xRequestType1->hasParameter( aFormatString ) &&
2496 xRequestType2->hasParameter( aFormatString ) &&
2497 xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
2498 {
2499 bRet = sal_True;
2500 }
2501 }
2502 else
2503 bRet = sal_True;
2504 }
2505 }
2506 }
2507 }
2508 catch( const ::com::sun::star::uno::Exception& )
2509 {
2510 bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
2511 }
2512
2513 return bRet;
2514 }
2515