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/XDesktop.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< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
531 :
532 0 : if( xFact.is() )
533 : {
534 0 : Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" )) ), UNO_QUERY );
535 :
536 0 : if( xDesktop.is() )
537 0 : xDesktop->removeTerminateListener( mxTerminateListener );
538 : }
539 :
540 0 : mxTerminateListener = Reference< XTerminateListener >();
541 : }
542 :
543 0 : ObjectReleased();
544 : }
545 0 : catch( const ::com::sun::star::uno::Exception& )
546 : {
547 0 : }
548 0 : }
549 :
550 : // -----------------------------------------------------------------------------
551 :
552 0 : void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
553 : {
554 0 : }
555 :
556 : // -----------------------------------------------------------------------------
557 :
558 0 : void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
559 : {
560 0 : const SolarMutexGuard aGuard;
561 :
562 : try
563 : {
564 0 : DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
565 0 : ObjectReleased();
566 : }
567 0 : catch( const ::com::sun::star::uno::Exception& )
568 : {
569 0 : }
570 0 : }
571 :
572 : // -----------------------------------------------------------------------------
573 :
574 0 : void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
575 : {
576 0 : }
577 :
578 : // -----------------------------------------------------------------------------
579 :
580 0 : void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
581 : {
582 0 : }
583 :
584 : // -----------------------------------------------------------------------------
585 :
586 0 : void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
587 : {
588 0 : }
589 :
590 : // -----------------------------------------------------------------------------
591 :
592 0 : void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
593 : {
594 0 : }
595 :
596 : // -----------------------------------------------------------------------------
597 :
598 0 : sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
599 : {
600 : sal_Int64 nRet;
601 :
602 0 : if( ( rId.getLength() == 16 ) &&
603 0 : ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
604 : {
605 0 : nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
606 : }
607 : else
608 0 : nRet = 0;
609 :
610 0 : return nRet;
611 : }
612 :
613 : // -----------------------------------------------------------------------------
614 :
615 0 : void TransferableHelper::ImplFlush()
616 : {
617 0 : if( mxClipboard.is() )
618 : {
619 0 : Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY );
620 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
621 :
622 : try
623 : {
624 0 : if( xFlushableClipboard.is() )
625 0 : xFlushableClipboard->flushClipboard();
626 : }
627 0 : catch( const ::com::sun::star::uno::Exception& )
628 : {
629 : OSL_FAIL( "Could not flush clipboard" );
630 : }
631 :
632 0 : Application::AcquireSolarMutex( nRef );
633 : }
634 0 : }
635 :
636 : // -----------------------------------------------------------------------------
637 :
638 0 : void TransferableHelper::AddFormat( SotFormatStringId nFormat )
639 : {
640 0 : DataFlavor aFlavor;
641 :
642 0 : if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
643 0 : AddFormat( aFlavor );
644 0 : }
645 :
646 : // -----------------------------------------------------------------------------
647 :
648 0 : void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
649 : {
650 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
651 0 : sal_Bool bAdd = sal_True;
652 :
653 0 : while( aIter != aEnd )
654 : {
655 0 : if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
656 : {
657 : // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
658 0 : if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId ) && mpObjDesc )
659 : {
660 0 : DataFlavor aObjDescFlavor;
661 :
662 0 : SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDescFlavor );
663 0 : aIter->MimeType = aObjDescFlavor.MimeType;
664 0 : aIter->MimeType += ::ImplGetParameterString( *mpObjDesc );
665 :
666 : #ifdef DEBUG
667 : fprintf( stderr, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
668 : rtl::OUStringToOString(aIter->MimeType, RTL_TEXTENCODING_ASCII_US).getStr() );
669 : #endif
670 : }
671 :
672 0 : aIter = aEnd;
673 0 : bAdd = sal_False;
674 : }
675 : else
676 0 : aIter++;
677 : }
678 :
679 0 : if( bAdd )
680 : {
681 0 : DataFlavorEx aFlavorEx;
682 0 : DataFlavor aObjDescFlavor;
683 :
684 0 : aFlavorEx.MimeType = rFlavor.MimeType;
685 0 : aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
686 0 : aFlavorEx.DataType = rFlavor.DataType;
687 0 : aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
688 :
689 0 : if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aFlavorEx.mnSotId ) && mpObjDesc )
690 0 : aFlavorEx.MimeType += ::ImplGetParameterString( *mpObjDesc );
691 :
692 0 : mpFormats->push_back( aFlavorEx );
693 :
694 0 : if( FORMAT_BITMAP == aFlavorEx.mnSotId )
695 : {
696 0 : AddFormat( SOT_FORMATSTR_ID_BMP );
697 : }
698 0 : else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
699 : {
700 0 : AddFormat( SOT_FORMATSTR_ID_EMF );
701 0 : AddFormat( SOT_FORMATSTR_ID_WMF );
702 0 : }
703 : }
704 0 : }
705 :
706 : // -----------------------------------------------------------------------------
707 :
708 0 : void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
709 : {
710 0 : DataFlavor aFlavor;
711 :
712 0 : if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
713 0 : RemoveFormat( aFlavor );
714 0 : }
715 :
716 : // -----------------------------------------------------------------------------
717 :
718 0 : void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
719 : {
720 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
721 :
722 0 : while( aIter != aEnd )
723 : {
724 0 : if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
725 : {
726 0 : aIter = mpFormats->erase( aIter );
727 0 : aEnd = mpFormats->end();
728 : }
729 : else
730 0 : ++aIter;
731 : }
732 0 : }
733 :
734 : // -----------------------------------------------------------------------------
735 :
736 0 : sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
737 : {
738 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
739 0 : sal_Bool bRet = sal_False;
740 :
741 0 : while( aIter != aEnd )
742 : {
743 0 : if( nFormat == (*aIter).mnSotId )
744 : {
745 0 : aIter = aEnd;
746 0 : bRet = sal_True;
747 : }
748 : else
749 0 : ++aIter;
750 : }
751 :
752 0 : return bRet;
753 : }
754 :
755 : // -----------------------------------------------------------------------------
756 :
757 0 : void TransferableHelper::ClearFormats()
758 : {
759 0 : mpFormats->clear();
760 0 : maAny.clear();
761 0 : }
762 :
763 : // -----------------------------------------------------------------------------
764 :
765 0 : sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
766 : {
767 0 : maAny = rAny;
768 0 : return( maAny.hasValue() );
769 : }
770 :
771 : // -----------------------------------------------------------------------------
772 :
773 0 : sal_Bool TransferableHelper::SetString( const ::rtl::OUString& rString, const DataFlavor& rFlavor )
774 : {
775 0 : DataFlavor aFileFlavor;
776 :
777 0 : if( !rString.isEmpty() &&
778 0 : SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
779 0 : TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
780 : {
781 0 : const rtl::OString aByteStr(rtl::OUStringToOString(rString, osl_getThreadTextEncoding()));
782 0 : Sequence< sal_Int8 > aSeq( aByteStr.getLength() + 1 );
783 :
784 0 : memcpy( aSeq.getArray(), aByteStr.getStr(), aByteStr.getLength() );
785 0 : aSeq[ aByteStr.getLength() ] = 0;
786 0 : maAny <<= aSeq;
787 : }
788 : else
789 0 : maAny <<= rString;
790 :
791 0 : return( maAny.hasValue() );
792 : }
793 :
794 : // -----------------------------------------------------------------------------
795 :
796 0 : sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& )
797 : {
798 0 : if( !rBitmap.IsEmpty() )
799 : {
800 0 : SvMemoryStream aMemStm( 65535, 65535 );
801 :
802 0 : aMemStm << rBitmap;
803 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
804 : }
805 :
806 0 : return( maAny.hasValue() );
807 : }
808 :
809 : // -----------------------------------------------------------------------------
810 :
811 0 : sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
812 : {
813 0 : if( rMtf.GetActionSize() )
814 : {
815 0 : SvMemoryStream aMemStm( 65535, 65535 );
816 :
817 0 : ( (GDIMetaFile&) rMtf ).Write( aMemStm );
818 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
819 : }
820 :
821 0 : return( maAny.hasValue() );
822 : }
823 :
824 : // -----------------------------------------------------------------------------
825 :
826 0 : sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
827 : {
828 0 : if( rGraphic.GetType() != GRAPHIC_NONE )
829 : {
830 0 : SvMemoryStream aMemStm( 65535, 65535 );
831 :
832 0 : aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
833 0 : aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
834 0 : aMemStm << rGraphic;
835 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
836 : }
837 :
838 0 : return( maAny.hasValue() );
839 : }
840 :
841 : // -----------------------------------------------------------------------------
842 :
843 0 : sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
844 : {
845 0 : SvMemoryStream aMemStm( 8192, 8192 );
846 :
847 0 : aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
848 0 : rIMap.Write( aMemStm, String() );
849 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
850 :
851 0 : return( maAny.hasValue() );
852 : }
853 :
854 : // -----------------------------------------------------------------------------
855 :
856 0 : sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
857 : const ::com::sun::star::datatransfer::DataFlavor& )
858 : {
859 0 : PrepareOLE( rDesc );
860 :
861 0 : SvMemoryStream aMemStm( 1024, 1024 );
862 :
863 0 : aMemStm << rDesc;
864 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
865 :
866 0 : return( maAny.hasValue() );
867 : }
868 :
869 : // -----------------------------------------------------------------------------
870 :
871 0 : sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
872 : const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
873 : {
874 0 : rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding();
875 :
876 0 : switch( SotExchange::GetFormat( rFlavor ) )
877 : {
878 : case( SOT_FORMATSTR_ID_SOLK ):
879 : {
880 0 : rtl::OString sURL(rtl::OUStringToOString(rBmk.GetURL(), eSysCSet));
881 0 : rtl::OString sDesc(rtl::OUStringToOString(rBmk.GetDescription(), eSysCSet));
882 0 : rtl::OStringBuffer sOut;
883 0 : sOut.append(sURL.getLength());
884 0 : sOut.append('@').append(sURL);
885 0 : sOut.append(sDesc.getLength());
886 0 : sOut.append('@').append(sDesc);
887 :
888 0 : Sequence< sal_Int8 > aSeq(sOut.getLength());
889 0 : memcpy(aSeq.getArray(), sOut.getStr(), sOut.getLength());
890 0 : maAny <<= aSeq;
891 : }
892 0 : break;
893 :
894 : case( FORMAT_STRING ):
895 0 : maAny <<= ::rtl::OUString( rBmk.GetURL() );
896 0 : break;
897 :
898 : case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
899 : {
900 0 : rtl::OString sURL(rtl::OUStringToOString(rBmk.GetURL(), eSysCSet));
901 0 : Sequence< sal_Int8 > aSeq( sURL.getLength() );
902 0 : memcpy( aSeq.getArray(), sURL.getStr(), sURL.getLength() );
903 0 : maAny <<= aSeq;
904 : }
905 0 : break;
906 :
907 : case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
908 : {
909 0 : Sequence< sal_Int8 > aSeq( 2048 );
910 :
911 0 : memset( aSeq.getArray(), 0, 2048 );
912 0 : strcpy( reinterpret_cast< char* >( aSeq.getArray() ), rtl::OUStringToOString(rBmk.GetURL(), eSysCSet).getStr() );
913 0 : strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, rtl::OUStringToOString(rBmk.GetDescription(), eSysCSet).getStr() );
914 :
915 0 : maAny <<= aSeq;
916 : }
917 0 : break;
918 :
919 : #ifdef WNT
920 : case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
921 : {
922 : Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
923 : FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
924 : FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
925 :
926 : pFDesc->cItems = 1;
927 : memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
928 : rFDesc1.dwFlags = FD_LINKUI;
929 :
930 : rtl::OStringBuffer aStr(rtl::OUStringToOString(
931 : rBmk.GetDescription(), eSysCSet));
932 : for( sal_uInt16 nChar = 0; nChar < aStr.getLength(); ++nChar )
933 : if( strchr( "\\/:*?\"<>|", aStr[nChar] ) )
934 : aStr.remove(nChar--, 1);
935 :
936 : aStr.insert(0, RTL_CONSTASCII_STRINGPARAM("Shortcut to "));
937 : aStr.append(RTL_CONSTASCII_STRINGPARAM(".URL"));
938 : strcpy( rFDesc1.cFileName, aStr.getStr() );
939 :
940 : maAny <<= aSeq;
941 : }
942 : break;
943 :
944 : case SOT_FORMATSTR_ID_FILECONTENT:
945 : {
946 : String aStr( RTL_CONSTASCII_USTRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
947 : maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
948 : }
949 : break;
950 : #endif
951 :
952 : default:
953 0 : break;
954 : }
955 :
956 0 : return( maAny.hasValue() );
957 : }
958 :
959 : // -----------------------------------------------------------------------------
960 :
961 0 : sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
962 : const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
963 : {
964 0 : SvMemoryStream aMemStm( 1024, 1024 );
965 :
966 0 : aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
967 0 : rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
968 :
969 0 : maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
970 :
971 0 : return( maAny.hasValue() );
972 : }
973 :
974 : // -----------------------------------------------------------------------------
975 :
976 0 : sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
977 : {
978 0 : SotStorageStreamRef xStm( new SotStorageStream( String() ) );
979 :
980 0 : xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
981 :
982 0 : if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
983 : {
984 0 : const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
985 0 : Sequence< sal_Int8 > aSeq( nLen );
986 :
987 0 : xStm->Seek( STREAM_SEEK_TO_BEGIN );
988 0 : xStm->Read( aSeq.getArray(), nLen );
989 :
990 0 : if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
991 : {
992 : //JP 24.7.2001: as I know was this only for the writer application and this
993 : // writes now UTF16 format into the stream
994 : //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
995 : // little / big endians! - Bug 88121
996 0 : maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
997 : }
998 : else
999 0 : maAny <<= aSeq;
1000 : }
1001 :
1002 0 : return( maAny.hasValue() );
1003 : }
1004 :
1005 : // -----------------------------------------------------------------------------
1006 :
1007 0 : sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
1008 : {
1009 : OSL_FAIL( "TransferableHelper::WriteObject( ... ) not implemented" );
1010 0 : return sal_False;
1011 : }
1012 :
1013 : // -----------------------------------------------------------------------------
1014 :
1015 0 : void TransferableHelper::DragFinished( sal_Int8 )
1016 : {
1017 0 : }
1018 :
1019 : // -----------------------------------------------------------------------------
1020 :
1021 0 : void TransferableHelper::ObjectReleased()
1022 : {
1023 0 : }
1024 :
1025 : // -----------------------------------------------------------------------------
1026 :
1027 0 : void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
1028 : {
1029 0 : delete mpObjDesc;
1030 0 : mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
1031 :
1032 0 : if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
1033 0 : AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
1034 0 : }
1035 :
1036 : // -----------------------------------------------------------------------------
1037 :
1038 0 : void TransferableHelper::CopyToClipboard( Window *pWindow ) const
1039 : {
1040 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
1041 0 : Reference< XClipboard > xClipboard;
1042 :
1043 0 : if( pWindow )
1044 0 : xClipboard = pWindow->GetClipboard();
1045 :
1046 0 : if( xClipboard.is() )
1047 0 : mxClipboard = xClipboard;
1048 :
1049 0 : if( mxClipboard.is() && !mxTerminateListener.is() )
1050 : {
1051 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1052 :
1053 : try
1054 : {
1055 0 : TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1056 0 : Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1057 :
1058 0 : if( xFact.is() )
1059 : {
1060 0 : Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" )) ), UNO_QUERY );
1061 :
1062 0 : if( xDesktop.is() )
1063 0 : xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1064 : }
1065 :
1066 0 : mxClipboard->setContents( pThis, pThis );
1067 : }
1068 0 : catch( const ::com::sun::star::uno::Exception& )
1069 : {
1070 : }
1071 :
1072 0 : Application::AcquireSolarMutex( nRef );
1073 0 : }
1074 0 : }
1075 :
1076 : // -----------------------------------------------------------------------------
1077 :
1078 0 : void TransferableHelper::CopyToSelection( Window *pWindow ) const
1079 : {
1080 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
1081 0 : Reference< XClipboard > xSelection;
1082 :
1083 0 : if( pWindow )
1084 0 : xSelection = pWindow->GetPrimarySelection();
1085 :
1086 0 : if( xSelection.is() && !mxTerminateListener.is() )
1087 : {
1088 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1089 :
1090 : try
1091 : {
1092 0 : TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1093 0 : Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1094 :
1095 0 : if( xFact.is() )
1096 : {
1097 0 : Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" )) ), UNO_QUERY );
1098 :
1099 0 : if( xDesktop.is() )
1100 0 : xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1101 : }
1102 :
1103 0 : xSelection->setContents( pThis, pThis );
1104 : }
1105 0 : catch( const ::com::sun::star::uno::Exception& )
1106 : {
1107 : }
1108 :
1109 0 : Application::AcquireSolarMutex( nRef );
1110 0 : }
1111 0 : }
1112 :
1113 : // -----------------------------------------------------------------------------
1114 :
1115 0 : void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
1116 : sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
1117 :
1118 : {
1119 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
1120 0 : Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
1121 :
1122 0 : if( xDragSource.is() )
1123 : {
1124 : /*
1125 : * #96792# release mouse before actually starting DnD.
1126 : * This is necessary for the X11 DnD implementation to work.
1127 : */
1128 0 : if( pWindow->IsMouseCaptured() )
1129 0 : pWindow->ReleaseMouse();
1130 :
1131 0 : const Point aPt( pWindow->GetPointerPosPixel() );
1132 :
1133 : // On Mac OS X we are forced to execute 'startDrag' synchronously
1134 : // contrary to the XDragSource interface specification because
1135 : // we can receive drag events from the system only in the main
1136 : // thread
1137 : #if !defined(QUARTZ)
1138 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1139 : #endif
1140 :
1141 : try
1142 : {
1143 0 : DragGestureEvent aEvt;
1144 0 : aEvt.DragAction = DNDConstants::ACTION_COPY;
1145 0 : aEvt.DragOriginX = aPt.X();
1146 0 : aEvt.DragOriginY = aPt.Y();
1147 0 : aEvt.DragSource = xDragSource;
1148 :
1149 0 : xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
1150 : }
1151 0 : catch( const ::com::sun::star::uno::Exception& )
1152 : {
1153 : }
1154 :
1155 : // See above for the reason of this define
1156 : #if !defined(QUARTZ)
1157 0 : Application::AcquireSolarMutex( nRef );
1158 : #endif
1159 0 : }
1160 0 : }
1161 :
1162 : // -----------------------------------------------------------------------------
1163 :
1164 0 : void TransferableHelper::ClearSelection( Window *pWindow )
1165 : {
1166 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
1167 0 : Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
1168 :
1169 0 : if( xSelection.is() )
1170 0 : xSelection->setContents( NULL, NULL );
1171 0 : }
1172 :
1173 : // -----------------------------------------------------------------------------
1174 :
1175 0 : Reference< XClipboard> TransferableHelper::GetSystemClipboard()
1176 : {
1177 0 : Window *pFocusWindow = Application::GetFocusWindow();
1178 :
1179 0 : if( pFocusWindow )
1180 0 : return pFocusWindow->GetClipboard();
1181 :
1182 0 : return Reference< XClipboard > ();
1183 : }
1184 :
1185 : namespace
1186 : {
1187 : class theTransferableHelperUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theTransferableHelperUnoTunnelId > {};
1188 : }
1189 :
1190 0 : const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
1191 : {
1192 0 : return theTransferableHelperUnoTunnelId::get().getSeq();
1193 : }
1194 :
1195 : // ---------------------------------
1196 : // - TransferableClipboardNotifier -
1197 : // ---------------------------------
1198 :
1199 0 : class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
1200 : {
1201 : private:
1202 : ::osl::Mutex& mrMutex;
1203 : Reference< XClipboardNotifier > mxNotifier;
1204 : TransferableDataHelper* mpListener;
1205 :
1206 : protected:
1207 : // XClipboardListener
1208 : virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
1209 :
1210 : // XEventListener
1211 : virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
1212 :
1213 : public:
1214 : TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
1215 :
1216 : /// determines whether we're currently listening
1217 0 : inline bool isListening() const { return !isDisposed(); }
1218 :
1219 : /// determines whether the instance is disposed
1220 0 : inline bool isDisposed() const { return mpListener == NULL; }
1221 :
1222 : /// makes the instance non-functional
1223 : void dispose();
1224 : };
1225 :
1226 : // -----------------------------------------------------------------------------
1227 :
1228 0 : TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
1229 : :mrMutex( _rMutex )
1230 : ,mxNotifier( _rxClipboard, UNO_QUERY )
1231 0 : ,mpListener( &_rListener )
1232 : {
1233 0 : osl_atomic_increment( &m_refCount );
1234 : {
1235 0 : if ( mxNotifier.is() )
1236 0 : mxNotifier->addClipboardListener( this );
1237 : else
1238 : // born dead
1239 0 : mpListener = NULL;
1240 : }
1241 0 : osl_atomic_decrement( &m_refCount );
1242 0 : }
1243 :
1244 : // -----------------------------------------------------------------------------
1245 :
1246 0 : void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
1247 : {
1248 0 : SolarMutexGuard aSolarGuard;
1249 : // the SolarMutex here is necessary, since
1250 : // - we cannot call mpListener without our own mutex locked
1251 : // - Rebind respectively InitFormats (called by Rebind) will
1252 : // try to lock the SolarMutex, too
1253 0 : ::osl::MutexGuard aGuard( mrMutex );
1254 0 : if( mpListener )
1255 0 : mpListener->Rebind( event.Contents );
1256 0 : }
1257 :
1258 : // -----------------------------------------------------------------------------
1259 :
1260 0 : void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
1261 : {
1262 : // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1263 0 : dispose();
1264 0 : }
1265 :
1266 : // -----------------------------------------------------------------------------
1267 :
1268 0 : void TransferableClipboardNotifier::dispose()
1269 : {
1270 0 : ::osl::MutexGuard aGuard( mrMutex );
1271 :
1272 0 : Reference< XClipboardListener > xKeepMeAlive( this );
1273 :
1274 0 : if ( mxNotifier.is() )
1275 0 : mxNotifier->removeClipboardListener( this );
1276 0 : mxNotifier.clear();
1277 :
1278 0 : mpListener = NULL;
1279 0 : }
1280 :
1281 : // -------------------------------
1282 : // - TransferableDataHelper_Impl -
1283 : // -------------------------------
1284 :
1285 9 : struct TransferableDataHelper_Impl
1286 : {
1287 : ::osl::Mutex maMutex;
1288 : TransferableClipboardNotifier* mpClipboardListener;
1289 :
1290 9 : TransferableDataHelper_Impl()
1291 9 : :mpClipboardListener( NULL )
1292 : {
1293 9 : }
1294 : };
1295 :
1296 : // --------------------------
1297 : // - TransferableDataHelper -
1298 : // --------------------------
1299 :
1300 9 : TransferableDataHelper::TransferableDataHelper() :
1301 9 : mpFormats( new DataFlavorExVector ),
1302 9 : mpObjDesc( new TransferableObjectDescriptor ),
1303 27 : mpImpl( new TransferableDataHelper_Impl )
1304 : {
1305 9 : }
1306 :
1307 : // -----------------------------------------------------------------------------
1308 :
1309 0 : TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
1310 : mxTransfer( rxTransferable ),
1311 0 : mpFormats( new DataFlavorExVector ),
1312 0 : mpObjDesc( new TransferableObjectDescriptor ),
1313 0 : mpImpl( new TransferableDataHelper_Impl )
1314 : {
1315 0 : InitFormats();
1316 0 : }
1317 :
1318 : // -----------------------------------------------------------------------------
1319 :
1320 0 : TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
1321 : mxTransfer( rDataHelper.mxTransfer ),
1322 : mxClipboard( rDataHelper.mxClipboard ),
1323 0 : mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
1324 0 : mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
1325 0 : mpImpl( new TransferableDataHelper_Impl )
1326 : {
1327 0 : }
1328 :
1329 : // -----------------------------------------------------------------------------
1330 :
1331 0 : TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
1332 : {
1333 0 : if ( this != &rDataHelper )
1334 : {
1335 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1336 :
1337 0 : bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
1338 :
1339 0 : if ( bWasClipboardListening )
1340 0 : StopClipboardListening();
1341 :
1342 0 : mxTransfer = rDataHelper.mxTransfer;
1343 0 : delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
1344 0 : delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
1345 0 : mxClipboard = rDataHelper.mxClipboard;
1346 :
1347 0 : if ( bWasClipboardListening )
1348 0 : StartClipboardListening();
1349 : }
1350 :
1351 0 : return *this;
1352 : }
1353 :
1354 : // -----------------------------------------------------------------------------
1355 :
1356 18 : TransferableDataHelper::~TransferableDataHelper()
1357 : {
1358 9 : StopClipboardListening( );
1359 : {
1360 9 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1361 9 : delete mpFormats, mpFormats = NULL;
1362 9 : delete mpObjDesc, mpObjDesc = NULL;
1363 : }
1364 9 : delete mpImpl;
1365 9 : }
1366 :
1367 : // -----------------------------------------------------------------------------
1368 :
1369 0 : void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
1370 : DataFlavorExVector& rDataFlavorExVector )
1371 : {
1372 : try
1373 : {
1374 0 : Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
1375 0 : Reference< XMimeContentTypeFactory > xMimeFact;
1376 0 : DataFlavorEx aFlavorEx;
1377 0 : const ::rtl::OUString aCharsetStr(RTL_CONSTASCII_USTRINGPARAM( "charset" ));
1378 :
1379 0 : if( xFact.is() )
1380 0 : xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.datatransfer.MimeContentTypeFactory" )) ),
1381 0 : UNO_QUERY );
1382 :
1383 0 : for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
1384 : {
1385 0 : const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
1386 0 : Reference< XMimeContentType > xMimeType;
1387 :
1388 : try
1389 : {
1390 0 : if( xMimeFact.is() && !rFlavor.MimeType.isEmpty() )
1391 0 : xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
1392 : }
1393 0 : catch( const ::com::sun::star::uno::Exception& )
1394 : {
1395 :
1396 : }
1397 :
1398 0 : aFlavorEx.MimeType = rFlavor.MimeType;
1399 0 : aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
1400 0 : aFlavorEx.DataType = rFlavor.DataType;
1401 0 : aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
1402 :
1403 0 : rDataFlavorExVector.push_back( aFlavorEx );
1404 :
1405 : // add additional formats for special mime types
1406 0 : if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId )
1407 : {
1408 0 : if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
1409 : {
1410 0 : aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
1411 0 : rDataFlavorExVector.push_back( aFlavorEx );
1412 : }
1413 : }
1414 0 : else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
1415 : {
1416 0 : if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
1417 : {
1418 0 : aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
1419 0 : rDataFlavorExVector.push_back( aFlavorEx );
1420 : }
1421 : }
1422 0 : else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
1423 : {
1424 : // #104735# HTML_SIMPLE may also be inserted without comments
1425 0 : aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
1426 0 : rDataFlavorExVector.push_back( aFlavorEx );
1427 : }
1428 0 : else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/plain" )) ) )
1429 : {
1430 : // add, if it is a UTF-8 byte buffer
1431 0 : if( xMimeType->hasParameter( aCharsetStr ) )
1432 : {
1433 0 : const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
1434 :
1435 0 : if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unicode" )) ) ||
1436 0 : xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "utf-16" )) ) )
1437 : {
1438 0 : rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
1439 :
1440 0 : }
1441 : }
1442 : }
1443 0 : else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/rtf" )) ) )
1444 : {
1445 0 : rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
1446 : }
1447 0 : else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/html" )) ) )
1448 :
1449 : {
1450 0 : rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
1451 : }
1452 0 : else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/uri-list" )) ) )
1453 : {
1454 0 : rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
1455 : }
1456 0 : else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-objectdescriptor-xml" )) ) )
1457 : {
1458 0 : rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
1459 : }
1460 0 : }
1461 : }
1462 0 : catch( const ::com::sun::star::uno::Exception& )
1463 : {
1464 : }
1465 0 : }
1466 :
1467 : // -----------------------------------------------------------------------------
1468 :
1469 0 : void TransferableDataHelper::InitFormats()
1470 : {
1471 0 : SolarMutexGuard aSolarGuard;
1472 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1473 :
1474 0 : mpFormats->clear();
1475 0 : delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
1476 :
1477 0 : if( mxTransfer.is() )
1478 : {
1479 0 : TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
1480 :
1481 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1482 :
1483 0 : while( aIter != aEnd )
1484 : {
1485 0 : if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
1486 : {
1487 0 : ImplSetParameterString( *mpObjDesc, *aIter );
1488 0 : aIter = aEnd;
1489 : }
1490 : else
1491 0 : ++aIter;
1492 : }
1493 0 : }
1494 0 : }
1495 :
1496 : // -----------------------------------------------------------------------------
1497 :
1498 133 : sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
1499 : {
1500 133 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1501 :
1502 133 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1503 133 : sal_Bool bRet = sal_False;
1504 :
1505 266 : while( aIter != aEnd )
1506 : {
1507 0 : if( nFormat == (*aIter++).mnSotId )
1508 : {
1509 0 : aIter = aEnd;
1510 0 : bRet = sal_True;
1511 : }
1512 : }
1513 :
1514 133 : return bRet;
1515 : }
1516 :
1517 : // -----------------------------------------------------------------------------
1518 :
1519 0 : sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
1520 : {
1521 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1522 :
1523 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1524 0 : sal_Bool bRet = sal_False;
1525 :
1526 0 : while( aIter != aEnd )
1527 : {
1528 0 : if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
1529 : {
1530 0 : aIter = aEnd;
1531 0 : bRet = sal_True;
1532 : }
1533 : }
1534 :
1535 0 : return bRet;
1536 : }
1537 :
1538 : // -----------------------------------------------------------------------------
1539 :
1540 0 : sal_uInt32 TransferableDataHelper::GetFormatCount() const
1541 : {
1542 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1543 0 : return mpFormats->size();
1544 : }
1545 :
1546 : // -----------------------------------------------------------------------------
1547 :
1548 :
1549 0 : SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
1550 : {
1551 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1552 : DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1553 0 : return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
1554 : }
1555 :
1556 : // -----------------------------------------------------------------------------
1557 :
1558 0 : DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
1559 : {
1560 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1561 : DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1562 :
1563 0 : DataFlavor aRet;
1564 :
1565 0 : if( nFormat < mpFormats->size() )
1566 0 : aRet = (*mpFormats)[ nFormat ];
1567 :
1568 0 : return aRet;
1569 : }
1570 :
1571 : // -----------------------------------------------------------------------------
1572 :
1573 2 : Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
1574 : {
1575 2 : Reference< XTransferable > xRet;
1576 :
1577 2 : if( mxTransfer.is() )
1578 : {
1579 : try
1580 : {
1581 0 : xRet = mxTransfer;
1582 :
1583 : // do a dummy call to check, if this interface is valid (nasty)
1584 0 : Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
1585 :
1586 : }
1587 0 : catch( const ::com::sun::star::uno::Exception& )
1588 : {
1589 0 : xRet = Reference< XTransferable >();
1590 : }
1591 : }
1592 :
1593 2 : return xRet;
1594 : }
1595 :
1596 : // -----------------------------------------------------------------------------
1597 :
1598 0 : Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
1599 : {
1600 0 : Any aReturn;
1601 :
1602 0 : DataFlavor aFlavor;
1603 0 : if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
1604 0 : aReturn = GetAny( aFlavor );
1605 :
1606 0 : return aReturn;
1607 : }
1608 :
1609 :
1610 : // -----------------------------------------------------------------------------
1611 :
1612 0 : Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
1613 : {
1614 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
1615 0 : Any aRet;
1616 :
1617 : try
1618 : {
1619 0 : if( mxTransfer.is() )
1620 : {
1621 0 : DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1622 0 : const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
1623 :
1624 0 : if( nRequestFormat )
1625 : {
1626 : // try to get alien format first
1627 0 : while( aIter != aEnd )
1628 : {
1629 0 : if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
1630 0 : aRet = mxTransfer->getTransferData( *aIter );
1631 :
1632 0 : if( aRet.hasValue() )
1633 0 : aIter = aEnd;
1634 : else
1635 0 : aIter++;
1636 : }
1637 : }
1638 :
1639 0 : if( !aRet.hasValue() )
1640 0 : aRet = mxTransfer->getTransferData( rFlavor );
1641 : }
1642 : }
1643 0 : catch( const ::com::sun::star::uno::Exception& )
1644 : {
1645 : }
1646 :
1647 0 : return aRet;
1648 : }
1649 :
1650 : // -----------------------------------------------------------------------------
1651 :
1652 0 : sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
1653 : {
1654 0 : ::rtl::OUString aOUString;
1655 0 : sal_Bool bRet = GetString( nFormat, aOUString );
1656 :
1657 0 : rStr = aOUString;
1658 :
1659 0 : return bRet;
1660 : }
1661 :
1662 : // -----------------------------------------------------------------------------
1663 :
1664 0 : sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
1665 : {
1666 0 : ::rtl::OUString aOUString;
1667 0 : sal_Bool bRet = GetString( rFlavor, aOUString );
1668 :
1669 0 : rStr = aOUString;
1670 :
1671 0 : return bRet;
1672 : }
1673 :
1674 : // -----------------------------------------------------------------------------
1675 :
1676 0 : sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
1677 : {
1678 0 : DataFlavor aFlavor;
1679 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
1680 : }
1681 :
1682 : // -----------------------------------------------------------------------------
1683 :
1684 0 : sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
1685 : {
1686 0 : Any aAny( GetAny( rFlavor ) );
1687 0 : sal_Bool bRet = sal_False;
1688 :
1689 0 : if( aAny.hasValue() )
1690 : {
1691 0 : ::rtl::OUString aOUString;
1692 0 : Sequence< sal_Int8 > aSeq;
1693 :
1694 0 : if( aAny >>= aOUString )
1695 : {
1696 0 : rStr = aOUString;
1697 0 : bRet = sal_True;
1698 : }
1699 0 : else if( aAny >>= aSeq )
1700 : {
1701 :
1702 0 : const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
1703 0 : sal_Int32 nLen = aSeq.getLength();
1704 :
1705 : //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1706 : //DVO 2002-05-27: strip _all_ trailing zeros
1707 0 : while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
1708 0 : --nLen;
1709 :
1710 0 : rStr = ::rtl::OUString( pChars, nLen, osl_getThreadTextEncoding() );
1711 0 : bRet = sal_True;
1712 0 : }
1713 : }
1714 :
1715 0 : return bRet;
1716 : }
1717 :
1718 : // -----------------------------------------------------------------------------
1719 :
1720 0 : sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp )
1721 : {
1722 0 : DataFlavor aFlavor;
1723 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) );
1724 : }
1725 :
1726 : // -----------------------------------------------------------------------------
1727 :
1728 0 : sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp )
1729 : {
1730 0 : SotStorageStreamRef xStm;
1731 0 : DataFlavor aSubstFlavor;
1732 0 : sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1733 :
1734 0 : if( bRet )
1735 : {
1736 0 : *xStm >> rBmp;
1737 0 : bRet = ( xStm->GetError() == ERRCODE_NONE );
1738 :
1739 : /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1740 : problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1741 : and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1742 : Due to this reason the following code assumes that bitmaps with a logical size
1743 : greater than 50 cm aren't having the correct mapmode set.
1744 :
1745 : The following code should be removed if DDBs and DIBs are supported via clipboard
1746 : properly.
1747 : */
1748 0 : if ( bRet )
1749 : {
1750 0 : MapMode aMapMode = rBmp.GetPrefMapMode();
1751 0 : if ( aMapMode.GetMapUnit() != MAP_PIXEL )
1752 : {
1753 0 : Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM );
1754 0 : if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) )
1755 0 : rBmp.SetPrefMapMode( MAP_PIXEL );
1756 0 : }
1757 : }
1758 : }
1759 :
1760 0 : if( !bRet &&
1761 0 : HasFormat( SOT_FORMATSTR_ID_BMP ) &&
1762 0 : SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
1763 0 : GetSotStorageStream( aSubstFlavor, xStm ) )
1764 : {
1765 0 : xStm->ResetError();
1766 0 : *xStm >> rBmp;
1767 0 : bRet = ( xStm->GetError() == ERRCODE_NONE );
1768 : }
1769 :
1770 0 : return bRet;
1771 : }
1772 :
1773 : // -----------------------------------------------------------------------------
1774 :
1775 0 : sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
1776 : {
1777 0 : DataFlavor aFlavor;
1778 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
1779 : }
1780 :
1781 : // -----------------------------------------------------------------------------
1782 :
1783 0 : sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
1784 : {
1785 0 : SotStorageStreamRef xStm;
1786 0 : DataFlavor aSubstFlavor;
1787 0 : sal_Bool bRet = sal_False;
1788 :
1789 0 : if( GetSotStorageStream( rFlavor, xStm ) )
1790 : {
1791 0 : *xStm >> rMtf;
1792 0 : bRet = ( xStm->GetError() == ERRCODE_NONE );
1793 : }
1794 :
1795 0 : if( !bRet &&
1796 0 : HasFormat( SOT_FORMATSTR_ID_EMF ) &&
1797 0 : SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
1798 0 : GetSotStorageStream( aSubstFlavor, xStm ) )
1799 : {
1800 0 : Graphic aGraphic;
1801 :
1802 0 : if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1803 : {
1804 0 : rMtf = aGraphic.GetGDIMetaFile();
1805 0 : bRet = sal_True;
1806 0 : }
1807 : }
1808 :
1809 0 : if( !bRet &&
1810 0 : HasFormat( SOT_FORMATSTR_ID_WMF ) &&
1811 0 : SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
1812 0 : GetSotStorageStream( aSubstFlavor, xStm ) )
1813 : {
1814 0 : Graphic aGraphic;
1815 :
1816 0 : if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1817 : {
1818 0 : rMtf = aGraphic.GetGDIMetaFile();
1819 0 : bRet = sal_True;
1820 0 : }
1821 : }
1822 :
1823 0 : return bRet;
1824 : }
1825 :
1826 : // -----------------------------------------------------------------------------
1827 :
1828 0 : sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
1829 : {
1830 0 : DataFlavor aFlavor;
1831 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
1832 : }
1833 :
1834 : // -----------------------------------------------------------------------------
1835 :
1836 0 : sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
1837 : {
1838 0 : DataFlavor aFlavor;
1839 0 : sal_Bool bRet = sal_False;
1840 :
1841 0 : if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
1842 0 : TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1843 : {
1844 0 : Bitmap aBmp;
1845 :
1846 0 : if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True )
1847 0 : rGraphic = aBmp;
1848 : }
1849 0 : else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
1850 0 : TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1851 : {
1852 0 : GDIMetaFile aMtf;
1853 :
1854 0 : if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
1855 0 : rGraphic = aMtf;
1856 : }
1857 : else
1858 : {
1859 0 : SotStorageStreamRef xStm;
1860 :
1861 0 : if( GetSotStorageStream( rFlavor, xStm ) )
1862 : {
1863 0 : *xStm >> rGraphic;
1864 0 : bRet = ( xStm->GetError() == ERRCODE_NONE );
1865 0 : }
1866 : }
1867 :
1868 0 : return bRet;
1869 : }
1870 :
1871 : // -----------------------------------------------------------------------------
1872 :
1873 0 : sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
1874 : {
1875 0 : DataFlavor aFlavor;
1876 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
1877 : }
1878 :
1879 : // -----------------------------------------------------------------------------
1880 :
1881 0 : sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
1882 : {
1883 0 : SotStorageStreamRef xStm;
1884 0 : sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1885 :
1886 0 : if( bRet )
1887 : {
1888 0 : rIMap.Read( *xStm, String() );
1889 0 : bRet = ( xStm->GetError() == ERRCODE_NONE );
1890 : }
1891 :
1892 0 : return bRet;
1893 : }
1894 :
1895 : // -----------------------------------------------------------------------------
1896 :
1897 0 : sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
1898 : {
1899 0 : DataFlavor aFlavor;
1900 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
1901 : }
1902 :
1903 : // -----------------------------------------------------------------------------
1904 :
1905 0 : sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
1906 : {
1907 0 : rDesc = *mpObjDesc;
1908 0 : return true;
1909 : }
1910 :
1911 : // -----------------------------------------------------------------------------
1912 :
1913 0 : sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
1914 : {
1915 0 : DataFlavor aFlavor;
1916 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
1917 : }
1918 :
1919 : // -----------------------------------------------------------------------------
1920 :
1921 0 : sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
1922 : {
1923 0 : sal_Bool bRet = sal_False;
1924 0 : if( HasFormat( rFlavor ))
1925 : {
1926 0 : const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
1927 0 : switch( nFormat )
1928 : {
1929 : case( SOT_FORMATSTR_ID_SOLK ):
1930 : case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
1931 : {
1932 0 : String aString;
1933 0 : if( GetString( rFlavor, aString ) )
1934 : {
1935 0 : if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
1936 : {
1937 0 : rBmk = INetBookmark( aString, aString );
1938 0 : bRet = sal_True;
1939 : }
1940 : else
1941 : {
1942 0 : String aURL, aDesc;
1943 0 : sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
1944 :
1945 0 : if( !nLen && aString.GetChar( 0 ) != '0' )
1946 : {
1947 : DBG_WARNING( "SOLK: 1. len=0" );
1948 : }
1949 0 : if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
1950 : {
1951 : DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
1952 : }
1953 0 : aURL = aString.Copy( nStart + 1, nLen );
1954 :
1955 0 : aString.Erase( 0, nStart + 1 + nLen );
1956 0 : nStart = aString.Search( '@' );
1957 0 : nLen = (sal_uInt16) aString.ToInt32();
1958 :
1959 0 : if( !nLen && aString.GetChar( 0 ) != '0' )
1960 : {
1961 : DBG_WARNING( "SOLK: 2. len=0" );
1962 : }
1963 0 : if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
1964 : {
1965 : DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
1966 : }
1967 0 : aDesc = aString.Copy( nStart+1, nLen );
1968 :
1969 0 : rBmk = INetBookmark( aURL, aDesc );
1970 0 : bRet = sal_True;
1971 : }
1972 0 : }
1973 : }
1974 0 : break;
1975 :
1976 : case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
1977 : {
1978 0 : Sequence< sal_Int8 > aSeq;
1979 :
1980 0 : if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
1981 : {
1982 0 : rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), osl_getThreadTextEncoding() ),
1983 0 : String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, osl_getThreadTextEncoding() ) );
1984 0 : bRet = sal_True;
1985 0 : }
1986 : }
1987 0 : break;
1988 :
1989 : #ifdef WNT
1990 : case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
1991 : {
1992 : Sequence< sal_Int8 > aSeq;
1993 :
1994 : if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
1995 : {
1996 : FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
1997 :
1998 : if( pFDesc->cItems )
1999 : {
2000 : rtl::OString aDesc( pFDesc->fgd[ 0 ].cFileName );
2001 : rtl_TextEncoding eTextEncoding = osl_getThreadTextEncoding();
2002 :
2003 : if( ( aDesc.getLength() > 4 ) && aDesc.copy(aDesc.getLength() - 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM(".URL")) )
2004 : {
2005 : SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( rtl::OStringToOUString(aDesc, eTextEncoding) ).GetMainURL( INetURLObject::NO_DECODE ),
2006 : STREAM_STD_READ );
2007 :
2008 : if( !pStream || pStream->GetError() )
2009 : {
2010 : DataFlavor aFileContentFlavor;
2011 :
2012 : aSeq.realloc( 0 );
2013 : delete pStream;
2014 :
2015 : if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
2016 : GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
2017 : {
2018 : pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
2019 : }
2020 : else
2021 : pStream = NULL;
2022 : }
2023 :
2024 : if( pStream )
2025 : {
2026 : rtl::OString aLine;
2027 : sal_Bool bSttFnd = sal_False;
2028 :
2029 : while( pStream->ReadLine( aLine ) )
2030 : {
2031 : if (aLine.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("[InternetShortcut]")))
2032 : bSttFnd = sal_True;
2033 : else if (bSttFnd && aLine.copy(0, 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("URL=")))
2034 : {
2035 : rBmk = INetBookmark( rtl::OStringToOUString(aLine.copy(4), eTextEncoding),
2036 : rtl::OStringToOUString(aDesc.copy(0, aDesc.getLength() - 4), eTextEncoding) );
2037 : bRet = sal_True;
2038 : break;
2039 : }
2040 : }
2041 :
2042 : delete pStream;
2043 : }
2044 : }
2045 : }
2046 : }
2047 : }
2048 : break;
2049 : #endif
2050 :
2051 : }
2052 : }
2053 0 : return bRet;
2054 : }
2055 :
2056 : // -----------------------------------------------------------------------------
2057 :
2058 0 : sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
2059 : INetImage& rINtImg )
2060 : {
2061 0 : DataFlavor aFlavor;
2062 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
2063 : }
2064 :
2065 : // -----------------------------------------------------------------------------
2066 :
2067 0 : sal_Bool TransferableDataHelper::GetINetImage(
2068 : const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
2069 : INetImage& rINtImg )
2070 : {
2071 0 : SotStorageStreamRef xStm;
2072 0 : sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2073 :
2074 0 : if( bRet )
2075 0 : bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
2076 0 : return bRet;
2077 : }
2078 :
2079 : // -----------------------------------------------------------------------------
2080 :
2081 0 : sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
2082 : FileList& rFileList )
2083 : {
2084 0 : DataFlavor aFlavor;
2085 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
2086 : }
2087 :
2088 : // -----------------------------------------------------------------------------
2089 :
2090 0 : sal_Bool TransferableDataHelper::GetFileList(
2091 : const ::com::sun::star::datatransfer::DataFlavor&,
2092 : FileList& rFileList )
2093 : {
2094 0 : SotStorageStreamRef xStm;
2095 0 : sal_Bool bRet = sal_False;
2096 :
2097 0 : for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
2098 : {
2099 0 : if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
2100 : {
2101 0 : const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
2102 :
2103 0 : if( GetSotStorageStream( aFlavor, xStm ) )
2104 : {
2105 0 : if( aFlavor.MimeType.indexOf( "text/uri-list" ) > -1 )
2106 : {
2107 0 : rtl::OString aDiskString;
2108 :
2109 0 : while( xStm->ReadLine( aDiskString ) )
2110 0 : if( !aDiskString.isEmpty() && aDiskString[0] != '#' )
2111 0 : rFileList.AppendFile( rtl::OStringToOUString(aDiskString, RTL_TEXTENCODING_UTF8) );
2112 :
2113 0 : bRet = sal_True;
2114 : }
2115 : else
2116 0 : bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
2117 0 : }
2118 : }
2119 : }
2120 :
2121 0 : return bRet;
2122 : }
2123 :
2124 : // -----------------------------------------------------------------------------
2125 :
2126 0 : sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
2127 : {
2128 0 : DataFlavor aFlavor;
2129 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
2130 : }
2131 :
2132 : // -----------------------------------------------------------------------------
2133 :
2134 0 : sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
2135 : {
2136 : #ifdef DEBUG
2137 : fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
2138 : #endif
2139 :
2140 0 : const Any aAny( GetAny( rFlavor ) );
2141 0 : return( aAny.hasValue() && ( aAny >>= rSeq ) );
2142 : }
2143 :
2144 : // -----------------------------------------------------------------------------
2145 :
2146 0 : sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
2147 : {
2148 0 : DataFlavor aFlavor;
2149 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
2150 : }
2151 :
2152 : // -----------------------------------------------------------------------------
2153 :
2154 0 : sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
2155 : {
2156 0 : Sequence< sal_Int8 > aSeq;
2157 0 : sal_Bool bRet = GetSequence( rFlavor, aSeq );
2158 :
2159 0 : if( bRet )
2160 : {
2161 0 : rxStream = new SotStorageStream( String() );
2162 0 : rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
2163 0 : rxStream->Seek( 0 );
2164 : }
2165 :
2166 0 : return bRet;
2167 : }
2168 :
2169 0 : sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
2170 : {
2171 0 : DataFlavor aFlavor;
2172 0 : return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
2173 : }
2174 :
2175 : // -----------------------------------------------------------------------------
2176 :
2177 0 : sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
2178 : {
2179 0 : Sequence< sal_Int8 > aSeq;
2180 0 : sal_Bool bRet = GetSequence( rFlavor, aSeq );
2181 :
2182 0 : if( bRet )
2183 0 : rxStream = new ::comphelper::SequenceInputStream( aSeq );
2184 :
2185 0 : return bRet;
2186 : }
2187 :
2188 : // -----------------------------------------------------------------------------
2189 :
2190 0 : void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
2191 : {
2192 0 : mxTransfer = _rxNewContent;
2193 0 : InitFormats();
2194 0 : }
2195 :
2196 : // -----------------------------------------------------------------------------
2197 :
2198 0 : sal_Bool TransferableDataHelper::StartClipboardListening( )
2199 : {
2200 0 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
2201 :
2202 0 : StopClipboardListening( );
2203 :
2204 0 : mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
2205 0 : mpImpl->mpClipboardListener->acquire();
2206 :
2207 0 : return mpImpl->mpClipboardListener->isListening();
2208 : }
2209 :
2210 : // -----------------------------------------------------------------------------
2211 :
2212 9 : void TransferableDataHelper::StopClipboardListening( )
2213 : {
2214 9 : ::osl::MutexGuard aGuard( mpImpl->maMutex );
2215 :
2216 9 : if ( mpImpl->mpClipboardListener )
2217 : {
2218 0 : mpImpl->mpClipboardListener->dispose();
2219 0 : mpImpl->mpClipboardListener->release();
2220 0 : mpImpl->mpClipboardListener = NULL;
2221 9 : }
2222 9 : }
2223 :
2224 : // -----------------------------------------------------------------------------
2225 :
2226 9 : TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
2227 : {
2228 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
2229 :
2230 9 : Reference< XClipboard > xClipboard;
2231 9 : TransferableDataHelper aRet;
2232 :
2233 9 : if( pWindow )
2234 9 : xClipboard = pWindow->GetClipboard();
2235 :
2236 9 : if( xClipboard.is() )
2237 : {
2238 : try
2239 : {
2240 9 : Reference< XTransferable > xTransferable( xClipboard->getContents() );
2241 :
2242 9 : if( xTransferable.is() )
2243 : {
2244 0 : aRet = TransferableDataHelper( xTransferable );
2245 : // also copy the clipboard
2246 0 : aRet.mxClipboard = xClipboard;
2247 9 : }
2248 : }
2249 0 : catch( const ::com::sun::star::uno::Exception& )
2250 : {
2251 : }
2252 : }
2253 :
2254 9 : return aRet;
2255 : }
2256 :
2257 :
2258 : // -----------------------------------------------------------------------------
2259 :
2260 0 : TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
2261 : {
2262 : DBG_ASSERT( pWindow, "Window pointer is NULL" );
2263 :
2264 0 : Reference< XClipboard > xSelection;
2265 0 : TransferableDataHelper aRet;
2266 :
2267 0 : if( pWindow )
2268 0 : xSelection = pWindow->GetPrimarySelection();
2269 :
2270 0 : if( xSelection.is() )
2271 : {
2272 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2273 :
2274 : try
2275 : {
2276 0 : Reference< XTransferable > xTransferable( xSelection->getContents() );
2277 :
2278 0 : if( xTransferable.is() )
2279 : {
2280 0 : aRet = TransferableDataHelper( xTransferable );
2281 0 : aRet.mxClipboard = xSelection;
2282 0 : }
2283 : }
2284 0 : catch( const ::com::sun::star::uno::Exception& )
2285 : {
2286 : }
2287 :
2288 0 : Application::AcquireSolarMutex( nRef );
2289 : }
2290 :
2291 0 : return aRet;
2292 : }
2293 :
2294 : // -----------------------------------------------------------------------------
2295 0 : sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
2296 : const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
2297 : sal_Bool )
2298 : {
2299 0 : Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
2300 0 : Reference< XMimeContentTypeFactory > xMimeFact;
2301 0 : sal_Bool bRet = sal_False;
2302 :
2303 : try
2304 : {
2305 0 : if( xFact.is() )
2306 0 : xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.datatransfer.MimeContentTypeFactory" )) ),
2307 0 : UNO_QUERY );
2308 :
2309 0 : if( xMimeFact.is() )
2310 : {
2311 0 : Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
2312 0 : Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2313 :
2314 0 : if( xRequestType1.is() && xRequestType2.is() )
2315 : {
2316 0 : if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2317 : {
2318 0 : if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/plain" )) ) )
2319 : {
2320 : // special handling for text/plain media types
2321 0 : const ::rtl::OUString aCharsetString(RTL_CONSTASCII_USTRINGPARAM( "charset" ));
2322 :
2323 0 : if( !xRequestType2->hasParameter( aCharsetString ) ||
2324 0 : xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "utf-16" )) ) ||
2325 0 : xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unicode" )) ) )
2326 : {
2327 0 : bRet = sal_True;
2328 0 : }
2329 : }
2330 0 : else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice" )) ) )
2331 : {
2332 : // special handling for application/x-openoffice media types
2333 0 : const ::rtl::OUString aFormatString(RTL_CONSTASCII_USTRINGPARAM( "windows_formatname" ));
2334 :
2335 0 : if( xRequestType1->hasParameter( aFormatString ) &&
2336 0 : xRequestType2->hasParameter( aFormatString ) &&
2337 0 : xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
2338 : {
2339 0 : bRet = sal_True;
2340 0 : }
2341 : }
2342 : else
2343 0 : bRet = sal_True;
2344 : }
2345 0 : }
2346 : }
2347 : }
2348 0 : catch( const ::com::sun::star::uno::Exception& )
2349 : {
2350 0 : bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
2351 : }
2352 :
2353 0 : return bRet;
2354 : }
2355 :
2356 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|