LCOV - code coverage report
Current view: top level - svtools/source/misc - transfer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 257 970 26.5 %
Date: 2015-06-13 12:38:46 Functions: 38 106 35.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11