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