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