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