Files
libreoffice/svtools/source/misc/transfer.cxx

2253 lines
73 KiB
C++
Raw Normal View History

2001-01-19 17:23:13 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
2001-01-19 17:23:13 +00:00
*
* $RCSfile: transfer.cxx,v $
2001-01-19 17:23:13 +00:00
*
* $Revision: 1.79 $
2001-01-19 17:23:13 +00:00
*
* last change: $Author: hr $ $Date: 2007-09-26 14:33:08 $
2001-01-19 17:23:13 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2001-01-19 17:23:13 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2001-01-19 17:23:13 +00:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
2001-01-19 17:23:13 +00:00
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2001-01-19 17:23:13 +00:00
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
2001-01-19 17:23:13 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
2001-01-19 17:23:13 +00:00
#ifdef WNT
#include <tools/prewin.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#pragma warning(disable: 4917)
#endif
2001-01-19 17:23:13 +00:00
#include <shlobj.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
2001-01-19 17:23:13 +00:00
#include <tools/postwin.h>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
2001-03-12 11:56:37 +00:00
#ifndef _RTL_MEMORY_H_
#include <rtl/memory.h>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
2001-01-19 17:23:13 +00:00
#ifndef DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _UNTOOLS_UCBSTREAMHELPER_HXX
#include <unotools/ucbstreamhelper.hxx>
#endif
2001-01-19 17:23:13 +00:00
#ifndef _SOT_EXCHANGE_HXX
#include <sot/exchange.hxx>
#endif
#ifndef _SOT_STORAGE_HXX
#include <sot/storage.hxx>
#endif
#ifndef _SV_BITMAP_HXX
#include <vcl/bitmap.hxx>
#endif
#ifndef _SV_GDIMTF_HXX
#include <vcl/gdimtf.hxx>
#endif
#ifndef _SV_GRAPH_HXX
#include <vcl/graph.hxx>
#endif
2001-03-16 16:47:03 +00:00
#ifndef _SV_CVTGRF_HXX
#include <vcl/cvtgrf.hxx>
#endif
2001-01-19 17:23:13 +00:00
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
2001-02-26 11:58:36 +00:00
#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif
2001-01-19 17:23:13 +00:00
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _FILELIST_HXX
#include <sot/filelist.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
2001-01-19 17:23:13 +00:00
#include <comphelper/seqstream.hxx>
#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XCLIPBOARDNOTIFIER_HPP_
#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
#endif
2001-03-07 11:32:20 +00:00
#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XFLUSHABLECLIPBOARD_HPP_
#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
#endif
2001-09-25 09:12:13 +00:00
#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPEFACTORY_HPP_
#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XMIMECONTENTTYPE_HPP_
#include <com/sun/star/datatransfer/XMimeContentType.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_
#include <com/sun/star/frame/XDesktop.hpp>
#endif
2001-03-07 11:32:20 +00:00
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
2001-01-19 17:23:13 +00:00
#include "urlbmk.hxx"
2001-10-18 10:53:11 +00:00
#include "inetimg.hxx"
#include <svtools/imap.hxx>
#include <svtools/transfer.hxx>
2001-01-19 17:23:13 +00:00
// --------------
// - Namespaces -
// --------------
using namespace ::com::sun::star::uno;
2001-02-26 11:58:36 +00:00
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
2001-01-19 17:23:13 +00:00
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::datatransfer::clipboard;
2001-02-26 11:58:36 +00:00
using namespace ::com::sun::star::datatransfer::dnd;
2001-01-19 17:23:13 +00:00
// --------------------------------
// - TransferableObjectDescriptor -
// --------------------------------
#define TOD_SIG1 0x01234567
#define TOD_SIG2 0x89abcdef
2001-01-19 17:23:13 +00:00
SvStream& operator>>( SvStream& rIStm, TransferableObjectDescriptor& rObjDesc )
{
sal_uInt32 nSize, nViewAspect, nSig1, nSig2;
2001-01-19 17:23:13 +00:00
rIStm >> nSize;
rIStm >> rObjDesc.maClassName;
rIStm >> nViewAspect;
2001-01-19 17:23:13 +00:00
rIStm >> rObjDesc.maSize.Width();
rIStm >> rObjDesc.maSize.Height();
rIStm >> rObjDesc.maDragStartPos.X();
rIStm >> rObjDesc.maDragStartPos.Y();
rIStm.ReadByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
rIStm.ReadByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
rIStm >> nSig1 >> nSig2;
rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( nViewAspect );
// don't use width/height info from external objects
if( ( TOD_SIG1 != nSig1 ) || ( TOD_SIG2 != nSig2 ) )
{
rObjDesc.maSize.Width() = 0;
rObjDesc.maSize.Height() = 0;
}
2001-01-19 17:23:13 +00:00
return rIStm;
}
// -----------------------------------------------------------------------------
SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc )
{
const sal_uInt32 nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect;
const sal_uInt32 nSig1 = TOD_SIG1, nSig2 = TOD_SIG2;
2001-01-19 17:23:13 +00:00
rOStm.SeekRel( 4 );
rOStm << rObjDesc.maClassName;
rOStm << nViewAspect;
2001-01-19 17:23:13 +00:00
rOStm << rObjDesc.maSize.Width();
rOStm << rObjDesc.maSize.Height();
rOStm << rObjDesc.maDragStartPos.X();
rOStm << rObjDesc.maDragStartPos.Y();
rOStm.WriteByteString( rObjDesc.maTypeName, gsl_getSystemTextEncoding() );
rOStm.WriteByteString( rObjDesc.maDisplayName, gsl_getSystemTextEncoding() );
rOStm << nSig1 << nSig2;
2001-01-19 17:23:13 +00:00
const sal_uInt32 nLastPos = rOStm.Tell();
rOStm.Seek( nFirstPos );
rOStm << ( nLastPos - nFirstPos );
rOStm.Seek( nLastPos );
return rOStm;
}
// -----------------------------------------
// - TransferableHelper::TerminateListener -
// -----------------------------------------
TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
mrParent( rTransferableHelper )
{
}
// -----------------------------------------------------------------------------
TransferableHelper::TerminateListener::~TerminateListener()
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
{
mrParent.ImplFlush();
}
2001-01-19 17:23:13 +00:00
// ----------------------
// - TransferableHelper -
// ----------------------
TransferableHelper::TransferableHelper() :
mpFormats( new DataFlavorExVector )
2001-01-19 17:23:13 +00:00
{
}
// -----------------------------------------------------------------------------
TransferableHelper::~TransferableHelper()
{
delete mpFormats;
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) throw( UnsupportedFlavorException, IOException, RuntimeException )
{
if( !maAny.hasValue() || !mpFormats->size() || ( maLastFormat != rFlavor.MimeType ) )
{
const ::vos::OGuard aGuard( Application::GetSolarMutex() );
maLastFormat = rFlavor.MimeType;
maAny = Any();
2001-01-19 17:23:13 +00:00
try
{
2001-10-18 10:53:11 +00:00
DataFlavor aSubstFlavor;
sal_Bool bDone = sal_False;
2001-10-18 10:53:11 +00:00
// add formats if not already done
if( !mpFormats->size() )
AddSupportedFormats();
2001-01-19 17:23:13 +00:00
// check alien formats first and try to get a substitution format
2001-10-18 10:53:11 +00:00
if( SotExchange::GetFormatDataFlavor( FORMAT_STRING, aSubstFlavor ) &&
TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) )
{
2001-10-18 10:53:11 +00:00
GetData( aSubstFlavor );
bDone = maAny.hasValue();
}
else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
SotExchange::GetFormatDataFlavor( FORMAT_BITMAP, aSubstFlavor ) )
{
GetData( aSubstFlavor );
bDone = sal_True;
}
2002-07-20 09:38:02 +00:00
else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
{
GetData( aSubstFlavor );
if( maAny.hasValue() )
{
Sequence< sal_Int8 > aSeq;
if( maAny >>= aSeq )
{
SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
GDIMetaFile aMtf;
*pSrcStm >> aMtf;
delete pSrcStm;
Graphic aGraphic( aMtf );
SvMemoryStream aDstStm( 65535, 65535 );
if( GraphicConverter::Export( aDstStm, aGraphic, CVT_EMF ) == ERRCODE_NONE )
{
maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
bDone = sal_True;
}
}
}
}
2001-10-18 10:53:11 +00:00
else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
{
GetData( aSubstFlavor );
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
if( maAny.hasValue() )
2001-09-25 09:12:13 +00:00
{
2001-10-18 10:53:11 +00:00
Sequence< sal_Int8 > aSeq;
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
if( maAny >>= aSeq )
2001-09-25 09:12:13 +00:00
{
2001-10-18 10:53:11 +00:00
SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
GDIMetaFile aMtf;
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
*pSrcStm >> aMtf;
delete pSrcStm;
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
Graphic aGraphic( aMtf );
SvMemoryStream aDstStm( 65535, 65535 );
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
if( GraphicConverter::Export( aDstStm, aGraphic, CVT_WMF ) == ERRCODE_NONE )
{
maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
bDone = sal_True;
2001-09-25 09:12:13 +00:00
}
}
}
}
2001-03-16 16:47:03 +00:00
2001-10-18 10:53:11 +00:00
// reset Any if substitute doesn't work
if( !bDone && maAny.hasValue() )
maAny = Any();
2001-09-25 09:12:13 +00:00
// if any is not yet filled, use standard format
if( !maAny.hasValue() )
GetData( rFlavor );
}
catch( const ::com::sun::star::uno::Exception& )
{
}
2001-03-05 11:44:24 +00:00
if( !maAny.hasValue() )
throw UnsupportedFlavorException();
}
2001-01-19 17:23:13 +00:00
return maAny;
}
// -----------------------------------------------------------------------------
Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() throw( RuntimeException )
{
const ::vos::OGuard aGuard( Application::GetSolarMutex() );
try
{
if( !mpFormats->size() )
AddSupportedFormats();
}
catch( const ::com::sun::star::uno::Exception& )
{
}
2001-01-19 17:23:13 +00:00
Sequence< DataFlavor > aRet( mpFormats->size() );
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
sal_uInt32 nCurPos = 0;
2001-01-19 17:23:13 +00:00
2001-10-18 10:53:11 +00:00
while( aIter != aEnd )
aRet[ nCurPos++ ] = *aIter++;
2001-01-19 17:23:13 +00:00
return aRet;
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) throw( RuntimeException )
{
const ::vos::OGuard aGuard( Application::GetSolarMutex() );
sal_Bool bRet = sal_False;
2001-01-19 17:23:13 +00:00
try
{
if( !mpFormats->size() )
AddSupportedFormats();
}
catch( const ::com::sun::star::uno::Exception& )
{
}
2001-01-19 17:23:13 +00:00
2001-10-18 10:53:11 +00:00
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
2001-01-19 17:23:13 +00:00
while( aIter != aEnd )
{
2001-10-18 10:53:11 +00:00
if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
2001-01-19 17:23:13 +00:00
{
aIter = aEnd;
2001-10-18 10:53:11 +00:00
bRet = sal_True;
}
else
aIter++;
2001-01-19 17:23:13 +00:00
}
return bRet;
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) throw( RuntimeException )
2001-01-19 17:23:13 +00:00
{
const ::vos::OGuard aGuard( Application::GetSolarMutex() );
try
{
if( mxTerminateListener.is() )
{
Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
if( xFact.is() )
{
Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
if( xDesktop.is() )
xDesktop->removeTerminateListener( mxTerminateListener );
}
mxTerminateListener = Reference< XTerminateListener >();
}
ObjectReleased();
}
catch( const ::com::sun::star::uno::Exception& )
{
}
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
{
const ::vos::OGuard aGuard( Application::GetSolarMutex() );
try
{
2001-08-14 08:32:25 +00:00
DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
ObjectReleased();
}
catch( const ::com::sun::star::uno::Exception& )
{
}
2001-02-26 11:58:36 +00:00
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
{
sal_Int64 nRet;
if( ( rId.getLength() == 16 ) &&
( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
{
nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
2001-10-18 10:53:11 +00:00
}
else
nRet = 0;
return nRet;
}
// -----------------------------------------------------------------------------
void TransferableHelper::ImplFlush()
{
if( mxClipboard.is() )
{
Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY );
const sal_uInt32 nRef = Application::ReleaseSolarMutex();
try
{
if( xFlushableClipboard.is() )
xFlushableClipboard->flushClipboard();
}
catch( const ::com::sun::star::uno::Exception& )
{
DBG_ERROR( "Could not flush clipboard" );
}
Application::AcquireSolarMutex( nRef );
}
}
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
void TransferableHelper::AddFormat( SotFormatStringId nFormat )
{
2001-10-18 10:53:11 +00:00
DataFlavor aFlavor;
2001-03-16 16:47:03 +00:00
2001-10-18 10:53:11 +00:00
if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
AddFormat( aFlavor );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
{
2001-10-18 12:23:27 +00:00
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
sal_Bool bAdd = sal_True;
while( aIter != aEnd )
2001-10-18 12:23:27 +00:00
{
2001-10-18 12:23:27 +00:00
if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
{
aIter = aEnd;
bAdd = sal_False;
}
else
aIter++;
}
if( bAdd )
2001-01-19 17:23:13 +00:00
{
DataFlavorEx aFlavorEx;
aFlavorEx.MimeType = rFlavor.MimeType;
aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
aFlavorEx.DataType = rFlavor.DataType;
aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
mpFormats->push_back( aFlavorEx );
2001-03-16 16:47:03 +00:00
if( FORMAT_BITMAP == aFlavorEx.mnSotId )
{
AddFormat( SOT_FORMATSTR_ID_BMP );
}
else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
2002-07-20 09:38:02 +00:00
{
AddFormat( SOT_FORMATSTR_ID_EMF );
2001-03-16 16:47:03 +00:00
AddFormat( SOT_FORMATSTR_ID_WMF );
2002-07-20 09:38:02 +00:00
}
2001-01-19 17:23:13 +00:00
}
}
// -----------------------------------------------------------------------------
void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
{
2001-10-18 10:53:11 +00:00
DataFlavor aFlavor;
2001-01-19 17:23:13 +00:00
2001-10-18 10:53:11 +00:00
if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
RemoveFormat( aFlavor );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
{
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
2001-01-19 17:23:13 +00:00
while( aIter != aEnd )
{
2001-10-18 10:53:11 +00:00
if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
{
aIter = mpFormats->erase( aIter );
aEnd = mpFormats->end();
}
2001-01-19 17:23:13 +00:00
else
++aIter;
2001-01-19 17:23:13 +00:00
}
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
{
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
sal_Bool bRet = sal_False;
2001-01-19 17:23:13 +00:00
while( aIter != aEnd )
{
if( nFormat == (*aIter).mnSotId )
2001-01-19 17:23:13 +00:00
{
aIter = aEnd;
2001-10-18 10:53:11 +00:00
bRet = sal_True;
2001-01-19 17:23:13 +00:00
}
else
++aIter;
2001-01-19 17:23:13 +00:00
}
return bRet;
}
// -----------------------------------------------------------------------------
void TransferableHelper::ClearFormats()
{
mpFormats->clear();
maAny.clear();
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
2001-01-19 17:23:13 +00:00
{
maAny = rAny;
return( maAny.hasValue() );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetString( const ::rtl::OUString& rString, const DataFlavor& rFlavor )
{
2001-03-12 11:56:37 +00:00
DataFlavor aFileFlavor;
if( rString.getLength() &&
SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
{
2001-03-13 15:05:23 +00:00
const String aString( rString );
const ByteString aByteStr( aString, gsl_getSystemTextEncoding() );
2001-03-12 11:56:37 +00:00
Sequence< sal_Int8 > aSeq( aByteStr.Len() + 1 );
rtl_copyMemory( aSeq.getArray(), aByteStr.GetBuffer(), aByteStr.Len() );
aSeq[ aByteStr.Len() ] = 0;
maAny <<= aSeq;
}
else
maAny <<= rString;
2001-01-19 17:23:13 +00:00
return( maAny.hasValue() );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& )
2001-01-19 17:23:13 +00:00
{
if( !rBitmap.IsEmpty() )
{
SvMemoryStream aMemStm( 65535, 65535 );
aMemStm << rBitmap;
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
2001-01-19 17:23:13 +00:00
}
return( maAny.hasValue() );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
2001-01-19 17:23:13 +00:00
{
if( rMtf.GetActionCount() )
{
SvMemoryStream aMemStm( 65535, 65535 );
( (GDIMetaFile&) rMtf ).Write( aMemStm );
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
2001-01-19 17:23:13 +00:00
}
return( maAny.hasValue() );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
2001-01-19 17:23:13 +00:00
{
if( rGraphic.GetType() != GRAPHIC_NONE )
{
SvMemoryStream aMemStm( 65535, 65535 );
2001-02-06 15:07:54 +00:00
aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
2001-01-19 17:23:13 +00:00
aMemStm << rGraphic;
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
2001-01-19 17:23:13 +00:00
}
return( maAny.hasValue() );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
2001-01-19 17:23:13 +00:00
{
SvMemoryStream aMemStm( 8192, 8192 );
2001-01-19 17:23:13 +00:00
2001-02-06 15:07:54 +00:00
aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
rIMap.Write( aMemStm, String() );
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
2001-01-19 17:23:13 +00:00
return( maAny.hasValue() );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
const ::com::sun::star::datatransfer::DataFlavor& )
2001-01-19 17:23:13 +00:00
{
SvMemoryStream aMemStm( 1024, 1024 );
aMemStm << rDesc;
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
2001-01-19 17:23:13 +00:00
return( maAny.hasValue() );
2001-10-18 10:53:11 +00:00
}
2001-01-19 17:23:13 +00:00
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
{
rtl_TextEncoding eSysCSet = gsl_getSystemTextEncoding();
2001-01-19 17:23:13 +00:00
switch( SotExchange::GetFormat( rFlavor ) )
{
case( SOT_FORMATSTR_ID_SOLK ):
{
ByteString sURL( rBmk.GetURL(), eSysCSet ),
sDesc( rBmk.GetDescription(), eSysCSet );
ByteString sOut( ByteString::CreateFromInt32( sURL.Len() ));
( sOut += '@' ) += sURL;
sOut += ByteString::CreateFromInt32( sDesc.Len() );
( sOut += '@' ) += sDesc;
Sequence< sal_Int8 > aSeq( sOut.Len() );
memcpy( aSeq.getArray(), sOut.GetBuffer(), sOut.Len() );
maAny <<= aSeq;
2001-01-19 17:23:13 +00:00
}
break;
case( FORMAT_STRING ):
maAny <<= ::rtl::OUString( rBmk.GetURL() );
break;
2001-01-19 17:23:13 +00:00
case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
{
ByteString sURL( rBmk.GetURL(), eSysCSet );
Sequence< sal_Int8 > aSeq( sURL.Len() );
memcpy( aSeq.getArray(), sURL.GetBuffer(), sURL.Len() );
maAny <<= aSeq;
2001-01-19 17:23:13 +00:00
}
break;
case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
{
Sequence< sal_Int8 > aSeq( 2048 );
memset( aSeq.getArray(), 0, 2048 );
2001-10-18 10:53:11 +00:00
strcpy( reinterpret_cast< char* >( aSeq.getArray() ), ByteString( rBmk.GetURL(), eSysCSet).GetBuffer() );
strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, ByteString( rBmk.GetDescription(), eSysCSet ).GetBuffer() );
2001-01-19 17:23:13 +00:00
maAny <<= aSeq;
}
break;
#ifdef WNT
case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
{
Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
pFDesc->cItems = 1;
memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
rFDesc1.dwFlags = FD_LINKUI;
ByteString aStr( rBmk.GetDescription(), eSysCSet );
2001-01-19 17:23:13 +00:00
for( USHORT nChar = 0; nChar < aStr.Len(); ++nChar )
if( strchr( "\\/:*?\"<>|", aStr.GetChar( nChar ) ) )
aStr.Erase( nChar--, 1 );
aStr.Insert( "Shortcut to ", 0 );
aStr += ".URL";
strcpy( rFDesc1.cFileName, aStr.GetBuffer() );
maAny <<= aSeq;
}
break;
case SOT_FORMATSTR_ID_FILECONTENT:
{
String aStr( RTL_CONSTASCII_STRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
maAny <<= ::rtl::OUString( aStr += rBmk.GetURL() );
}
break;
#endif
default:
break;
}
return( maAny.hasValue() );
}
// -----------------------------------------------------------------------------
2001-01-30 12:23:14 +00:00
sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
2001-01-30 12:23:14 +00:00
{
SvMemoryStream aMemStm( 1024, 1024 );
2001-01-30 12:23:14 +00:00
2001-02-06 15:07:54 +00:00
aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
return( maAny.hasValue() );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetFileList( const FileList& rFileList,
const ::com::sun::star::datatransfer::DataFlavor& )
{
SvMemoryStream aMemStm( 4096, 4096 );
2001-02-06 15:07:54 +00:00
aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
aMemStm << rFileList;
2001-10-18 10:53:11 +00:00
maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
return( maAny.hasValue() );
2001-01-30 12:23:14 +00:00
}
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
{
SotStorageStreamRef xStm( new SotStorageStream( String() ) );
2001-02-06 15:07:54 +00:00
xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
2001-01-19 17:23:13 +00:00
if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
{
const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
Sequence< sal_Int8 > aSeq( nLen );
xStm->Seek( STREAM_SEEK_TO_BEGIN );
xStm->Read( aSeq.getArray(), nLen );
if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
2001-10-18 10:53:11 +00:00
{
//JP 24.7.2001: as I know was this only for the writer application and this
// writes now UTF16 format into the stream
//JP 6.8.2001: and now it writes UTF8 because then exist no problem with
// little / big endians! - Bug 88121
maAny <<= ::rtl::OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
}
else
maAny <<= aSeq;
2001-01-19 17:23:13 +00:00
}
return( maAny.hasValue() );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::SetInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rIf,
const ::com::sun::star::datatransfer::DataFlavor& )
2001-01-19 17:23:13 +00:00
{
maAny <<= rIf;
return( maAny.hasValue() );
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
2001-01-19 17:23:13 +00:00
{
DBG_ERROR( "TransferableHelper::WriteObject( ... ) not implemented" );
return sal_False;
}
// -----------------------------------------------------------------------------
void TransferableHelper::DragFinished( sal_Int8 )
2001-02-26 11:58:36 +00:00
{
}
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
void TransferableHelper::ObjectReleased()
{
}
// -----------------------------------------------------------------------------
void TransferableHelper::CopyToClipboard( Window *pWindow ) const
2001-01-19 17:23:13 +00:00
{
2001-10-18 10:53:11 +00:00
DBG_ASSERT( pWindow, "Window pointer is NULL" );
Reference< XClipboard > xClipboard;
if( pWindow )
xClipboard = pWindow->GetClipboard();
2001-05-25 10:36:44 +00:00
if( xClipboard.is() )
mxClipboard = xClipboard;
2001-02-26 11:58:36 +00:00
if( mxClipboard.is() && !mxTerminateListener.is() )
2001-02-26 11:58:36 +00:00
{
const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2001-02-26 11:58:36 +00:00
try
{
2001-10-18 10:53:11 +00:00
TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
if( xFact.is() )
{
Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
if( xDesktop.is() )
xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
}
2001-10-18 10:53:11 +00:00
mxClipboard->setContents( pThis, pThis );
2001-02-26 11:58:36 +00:00
}
2001-03-05 11:44:24 +00:00
catch( const ::com::sun::star::uno::Exception& )
2001-02-26 11:58:36 +00:00
{
}
Application::AcquireSolarMutex( nRef );
2001-03-05 11:44:24 +00:00
}
}
// -----------------------------------------------------------------------------
void TransferableHelper::CopyToSelection( Window *pWindow ) const
{
DBG_ASSERT( pWindow, "Window pointer is NULL" );
2001-10-18 10:53:11 +00:00
Reference< XClipboard > xSelection;
if( pWindow )
xSelection = pWindow->GetPrimarySelection();
if( xSelection.is() && !mxTerminateListener.is() )
{
const sal_uInt32 nRef = Application::ReleaseSolarMutex();
try
{
2001-10-18 10:53:11 +00:00
TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
if( xFact.is() )
{
Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
if( xDesktop.is() )
xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
}
2001-10-18 10:53:11 +00:00
xSelection->setContents( pThis, pThis );
}
catch( const ::com::sun::star::uno::Exception& )
{
}
Application::AcquireSolarMutex( nRef );
}
}
// -----------------------------------------------------------------------------
2001-03-05 11:44:24 +00:00
void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
2001-02-26 11:58:36 +00:00
sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
2001-02-26 11:58:36 +00:00
{
2001-03-05 11:44:24 +00:00
DBG_ASSERT( pWindow, "Window pointer is NULL" );
Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
2001-02-26 11:58:36 +00:00
if( xDragSource.is() )
2001-01-19 17:23:13 +00:00
{
/*
* #96792# release mouse before actually starting DnD.
* This is necessary for the X11 DnD implementation to work.
*/
if( pWindow->IsMouseCaptured() )
pWindow->ReleaseMouse();
const Point aPt( pWindow->GetPointerPosPixel() );
const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2001-02-26 11:58:36 +00:00
try
{
DragGestureEvent aEvt;
aEvt.DragAction = DNDConstants::ACTION_COPY;
aEvt.DragOriginX = aPt.X();
aEvt.DragOriginY = aPt.Y();
aEvt.DragSource = xDragSource;
2001-02-26 11:58:36 +00:00
xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
}
2001-03-05 11:44:24 +00:00
catch( const ::com::sun::star::uno::Exception& )
2001-02-26 11:58:36 +00:00
{
}
Application::AcquireSolarMutex( nRef );
2001-01-19 17:23:13 +00:00
}
}
// -----------------------------------------------------------------------------
void TransferableHelper::ClearSelection( Window *pWindow )
2001-01-19 17:23:13 +00:00
{
DBG_ASSERT( pWindow, "Window pointer is NULL" );
Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
2001-01-19 17:23:13 +00:00
if( xSelection.is() )
xSelection->setContents( NULL, NULL );
}
2001-01-19 17:23:13 +00:00
// -----------------------------------------------------------------------------
Reference< XClipboard> TransferableHelper::GetSystemClipboard()
{
Window *pFocusWindow = Application::GetFocusWindow();
2001-01-19 17:23:13 +00:00
if( pFocusWindow )
return pFocusWindow->GetClipboard();
return Reference< XClipboard > ();
2001-01-19 17:23:13 +00:00
}
2001-10-18 10:53:11 +00:00
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
{
static Sequence< sal_Int8 > aSeq;
2001-10-18 10:53:11 +00:00
if( !aSeq.getLength() )
{
2001-10-18 10:53:11 +00:00
static osl::Mutex aCreateMutex;
osl::Guard< osl::Mutex > aGuard( aCreateMutex );
aSeq.realloc( 16 );
2001-10-18 10:53:11 +00:00
rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
}
2001-10-18 10:53:11 +00:00
return aSeq;
}
// ---------------------------------
// - TransferableClipboardNotifier -
// ---------------------------------
class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
{
2001-10-18 10:53:11 +00:00
private:
::osl::Mutex& mrMutex;
Reference< XClipboardNotifier > mxNotifier;
TransferableDataHelper* mpListener;
protected:
// XClipboardListener
virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
2001-10-18 10:53:11 +00:00
// XEventListener
virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
2001-10-18 10:53:11 +00:00
public:
TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
/// determines whether we're currently listening
inline bool isListening() const { return !isDisposed(); }
2001-10-18 10:53:11 +00:00
/// determines whether the instance is disposed
inline bool isDisposed() const { return mpListener == NULL; }
/// makes the instance non-functional
void dispose();
};
// -----------------------------------------------------------------------------
TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
:mrMutex( _rMutex )
,mxNotifier( _rxClipboard, UNO_QUERY )
,mpListener( &_rListener )
{
osl_incrementInterlockedCount( &m_refCount );
{
if ( mxNotifier.is() )
mxNotifier->addClipboardListener( this );
else
// born dead
mpListener = NULL;
}
osl_decrementInterlockedCount( &m_refCount );
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
{
::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
// the SolarMutex here is necessary, since
// - we cannot call mpListener without our own mutex locked
// - Rebind respectively InitFormats (called by Rebind) will
// try to lock the SolarMutex, too
::osl::MutexGuard aGuard( mrMutex );
2001-10-18 10:53:11 +00:00
if( mpListener )
mpListener->Rebind( event.Contents );
}
// -----------------------------------------------------------------------------
void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
{
// clipboard is being disposed. Hmm. Okay, become disfunctional myself.
dispose();
}
// -----------------------------------------------------------------------------
void TransferableClipboardNotifier::dispose()
{
::osl::MutexGuard aGuard( mrMutex );
Reference< XClipboardListener > xKeepMeAlive( this );
if ( mxNotifier.is() )
mxNotifier->removeClipboardListener( this );
mxNotifier.clear();
mpListener = NULL;
}
// -------------------------------
// - TransferableDataHelper_Impl -
// -------------------------------
struct TransferableDataHelper_Impl
{
::osl::Mutex maMutex;
TransferableClipboardNotifier* mpClipboardListener;
TransferableDataHelper_Impl()
:mpClipboardListener( NULL )
{
}
};
2001-01-19 17:23:13 +00:00
// --------------------------
// - TransferableDataHelper -
// --------------------------
TransferableDataHelper::TransferableDataHelper()
:mpFormats( new DataFlavorExVector )
,mpImpl( new TransferableDataHelper_Impl )
2001-01-19 17:23:13 +00:00
{
}
// -----------------------------------------------------------------------------
TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable )
:mxTransfer( rxTransferable )
,mpFormats( new DataFlavorExVector )
,mpImpl( new TransferableDataHelper_Impl )
2001-01-19 17:23:13 +00:00
{
InitFormats();
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper )
:mxTransfer( rDataHelper.mxTransfer )
,mxClipboard( rDataHelper.mxClipboard )
,mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) )
,mpImpl( new TransferableDataHelper_Impl )
2001-01-19 17:23:13 +00:00
{
}
// -----------------------------------------------------------------------------
TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
{
if ( this != &rDataHelper )
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
if ( bWasClipboardListening )
StopClipboardListening();
mxTransfer = rDataHelper.mxTransfer;
delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
mxClipboard = rDataHelper.mxClipboard;
if ( bWasClipboardListening )
StartClipboardListening();
}
2001-01-19 17:23:13 +00:00
return *this;
}
// -----------------------------------------------------------------------------
TransferableDataHelper::~TransferableDataHelper()
{
StopClipboardListening( );
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
delete mpFormats, mpFormats = NULL;
}
delete mpImpl;
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
DataFlavorExVector& rDataFlavorExVector )
2001-01-19 17:23:13 +00:00
{
try
{
2001-10-18 10:53:11 +00:00
Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
Reference< XMimeContentTypeFactory > xMimeFact;
DataFlavorEx aFlavorEx;
const ::rtl::OUString aCharsetStr( ::rtl::OUString::createFromAscii( "charset" ) );
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
if( xFact.is() )
xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
"com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
UNO_QUERY );
2001-10-18 10:53:11 +00:00
for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
{
const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
Reference< XMimeContentType > xMimeType;
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
try
{
if( xMimeFact.is() && rFlavor.MimeType.getLength() )
xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
}
catch( const ::com::sun::star::uno::Exception& )
{
2001-10-18 10:53:11 +00:00
}
2001-10-18 10:53:11 +00:00
aFlavorEx.MimeType = rFlavor.MimeType;
aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
aFlavorEx.DataType = rFlavor.DataType;
aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
2001-10-18 10:53:11 +00:00
rDataFlavorExVector.push_back( aFlavorEx );
2001-03-16 16:47:03 +00:00
2001-10-18 10:53:11 +00:00
// add additional formats for special mime types
if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId )
{
if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
{
aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
rDataFlavorExVector.push_back( aFlavorEx );
}
}
else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
2001-10-18 10:53:11 +00:00
{
if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
2001-09-25 09:12:13 +00:00
{
2001-10-18 10:53:11 +00:00
aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
rDataFlavorExVector.push_back( aFlavorEx );
2001-09-25 09:12:13 +00:00
}
2001-10-18 10:53:11 +00:00
}
else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
{
// #104735# HTML_SIMPLE may also be inserted without comments
aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
rDataFlavorExVector.push_back( aFlavorEx );
}
2001-10-18 10:53:11 +00:00
else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
{
// add, if it is a UTF-8 byte buffer
if( xMimeType->hasParameter( aCharsetStr ) )
{
2001-10-18 10:53:11 +00:00
const ::rtl::OUString aCharset( xMimeType->getParameterValue( aCharsetStr ) );
2001-10-18 10:53:11 +00:00
if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) ||
xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) )
{
2001-10-18 10:53:11 +00:00
rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
}
}
}
2001-10-18 10:53:11 +00:00
else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/rtf" ) ) )
{
rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
}
else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/html" ) ) )
2001-10-18 10:53:11 +00:00
{
rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
}
else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) )
{
rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
}
}
2001-01-19 17:23:13 +00:00
}
2001-03-05 11:44:24 +00:00
catch( const ::com::sun::star::uno::Exception& )
2001-01-19 17:23:13 +00:00
{
}
}
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
void TransferableDataHelper::InitFormats()
{
::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
::osl::MutexGuard aGuard( mpImpl->maMutex );
2001-10-18 10:53:11 +00:00
mpFormats->clear();
2001-10-18 10:53:11 +00:00
if( mxTransfer.is() )
TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
}
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
sal_Bool bRet = sal_False;
2001-01-19 17:23:13 +00:00
while( aIter != aEnd )
{
if( nFormat == (*aIter++).mnSotId )
{
aIter = aEnd;
2001-10-18 10:53:11 +00:00
bRet = sal_True;
}
}
return bRet;
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
sal_Bool bRet = sal_False;
while( aIter != aEnd )
{
if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
{
aIter = aEnd;
2001-10-18 10:53:11 +00:00
bRet = sal_True;
}
}
return bRet;
}
// -----------------------------------------------------------------------------
sal_uInt32 TransferableDataHelper::GetFormatCount() const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
return mpFormats->size();
}
// -----------------------------------------------------------------------------
SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
}
// -----------------------------------------------------------------------------
DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
2001-10-18 10:53:11 +00:00
DataFlavor aRet;
if( nFormat < mpFormats->size() )
2001-10-18 10:53:11 +00:00
aRet = (*mpFormats)[ nFormat ];
return aRet;
}
// -----------------------------------------------------------------------------
Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
{
Reference< XTransferable > xRet;
if( mxTransfer.is() )
{
try
{
xRet = mxTransfer;
// do a dummy call to check, if this interface is valid (nasty)
Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
}
catch( const ::com::sun::star::uno::Exception& )
{
xRet = Reference< XTransferable >();
}
}
return xRet;
}
// -----------------------------------------------------------------------------
2002-05-16 14:21:00 +00:00
Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
{
Any aReturn;
DataFlavor aFlavor;
if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
aReturn = GetAny( aFlavor );
return aReturn;
}
2002-05-16 14:21:00 +00:00
// -----------------------------------------------------------------------------
Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
Any aRet;
try
{
if( mxTransfer.is() )
{
DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
if( nRequestFormat )
{
// try to get alien format first
while( aIter != aEnd )
{
2001-10-18 10:53:11 +00:00
if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
aRet = mxTransfer->getTransferData( *aIter );
if( aRet.hasValue() )
aIter = aEnd;
else
aIter++;
}
}
if( !aRet.hasValue() )
aRet = mxTransfer->getTransferData( rFlavor );
}
}
catch( const ::com::sun::star::uno::Exception& )
{
}
return aRet;
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
{
2001-09-25 09:12:13 +00:00
::rtl::OUString aOUString;
sal_Bool bRet = GetString( nFormat, aOUString );
rStr = aOUString;
return bRet;
2001-01-19 17:23:13 +00:00
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
{
::rtl::OUString aOUString;
sal_Bool bRet = GetString( rFlavor, aOUString );
rStr = aOUString;
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, ::rtl::OUString& rStr )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, ::rtl::OUString& rStr )
{
2001-10-18 10:53:11 +00:00
Any aAny( GetAny( rFlavor ) );
sal_Bool bRet = sal_False;
2001-10-18 10:53:11 +00:00
if( aAny.hasValue() )
{
2001-10-18 10:53:11 +00:00
::rtl::OUString aOUString;
Sequence< sal_Int8 > aSeq;
2001-10-18 10:53:11 +00:00
if( aAny >>= aOUString )
{
rStr = aOUString;
bRet = sal_True;
2001-09-25 09:12:13 +00:00
}
2001-10-18 10:53:11 +00:00
else if( aAny >>= aSeq )
2001-09-25 09:12:13 +00:00
{
2001-10-18 10:53:11 +00:00
const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
sal_Int32 nLen = aSeq.getLength();
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
//JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
//DVO 2002-05-27: strip _all_ trailing zeros
while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
2001-10-18 10:53:11 +00:00
--nLen;
2001-09-25 09:12:13 +00:00
2001-10-18 10:53:11 +00:00
rStr = ::rtl::OUString( pChars, nLen, gsl_getSystemTextEncoding() );
bRet = sal_True;
2001-09-25 09:12:13 +00:00
}
}
2001-01-19 17:23:13 +00:00
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp )
{
SotStorageStreamRef xStm;
DataFlavor aSubstFlavor;
2001-01-19 17:23:13 +00:00
sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
if( bRet )
{
*xStm >> rBmp;
bRet = ( xStm->GetError() == ERRCODE_NONE );
/* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
problem is, that some graphics are inserted much too big because the nXPelsPerMeter
and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
Due to this reason the following code assumes that bitmaps with a logical size
greater than 50 cm aren't having the correct mapmode set.
The following code should be removed if DDBs and DIBs are supported via clipboard
properly.
*/
if ( bRet )
{
MapMode aMapMode = rBmp.GetPrefMapMode();
if ( aMapMode.GetMapUnit() != MAP_PIXEL )
{
Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM );
if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) )
rBmp.SetPrefMapMode( MAP_PIXEL );
}
}
2001-01-19 17:23:13 +00:00
}
if( !bRet &&
HasFormat( SOT_FORMATSTR_ID_BMP ) &&
SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
GetSotStorageStream( aSubstFlavor, xStm ) )
{
xStm->ResetError();
*xStm >> rBmp;
bRet = ( xStm->GetError() == ERRCODE_NONE );
}
2001-01-19 17:23:13 +00:00
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
{
SotStorageStreamRef xStm;
2002-07-20 09:38:02 +00:00
DataFlavor aSubstFlavor;
sal_Bool bRet = sal_False;
2001-01-19 17:23:13 +00:00
2002-07-20 09:38:02 +00:00
if( GetSotStorageStream( rFlavor, xStm ) )
2001-01-19 17:23:13 +00:00
{
*xStm >> rMtf;
bRet = ( xStm->GetError() == ERRCODE_NONE );
}
2002-07-20 09:38:02 +00:00
if( !bRet &&
HasFormat( SOT_FORMATSTR_ID_EMF ) &&
SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
GetSotStorageStream( aSubstFlavor, xStm ) )
2001-03-16 16:47:03 +00:00
{
2002-07-20 09:38:02 +00:00
Graphic aGraphic;
2001-03-16 16:47:03 +00:00
2002-07-20 09:38:02 +00:00
if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
2001-03-16 16:47:03 +00:00
{
2002-07-20 09:38:02 +00:00
rMtf = aGraphic.GetGDIMetaFile();
bRet = TRUE;
}
}
2001-03-16 16:47:03 +00:00
2002-07-20 09:38:02 +00:00
if( !bRet &&
HasFormat( SOT_FORMATSTR_ID_WMF ) &&
SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
GetSotStorageStream( aSubstFlavor, xStm ) )
{
Graphic aGraphic;
if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
{
rMtf = aGraphic.GetGDIMetaFile();
bRet = TRUE;
2001-03-16 16:47:03 +00:00
}
}
2001-01-19 17:23:13 +00:00
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
{
2001-03-16 16:47:03 +00:00
DataFlavor aFlavor;
sal_Bool bRet = sal_False;
2001-01-19 17:23:13 +00:00
2001-03-16 16:47:03 +00:00
if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
2001-01-19 17:23:13 +00:00
{
2001-03-16 16:47:03 +00:00
Bitmap aBmp;
if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True )
rGraphic = aBmp;
2001-03-16 16:47:03 +00:00
}
else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
{
GDIMetaFile aMtf;
if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
rGraphic = aMtf;
2001-03-16 16:47:03 +00:00
}
else
{
SotStorageStreamRef xStm;
2001-02-26 11:58:36 +00:00
2001-03-16 16:47:03 +00:00
if( GetSotStorageStream( rFlavor, xStm ) )
{
*xStm >> rGraphic;
bRet = ( xStm->GetError() == ERRCODE_NONE );
}
2001-01-19 17:23:13 +00:00
}
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
{
SotStorageStreamRef xStm;
sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
if( bRet )
{
rIMap.Read( *xStm, String() );
2001-01-19 17:23:13 +00:00
bRet = ( xStm->GetError() == ERRCODE_NONE );
}
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, TransferableObjectDescriptor& rDesc )
{
SotStorageStreamRef xStm;
sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
if( bRet )
{
*xStm >> rDesc;
bRet = ( xStm->GetError() == ERRCODE_NONE );
}
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
{
sal_Bool bRet = sal_False;
if( HasFormat( rFlavor ))
{
2001-01-19 17:23:13 +00:00
const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
switch( nFormat )
{
case( SOT_FORMATSTR_ID_SOLK ):
case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
{
String aString;
if( GetString( rFlavor, aString ) )
{
if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
{
rBmk = INetBookmark( aString, aString );
bRet = sal_True;
}
else
{
String aURL, aDesc;
sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
if( !nLen && aString.GetChar( 0 ) != '0' )
{
DBG_WARNING( "SOLK: 1. len=0" )
}
if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
{
DBG_WARNING( "SOLK: 1. illegal start or wrong len" )
}
aURL = aString.Copy( nStart + 1, nLen );
aString.Erase( 0, nStart + 1 + nLen );
nStart = aString.Search( '@' );
nLen = (sal_uInt16) aString.ToInt32();
if( !nLen && aString.GetChar( 0 ) != '0' )
{
DBG_WARNING( "SOLK: 2. len=0" )
}
if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
{
DBG_WARNING( "SOLK: 2. illegal start or wrong len" )
}
aDesc = aString.Copy( nStart+1, nLen );
rBmk = INetBookmark( aURL, aDesc );
bRet = sal_True;
}
}
}
break;
case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
{
Sequence< sal_Int8 > aSeq;
if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
{
2001-10-18 10:53:11 +00:00
rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), gsl_getSystemTextEncoding() ),
String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, gsl_getSystemTextEncoding() ) );
2001-01-19 17:23:13 +00:00
bRet = sal_True;
}
}
break;
#ifdef WNT
case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
{
Sequence< sal_Int8 > aSeq;
if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
{
FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
if( pFDesc->cItems )
{
ByteString aDesc( pFDesc->fgd[ 0 ].cFileName );
rtl_TextEncoding eTextEncoding = gsl_getSystemTextEncoding();
if( ( aDesc.Len() > 4 ) && aDesc.Copy( aDesc.Len() - 4 ).EqualsIgnoreCaseAscii( ".URL" ) )
{
SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( String( aDesc, eTextEncoding ) ).GetMainURL( INetURLObject::NO_DECODE ),
STREAM_STD_READ );
if( !pStream || pStream->GetError() )
{
DataFlavor aFileContentFlavor;
aSeq.realloc( 0 );
delete pStream;
if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
{
pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
}
else
pStream = NULL;
}
if( pStream )
{
ByteString aLine;
sal_Bool bSttFnd = sal_False;
while( pStream->ReadLine( aLine ) )
{
if( aLine.EqualsIgnoreCaseAscii( "[InternetShortcut]" ) )
bSttFnd = sal_True;
else if( bSttFnd && aLine.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "URL=" ) )
{
rBmk = INetBookmark( String( aLine.Erase( 0, 4 ), eTextEncoding ),
String( aDesc.Erase( aDesc.Len() - 4 ), eTextEncoding ) );
bRet = sal_True;
break;
}
}
delete pStream;
}
}
}
}
2001-01-19 17:23:13 +00:00
}
break;
#endif
}
}
2001-01-19 17:23:13 +00:00
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
INetImage& rINtImg )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetINetImage(
const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
INetImage& rINtImg )
{
SotStorageStreamRef xStm;
sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
if( bRet )
bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
return bRet;
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
FileList& rFileList )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetFileList(
const ::com::sun::star::datatransfer::DataFlavor&,
FileList& rFileList )
{
SotStorageStreamRef xStm;
sal_Bool bRet = sal_False;
for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
{
if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
{
const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
if( GetSotStorageStream( aFlavor, xStm ) )
{
if( aFlavor.MimeType.indexOf( ::rtl::OUString::createFromAscii( "text/uri-list" ) ) > -1 )
{
ByteString aByteString;
while( xStm->ReadLine( aByteString ) )
if( aByteString.Len() && aByteString.GetChar( 0 ) != '#' )
rFileList.AppendFile( String( aByteString, RTL_TEXTENCODING_UTF8 ) );
bRet = sal_True;
}
else
bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
}
}
}
return bRet;
}
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
{
const Any aAny( GetAny( rFlavor ) );
return( aAny.hasValue() && ( aAny >>= rSeq ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
{
Sequence< sal_Int8 > aSeq;
sal_Bool bRet = GetSequence( rFlavor, aSeq );
if( bRet )
2001-01-19 17:23:13 +00:00
{
rxStream = new SotStorageStream( String() );
rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
rxStream->Seek( 0 );
}
return bRet;
}
sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
{
Sequence< sal_Int8 > aSeq;
sal_Bool bRet = GetSequence( rFlavor, aSeq );
if( bRet )
rxStream = new ::comphelper::SequenceInputStream( aSeq );
return bRet;
}
2001-01-19 17:23:13 +00:00
// -----------------------------------------------------------------------------
2001-01-19 17:23:13 +00:00
sal_Bool TransferableDataHelper::GetInterface( SotFormatStringId nFormat, Reference< XInterface >& rIf )
{
DataFlavor aFlavor;
return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInterface( aFlavor, rIf ) );
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::GetInterface( const DataFlavor& rFlavor, Reference< XInterface >& rIf )
{
const Any aAny( GetAny( rFlavor ) );
return( aAny.hasValue() && ( aAny >>= rIf ) );
}
// -----------------------------------------------------------------------------
void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
{
mxTransfer = _rxNewContent;
InitFormats();
}
// -----------------------------------------------------------------------------
sal_Bool TransferableDataHelper::StartClipboardListening( )
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
StopClipboardListening( );
2001-10-18 10:53:11 +00:00
mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
mpImpl->mpClipboardListener->acquire();
2001-10-18 10:53:11 +00:00
return mpImpl->mpClipboardListener->isListening();
}
// -----------------------------------------------------------------------------
void TransferableDataHelper::StopClipboardListening( )
{
::osl::MutexGuard aGuard( mpImpl->maMutex );
2001-10-18 10:53:11 +00:00
if ( mpImpl->mpClipboardListener )
{
mpImpl->mpClipboardListener->dispose();
mpImpl->mpClipboardListener->release();
mpImpl->mpClipboardListener = NULL;
}
}
2001-01-19 17:23:13 +00:00
// -----------------------------------------------------------------------------
TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
{
2001-10-18 10:53:11 +00:00
DBG_ASSERT( pWindow, "Window pointer is NULL" );
Reference< XClipboard > xClipboard;
2001-10-18 10:53:11 +00:00
TransferableDataHelper aRet;
if( pWindow )
xClipboard = pWindow->GetClipboard();
2001-05-25 10:36:44 +00:00
if( xClipboard.is() )
{
try
{
Reference< XTransferable > xTransferable( xClipboard->getContents() );
if( xTransferable.is() )
{
aRet = TransferableDataHelper( xTransferable );
aRet.mxClipboard = xClipboard;
// also copy the clipboard - 99030 - 23.05.2002 - fs@openoffice.org
}
}
catch( const ::com::sun::star::uno::Exception& )
{
}
}
return aRet;
}
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
{
DBG_ASSERT( pWindow, "Window pointer is NULL" );
Reference< XClipboard > xSelection;
TransferableDataHelper aRet;
2001-10-18 10:53:11 +00:00
if( pWindow )
xSelection = pWindow->GetPrimarySelection();
2001-10-18 10:53:11 +00:00
if( xSelection.is() )
{
const sal_uInt32 nRef = Application::ReleaseSolarMutex();
try
{
Reference< XTransferable > xTransferable( xSelection->getContents() );
if( xTransferable.is() )
{
aRet = TransferableDataHelper( xTransferable );
aRet.mxClipboard = xSelection;
}
}
catch( const ::com::sun::star::uno::Exception& )
{
}
Application::AcquireSolarMutex( nRef );
}
return aRet;
}
// -----------------------------------------------------------------------------
2001-10-18 10:53:11 +00:00
sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
sal_Bool )
2001-02-26 11:58:36 +00:00
{
2001-10-18 10:53:11 +00:00
Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
Reference< XMimeContentTypeFactory > xMimeFact;
sal_Bool bRet = sal_False;
2001-10-18 10:53:11 +00:00
try
{
2001-10-18 10:53:11 +00:00
if( xFact.is() )
xMimeFact = Reference< XMimeContentTypeFactory >( xFact->createInstance( ::rtl::OUString::createFromAscii(
"com.sun.star.datatransfer.MimeContentTypeFactory" ) ),
UNO_QUERY );
2001-10-18 10:53:11 +00:00
if( xMimeFact.is() )
{
2001-10-18 10:53:11 +00:00
Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2001-10-18 12:23:27 +00:00
if( xRequestType1.is() && xRequestType2.is() )
2001-10-18 10:53:11 +00:00
{
2001-10-18 12:23:27 +00:00
if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2001-10-18 10:53:11 +00:00
{
2001-10-18 12:23:27 +00:00
if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "text/plain" ) ) )
{
// special handling for text/plain media types
const ::rtl::OUString aCharsetString( ::rtl::OUString::createFromAscii( "charset" ) );
2001-10-18 12:23:27 +00:00
if( !xRequestType2->hasParameter( aCharsetString ) ||
xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "utf-16" ) ) ||
xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "unicode" ) ) )
{
bRet = sal_True;
}
}
else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-openoffice" ) ) )
2001-10-18 10:53:11 +00:00
{
2001-10-18 12:23:27 +00:00
// special handling for application/x-openoffice media types
const ::rtl::OUString aFormatString( ::rtl::OUString::createFromAscii( "windows_formatname" ) );
if( xRequestType1->hasParameter( aFormatString ) &&
xRequestType2->hasParameter( aFormatString ) &&
xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
{
bRet = sal_True;
}
2001-10-18 10:53:11 +00:00
}
2001-10-18 12:23:27 +00:00
else
bRet = sal_True;
2001-10-18 10:53:11 +00:00
}
}
}
}
2001-10-18 10:53:11 +00:00
catch( const ::com::sun::star::uno::Exception& )
{
2001-10-18 10:53:11 +00:00
bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
}
2001-10-18 10:53:11 +00:00
return bRet;
}