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