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