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

Generated by: LCOV version 1.10