summaryrefslogtreecommitdiff
path: root/dtrans/source/win32/dtobj
diff options
context:
space:
mode:
Diffstat (limited to 'dtrans/source/win32/dtobj')
-rw-r--r--dtrans/source/win32/dtobj/APNDataObject.cxx378
-rw-r--r--dtrans/source/win32/dtobj/APNDataObject.hxx89
-rw-r--r--dtrans/source/win32/dtobj/DOTransferable.cxx605
-rw-r--r--dtrans/source/win32/dtobj/DOTransferable.hxx133
-rw-r--r--dtrans/source/win32/dtobj/DTransHelper.cxx239
-rw-r--r--dtrans/source/win32/dtobj/DTransHelper.hxx214
-rw-r--r--dtrans/source/win32/dtobj/DataFmtTransl.cxx336
-rw-r--r--dtrans/source/win32/dtobj/DataFmtTransl.hxx83
-rw-r--r--dtrans/source/win32/dtobj/DtObjFactory.cxx74
-rw-r--r--dtrans/source/win32/dtobj/Fetc.cxx259
-rw-r--r--dtrans/source/win32/dtobj/Fetc.hxx93
-rw-r--r--dtrans/source/win32/dtobj/FetcList.cxx480
-rw-r--r--dtrans/source/win32/dtobj/FetcList.hxx156
-rw-r--r--dtrans/source/win32/dtobj/FmtFilter.cxx536
-rw-r--r--dtrans/source/win32/dtobj/FmtFilter.hxx90
-rw-r--r--dtrans/source/win32/dtobj/MimeAttrib.hxx50
-rw-r--r--dtrans/source/win32/dtobj/TxtCnvtHlp.cxx145
-rw-r--r--dtrans/source/win32/dtobj/TxtCnvtHlp.hxx63
-rw-r--r--dtrans/source/win32/dtobj/XNotifyingDataObject.cxx163
-rw-r--r--dtrans/source/win32/dtobj/XNotifyingDataObject.hxx105
-rw-r--r--dtrans/source/win32/dtobj/XTDataObject.cxx848
-rw-r--r--dtrans/source/win32/dtobj/XTDataObject.hxx177
-rw-r--r--dtrans/source/win32/dtobj/makefile.mk76
23 files changed, 5392 insertions, 0 deletions
diff --git a/dtrans/source/win32/dtobj/APNDataObject.cxx b/dtrans/source/win32/dtobj/APNDataObject.cxx
new file mode 100644
index 000000000000..775e952ac885
--- /dev/null
+++ b/dtrans/source/win32/dtobj/APNDataObject.cxx
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include "APNDataObject.hxx"
+#include <osl/diagnose.h>
+
+#include <systools/win32/comtools.hxx>
+#ifdef __MINGW32__
+#define __uuidof(I) IID_##I
+#endif
+
+//------------------------------------------------------------------------
+// defines
+//------------------------------------------------------------------------
+
+#define FREE_HGLOB_ON_RELEASE TRUE
+#define KEEP_HGLOB_ON_RELEASE FALSE
+
+//------------------------------------------------------------------------
+// ctor
+//------------------------------------------------------------------------
+
+CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) :
+ m_rIDataObjectOrg( rIDataObject ),
+ m_hGlobal( NULL ),
+ m_nRefCnt( 0 )
+{
+
+ OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" );
+
+ // we marshal the IDataObject interface pointer here so
+ // that it can be unmarshaled multiple times when this
+ // class will be used from another apartment
+ IStreamPtr pStm;
+ HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm );
+
+ OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
+
+ if ( SUCCEEDED( hr ) )
+ {
+ HRESULT hr_marshal = CoMarshalInterface(
+ pStm.get(),
+ __uuidof(IDataObject),
+ static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()),
+ MSHCTX_LOCAL,
+ NULL,
+ MSHLFLAGS_TABLEWEAK );
+
+ OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" );
+
+ // marshalling may fail if COM is not initialized
+ // for the calling thread which is a program time
+ // error or because of stream errors which are runtime
+ // errors for instance E_OUTOFMEMORY etc.
+
+ hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal );
+
+ OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" );
+
+ // if the marshalling failed we free the
+ // global memory again and set m_hGlobal
+ // to a defined value
+ if (FAILED(hr_marshal))
+ {
+ OSL_ENSURE(sal_False, "marshalling failed");
+
+ #if OSL_DEBUG_LEVEL > 0
+ HGLOBAL hGlobal =
+ #endif
+ GlobalFree(m_hGlobal);
+ OSL_ENSURE(NULL == hGlobal, "GlobalFree failed");
+ m_hGlobal = NULL;
+ }
+ }
+}
+
+CAPNDataObject::~CAPNDataObject( )
+{
+ if (m_hGlobal)
+ {
+ IStreamPtr pStm;
+ HRESULT hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm);
+
+ OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CoReleaseMarshalData(pStm.get());
+ OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed");
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// IUnknown->QueryInterface
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ OSL_ASSERT( NULL != ppvObject );
+
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+ *ppvObject = NULL;
+
+ if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ ( (LPUNKNOWN)*ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IUnknown->AddRef
+//------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( )
+{
+ return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
+}
+
+//------------------------------------------------------------------------
+// IUnknown->Release
+//------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CAPNDataObject::Release( )
+{
+ // we need a helper variable because it's not allowed to access
+ // a member variable after an object is destroyed
+ ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
+
+ if ( 0 == nRefCnt )
+ delete this;
+
+ return nRefCnt;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->GetData
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
+{
+ HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium );
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->GetData(pFormatetc, pmedium);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->EnumFormatEtc
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
+{
+ HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc);
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->QueryGetData
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc )
+{
+ HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc );
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp );
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->QueryGetData(pFormatetc);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->GetDataHere
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
+{
+ HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium);
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->GetDataHere(pFormatetc, pmedium);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->GetCanonicalFormatEtc
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut)
+{
+ HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut );
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->SetData
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease )
+{
+ HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease );
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->DAdvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection )
+{
+ HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->DUnadvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection )
+{
+ HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection );
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->DUnadvise(dwConnection);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->EnumDAdvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
+{
+ HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise);
+
+ if (RPC_E_WRONG_THREAD == hr)
+ {
+ IDataObjectPtr pIDOTmp;
+ hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
+
+ if (SUCCEEDED(hr))
+ hr = pIDOTmp->EnumDAdvise(ppenumAdvise);
+ }
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// for our convenience
+//------------------------------------------------------------------------
+
+CAPNDataObject::operator IDataObject*( )
+{
+ return static_cast< IDataObject* >( this );
+}
+
+//------------------------------------------------------------------------
+// helper function
+//------------------------------------------------------------------------
+
+HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj )
+{
+ OSL_ASSERT(NULL != ppIDataObj);
+
+ *ppIDataObj = NULL;
+ HRESULT hr = E_FAIL;
+
+ if (m_hGlobal)
+ {
+ IStreamPtr pStm;
+ hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm);
+
+ OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called");
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj);
+ OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized");
+ }
+ }
+ return hr;
+}
diff --git a/dtrans/source/win32/dtobj/APNDataObject.hxx b/dtrans/source/win32/dtobj/APNDataObject.hxx
new file mode 100644
index 000000000000..990e38236e66
--- /dev/null
+++ b/dtrans/source/win32/dtobj/APNDataObject.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _APNDATAOBJECT_HXX_
+#define _APNDATAOBJECT_HXX_
+
+#include <systools/win32/comtools.hxx>
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+/*
+ an APartment Neutral dataobject wrapper; this wrapper of a IDataObject
+ pointer can be used from any apartment without RPC_E_WRONG_THREAD
+ which normally occurs if an apartment tries to use an interface
+ pointer of another apartment; we use containment to hold the original
+ DataObject
+*/
+class CAPNDataObject : public IDataObject
+{
+public:
+ CAPNDataObject( IDataObjectPtr rIDataObject );
+ virtual ~CAPNDataObject( );
+
+ //-----------------------------------------------------------------
+ //IUnknown interface methods
+ //-----------------------------------------------------------------
+
+ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ //-----------------------------------------------------------------
+ // IDataObject interface methods
+ //-----------------------------------------------------------------
+
+ STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc );
+ STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut );
+ STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease );
+ STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc );
+ STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection );
+ STDMETHODIMP DUnadvise( DWORD dwConnection );
+ STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise );
+
+ operator IDataObject*( );
+
+private:
+ HRESULT MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj );
+
+private:
+ IDataObjectPtr m_rIDataObjectOrg;
+ HGLOBAL m_hGlobal;
+ LONG m_nRefCnt;
+
+// prevent copy and assignment
+private:
+ CAPNDataObject( const CAPNDataObject& theOther );
+ CAPNDataObject& operator=( const CAPNDataObject& theOther );
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/DOTransferable.cxx b/dtrans/source/win32/dtobj/DOTransferable.cxx
new file mode 100644
index 000000000000..951c3a69d291
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DOTransferable.cxx
@@ -0,0 +1,605 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <sal/types.h>
+#include <rtl/process.h>
+
+#ifndef _DOWRAPPERTRANSFERABLE_HXX_
+#include "DOTransferable.hxx"
+#endif
+#include "..\misc\ImplHelper.hxx"
+#include "..\misc\WinClip.hxx"
+#include "DTransHelper.hxx"
+#include "..\misc\ImplHelper.hxx"
+#include "TxtCnvtHlp.hxx"
+#include "MimeAttrib.hxx"
+#include "FmtFilter.hxx"
+#include "Fetc.hxx"
+
+
+#if(_MSC_VER < 1300) && !defined(__MINGW32__)
+#include <olestd.h>
+#endif
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+#define PRAGMA_MSG( msg ) message( __FILE__ "(" STR(__LINE__) "): " #msg )
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace rtl;
+using namespace std;
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::io;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+namespace
+{
+ const Type CPPUTYPE_SEQINT8 = getCppuType( ( Sequence< sal_Int8 >* )0 );
+ const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
+
+ inline
+ sal_Bool isValidFlavor( const DataFlavor& aFlavor )
+ {
+ return ( aFlavor.MimeType.getLength( ) &&
+ ( ( aFlavor.DataType == CPPUTYPE_SEQINT8 ) ||
+ ( aFlavor.DataType == CPPUTYPE_OUSTRING ) ) );
+ }
+
+} // end namespace
+
+
+//------------------------------------------------------------------------
+// ctor
+//------------------------------------------------------------------------
+
+CDOTransferable::CDOTransferable(
+ const Reference< XMultiServiceFactory >& ServiceManager, IDataObjectPtr rDataObject ) :
+ m_rDataObject( rDataObject ),
+ m_SrvMgr( ServiceManager ),
+ m_DataFormatTranslator( m_SrvMgr ),
+ m_bUnicodeRegistered( sal_False ),
+ m_TxtFormatOnClipboard( CF_INVALID )
+{
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+Any SAL_CALL CDOTransferable::getTransferData( const DataFlavor& aFlavor )
+ throw( UnsupportedFlavorException, IOException, RuntimeException )
+{
+ OSL_ASSERT( isValidFlavor( aFlavor ) );
+
+ MutexGuard aGuard( m_aMutex );
+
+ //------------------------------------------------
+ // convert dataflavor to formatetc
+ //------------------------------------------------
+
+ CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor );
+ OSL_ASSERT( CF_INVALID != fetc.getClipformat() );
+
+ //------------------------------------------------
+ // get the data from clipboard in a byte stream
+ //------------------------------------------------
+
+ ByteSequence_t clipDataStream;
+
+ try
+ {
+ clipDataStream = getClipboardData( fetc );
+ }
+ catch( UnsupportedFlavorException& )
+ {
+ if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat( ) ) &&
+ m_bUnicodeRegistered )
+ {
+ OUString aUnicodeText = synthesizeUnicodeText( );
+ Any aAny = makeAny( aUnicodeText );
+ return aAny;
+ }
+ else
+ throw; // pass through exception
+ }
+
+ //------------------------------------------------
+ // return the data as any
+ //------------------------------------------------
+
+ return byteStreamToAny( clipDataStream, aFlavor.DataType );
+}
+
+//------------------------------------------------------------------------
+// getTransferDataFlavors
+//------------------------------------------------------------------------
+
+Sequence< DataFlavor > SAL_CALL CDOTransferable::getTransferDataFlavors( )
+ throw( RuntimeException )
+{
+ return m_FlavorList;
+}
+
+//------------------------------------------------------------------------
+// isDataFlavorSupported
+// returns true if we find a DataFlavor with the same MimeType and
+// DataType
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDOTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
+ throw( RuntimeException )
+{
+ OSL_ASSERT( isValidFlavor( aFlavor ) );
+
+ for ( sal_Int32 i = 0; i < m_FlavorList.getLength( ); i++ )
+ if ( compareDataFlavors( aFlavor, m_FlavorList[i] ) )
+ return sal_True;
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+// helper function
+// the list of datafalvors currently on the clipboard will be initialized
+// only once; if the client of this Transferable will hold a reference
+// to it und the underlying clipboard content changes, the client does
+// possible operate on a invalid list
+// if there is only text on the clipboard we will also offer unicode text
+// an synthesize this format on the fly if requested, to accomplish this
+// we save the first offered text format which we will later use for the
+// conversion
+//------------------------------------------------------------------------
+
+void SAL_CALL CDOTransferable::initFlavorList( )
+{
+ IEnumFORMATETCPtr pEnumFormatEtc;
+ HRESULT hr = m_rDataObject->EnumFormatEtc( DATADIR_GET, &pEnumFormatEtc );
+ if ( SUCCEEDED( hr ) )
+ {
+ pEnumFormatEtc->Reset( );
+
+ FORMATETC fetc;
+ while ( S_FALSE != pEnumFormatEtc->Next( 1, &fetc, NULL ) )
+ {
+ // we use locales only to determine the
+ // charset if there is text on the cliboard
+ // we don't offer this format
+ if ( CF_LOCALE == fetc.cfFormat )
+ continue;
+
+ DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
+
+ // if text or oemtext is offered we also pretend to have unicode text
+ if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) &&
+ !m_bUnicodeRegistered )
+ {
+ addSupportedFlavor( aFlavor );
+
+ m_TxtFormatOnClipboard = fetc.cfFormat;
+ m_bUnicodeRegistered = sal_True;
+
+ // register unicode text as accompany format
+ aFlavor = formatEtcToDataFlavor(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
+ addSupportedFlavor( aFlavor );
+ }
+ else if ( (CF_UNICODETEXT == fetc.cfFormat) && !m_bUnicodeRegistered )
+ {
+ addSupportedFlavor( aFlavor );
+ m_bUnicodeRegistered = sal_True;
+ }
+ else
+ addSupportedFlavor( aFlavor );
+
+ // see MSDN IEnumFORMATETC
+ CoTaskMemFree( fetc.ptd );
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+void SAL_CALL CDOTransferable::addSupportedFlavor( const DataFlavor& aFlavor )
+{
+ // we ignore all formats that couldn't be translated
+ if ( aFlavor.MimeType.getLength( ) )
+ {
+ OSL_ASSERT( isValidFlavor( aFlavor ) );
+
+ m_FlavorList.realloc( m_FlavorList.getLength( ) + 1 );
+ m_FlavorList[m_FlavorList.getLength( ) - 1] = aFlavor;
+ }
+}
+
+//------------------------------------------------------------------------
+// helper function
+//------------------------------------------------------------------------
+
+//inline
+DataFlavor SAL_CALL CDOTransferable::formatEtcToDataFlavor( const FORMATETC& aFormatEtc )
+{
+ DataFlavor aFlavor;
+ LCID lcid = 0;
+
+ // for non-unicode text format we must provid a locale to get
+ // the character-set of the text, if there is no locale on the
+ // clipboard we assume the text is in a charset appropriate for
+ // the current thread locale
+ if ( (CF_TEXT == aFormatEtc.cfFormat) || (CF_OEMTEXT == aFormatEtc.cfFormat) )
+ lcid = getLocaleFromClipboard( );
+
+ return m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, lcid );
+}
+
+//------------------------------------------------------------------------
+// returns the current locale on clipboard; if there is no locale on
+// clipboard the function returns the current thread locale
+//------------------------------------------------------------------------
+
+LCID SAL_CALL CDOTransferable::getLocaleFromClipboard( )
+{
+ LCID lcid = GetThreadLocale( );
+
+ try
+ {
+ CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE );
+ ByteSequence_t aLCIDSeq = getClipboardData( fetc );
+ lcid = *(reinterpret_cast<LCID*>( aLCIDSeq.getArray( ) ) );
+
+ // because of a Win95/98 Bug; there the high word
+ // of a locale has the same value as the
+ // low word e.g. 0x07040704 that's not right
+ // correct is 0x00000704
+ lcid &= 0x0000FFFF;
+ }
+ catch(...)
+ {
+ // we take the default locale
+ }
+
+ return lcid;
+}
+
+//------------------------------------------------------------------------
+// i think it's not necessary to call ReleaseStgMedium
+// in case of failures because nothing should have been
+// allocated etc.
+//------------------------------------------------------------------------
+
+CDOTransferable::ByteSequence_t SAL_CALL CDOTransferable::getClipboardData( CFormatEtc& aFormatEtc )
+{
+ STGMEDIUM stgmedium;
+ HRESULT hr = m_rDataObject->GetData( aFormatEtc, &stgmedium );
+
+ // in case of failure to get a WMF metafile handle, try to get a memory block
+ if( FAILED( hr ) &&
+ ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) &&
+ ( TYMED_MFPICT == aFormatEtc.getTymed() ) )
+ {
+ CFormatEtc aTempFormat( aFormatEtc );
+ aTempFormat.setTymed( TYMED_HGLOBAL );
+ hr = m_rDataObject->GetData( aTempFormat, &stgmedium );
+ }
+
+ if ( FAILED( hr ) )
+ {
+ OSL_ASSERT( (hr != E_INVALIDARG) &&
+ (hr != DV_E_DVASPECT) &&
+ (hr != DV_E_LINDEX) &&
+ (hr != DV_E_TYMED) );
+
+ if ( DV_E_FORMATETC == hr )
+ throw UnsupportedFlavorException( );
+ else if ( STG_E_MEDIUMFULL == hr )
+ throw IOException( );
+ else
+ throw RuntimeException( );
+ }
+
+ ByteSequence_t byteStream;
+
+ try
+ {
+ if ( CF_ENHMETAFILE == aFormatEtc.getClipformat() )
+ byteStream = WinENHMFPictToOOMFPict( stgmedium.hEnhMetaFile );
+ else if (CF_HDROP == aFormatEtc.getClipformat())
+ byteStream = CF_HDROPToFileList(stgmedium.hGlobal);
+ else
+ {
+ clipDataToByteStream( aFormatEtc.getClipformat( ), stgmedium, byteStream );
+
+ // format conversion if necessary
+ if ( CF_DIB == aFormatEtc.getClipformat() )
+ byteStream = WinDIBToOOBMP( byteStream );
+ else if ( CF_METAFILEPICT == aFormatEtc.getClipformat() )
+ byteStream = WinMFPictToOOMFPict( byteStream );
+ }
+
+ ReleaseStgMedium( &stgmedium );
+ }
+ catch( CStgTransferHelper::CStgTransferException& )
+ {
+ ReleaseStgMedium( &stgmedium );
+ throw IOException( );
+ }
+
+ return byteStream;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+OUString SAL_CALL CDOTransferable::synthesizeUnicodeText( )
+{
+ ByteSequence_t aTextSequence;
+ CFormatEtc fetc;
+ LCID lcid = getLocaleFromClipboard( );
+ sal_uInt32 cpForTxtCnvt = 0;
+
+ if ( CF_TEXT == m_TxtFormatOnClipboard )
+ {
+ fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT );
+ aTextSequence = getClipboardData( fetc );
+
+ // determine the codepage used for text conversion
+ cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTANSICODEPAGE ).toInt32( );
+ }
+ else if ( CF_OEMTEXT == m_TxtFormatOnClipboard )
+ {
+ fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT );
+ aTextSequence = getClipboardData( fetc );
+
+ // determine the codepage used for text conversion
+ cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTCODEPAGE ).toInt32( );
+ }
+ else
+ OSL_ASSERT( sal_False );
+
+ CStgTransferHelper stgTransferHelper;
+
+ // convert the text
+ MultiByteToWideCharEx( cpForTxtCnvt,
+ reinterpret_cast<char*>( aTextSequence.getArray( ) ),
+ sal::static_int_cast<sal_uInt32>(-1), // Huh ?
+ stgTransferHelper,
+ sal_False);
+
+ CRawHGlobalPtr ptrHGlob(stgTransferHelper);
+ sal_Unicode* pWChar = reinterpret_cast<sal_Unicode*>(ptrHGlob.GetMemPtr());
+
+ return OUString(pWChar);
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CDOTransferable::clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence )
+{
+ CStgTransferHelper memTransferHelper;
+
+ switch( stgmedium.tymed )
+ {
+ case TYMED_HGLOBAL:
+ memTransferHelper.init( stgmedium.hGlobal );
+ break;
+
+ case TYMED_MFPICT:
+ memTransferHelper.init( stgmedium.hMetaFilePict );
+ break;
+
+ case TYMED_ENHMF:
+ memTransferHelper.init( stgmedium.hEnhMetaFile );
+ break;
+
+ case TYMED_ISTREAM:
+ #ifdef _MSC_VER
+ #pragma PRAGMA_MSG( Has to be implemented )
+ #endif
+ break;
+
+ default:
+ throw UnsupportedFlavorException( );
+ break;
+ }
+
+ int nMemSize = memTransferHelper.memSize( cf );
+ aByteSequence.realloc( nMemSize );
+ memTransferHelper.read( aByteSequence.getArray( ), nMemSize );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+Any CDOTransferable::byteStreamToAny( ByteSequence_t& aByteStream, const Type& aRequestedDataType )
+{
+ Any aAny;
+
+ if ( aRequestedDataType == CPPUTYPE_OUSTRING )
+ {
+ OUString str = byteStreamToOUString( aByteStream );
+ aAny = makeAny( str );
+ }
+ else
+ aAny = makeAny( aByteStream );
+
+ return aAny;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+OUString CDOTransferable::byteStreamToOUString( ByteSequence_t& aByteStream )
+{
+ sal_Int32 nWChars;
+ sal_Int32 nMemSize = aByteStream.getLength( );
+
+ // if there is a trailing L"\0" substract 1 from length
+ if ( 0 == aByteStream[ aByteStream.getLength( ) - 2 ] &&
+ 0 == aByteStream[ aByteStream.getLength( ) - 1 ] )
+ nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) ) - 1;
+ else
+ nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) );
+
+ return OUString( reinterpret_cast< sal_Unicode* >( aByteStream.getArray( ) ), nWChars );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDOTransferable::compareDataFlavors(
+ const DataFlavor& lhs, const DataFlavor& rhs )
+{
+ if ( !m_rXMimeCntFactory.is( ) )
+ {
+ m_rXMimeCntFactory = Reference< XMimeContentTypeFactory >( m_SrvMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY );
+ }
+ OSL_ASSERT( m_rXMimeCntFactory.is( ) );
+
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ Reference< XMimeContentType > xLhs( m_rXMimeCntFactory->createMimeContentType( lhs.MimeType ) );
+ Reference< XMimeContentType > xRhs( m_rXMimeCntFactory->createMimeContentType( rhs.MimeType ) );
+
+ if ( cmpFullMediaType( xLhs, xRhs ) )
+ {
+ bRet = cmpAllContentTypeParameter( xLhs, xRhs );
+ }
+ }
+ catch( IllegalArgumentException& )
+ {
+ OSL_ENSURE( sal_False, "Invalid content type detected" );
+ bRet = sal_False;
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDOTransferable::cmpFullMediaType(
+ const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
+{
+ return xLhs->getFullMediaType().equalsIgnoreAsciiCase( xRhs->getFullMediaType( ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDOTransferable::cmpAllContentTypeParameter(
+ const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
+{
+ Sequence< OUString > xLhsFlavors = xLhs->getParameters( );
+ Sequence< OUString > xRhsFlavors = xRhs->getParameters( );
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ if ( xLhsFlavors.getLength( ) == xRhsFlavors.getLength( ) )
+ {
+ OUString pLhs;
+ OUString pRhs;
+
+ for ( sal_Int32 i = 0; i < xLhsFlavors.getLength( ); i++ )
+ {
+ pLhs = xLhs->getParameterValue( xLhsFlavors[i] );
+ pRhs = xRhs->getParameterValue( xLhsFlavors[i] );
+
+ if ( !pLhs.equalsIgnoreAsciiCase( pRhs ) )
+ {
+ bRet = sal_False;
+ break;
+ }
+ }
+ }
+ else
+ bRet = sal_False;
+ }
+ catch( NoSuchElementException& )
+ {
+ bRet = sal_False;
+ }
+ catch( IllegalArgumentException& )
+ {
+ bRet = sal_False;
+ }
+
+ return bRet;
+}
+
+::com::sun::star::uno::Any SAL_CALL CDOTransferable::getData( const Sequence< sal_Int8>& aProcessId )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ Any retVal;
+
+ sal_uInt8 * arProcCaller= (sal_uInt8*)(sal_Int8*) aProcessId.getConstArray();
+ sal_uInt8 arId[16];
+ rtl_getGlobalProcessId(arId);
+ if( ! memcmp( arId, arProcCaller,16))
+ {
+ if (m_rDataObject.is())
+ {
+ IDataObject* pObj= m_rDataObject.get();
+ pObj->AddRef();
+ retVal.setValue( &pObj, getCppuType((sal_uInt32*)0));
+ }
+ }
+ return retVal;
+}
+
diff --git a/dtrans/source/win32/dtobj/DOTransferable.hxx b/dtrans/source/win32/dtobj/DOTransferable.hxx
new file mode 100644
index 000000000000..dd99e857b908
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DOTransferable.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _DOTRANSFERABLE_HXX_
+#define _DOTRANSFERABLE_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+
+#ifndef _CPPUHELPER_IMPLBASE1_HXX_
+#include <cppuhelper/implbase2.hxx>
+#endif
+#include "DataFmtTransl.hxx"
+#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+#include <com/sun/star/datatransfer/XSystemTransferable.hpp>
+
+#include <systools/win32/comtools.hxx>
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+// forward
+class CDTransObjFactory;
+class CFormatEtc;
+
+class CDOTransferable : public ::cppu::WeakImplHelper2< ::com::sun::star::datatransfer::XTransferable,
+ ::com::sun::star::datatransfer::XSystemTransferable>
+{
+public:
+ typedef com::sun::star::uno::Sequence< sal_Int8 > ByteSequence_t;
+
+ //------------------------------------------------------------------------
+ // XTransferable
+ //------------------------------------------------------------------------
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
+ throw( ::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
+ throw( ::com::sun::star::uno::RuntimeException );
+ //------------------------------------------------------------------------
+ // XSystemTransferable
+ //------------------------------------------------------------------------
+ virtual ::com::sun::star::uno::Any SAL_CALL getData( const com::sun::star::uno::Sequence<sal_Int8>& aProcessId ) throw
+ (::com::sun::star::uno::RuntimeException);
+
+
+private:
+ // should be created only by CDTransObjFactory
+ explicit CDOTransferable(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager,
+ IDataObjectPtr rDataObject );
+
+ //------------------------------------------------------------------------
+ // some helper functions
+ //------------------------------------------------------------------------
+
+ void SAL_CALL initFlavorList( );
+
+ void SAL_CALL addSupportedFlavor( const com::sun::star::datatransfer::DataFlavor& aFlavor );
+ com::sun::star::datatransfer::DataFlavor SAL_CALL formatEtcToDataFlavor( const FORMATETC& aFormatEtc );
+
+ ByteSequence_t SAL_CALL getClipboardData( CFormatEtc& aFormatEtc );
+ rtl::OUString SAL_CALL synthesizeUnicodeText( );
+
+ void SAL_CALL clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence );
+
+ ::com::sun::star::uno::Any SAL_CALL byteStreamToAny( ByteSequence_t& aByteStream, const com::sun::star::uno::Type& aRequestedDataType );
+ rtl::OUString SAL_CALL byteStreamToOUString( ByteSequence_t& aByteStream );
+
+ LCID SAL_CALL getLocaleFromClipboard( );
+
+ sal_Bool SAL_CALL compareDataFlavors( const com::sun::star::datatransfer::DataFlavor& lhs,
+ const com::sun::star::datatransfer::DataFlavor& rhs );
+
+ sal_Bool SAL_CALL cmpFullMediaType( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xLhs,
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xRhs ) const;
+
+ sal_Bool SAL_CALL cmpAllContentTypeParameter( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xLhs,
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xRhs ) const;
+
+private:
+ IDataObjectPtr m_rDataObject;
+ com::sun::star::uno::Sequence< com::sun::star::datatransfer::DataFlavor > m_FlavorList;
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr;
+ CDataFormatTranslator m_DataFormatTranslator;
+ com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentTypeFactory > m_rXMimeCntFactory;
+ ::osl::Mutex m_aMutex;
+ sal_Bool m_bUnicodeRegistered;
+ CLIPFORMAT m_TxtFormatOnClipboard;
+
+// non supported operations
+private:
+ CDOTransferable( const CDOTransferable& );
+ CDOTransferable& operator=( const CDOTransferable& );
+
+ friend class CDTransObjFactory;
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/DTransHelper.cxx b/dtrans/source/win32/dtobj/DTransHelper.cxx
new file mode 100644
index 000000000000..30370fdaf3c8
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DTransHelper.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <rtl/ustring.h>
+#include <osl/diagnose.h>
+#include "DTransHelper.hxx"
+
+//------------------------------------------------------------------------
+// implementation
+//------------------------------------------------------------------------
+
+CStgTransferHelper::CStgTransferHelper( sal_Bool bAutoInit,
+ HGLOBAL hGlob,
+ sal_Bool bDelStgOnRelease ) :
+ m_lpStream( NULL ),
+ m_bDelStgOnRelease( bDelStgOnRelease )
+{
+ if ( bAutoInit )
+ init( hGlob, m_bDelStgOnRelease );
+}
+
+//------------------------------------------------------------------------
+// dtor
+//------------------------------------------------------------------------
+
+
+CStgTransferHelper::~CStgTransferHelper( )
+{
+ if ( m_lpStream )
+ m_lpStream->Release( );
+}
+
+//------------------------------------------------------------------------
+// TransferData into the
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::write( const void* lpData, ULONG cb, ULONG* cbWritten )
+{
+ HRESULT hr = E_FAIL;
+
+ if ( m_lpStream )
+ hr = m_lpStream->Write( lpData, cb, cbWritten );
+
+ if ( FAILED( hr ) )
+ throw CStgTransferException( hr );
+
+#if OSL_DEBUG_LEVEL > 0
+ HGLOBAL hGlob;
+ hr = GetHGlobalFromStream( m_lpStream, &hGlob );
+ OSL_ASSERT( SUCCEEDED( hr ) );
+
+ /*DWORD dwSize =*/ GlobalSize( hGlob );
+ /*LPVOID lpdbgData =*/ GlobalLock( hGlob );
+ GlobalUnlock( hGlob );
+#endif
+}
+
+//------------------------------------------------------------------------
+// read
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::read( LPVOID pv, ULONG cb, ULONG* pcbRead )
+{
+ HRESULT hr = E_FAIL;
+
+ if ( m_lpStream )
+ hr = m_lpStream->Read( pv, cb , pcbRead );
+
+ if ( FAILED( hr ) )
+ throw CStgTransferException( hr );
+}
+
+//------------------------------------------------------------------------
+// GetHGlobal
+//------------------------------------------------------------------------
+
+HGLOBAL SAL_CALL CStgTransferHelper::getHGlobal( ) const
+{
+ OSL_ASSERT( m_lpStream );
+
+ HGLOBAL hGlob = NULL;
+
+ if ( m_lpStream )
+ {
+ HRESULT hr = GetHGlobalFromStream( m_lpStream, &hGlob );
+ if ( FAILED( hr ) )
+ hGlob = NULL;
+ }
+
+ return hGlob;
+}
+
+//------------------------------------------------------------------------
+// getIStream
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::getIStream( LPSTREAM* ppStream )
+{
+ OSL_ASSERT( ppStream );
+ *ppStream = m_lpStream;
+ if ( *ppStream )
+ static_cast< LPUNKNOWN >( *ppStream )->AddRef( );
+}
+
+//------------------------------------------------------------------------
+// Init
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::init( SIZE_T newSize,
+ sal_uInt32 uiFlags,
+ sal_Bool bDelStgOnRelease )
+{
+ cleanup( );
+
+ m_bDelStgOnRelease = bDelStgOnRelease;
+
+ HGLOBAL hGlob = GlobalAlloc( uiFlags, newSize );
+ if ( NULL == hGlob )
+ throw CStgTransferException( STG_E_MEDIUMFULL );
+
+ HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
+ if ( FAILED( hr ) )
+ {
+ GlobalFree( hGlob );
+ m_lpStream = NULL;
+ throw CStgTransferException( hr );
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ STATSTG statstg;
+ hr = m_lpStream->Stat( &statstg, STATFLAG_DEFAULT );
+ OSL_ASSERT( SUCCEEDED( hr ) );
+#endif
+}
+
+//------------------------------------------------------------------------
+// Init
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::init( HGLOBAL hGlob,
+ sal_Bool bDelStgOnRelease )
+{
+ cleanup( );
+
+ m_bDelStgOnRelease = bDelStgOnRelease;
+
+ HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream );
+ if ( FAILED( hr ) )
+ throw CStgTransferException( hr );
+}
+
+//------------------------------------------------------------------------
+// free the global memory and invalidate the stream pointer
+//------------------------------------------------------------------------
+
+void SAL_CALL CStgTransferHelper::cleanup( )
+{
+ if ( m_lpStream && !m_bDelStgOnRelease )
+ {
+ HGLOBAL hGlob;
+ GetHGlobalFromStream( m_lpStream, &hGlob );
+ GlobalFree( hGlob );
+ }
+
+ if ( m_lpStream )
+ {
+ m_lpStream->Release( );
+ m_lpStream = NULL;
+ }
+}
+
+//------------------------------------------------------------------------
+// return the size of memory we point to
+//------------------------------------------------------------------------
+
+sal_uInt32 SAL_CALL CStgTransferHelper::memSize( CLIPFORMAT cf ) const
+{
+ DWORD dwSize = 0;
+
+ if ( NULL != m_lpStream )
+ {
+ HGLOBAL hGlob;
+ GetHGlobalFromStream( m_lpStream, &hGlob );
+
+ if ( CF_TEXT == cf || RegisterClipboardFormat( "HTML Format" ) == cf )
+ {
+ sal_Char* pText = static_cast< sal_Char* >( GlobalLock( hGlob ) );
+ if ( pText )
+ {
+ dwSize = strlen(pText) + 1; // strlen + trailing '\0'
+ GlobalUnlock( hGlob );
+ }
+ }
+ else if ( CF_UNICODETEXT == cf )
+ {
+ sal_Unicode* pText = static_cast< sal_Unicode* >( GlobalLock( hGlob ) );
+ if ( pText )
+ {
+ dwSize = rtl_ustr_getLength( pText ) * sizeof( sal_Unicode );
+ GlobalUnlock( hGlob );
+ }
+ }
+ else
+ dwSize = GlobalSize( hGlob );
+ }
+
+ return dwSize;
+}
+
diff --git a/dtrans/source/win32/dtobj/DTransHelper.hxx b/dtrans/source/win32/dtobj/DTransHelper.hxx
new file mode 100644
index 000000000000..7975b84eec57
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DTransHelper.hxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _DTRANSHELPER_HXX_
+#define _DTRANSHELPER_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include "..\misc\WinClip.hxx"
+
+//------------------------------------------------------------------------
+// defines
+//------------------------------------------------------------------------
+
+#define AUTO_INIT TRUE
+#define NO_AUTO_INIT FALSE
+#define MEM_DESTROY_ON_RELEASE TRUE
+#define NO_MEM_DESTROY_ON_RELEASE FALSE
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------------
+// a helper class to manage a global memory area, the clients can write
+// into the global memory area and extract the handle to the global mem
+// note: not thread-safe
+//-------------------------------------------------------------------------
+
+class CStgTransferHelper
+{
+public:
+ // will be thrown in case of failures
+ class CStgTransferException
+ {
+ public:
+ HRESULT m_hr;
+ CStgTransferException( HRESULT hr ) : m_hr( hr ) {};
+ };
+
+public:
+ CStgTransferHelper(
+ sal_Bool bAutoInit = sal_False,
+ HGLOBAL hGlob = NULL,
+ sal_Bool bDelStgOnRelease = sal_False );
+
+ ~CStgTransferHelper( );
+
+ void SAL_CALL write( const void* lpData, ULONG cb, ULONG* cbWritten = NULL );
+ void SAL_CALL read( LPVOID pv, ULONG cb, ULONG* pcbRead = NULL );
+
+ HGLOBAL SAL_CALL getHGlobal( ) const;
+ void SAL_CALL getIStream( LPSTREAM* ppStream );
+
+ void SAL_CALL init(
+ SIZE_T newSize,
+ sal_uInt32 uiFlags = GHND,
+ sal_Bool bDelStgOnRelease = sal_False );
+
+ void SAL_CALL init(
+ HGLOBAL hGlob,
+ sal_Bool bDelStgOnRelease = sal_False );
+
+ // returns the size of the managed memory
+ sal_uInt32 SAL_CALL memSize( CLIPFORMAT cf = CF_INVALID ) const;
+
+ // free the global memory and necessary
+ // release the internal stream pointer
+ void SAL_CALL cleanup( );
+
+private:
+ LPSTREAM m_lpStream;
+ sal_Bool m_bDelStgOnRelease;
+
+private:
+ CStgTransferHelper( const CStgTransferHelper& );
+ CStgTransferHelper& operator=( const CStgTransferHelper& );
+};
+
+//-------------------------------------------------------------------------
+// something like an auto-pointer - allows access to the memory belonging
+// to a HGLOBAL and automatically unlocks a global memory at destruction
+// time
+//-------------------------------------------------------------------------
+
+class CRawHGlobalPtr
+{
+public:
+
+ //---------------------------------------------
+ // ctor
+ //---------------------------------------------
+
+ CRawHGlobalPtr( HGLOBAL hGlob ) :
+ m_hGlob( hGlob ),
+ m_bIsLocked( FALSE ),
+ m_pGlobMem( NULL )
+ {
+ }
+
+
+ //---------------------------------------------
+ // ctor
+ //---------------------------------------------
+
+ CRawHGlobalPtr( const CStgTransferHelper& theHGlobalHelper ) :
+ m_hGlob( theHGlobalHelper.getHGlobal( ) ),
+ m_bIsLocked( FALSE ),
+ m_pGlobMem( NULL )
+ {
+ }
+
+ //---------------------------------------------
+ // dtor
+ //---------------------------------------------
+
+ ~CRawHGlobalPtr( )
+ {
+ if ( m_bIsLocked )
+ GlobalUnlock( m_hGlob );
+ }
+
+ //---------------------------------------------
+ // lock the global memory (initializes a
+ // pointer to this memory)
+ //---------------------------------------------
+
+ BOOL Lock( )
+ {
+ if ( !m_bIsLocked && ( NULL != m_hGlob ) )
+ {
+ m_pGlobMem = GlobalLock( m_hGlob );
+ m_bIsLocked = ( NULL != m_pGlobMem );
+ }
+
+ return m_bIsLocked;
+ }
+
+ //---------------------------------------------
+ // unlock the global memory (invalidates the
+ // pointer to this memory)
+ //---------------------------------------------
+
+ BOOL Unlock( )
+ {
+ GlobalUnlock( m_hGlob );
+ m_bIsLocked = FALSE;
+ m_pGlobMem = NULL;
+
+ return ( NO_ERROR == GetLastError( ) );
+ }
+
+ //---------------------------------------------
+ // locks the global memory and returns a
+ // pointer to this memory
+ //---------------------------------------------
+
+ LPVOID GetMemPtr( )
+ {
+ Lock( );
+ return m_pGlobMem;
+ }
+
+ //---------------------------------------------
+ // size of mem we point to
+ //---------------------------------------------
+
+ int MemSize( ) const
+ {
+ return GlobalSize( m_hGlob );
+ }
+
+private:
+ HGLOBAL m_hGlob;
+ BOOL m_bIsLocked;
+ LPVOID m_pGlobMem;
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/DataFmtTransl.cxx b/dtrans/source/win32/dtobj/DataFmtTransl.cxx
new file mode 100644
index 000000000000..f72e8bb714a7
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DataFmtTransl.cxx
@@ -0,0 +1,336 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include "DataFmtTransl.hxx"
+#include <rtl/string.hxx>
+#include <osl/diagnose.h>
+#include <rtl/tencinfo.h>
+#include "..\misc\ImplHelper.hxx"
+#include "..\misc\WinClip.hxx"
+#include "MimeAttrib.hxx"
+#include "DTransHelper.hxx"
+#include <rtl/string.h>
+#include "Fetc.hxx"
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#pragma warning(disable:4917)
+#endif
+#include <windows.h>
+#if (_MSC_VER < 1300) && !defined(__MINGW32__)
+#include <olestd.h>
+#endif
+#include <shlobj.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace rtl;
+using namespace std;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::lang;
+
+//------------------------------------------------------------------------
+// const
+//------------------------------------------------------------------------
+
+const Type CPPUTYPE_SALINT32 = getCppuType((sal_Int32*)0);
+const Type CPPUTYPE_SALINT8 = getCppuType((sal_Int8*)0);
+const Type CPPUTYPE_OUSTRING = getCppuType((OUString*)0);
+const Type CPPUTYPE_SEQSALINT8 = getCppuType((Sequence< sal_Int8>*)0);
+const sal_Int32 MAX_CLIPFORMAT_NAME = 256;
+
+const OUString TEXT_PLAIN_CHARSET = OUString::createFromAscii( "text/plain;charset=" );
+const OUString HPNAME_OEM_ANSI_TEXT = OUString::createFromAscii( "OEM/ANSI Text" );
+
+const OUString HTML_FORMAT_NAME_WINDOWS = OUString::createFromAscii( "HTML Format" );
+const OUString HTML_FORMAT_NAME_SOFFICE = OUString::createFromAscii( "HTML (HyperText Markup Language)" );
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CDataFormatTranslator::CDataFormatTranslator( const Reference< XMultiServiceFactory >& aServiceManager ) :
+ m_SrvMgr( aServiceManager )
+{
+ m_XDataFormatTranslator = Reference< XDataFormatTranslator >(
+ m_SrvMgr->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.DataFormatTranslator" ) ), UNO_QUERY );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc CDataFormatTranslator::getFormatEtcFromDataFlavor( const DataFlavor& aDataFlavor ) const
+{
+ sal_Int32 cf = CF_INVALID;
+
+ try
+ {
+ if( m_XDataFormatTranslator.is( ) )
+ {
+ Any aFormat = m_XDataFormatTranslator->getSystemDataTypeFromDataFlavor( aDataFlavor );
+
+ if ( aFormat.hasValue( ) )
+ {
+ if ( aFormat.getValueType( ) == CPPUTYPE_SALINT32 )
+ {
+ aFormat >>= cf;
+ OSL_ENSURE( CF_INVALID != cf, "Invalid Clipboard format delivered" );
+ }
+ else if ( aFormat.getValueType( ) == CPPUTYPE_OUSTRING )
+ {
+ OUString aClipFmtName;
+ aFormat >>= aClipFmtName;
+
+ OSL_ASSERT( aClipFmtName.getLength( ) );
+ cf = RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) );
+
+ OSL_ENSURE( CF_INVALID != cf, "RegisterClipboardFormat failed" );
+ }
+ else
+ OSL_ENSURE( sal_False, "Wrong Any-Type detected" );
+ }
+ }
+ }
+ catch( ... )
+ {
+ OSL_ENSURE( sal_False, "Unexpected error" );
+ }
+
+ return sal::static_int_cast<CFormatEtc>(getFormatEtcForClipformat( sal::static_int_cast<CLIPFORMAT>(cf) ));
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+DataFlavor CDataFormatTranslator::getDataFlavorFromFormatEtc( const FORMATETC& aFormatEtc, LCID lcid ) const
+{
+ DataFlavor aFlavor;
+
+ try
+ {
+ CLIPFORMAT aClipformat = aFormatEtc.cfFormat;
+
+ Any aAny;
+ aAny <<= static_cast< sal_Int32 >( aClipformat );
+
+ if ( isOemOrAnsiTextFormat( aClipformat ) )
+ {
+ aFlavor.MimeType = TEXT_PLAIN_CHARSET;
+ aFlavor.MimeType += getTextCharsetFromLCID( lcid, aClipformat );
+
+ aFlavor.HumanPresentableName = HPNAME_OEM_ANSI_TEXT;
+ aFlavor.DataType = CPPUTYPE_SEQSALINT8;
+ }
+ else if ( CF_INVALID != aClipformat )
+ {
+ if ( m_XDataFormatTranslator.is( ) )
+ {
+ aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny );
+
+ if ( !aFlavor.MimeType.getLength( ) )
+ {
+ // lookup of DataFlavor from clipboard format id
+ // failed, so we try to resolve via clipboard
+ // format name
+ OUString clipFormatName = getClipboardFormatName( aClipformat );
+
+ // if we could not get a clipboard format name an
+ // error must have occured or it is a standard
+ // clipboard format that we don't translate, e.g.
+ // CF_BITMAP (the office only uses CF_DIB)
+ if ( clipFormatName.getLength( ) )
+ {
+ aAny <<= clipFormatName;
+ aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny );
+ }
+ }
+ }
+ }
+ }
+ catch( ... )
+ {
+ OSL_ENSURE( sal_False, "Unexpected error" );
+ }
+
+ return aFlavor;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformatName( const OUString& aClipFmtName ) const
+{
+ // check parameter
+ if ( !aClipFmtName.getLength( ) )
+ return CFormatEtc( CF_INVALID );
+
+ CLIPFORMAT cf = sal::static_int_cast<CLIPFORMAT>(RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) ));
+ return getFormatEtcForClipformat( cf );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+OUString CDataFormatTranslator::getClipboardFormatName( CLIPFORMAT aClipformat ) const
+{
+ OSL_PRECOND( CF_INVALID != aClipformat, "Invalid clipboard format" );
+
+ sal_Unicode wBuff[ MAX_CLIPFORMAT_NAME ];
+ sal_Int32 nLen = GetClipboardFormatNameW( aClipformat, reinterpret_cast<LPWSTR>(wBuff), MAX_CLIPFORMAT_NAME );
+
+ return OUString( wBuff, nLen );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformat( CLIPFORMAT cf ) const
+{
+ CFormatEtc fetc( cf, TYMED_NULL, NULL, DVASPECT_CONTENT );
+
+ switch( cf )
+ {
+ case CF_METAFILEPICT:
+ fetc.setTymed( TYMED_MFPICT );
+ break;
+
+ case CF_ENHMETAFILE:
+ fetc.setTymed( TYMED_ENHMF );
+ break;
+
+ default:
+ fetc.setTymed( TYMED_HGLOBAL /*| TYMED_ISTREAM*/ );
+ }
+
+ /*
+ hack: in order to paste urls copied by Internet Explorer
+ with "copy link" we set the lindex member to 0
+ but if we really want to support CFSTR_FILECONTENT and
+ the accompany format CFSTR_FILEDESCRIPTOR (FileGroupDescriptor)
+ the client of the clipboard service has to provide a id
+ of which FileContents it wants to paste
+ see MSDN: "Handling Shell Data Transfer Scenarios"
+ */
+ if ( cf == RegisterClipboardFormatA( CFSTR_FILECONTENTS ) )
+ fetc.setLindex( 0 );
+
+ return fetc;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDataFormatTranslator::isOemOrAnsiTextFormat( CLIPFORMAT cf ) const
+{
+ return ( (cf == CF_TEXT) || (cf == CF_OEMTEXT) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDataFormatTranslator::isUnicodeTextFormat( CLIPFORMAT cf ) const
+{
+ return ( cf == CF_UNICODETEXT );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDataFormatTranslator::isTextFormat( CLIPFORMAT cf ) const
+{
+ return ( isOemOrAnsiTextFormat( cf ) || isUnicodeTextFormat( cf ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDataFormatTranslator::isHTMLFormat( CLIPFORMAT cf ) const
+{
+ OUString clipFormatName = getClipboardFormatName( cf );
+ return ( clipFormatName == HTML_FORMAT_NAME_WINDOWS );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CDataFormatTranslator::isTextHtmlFormat( CLIPFORMAT cf ) const
+{
+ OUString clipFormatName = getClipboardFormatName( cf );
+ return ( clipFormatName.equalsIgnoreAsciiCase( HTML_FORMAT_NAME_SOFFICE ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+OUString SAL_CALL CDataFormatTranslator::getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const
+{
+ OSL_ASSERT( isOemOrAnsiTextFormat( aClipformat ) );
+
+ OUString charset;
+ if ( CF_TEXT == aClipformat )
+ {
+ charset = getMimeCharsetFromLocaleId(
+ lcid,
+ LOCALE_IDEFAULTANSICODEPAGE,
+ PRE_WINDOWS_CODEPAGE );
+ }
+ else if ( CF_OEMTEXT == aClipformat )
+ {
+ charset = getMimeCharsetFromLocaleId(
+ lcid,
+ LOCALE_IDEFAULTCODEPAGE,
+ PRE_OEM_CODEPAGE );
+ }
+ else // CF_UNICODE
+ OSL_ASSERT( sal_False );
+
+ return charset;
+}
diff --git a/dtrans/source/win32/dtobj/DataFmtTransl.hxx b/dtrans/source/win32/dtobj/DataFmtTransl.hxx
new file mode 100644
index 000000000000..70982ccaf6b9
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DataFmtTransl.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _DATAFMTTRANSL_HXX_
+#define _DATAFMTTRANSL_HXX_
+
+//-----------------------------------------------
+// includes
+//-----------------------------------------------
+
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+//-----------------------------------------------
+// declaration
+//-----------------------------------------------
+
+class CFormatEtc;
+
+class CDataFormatTranslator
+{
+public:
+ CDataFormatTranslator( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager );
+
+ CFormatEtc getFormatEtcFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const;
+ com::sun::star::datatransfer::DataFlavor getDataFlavorFromFormatEtc(
+ const FORMATETC& aFormatEtc, LCID lcid = GetThreadLocale( ) ) const;
+
+ CFormatEtc SAL_CALL getFormatEtcForClipformat( CLIPFORMAT cf ) const;
+ CFormatEtc SAL_CALL getFormatEtcForClipformatName( const rtl::OUString& aClipFmtName ) const;
+ rtl::OUString SAL_CALL getClipboardFormatName( CLIPFORMAT aClipformat ) const;
+
+ sal_Bool SAL_CALL isHTMLFormat( CLIPFORMAT cf ) const;
+ sal_Bool SAL_CALL isTextHtmlFormat( CLIPFORMAT cf ) const;
+ sal_Bool SAL_CALL isOemOrAnsiTextFormat( CLIPFORMAT cf ) const;
+ sal_Bool SAL_CALL isUnicodeTextFormat( CLIPFORMAT cf ) const;
+ sal_Bool SAL_CALL isTextFormat( CLIPFORMAT cf ) const;
+
+private:
+ rtl::OUString SAL_CALL getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const;
+
+private:
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr;
+ com::sun::star::uno::Reference< com::sun::star::datatransfer::XDataFormatTranslator > m_XDataFormatTranslator;
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/DtObjFactory.cxx b/dtrans/source/win32/dtobj/DtObjFactory.cxx
new file mode 100644
index 000000000000..e6cadec92983
--- /dev/null
+++ b/dtrans/source/win32/dtobj/DtObjFactory.cxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include "..\..\inc\DtObjFactory.hxx"
+
+#ifndef _TWRAPPERDATAOBJECT_HXX_
+#include "XTDataObject.hxx"
+#endif
+
+#ifndef _DOWRAPPERTRANSFERABLE_HXX_
+#include "DOTransferable.hxx"
+#endif
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::lang;
+
+//------------------------------------------------------------------------
+// implementation
+//------------------------------------------------------------------------
+
+IDataObjectPtr SAL_CALL CDTransObjFactory::createDataObjFromTransferable(const Reference<XMultiServiceFactory>& aServiceManager,
+ const Reference< XTransferable >& refXTransferable)
+{
+ return (IDataObjectPtr(new CXTDataObject(aServiceManager, refXTransferable)));
+}
+
+Reference< XTransferable > SAL_CALL CDTransObjFactory::createTransferableFromDataObj( const Reference< XMultiServiceFactory >& aServiceManager,
+ IDataObjectPtr pIDataObject )
+{
+ CDOTransferable* pTransf = new CDOTransferable(aServiceManager, pIDataObject);
+ Reference<XTransferable> refDOTransf(pTransf);
+
+ pTransf->acquire();
+ pTransf->initFlavorList();
+ pTransf->release();
+
+ return refDOTransf;
+}
+
diff --git a/dtrans/source/win32/dtobj/Fetc.cxx b/dtrans/source/win32/dtobj/Fetc.cxx
new file mode 100644
index 000000000000..525bfd58be4d
--- /dev/null
+++ b/dtrans/source/win32/dtobj/Fetc.cxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <osl/diagnose.h>
+#include "Fetc.hxx"
+#include "..\misc\ImplHelper.hxx"
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::CFormatEtc( )
+{
+ m_FormatEtc.cfFormat = 0;
+ m_FormatEtc.ptd = NULL;
+ m_FormatEtc.dwAspect = 0;
+ m_FormatEtc.lindex = -1;
+ m_FormatEtc.tymed = TYMED_NULL;
+}
+
+//------------------------------------------------------------------------
+// transfer of ownership
+//------------------------------------------------------------------------
+
+CFormatEtc::CFormatEtc( const FORMATETC& aFormatEtc )
+{
+ CopyFormatEtc( &m_FormatEtc, &const_cast< FORMATETC& >( aFormatEtc ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::~CFormatEtc( )
+{
+ DeleteTargetDevice( m_FormatEtc.ptd );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::CFormatEtc( CLIPFORMAT cf, DWORD tymed, DVTARGETDEVICE* ptd, DWORD dwAspect, LONG lindex )
+{
+ m_FormatEtc.cfFormat = cf;
+ m_FormatEtc.ptd = CopyTargetDevice( ptd );
+ m_FormatEtc.dwAspect = dwAspect;
+ m_FormatEtc.lindex = lindex;
+ m_FormatEtc.tymed = tymed;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::CFormatEtc( const CFormatEtc& theOther )
+{
+ m_FormatEtc.cfFormat = theOther.m_FormatEtc.cfFormat;
+ m_FormatEtc.ptd = CopyTargetDevice( theOther.m_FormatEtc.ptd );
+ m_FormatEtc.dwAspect = theOther.m_FormatEtc.dwAspect;
+ m_FormatEtc.lindex = theOther.m_FormatEtc.lindex;
+ m_FormatEtc.tymed = theOther.m_FormatEtc.tymed;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc& CFormatEtc::operator=( const CFormatEtc& theOther )
+{
+ if ( this != &theOther )
+ {
+ DeleteTargetDevice( m_FormatEtc.ptd );
+
+ m_FormatEtc.cfFormat = theOther.m_FormatEtc.cfFormat;
+ m_FormatEtc.ptd = CopyTargetDevice( theOther.m_FormatEtc.ptd );
+ m_FormatEtc.dwAspect = theOther.m_FormatEtc.dwAspect;
+ m_FormatEtc.lindex = theOther.m_FormatEtc.lindex;
+ m_FormatEtc.tymed = theOther.m_FormatEtc.tymed;
+ }
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::operator FORMATETC*( )
+{
+ return &m_FormatEtc;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtc::operator FORMATETC( )
+{
+ return m_FormatEtc;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::getFORMATETC( LPFORMATETC lpFormatEtc )
+{
+ OSL_ASSERT( lpFormatEtc );
+ OSL_ASSERT( !IsBadWritePtr( lpFormatEtc, sizeof( FORMATETC ) ) );
+
+ CopyFormatEtc( lpFormatEtc, &m_FormatEtc );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CLIPFORMAT CFormatEtc::getClipformat( ) const
+{
+ return m_FormatEtc.cfFormat;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+DWORD CFormatEtc::getTymed( ) const
+{
+ return m_FormatEtc.tymed;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::getTargetDevice( DVTARGETDEVICE** lpDvTargetDevice ) const
+{
+ OSL_ASSERT( lpDvTargetDevice );
+ OSL_ASSERT( !IsBadWritePtr( lpDvTargetDevice, sizeof( DVTARGETDEVICE ) ) );
+
+ *lpDvTargetDevice = NULL;
+
+ if ( m_FormatEtc.ptd )
+ *lpDvTargetDevice = CopyTargetDevice( m_FormatEtc.ptd );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+DWORD CFormatEtc::getDvAspect( ) const
+{
+ return m_FormatEtc.dwAspect;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+LONG CFormatEtc::getLindex( ) const
+{
+ return m_FormatEtc.lindex;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::setClipformat( CLIPFORMAT cf )
+{
+ m_FormatEtc.cfFormat = cf;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::setTymed( DWORD tymed )
+{
+ m_FormatEtc.tymed = tymed;
+}
+
+//------------------------------------------------------------------------
+// transfer of ownership!
+//------------------------------------------------------------------------
+
+void CFormatEtc::setTargetDevice( DVTARGETDEVICE* ptd )
+{
+ DeleteTargetDevice( m_FormatEtc.ptd );
+ m_FormatEtc.ptd = ptd;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::setDvAspect( DWORD dwAspect )
+{
+ m_FormatEtc.dwAspect = dwAspect;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtc::setLindex( LONG lindex )
+{
+ m_FormatEtc.lindex = lindex;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs )
+{
+ return CompareFormatEtc( &lhs.m_FormatEtc, &rhs.m_FormatEtc );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs )
+{
+ return ( ( lhs == rhs ) != 1 );
+}
+
diff --git a/dtrans/source/win32/dtobj/Fetc.hxx b/dtrans/source/win32/dtobj/Fetc.hxx
new file mode 100644
index 000000000000..a0af6dead8c1
--- /dev/null
+++ b/dtrans/source/win32/dtobj/Fetc.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _FETC_HXX_
+#define _FETC_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <sal/types.h>
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+/**********************************************************************
+ stl container elements must fulfill the following requirements:
+ 1. they need a copy ctor and assignement operator(?)
+ 2. they must be compareable
+ because the FORMATETC structure has a pointer to a TARGETDEVICE
+ structure we need a simple wrapper class to fulfill these needs
+***********************************************************************/
+
+class CFormatEtc
+{
+public:
+ CFormatEtc( );
+ CFormatEtc( const FORMATETC& aFormatEtc );
+ CFormatEtc( CLIPFORMAT cf, DWORD tymed = TYMED_HGLOBAL, DVTARGETDEVICE* ptd = NULL, DWORD dwAspect = DVASPECT_CONTENT, LONG lindex = -1 );
+ CFormatEtc( const CFormatEtc& theOther );
+
+ ~CFormatEtc( );
+
+ CFormatEtc& operator=( const CFormatEtc& theOther );
+ operator FORMATETC*( );
+ operator FORMATETC( );
+
+ void getFORMATETC( LPFORMATETC lpFormatEtc );
+
+ CLIPFORMAT getClipformat( ) const;
+ DWORD getTymed( ) const;
+ void getTargetDevice( DVTARGETDEVICE** ptd ) const;
+ DWORD getDvAspect( ) const;
+ LONG getLindex( ) const;
+
+ void setClipformat( CLIPFORMAT cf );
+ void setTymed( DWORD tymed );
+ void setTargetDevice( DVTARGETDEVICE* ptd );
+ void setDvAspect( DWORD dwAspect );
+ void setLindex( LONG lindex );
+
+private:
+ FORMATETC m_FormatEtc;
+
+ friend sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs );
+ friend sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs );
+};
+
+sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs );
+sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs );
+
+
+#endif
diff --git a/dtrans/source/win32/dtobj/FetcList.cxx b/dtrans/source/win32/dtobj/FetcList.cxx
new file mode 100644
index 000000000000..8deb2296ad80
--- /dev/null
+++ b/dtrans/source/win32/dtobj/FetcList.cxx
@@ -0,0 +1,480 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <osl/diagnose.h>
+#include "FetcList.hxx"
+#include "Fetc.hxx"
+#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp>
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+
+#ifndef _DATAFORMATTRANSLATOR_HXX_
+#include "DataFmtTransl.hxx"
+#endif
+#include "..\misc\ImplHelper.hxx"
+#include "..\misc\WinClip.hxx"
+
+#include <algorithm>
+
+#include "MimeAttrib.hxx"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace rtl;
+using namespace std;
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+LCID CFormatRegistrar::m_TxtLocale = 0;
+sal_uInt32 CFormatRegistrar::m_TxtCodePage = GetACP( );
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatEtcContainer::CFormatEtcContainer( )
+{
+ m_EnumIterator = m_FormatMap.begin( );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtcContainer::addFormatEtc( const CFormatEtc& fetc )
+{
+ m_FormatMap.push_back( CFormatEtc( fetc ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void SAL_CALL CFormatEtcContainer::removeFormatEtc( const CFormatEtc& fetc )
+{
+ FormatEtcMap_t::iterator iter =
+ find( m_FormatMap.begin(), m_FormatMap.end(), fetc );
+
+ if ( iter != m_FormatMap.end( ) )
+ m_FormatMap.erase( iter );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void SAL_CALL CFormatEtcContainer::removeAllFormatEtc( )
+{
+ m_FormatMap.clear( );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool CFormatEtcContainer::hasFormatEtc( const CFormatEtc& fetc ) const
+{
+ FormatEtcMap_t::const_iterator iter =
+ find( m_FormatMap.begin(), m_FormatMap.end(), fetc );
+
+ return ( iter != m_FormatMap.end( ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool CFormatEtcContainer::hasElements( ) const
+{
+ return ( m_FormatMap.size( ) > 0 );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void CFormatEtcContainer::beginEnumFormatEtc( )
+{
+ m_EnumIterator = m_FormatMap.begin( );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_uInt32 SAL_CALL CFormatEtcContainer::nextFormatEtc( LPFORMATETC lpFetc,
+ sal_uInt32 aNum )
+{
+ OSL_ASSERT( lpFetc );
+ OSL_ASSERT( !IsBadWritePtr( lpFetc, sizeof( FORMATETC ) * aNum ) );
+
+ sal_uInt32 nFetched = 0;
+
+ if ( m_EnumIterator != m_FormatMap.end( ) )
+ {
+ for ( sal_uInt32 i = 0; i < aNum; i++, nFetched++, lpFetc++, ++m_EnumIterator )
+ CopyFormatEtc( lpFetc, *m_EnumIterator );
+ }
+
+ return nFetched;
+}
+
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatEtcContainer::skipFormatEtc( sal_uInt32 aNum )
+{
+ FormatEtcMap_t::const_iterator iter_end = m_FormatMap.end( );
+ for ( sal_uInt32 i = 0;
+ (i < aNum) && (m_EnumIterator != iter_end);
+ i++, ++m_EnumIterator )
+ ;/* intentionally left empty */
+
+ return ( m_EnumIterator != m_FormatMap.end( ) );
+}
+
+
+//#########################################################################
+
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+CFormatRegistrar::CFormatRegistrar( const Reference< XMultiServiceFactory >& ServiceManager,
+ const CDataFormatTranslator& aDataFormatTranslator ) :
+ m_DataFormatTranslator( aDataFormatTranslator ),
+ m_bHasSynthesizedLocale( sal_False ),
+ m_SrvMgr( ServiceManager )
+{
+}
+
+// ----------------------------------------------------------------------------------------
+// this function converts all DataFlavors of the given FlavorList into
+// an appropriate FORMATETC structure, for some formats like unicodetext,
+// text and text/html we will offer an accompany format e.g.:
+//
+// DataFlavor | Registered Clipformat | Registered accompany clipformat
+// -------------------------|---------------------------|-----------------------------------
+// text/plain;charset=ansi | CF_TEXT | CF_UNICODETEXT
+// | | CF_LOCALE (if charset != GetACP()
+// | |
+// text/plain;charset=oem | CF_OEMTEXT | CF_UNICODETEXT
+// | | CF_LOCALE (if charset != GetOEMCP()
+// | |
+// text/plain;charset=utf-16| CF_UNICODETEXT | CF_TEXT
+// | |
+// text/html | HTML (Hypertext ...) | HTML Format
+// | |
+//
+// if some tries to register different text formats with different charsets the last
+// registered wins and the others are ignored
+// ----------------------------------------------------------------------------------------
+
+void SAL_CALL CFormatRegistrar::RegisterFormats(
+ const Reference< XTransferable >& aXTransferable, CFormatEtcContainer& aFormatEtcContainer )
+{
+ Sequence< DataFlavor > aFlavorList = aXTransferable->getTransferDataFlavors( );
+ sal_Int32 nFlavors = aFlavorList.getLength( );
+ sal_Bool bUnicodeRegistered = sal_False;
+ DataFlavor aFlavor;
+
+ for( sal_Int32 i = 0; i < nFlavors; i++ )
+ {
+ aFlavor = aFlavorList[i];
+ CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor );
+
+ // maybe an internal format so we ignore it
+ if ( CF_INVALID == fetc.getClipformat( ) )
+ continue;
+
+ if ( !needsToSynthesizeAccompanyFormats( fetc ) )
+ aFormatEtcContainer.addFormatEtc( fetc );
+ else
+ {
+ // if we haven't registered any text format up to now
+ if ( m_DataFormatTranslator.isTextFormat( fetc.getClipformat() ) && !bUnicodeRegistered )
+ {
+ // if the transferable supports unicode text we ignore
+ // any further text format the transferable offers
+ // because we can create it from Unicode text in addition
+ // we register CF_TEXT for non unicode clients
+ if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat() ) )
+ {
+ aFormatEtcContainer.addFormatEtc( fetc ); // add CF_UNICODE
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT ) ); // add CF_TEXT
+ bUnicodeRegistered = sal_True;
+ }
+ else if ( !hasUnicodeFlavor( aXTransferable ) )
+ {
+ // we try to investigate the charset and make a valid
+ // windows codepage from this charset the default
+ // return value is the result of GetACP( )
+ OUString charset = getCharsetFromDataFlavor( aFlavor );
+ sal_uInt32 txtCP = getWinCPFromMimeCharset( charset );
+
+ // we try to get a Locale appropriate for this codepage
+ if ( findLocaleForTextCodePage( ) )
+ {
+ m_TxtCodePage = txtCP;
+
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
+
+ if ( !IsOEMCP( m_TxtCodePage ) )
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT ) );
+ else
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT ) );
+
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE ) );
+
+ // we save the flavor so it's easier when
+ // queried for it in XTDataObject::GetData(...)
+ m_RegisteredTextFlavor = aFlavor;
+ m_bHasSynthesizedLocale = sal_True;
+ }
+ }
+ }
+ else if ( m_DataFormatTranslator.isTextHtmlFormat( fetc.getClipformat( ) ) ) // Html (Hyper Text...)
+ {
+ // we add text/html ( HTML (HyperText Markup Language) )
+ aFormatEtcContainer.addFormatEtc( fetc );
+
+ // and HTML Format
+ OUString htmlFormat( OUString::createFromAscii( "HTML Format" ) );
+ aFormatEtcContainer.addFormatEtc(
+ m_DataFormatTranslator.getFormatEtcForClipformatName( htmlFormat ) );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatRegistrar::hasSynthesizedLocale( ) const
+{
+ return m_bHasSynthesizedLocale;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+LCID SAL_CALL CFormatRegistrar::getSynthesizedLocale( ) const
+{
+ return m_TxtLocale;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_uInt32 SAL_CALL CFormatRegistrar::getRegisteredTextCodePage( ) const
+{
+ return m_TxtCodePage;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+DataFlavor SAL_CALL CFormatRegistrar::getRegisteredTextFlavor( ) const
+{
+ return m_RegisteredTextFlavor;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatRegistrar::isSynthesizeableFormat( const CFormatEtc& aFormatEtc ) const
+{
+ return ( m_DataFormatTranslator.isOemOrAnsiTextFormat( aFormatEtc.getClipformat() ) ||
+ m_DataFormatTranslator.isUnicodeTextFormat( aFormatEtc.getClipformat() ) ||
+ m_DataFormatTranslator.isHTMLFormat( aFormatEtc.getClipformat() ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+sal_Bool SAL_CALL CFormatRegistrar::needsToSynthesizeAccompanyFormats( const CFormatEtc& aFormatEtc ) const
+{
+ return ( m_DataFormatTranslator.isOemOrAnsiTextFormat( aFormatEtc.getClipformat() ) ||
+ m_DataFormatTranslator.isUnicodeTextFormat( aFormatEtc.getClipformat() ) ||
+ m_DataFormatTranslator.isTextHtmlFormat( aFormatEtc.getClipformat( ) ) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+OUString SAL_CALL CFormatRegistrar::getCharsetFromDataFlavor( const DataFlavor& aFlavor )
+{
+ OUString charset;
+
+ try
+ {
+ Reference< XMimeContentTypeFactory > xMimeFac(
+ m_SrvMgr->createInstance( OUString::createFromAscii( \
+ "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY );
+
+ if( xMimeFac.is( ) )
+ {
+ Reference< XMimeContentType > xMimeType( xMimeFac->createMimeContentType( aFlavor.MimeType ) );
+ if ( xMimeType->hasParameter( TEXTPLAIN_PARAM_CHARSET ) )
+ charset = xMimeType->getParameterValue( TEXTPLAIN_PARAM_CHARSET );
+ else
+ charset = getMimeCharsetFromWinCP( GetACP( ), PRE_WINDOWS_CODEPAGE );
+ }
+ }
+ catch(NoSuchElementException&)
+ {
+ OSL_ENSURE( sal_False, "Unexpected" );
+ }
+ catch(...)
+ {
+ OSL_ENSURE( sal_False, "Invalid data flavor" );
+ }
+
+ return charset;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatRegistrar::hasUnicodeFlavor( const Reference< XTransferable >& aXTransferable ) const
+{
+ CFormatEtc fetc( CF_UNICODETEXT );
+
+ DataFlavor aFlavor =
+ m_DataFormatTranslator.getDataFlavorFromFormatEtc( fetc );
+
+ return aXTransferable->isDataFlavorSupported( aFlavor );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+sal_Bool CFormatRegistrar::isEqualCurrentSystemCodePage( sal_uInt32 aCodePage ) const
+{
+ return ( (aCodePage == GetOEMCP()) || (aCodePage == GetACP()) );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatRegistrar::findLocaleForTextCodePage( )
+{
+ m_TxtLocale = 0;
+ EnumSystemLocalesA( CFormatRegistrar::EnumLocalesProc, LCID_INSTALLED );
+ return ( IsValidLocale( m_TxtLocale, LCID_INSTALLED ) ) ? sal_True : sal_False;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CFormatRegistrar::isLocaleCodePage( LCID lcid, LCTYPE lctype, sal_uInt32 codepage )
+{
+ char buff[6];
+ sal_uInt32 localeCodePage;
+
+ OSL_ASSERT( IsValidLocale( lcid, LCID_INSTALLED ) );
+
+ // get the ansi codepage of the current locale
+ GetLocaleInfoA( lcid, lctype, buff, sizeof( buff ) );
+ localeCodePage = atol( buff );
+
+ return ( localeCodePage == codepage );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+sal_Bool SAL_CALL CFormatRegistrar::isLocaleOemCodePage( LCID lcid, sal_uInt32 codepage )
+{
+ return isLocaleCodePage( lcid, LOCALE_IDEFAULTCODEPAGE, codepage );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+sal_Bool SAL_CALL CFormatRegistrar::isLocaleAnsiCodePage( LCID lcid, sal_uInt32 codepage )
+{
+ return isLocaleCodePage( lcid, LOCALE_IDEFAULTANSICODEPAGE, codepage );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+BOOL CALLBACK CFormatRegistrar::EnumLocalesProc( LPSTR lpLocaleStr )
+{
+ // the lpLocaleStr parametere is hexadecimal
+ LCID lcid = strtol( lpLocaleStr, NULL, 16 );
+
+ if ( isLocaleAnsiCodePage( lcid, CFormatRegistrar::m_TxtCodePage ) ||
+ isLocaleOemCodePage( lcid, CFormatRegistrar::m_TxtCodePage ) )
+ {
+ CFormatRegistrar::m_TxtLocale = lcid;
+ return sal_False; // stop enumerating
+ }
+
+ return sal_True;
+}
+
diff --git a/dtrans/source/win32/dtobj/FetcList.hxx b/dtrans/source/win32/dtobj/FetcList.hxx
new file mode 100644
index 000000000000..c5105a8662b6
--- /dev/null
+++ b/dtrans/source/win32/dtobj/FetcList.hxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _FETCLIST_HXX_
+#define _FETCLIST_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <sal/types.h>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include "Fetc.hxx"
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <vector>
+
+/*****************************************************************
+ a simple container for FORMATECT structures
+ instances of this class are not thread-safe
+*****************************************************************/
+
+class CFormatEtcContainer
+{
+public:
+ CFormatEtcContainer( );
+
+ // duplicates not allowed
+ void SAL_CALL addFormatEtc( const CFormatEtc& fetc );
+
+ // removes the specified formatetc
+ void SAL_CALL removeFormatEtc( const CFormatEtc& fetc );
+
+ // removes the formatetc at pos
+ void SAL_CALL removeAllFormatEtc( );
+
+ sal_Bool SAL_CALL hasFormatEtc( const CFormatEtc& fetc ) const;
+
+ sal_Bool SAL_CALL hasElements( ) const;
+
+ // begin enumeration
+ void SAL_CALL beginEnumFormatEtc( );
+
+ // copies the specified number of formatetc structures starting
+ // at the current enum position
+ // the return value is the number of copied elements; if the
+ // current enum position is at the end the return value is 0
+ sal_uInt32 SAL_CALL nextFormatEtc( LPFORMATETC lpFetc, sal_uInt32 aNum = 1 );
+
+ // skips the specified number of elements in the container
+ sal_Bool SAL_CALL skipFormatEtc( sal_uInt32 aNum );
+
+protected:
+ typedef std::vector< CFormatEtc > FormatEtcMap_t;
+
+private:
+ FormatEtcMap_t m_FormatMap;
+ FormatEtcMap_t::iterator m_EnumIterator;
+};
+
+/*****************************************************************
+ a helper class which converts data flavors to clipformats,
+ creates an appropriate formatetc structures and if possible
+ synthesizes clipboard formats if necessary, e.g. if text
+ is provided a locale will also be provided;
+ the class registers the formatetc within a CFormatEtcContainer
+
+ instances of this class are not thread-safe and multiple
+ instances of this class would use the same static variables
+ that's why this class should not be used by multiple threads,
+ only one thread of a process should use it
+*****************************************************************/
+
+// forward
+class CDataFormatTranslator;
+
+class CFormatRegistrar
+{
+public:
+ CFormatRegistrar( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager,
+ const CDataFormatTranslator& aDataFormatTranslator );
+
+ void SAL_CALL RegisterFormats( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable,
+ CFormatEtcContainer& aFormatEtcContainer );
+
+ sal_Bool SAL_CALL hasSynthesizedLocale( ) const;
+ LCID SAL_CALL getSynthesizedLocale( ) const;
+ sal_uInt32 SAL_CALL getRegisteredTextCodePage( ) const;
+ com::sun::star::datatransfer::DataFlavor SAL_CALL getRegisteredTextFlavor( ) const;
+
+ sal_Bool SAL_CALL isSynthesizeableFormat( const CFormatEtc& aFormatEtc ) const;
+ sal_Bool SAL_CALL needsToSynthesizeAccompanyFormats( const CFormatEtc& aFormatEtc ) const;
+
+private:
+ sal_Bool SAL_CALL isEqualCurrentSystemCodePage( sal_uInt32 aCodePage ) const;
+ rtl::OUString SAL_CALL getCharsetFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aFlavor );
+
+ sal_Bool SAL_CALL hasUnicodeFlavor(
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable ) const;
+
+ sal_Bool SAL_CALL findLocaleForTextCodePage( );
+
+ static sal_Bool SAL_CALL isLocaleOemCodePage( LCID lcid, sal_uInt32 codepage );
+ static sal_Bool SAL_CALL isLocaleAnsiCodePage( LCID lcid, sal_uInt32 codepage );
+ static sal_Bool SAL_CALL isLocaleCodePage( LCID lcid, LCTYPE lctype, sal_uInt32 codepage );
+
+ static BOOL CALLBACK EnumLocalesProc( LPSTR lpLocaleStr );
+
+private:
+ const CDataFormatTranslator& m_DataFormatTranslator;
+ sal_Bool m_bHasSynthesizedLocale;
+ com::sun::star::datatransfer::DataFlavor m_RegisteredTextFlavor;
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr;
+
+ static LCID m_TxtLocale;
+ static sal_uInt32 m_TxtCodePage;
+
+private:
+ CFormatRegistrar( const CFormatRegistrar& );
+ CFormatRegistrar& operator=( const CFormatRegistrar& );
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/FmtFilter.cxx b/dtrans/source/win32/dtobj/FmtFilter.cxx
new file mode 100644
index 000000000000..c8a8743647a9
--- /dev/null
+++ b/dtrans/source/win32/dtobj/FmtFilter.cxx
@@ -0,0 +1,536 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+#include "FmtFilter.hxx"
+#include <osl/diagnose.h>
+#include <comphelper/sequence.hxx>
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#pragma warning(disable:4917)
+#endif
+#include <Shobjidl.h>
+#include <shlguid.h>
+#include <ObjIdl.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <iomanip>
+
+#include <systools/win32/comtools.hxx>
+
+using namespace com::sun::star::uno;
+using rtl::OString;
+
+#pragma pack(2)
+struct METAFILEHEADER
+{
+ DWORD key;
+ short hmf;
+ SMALL_RECT bbox;
+ WORD inch;
+ DWORD reserved;
+ WORD checksum;
+};
+#pragma pack()
+
+//------------------------------------------------------------------------
+// convert a windows metafile picture to a openoffice metafile picture
+//------------------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( Sequence< sal_Int8 >& aMetaFilePict )
+{
+ OSL_ASSERT( aMetaFilePict.getLength( ) == sizeof( METAFILEPICT ) );
+
+ Sequence< sal_Int8 > mfpictStream;
+ METAFILEPICT* pMFPict = reinterpret_cast< METAFILEPICT* >( aMetaFilePict.getArray( ) );
+ HMETAFILE hMf = pMFPict->hMF;
+ sal_uInt32 nCount = GetMetaFileBitsEx( hMf, 0, NULL );
+
+ if ( nCount > 0 )
+ {
+ mfpictStream.realloc( nCount + sizeof( METAFILEHEADER ) );
+
+ METAFILEHEADER* pMFHeader = reinterpret_cast< METAFILEHEADER* >( mfpictStream.getArray( ) );
+ SMALL_RECT aRect = { 0,
+ 0,
+ static_cast< short >( pMFPict->xExt ),
+ static_cast< short >( pMFPict->yExt ) };
+ USHORT nInch;
+
+ switch( pMFPict->mm )
+ {
+ case MM_TEXT:
+ nInch = 72;
+ break;
+
+ case MM_LOMETRIC:
+ nInch = 100;
+ break;
+
+ case MM_HIMETRIC:
+ nInch = 1000;
+ break;
+
+ case MM_LOENGLISH:
+ nInch = 254;
+ break;
+
+ case MM_HIENGLISH:
+ case MM_ISOTROPIC:
+ case MM_ANISOTROPIC:
+ nInch = 2540;
+ break;
+
+ case MM_TWIPS:
+ nInch = 1440;
+ break;
+
+ default:
+ nInch = 576;
+ }
+
+ pMFHeader->key = 0x9AC6CDD7L;
+ pMFHeader->hmf = 0;
+ pMFHeader->bbox = aRect;
+ pMFHeader->inch = nInch;
+ pMFHeader->reserved = 0;
+ pMFHeader->checksum = 0;
+
+ char* pMFBuff = reinterpret_cast< char* >( mfpictStream.getArray( ) );
+
+ nCount = GetMetaFileBitsEx( pMFPict->hMF, nCount, pMFBuff + sizeof( METAFILEHEADER ) );
+ OSL_ASSERT( nCount > 0 );
+ }
+
+ return mfpictStream;
+}
+
+//-------------------------------------------------------------
+// convert a windows enhanced metafile to a openoffice metafile
+//-------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL WinENHMFPictToOOMFPict( HENHMETAFILE hEnhMetaFile )
+{
+ Sequence< sal_Int8 > aRet;
+ UINT nSize = 0;
+
+ if( hEnhMetaFile &&
+ ( ( nSize = GetEnhMetaFileBits( hEnhMetaFile, 0, NULL ) ) != 0 ) )
+ {
+ aRet.realloc( nSize );
+
+ if( GetEnhMetaFileBits( hEnhMetaFile, nSize, (sal_uChar*) aRet.getArray() ) != nSize )
+ aRet.realloc( 0 );
+ }
+
+ return aRet;
+}
+
+//------------------------------------------------------------------------
+// convert a openoffice metafile picture to a windows metafile picture
+//------------------------------------------------------------------------
+
+HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( Sequence< sal_Int8 >& aOOMetaFilePict )
+{
+ HMETAFILEPICT hPict = NULL;
+ HMETAFILE hMtf = SetMetaFileBitsEx( aOOMetaFilePict.getLength(), (sal_uChar*) aOOMetaFilePict.getConstArray() );
+
+ if( hMtf )
+ {
+ METAFILEPICT* pPict = (METAFILEPICT*) GlobalLock( hPict = GlobalAlloc( GHND, sizeof( METAFILEPICT ) ) );
+
+ pPict->mm = 8;
+ pPict->xExt = 0;
+ pPict->yExt = 0;
+ pPict->hMF = hMtf;
+
+ GlobalUnlock( hPict );
+ }
+
+ return hPict;
+}
+
+//-----------------------------------------------------------------------------
+// convert a openoffice metafile picture to a windows enhanced metafile picture
+//-----------------------------------------------------------------------------
+
+HENHMETAFILE SAL_CALL OOMFPictToWinENHMFPict( Sequence< sal_Int8 >& aOOMetaFilePict )
+{
+ HENHMETAFILE hEnhMtf = SetEnhMetaFileBits( aOOMetaFilePict.getLength(), (sal_uChar*) aOOMetaFilePict.getConstArray() );
+
+ return hEnhMtf;
+}
+
+//------------------------------------------------------------------------
+// convert a windows device independent bitmap into a openoffice bitmap
+//------------------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB )
+{
+ OSL_ASSERT( aWinDIB.getLength( ) > sizeof( BITMAPINFOHEADER ) );
+
+ Sequence< sal_Int8 > ooBmpStream;
+
+ ooBmpStream.realloc( aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER) );
+
+ const BITMAPINFOHEADER *pBmpInfoHdr = (const BITMAPINFOHEADER*)aWinDIB.getConstArray();
+ BITMAPFILEHEADER *pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >( ooBmpStream.getArray() );
+ DWORD nOffset = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
+
+ rtl_copyMemory( pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength( ) );
+
+ if( pBmpInfoHdr->biBitCount <= 8 )
+ nOffset += ( pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : ( 1 << pBmpInfoHdr->biBitCount ) ) << 2;
+ else if( ( BI_BITFIELDS == pBmpInfoHdr->biCompression ) && ( ( 16 == pBmpInfoHdr->biBitCount ) || ( 32 == pBmpInfoHdr->biBitCount ) ) )
+ nOffset += 12;
+
+ pBmpFileHdr->bfType = 'MB';
+ pBmpFileHdr->bfSize = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER)
+ pBmpFileHdr->bfReserved1 = 0;
+ pBmpFileHdr->bfReserved2 = 0;
+ pBmpFileHdr->bfOffBits = nOffset;
+
+ return ooBmpStream;
+}
+
+//------------------------------------------------------------------------
+// convert a openoffice bitmap into a windows device independent bitmap
+//------------------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( Sequence< sal_Int8 >& aOOBmp )
+{
+ OSL_ASSERT( aOOBmp.getLength( ) >
+ ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ) );
+
+ Sequence< sal_Int8 > winDIBStream( aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );
+
+ rtl_copyMemory( winDIBStream.getArray( ),
+ aOOBmp.getArray( ) + sizeof( BITMAPFILEHEADER ),
+ aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) );
+
+ return winDIBStream;
+}
+
+//------------------------------------------------------------------------------
+// converts the openoffice text/html clipboard format to the HTML Format
+// well known under MS Windows
+// the MS HTML Format has a header before the real html data
+//
+// Version:1.0 Version number of the clipboard. Staring is 0.9
+// StartHTML: Byte count from the beginning of the clipboard to the start
+// of the context, or -1 if no context
+// EndHTML: Byte count from the beginning of the clipboard to the end
+// of the context, or -1 if no context
+// StartFragment: Byte count from the beginning of the clipboard to the
+// start of the fragment
+// EndFragment: Byte count from the beginning of the clipboard to the
+// end of the fragment
+// StartSelection: Byte count from the beginning of the clipboard to the
+// start of the selection
+// EndSelection: Byte count from the beginning of the clipboard to the
+// end of the selection
+//
+// StartSelection and EndSelection are optional
+// The fragment should be preceded and followed by the HTML comments
+// <!--StartFragment--> and <!--EndFragment--> (no space between !-- and the
+// text
+//------------------------------------------------------------------------------
+/*
+Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( Sequence< sal_Int8 >& aTextHtml )
+{
+ OSL_ASSERT( aTextHtml.getLength( ) > 0 );
+
+ // check parameter
+ if ( !(aTextHtml.getLength( ) > 0) )
+ return Sequence< sal_Int8 >( );
+
+ // we create a buffer with the approximated size of
+ // the HTML Format header
+ char aHTMLFmtHdr[120];
+
+ rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );
+
+ // fill the buffer with dummy values to calc the
+ // exact length
+
+ wsprintf(
+ aHTMLFmtHdr,
+ "Version:1.0\nStartHTML:%010d\r\nnEndHTML:%010d\r\nStartFragment:%010\r\nnEndFragment:%010d\r\n", 0, 0, 0, 0 );
+
+ sal_uInt32 lHTMLFmtHdr = rtl_str_getLength( aHTMLFmtHdr );
+
+ // the office allways writes the start
+ // and end html tag in upper cases and
+ // without spaces
+ // both tags don't allow parameters
+ OString startHtmlTag( "<HTML>" );
+ OString endHtmlTag( "</HTML>" );
+
+ // we don't include '>' into the search
+ // because the body tag allows parameters
+ // e.g. <BODY param>
+ // #92840#
+ OString startBodyTag( "<BODY" );
+ OString endBodyTag( "</BODY" );
+
+ OString textHtml(
+ reinterpret_cast< const sal_Char* >( aTextHtml.getConstArray( ) ),
+ aTextHtml.getLength( ) );
+
+ sal_Int32 nStartHtml = textHtml.indexOf( startHtmlTag );
+ sal_Int32 nEndHtml = textHtml.indexOf( endHtmlTag );
+ sal_Int32 nStartFrgmt = textHtml.indexOf( startBodyTag );
+ sal_Int32 nEndFrgmt = textHtml.indexOf( endBodyTag );
+
+ OSL_ASSERT( (nStartHtml >= 0) && (nEndHtml > nStartHtml) && (nStartFrgmt > nStartHtml) && (nEndFrgmt > nStartFrgmt) );
+
+ Sequence< sal_Int8 > aHTMLFmtSequence;
+
+ if ( (nStartHtml > -1) && (nEndHtml > -1) && (nStartFrgmt > -1) && (nEndFrgmt > -1) )
+ {
+ nStartHtml = nStartHtml + lHTMLFmtHdr - 1; // we start one before <HTML> Word 2000 does also so
+ nEndHtml = nEndHtml + lHTMLFmtHdr + endHtmlTag.getLength( ) + 1; // our SOffice 5.2 wants 2 behind </HTML>?
+ nStartFrgmt = nStartFrgmt + startBodyTag.getLength( ) + lHTMLFmtHdr; // after the <BODY> tag
+ nEndFrgmt = nEndFrgmt + lHTMLFmtHdr;
+
+ // fill the html header
+ rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) );
+
+ wsprintf(
+ aHTMLFmtHdr,
+ "Version:1.0\nStartHTML:%010d\r\nEndHTML:%010d\r\nStartFragment:%010d\r\nEndFragment:%010d\r\n",
+ nStartHtml, nEndHtml, nStartFrgmt, nEndFrgmt );
+
+ // we add space for a trailing \0
+ aHTMLFmtSequence.realloc( lHTMLFmtHdr + aTextHtml.getLength( ) + 1 );
+ rtl_zeroMemory( aHTMLFmtSequence.getArray( ), aHTMLFmtSequence.getLength( ) );
+
+ // copy the HTML Format header
+ rtl_copyMemory(
+ static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) ),
+ static_cast< LPVOID >( aHTMLFmtHdr ), lHTMLFmtHdr );
+
+ // concat the text/html
+ rtl_copyMemory(
+ static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) + lHTMLFmtHdr ),
+ static_cast< LPVOID >( aTextHtml.getArray( ) ),
+ aTextHtml.getLength( ) );
+ }
+
+ return aHTMLFmtSequence;
+}
+*/
+
+std::string GetHtmlFormatHeader(size_t startHtml, size_t endHtml, size_t startFragment, size_t endFragment)
+{
+ std::ostringstream htmlHeader;
+ htmlHeader << "Version:1.0" << '\r' << '\n';
+ htmlHeader << "StartHTML:" << std::setw(10) << std::setfill('0') << std::dec << startHtml << '\r' << '\n';
+ htmlHeader << "EndHTML:" << std::setw(10) << std::setfill('0') << std::dec << endHtml << '\r' << '\n';
+ htmlHeader << "StartFragment:" << std::setw(10) << std::setfill('0') << std::dec << startFragment << '\r' << '\n';
+ htmlHeader << "EndFragment:" << std::setw(10) << std::setfill('0') << std::dec << endFragment << '\r' << '\n';
+ return htmlHeader.str();
+}
+
+// the office allways writes the start and end html tag in upper cases and
+// without spaces both tags don't allow parameters
+const std::string TAG_HTML = std::string("<HTML>");
+const std::string TAG_END_HTML = std::string("</HTML>");
+
+// The body tag may have parameters so we need to search for the
+// closing '>' manually e.g. <BODY param> #92840#
+const std::string TAG_BODY = std::string("<BODY");
+const std::string TAG_END_BODY = std::string("</BODY");
+
+Sequence<sal_Int8> SAL_CALL TextHtmlToHTMLFormat(Sequence<sal_Int8>& aTextHtml)
+{
+ OSL_ASSERT(aTextHtml.getLength() > 0);
+
+ if (!(aTextHtml.getLength() > 0))
+ return Sequence<sal_Int8>();
+
+ // fill the buffer with dummy values to calc the exact length
+ std::string dummyHtmlHeader = GetHtmlFormatHeader(0, 0, 0, 0);
+ size_t lHtmlFormatHeader = dummyHtmlHeader.length();
+
+ std::string textHtml(
+ reinterpret_cast<const sal_Char*>(aTextHtml.getConstArray()),
+ reinterpret_cast<const sal_Char*>(aTextHtml.getConstArray()) + aTextHtml.getLength());
+
+ std::string::size_type nStartHtml = textHtml.find(TAG_HTML) + lHtmlFormatHeader - 1; // we start one before '<HTML>' Word 2000 does also so
+ std::string::size_type nEndHtml = textHtml.find(TAG_END_HTML) + lHtmlFormatHeader + TAG_END_HTML.length() + 1; // our SOffice 5.2 wants 2 behind </HTML>?
+
+ // The body tag may have parameters so we need to search for the
+ // closing '>' manually e.g. <BODY param> #92840#
+ std::string::size_type nStartFragment = textHtml.find(">", textHtml.find(TAG_BODY)) + lHtmlFormatHeader + 1;
+ std::string::size_type nEndFragment = textHtml.find(TAG_END_BODY) + lHtmlFormatHeader;
+
+ std::string htmlFormat = GetHtmlFormatHeader(nStartHtml, nEndHtml, nStartFragment, nEndFragment);
+ htmlFormat += textHtml;
+
+ Sequence<sal_Int8> byteSequence(htmlFormat.length() + 1); // space the trailing '\0'
+ rtl_zeroMemory(byteSequence.getArray(), byteSequence.getLength());
+
+ rtl_copyMemory(
+ static_cast<void*>(byteSequence.getArray()),
+ static_cast<const void*>(htmlFormat.c_str()),
+ htmlFormat.length());
+
+ return byteSequence;
+}
+
+std::wstring getFileExtension(const std::wstring& aFilename)
+{
+ std::wstring::size_type idx = aFilename.rfind(L".");
+ if ((idx != std::wstring::npos))
+ {
+ return std::wstring(aFilename, idx);
+ }
+ return std::wstring();
+}
+
+const std::wstring SHELL_LINK_FILE_EXTENSION = L".lnk";
+
+bool isShellLink(const std::wstring& aFilename)
+{
+ std::wstring ext = getFileExtension(aFilename);
+ return (_wcsicmp(ext.c_str(), SHELL_LINK_FILE_EXTENSION.c_str()) == 0);
+}
+
+/** Resolve a Windows Shell Link (lnk) file. If a resolution
+ is not possible simply return the provided name of the
+ lnk file. */
+std::wstring getShellLinkTarget(const std::wstring& aLnkFile)
+{
+ OSL_ASSERT(isShellLink(aLnkFile));
+
+ std::wstring target = aLnkFile;
+
+ try
+ {
+ sal::systools::COMReference<IShellLinkA> pIShellLink;
+ HRESULT hr = CoCreateInstance(
+ CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast<LPVOID*>(&pIShellLink));
+ if (FAILED(hr))
+ return target;
+
+ sal::systools::COMReference<IPersistFile> pIPersistFile =
+ pIShellLink.QueryInterface<IPersistFile>(IID_IPersistFile);
+
+ hr = pIPersistFile->Load(aLnkFile.c_str(), STGM_READ);
+ if (FAILED(hr))
+ return target;
+
+ hr = pIShellLink->Resolve(NULL, SLR_UPDATE | SLR_NO_UI);
+ if (FAILED(hr))
+ return target;
+
+ char pathA[MAX_PATH];
+ WIN32_FIND_DATA wfd;
+ hr = pIShellLink->GetPath(pathA, MAX_PATH, &wfd, SLGP_RAWPATH);
+ if (FAILED(hr))
+ return target;
+
+ wchar_t pathW[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, pathA, -1, pathW, MAX_PATH);
+ target = pathW;
+ }
+ catch(sal::systools::ComError& ex)
+ {
+ OSL_ENSURE(false, ex.what());
+ ex = ex;
+ }
+ return target;
+}
+
+typedef std::vector<std::wstring> FileList_t;
+typedef FileList_t::value_type FileList_ValueType_t;
+typedef Sequence<sal_Int8> ByteSequence_t;
+
+/* Calculate the size required for turning a string list into
+ a double '\0' terminated string buffer */
+size_t CalcSizeForStringListBuffer(const FileList_t& fileList)
+{
+ if (fileList.size() == 0)
+ return 0;
+
+ size_t size = 1; // one for the very final '\0'
+ FileList_t::const_iterator iter_end = fileList.end();
+ for (FileList_t::const_iterator iter = fileList.begin(); iter != iter_end; ++iter)
+ {
+ size += iter->length() + 1; // length including terminating '\0'
+ }
+ return (size * sizeof(FileList_ValueType_t::value_type));
+}
+
+ByteSequence_t FileListToByteSequence(const FileList_t& fileList)
+{
+ ByteSequence_t bseq;
+ size_t size = CalcSizeForStringListBuffer(fileList);
+
+ if (size > 0)
+ {
+ bseq.realloc(size);
+ wchar_t* p = reinterpret_cast<wchar_t*>(bseq.getArray());
+ ZeroMemory(p, size);
+
+ FileList_t::const_iterator iter;
+ FileList_t::const_iterator iter_end = fileList.end();
+ for (iter = fileList.begin(); iter != iter_end; ++iter)
+ {
+ wcsncpy(p, iter->c_str(), iter->length());
+ p += (iter->length() + 1);
+ }
+ }
+ return bseq;
+}
+
+ByteSequence_t CF_HDROPToFileList(HGLOBAL hGlobal)
+{
+ UINT nFiles = DragQueryFileW((HDROP)hGlobal, 0xFFFFFFFF, NULL, 0);
+ FileList_t files;
+
+ for (UINT i = 0; i < nFiles; i++)
+ {
+ wchar_t buff[MAX_PATH];
+ /*UINT size =*/ DragQueryFileW((HDROP)hGlobal, i, buff, MAX_PATH);
+ std::wstring filename = buff;
+ if (isShellLink(filename))
+ filename = getShellLinkTarget(filename);
+ files.push_back(filename);
+ }
+ return FileListToByteSequence(files);
+}
+
diff --git a/dtrans/source/win32/dtobj/FmtFilter.hxx b/dtrans/source/win32/dtobj/FmtFilter.hxx
new file mode 100644
index 000000000000..3f433561a3b1
--- /dev/null
+++ b/dtrans/source/win32/dtobj/FmtFilter.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _FMTFILTER_HXX_
+#define _FMTFILTER_HXX_
+
+#include <sal/types.h>
+
+#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
+#include <com/sun/star/uno/Sequence.hxx>
+#endif
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+/*------------------------------------------------------------------------
+ input:
+ aMetaFilePict - a sequence of bytes containing a METAFILEPICT struct
+------------------------------------------------------------------------*/
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aMetaFilePict );
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinENHMFPictToOOMFPict( HENHMETAFILE hEnhMetaFile );
+
+/*------------------------------------------------------------------------
+ input:
+ aByteStream - a sequence of bytes containing a openoffice metafile
+ picture with a leading METAFILEHEADER
+------------------------------------------------------------------------*/
+HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aOOMetaFilePict );
+HENHMETAFILE SAL_CALL OOMFPictToWinENHMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aOOMetaFilePict );
+
+/*------------------------------------------------------------------------
+ input:
+ aWinDIB - sequence of bytes containing a windows device independent
+ bitmap
+------------------------------------------------------------------------*/
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const com::sun::star::uno::Sequence< sal_Int8 >& aWinDIB );
+
+/*------------------------------------------------------------------------
+ input:
+ aOOBmp - sequence of bytes containing a openoffice bitmap
+------------------------------------------------------------------------*/
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( com::sun::star::uno::Sequence< sal_Int8 >& aOOBmp );
+
+/*------------------------------------------------------------------------
+ input:
+ aTextHtml - a sequence of text/html which will be converted to the
+ HTML Format; the HTML Format has header before the real html data
+ the Format is described in the MSDN Library under HTML Clipboard
+ Format
+------------------------------------------------------------------------*/
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( com::sun::star::uno::Sequence< sal_Int8 >& aTextHtml );
+
+/**
+ Return a FileList in which Windows Shell Links (lnk) are resolved.
+ If for what ever reason a resolution is not possible leave the
+ original lnk file.
+*/
+com::sun::star::uno::Sequence< sal_Int8 > CF_HDROPToFileList(HGLOBAL hGlobal);
+
+#endif
diff --git a/dtrans/source/win32/dtobj/MimeAttrib.hxx b/dtrans/source/win32/dtobj/MimeAttrib.hxx
new file mode 100644
index 000000000000..7bd631cc79d5
--- /dev/null
+++ b/dtrans/source/win32/dtobj/MimeAttrib.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _MIMEATTRIB_HXX_
+#define _MIMEATTRIB_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <rtl/ustring.hxx>
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+const rtl::OUString TEXTPLAIN_PARAM_CHARSET = rtl::OUString::createFromAscii( "charset" );
+
+const rtl::OUString PRE_WINDOWS_CODEPAGE = rtl::OUString::createFromAscii( "windows" );
+const rtl::OUString PRE_OEM_CODEPAGE = rtl::OUString::createFromAscii( "cp" );
+const rtl::OUString CHARSET_UTF16 = rtl::OUString::createFromAscii( "utf-16" );
+const rtl::OUString CHARSET_UNICODE = rtl::OUString::createFromAscii( "unicode" );
+
+
+#endif
diff --git a/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx b/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx
new file mode 100644
index 000000000000..3eecad271567
--- /dev/null
+++ b/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <osl/diagnose.h>
+#include "TxtCnvtHlp.hxx"
+#include "DTransHelper.hxx"
+#include "..\misc\ImplHelper.hxx"
+
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------
+// assuming a '\0' terminated string if no length specified
+//------------------------------------------------------------------
+
+int CalcBuffSizeForTextConversion( UINT code_page, LPCSTR lpMultiByteString, int nLen = -1 )
+{
+ return ( MultiByteToWideChar( code_page,
+ 0,
+ lpMultiByteString,
+ nLen,
+ NULL,
+ 0 ) * sizeof( sal_Unicode ) );
+}
+
+//------------------------------------------------------------------
+// assuming a '\0' terminated string if no length specified
+//------------------------------------------------------------------
+
+int CalcBuffSizeForTextConversion( UINT code_page, LPCWSTR lpWideCharString, int nLen = -1 )
+{
+ return WideCharToMultiByte( code_page,
+ 0,
+ lpWideCharString,
+ nLen,
+ NULL,
+ 0,
+ NULL,
+ NULL );
+}
+
+//------------------------------------------------------------------
+// converts text in one code page into unicode text
+// automatically calculates the necessary buffer size and allocates
+// the buffer
+//------------------------------------------------------------------
+
+int MultiByteToWideCharEx( UINT cp_src,
+ LPCSTR lpMultiByteString,
+ sal_uInt32 lenStr,
+ CStgTransferHelper& refDTransHelper,
+ BOOL bEnsureTrailingZero )
+{
+ OSL_ASSERT( IsValidCodePage( cp_src ) );
+ OSL_ASSERT( NULL != lpMultiByteString );
+
+ // calculate the required buff size
+ int reqSize = CalcBuffSizeForTextConversion( cp_src, lpMultiByteString, lenStr );
+
+ if ( bEnsureTrailingZero )
+ reqSize += sizeof( sal_Unicode );
+
+ // initialize the data-transfer helper
+ refDTransHelper.init( reqSize );
+
+ // setup a global memory pointer
+ CRawHGlobalPtr ptrHGlob( refDTransHelper );
+
+ // do the converssion an return
+ return MultiByteToWideChar( cp_src,
+ 0,
+ lpMultiByteString,
+ lenStr,
+ static_cast< LPWSTR >( ptrHGlob.GetMemPtr( ) ),
+ ptrHGlob.MemSize( ) );
+}
+
+//------------------------------------------------------------------
+// converts unicode text into text of the specified code page
+// automatically calculates the necessary buffer size and allocates
+// the buffer
+//------------------------------------------------------------------
+
+int WideCharToMultiByteEx( UINT cp_dest,
+ LPCWSTR lpWideCharString,
+ sal_uInt32 lenStr,
+ CStgTransferHelper& refDTransHelper,
+ BOOL bEnsureTrailingZero )
+{
+ OSL_ASSERT( IsValidCodePage( cp_dest ) );
+ OSL_ASSERT( NULL != lpWideCharString );
+
+ // calculate the required buff size
+ int reqSize = CalcBuffSizeForTextConversion( cp_dest, lpWideCharString, lenStr );
+
+ if ( bEnsureTrailingZero )
+ reqSize += sizeof( sal_Int8 );
+
+ // initialize the data-transfer helper
+ refDTransHelper.init( reqSize );
+
+ // setup a global memory pointer
+ CRawHGlobalPtr ptrHGlob( refDTransHelper );
+
+ // do the converssion an return
+ return WideCharToMultiByte( cp_dest,
+ 0,
+ lpWideCharString,
+ lenStr,
+ static_cast< LPSTR >( ptrHGlob.GetMemPtr( ) ),
+ ptrHGlob.MemSize( ),
+ NULL,
+ NULL );
+}
+
diff --git a/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx b/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx
new file mode 100644
index 000000000000..a4d59a69284e
--- /dev/null
+++ b/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _TXTCNVTHLP_HXX_
+#define _TXTCNVTHLP_HXX_
+
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+
+#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HPP_
+#include <com/sun/star/uno/Sequence.h>
+#endif
+#include "DTransHelper.hxx"
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+int MultiByteToWideCharEx( UINT cp_src,
+ LPCSTR lpMultiByteString,
+ sal_uInt32 lenStr,
+ CStgTransferHelper& refDTransHelper,
+ BOOL bEnsureTrailingZero = TRUE );
+
+int WideCharToMultiByteEx( UINT cp_dest,
+ LPCWSTR lpWideCharString,
+ sal_uInt32 lenStr,
+ CStgTransferHelper& refDTransHelper,
+ BOOL bEnsureTrailingZero = TRUE );
+
+#endif
diff --git a/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx b/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx
new file mode 100644
index 000000000000..25e3fab3a702
--- /dev/null
+++ b/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+#include <osl/diagnose.h>
+#include "XNotifyingDataObject.hxx"
+#include "..\clipb\WinClipbImpl.hxx"
+#include "..\clipb\WinClipboard.hxx"
+#include "..\..\inc\DtObjFactory.hxx"
+
+#ifdef __MINGW32__
+#define __uuidof(I) IID_##I
+#endif
+
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::datatransfer::clipboard;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Reference;
+
+
+CXNotifyingDataObject::CXNotifyingDataObject(
+ const IDataObjectPtr& aIDataObject,
+ const Reference< XTransferable >& aXTransferable,
+ const Reference< XClipboardOwner >& aXClipOwner,
+ CWinClipbImpl* theWinClipImpl ) :
+ m_nRefCnt( 0 ),
+ m_aIDataObject( aIDataObject ),
+ m_XTransferable( aXTransferable ),
+ m_XClipboardOwner( aXClipOwner ),
+ m_pWinClipImpl( theWinClipImpl )
+{
+}
+
+STDMETHODIMP CXNotifyingDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+
+ *ppvObject = NULL;
+ if ( ( __uuidof( IUnknown ) == iid ) ||
+ ( __uuidof( IDataObject ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ ( (LPUNKNOWN)*ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+STDMETHODIMP_(ULONG) CXNotifyingDataObject::AddRef( )
+{
+ return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
+}
+
+STDMETHODIMP_(ULONG) CXNotifyingDataObject::Release( )
+{
+ ULONG nRefCnt =
+ static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
+
+ if ( 0 == nRefCnt )
+ {
+ if ( m_pWinClipImpl )
+ m_pWinClipImpl->onReleaseDataObject( this );
+
+ delete this;
+ }
+
+ return nRefCnt;
+}
+
+STDMETHODIMP CXNotifyingDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
+{
+ return m_aIDataObject->GetData(pFormatetc, pmedium);
+}
+
+STDMETHODIMP CXNotifyingDataObject::EnumFormatEtc(
+ DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
+{
+ return m_aIDataObject->EnumFormatEtc(dwDirection, ppenumFormatetc);
+}
+
+STDMETHODIMP CXNotifyingDataObject::QueryGetData( LPFORMATETC pFormatetc )
+{
+ return m_aIDataObject->QueryGetData(pFormatetc);
+}
+
+STDMETHODIMP CXNotifyingDataObject::GetDataHere( LPFORMATETC lpFetc, LPSTGMEDIUM lpStgMedium )
+{
+ return m_aIDataObject->GetDataHere(lpFetc, lpStgMedium);
+}
+
+STDMETHODIMP CXNotifyingDataObject::GetCanonicalFormatEtc( LPFORMATETC lpFetc, LPFORMATETC lpCanonicalFetc )
+{
+ return m_aIDataObject->GetCanonicalFormatEtc(lpFetc, lpCanonicalFetc);
+}
+
+STDMETHODIMP CXNotifyingDataObject::SetData( LPFORMATETC lpFetc, LPSTGMEDIUM lpStgMedium, BOOL bRelease )
+{
+ return m_aIDataObject->SetData( lpFetc, lpStgMedium, bRelease );
+}
+
+STDMETHODIMP CXNotifyingDataObject::DAdvise(
+ LPFORMATETC lpFetc, DWORD advf, LPADVISESINK lpAdvSink, DWORD* pdwConnection )
+{
+ return m_aIDataObject->DAdvise( lpFetc, advf, lpAdvSink, pdwConnection );
+}
+
+STDMETHODIMP CXNotifyingDataObject::DUnadvise( DWORD dwConnection )
+{
+ return m_aIDataObject->DUnadvise( dwConnection );
+}
+
+STDMETHODIMP CXNotifyingDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
+{
+ return m_aIDataObject->EnumDAdvise( ppenumAdvise );
+}
+
+CXNotifyingDataObject::operator IDataObject*( )
+{
+ return static_cast< IDataObject* >( this );
+}
+
+void SAL_CALL CXNotifyingDataObject::lostOwnership( )
+{
+ try
+ {
+ if (m_XClipboardOwner.is())
+ m_XClipboardOwner->lostOwnership(
+ static_cast<XClipboardEx*>(m_pWinClipImpl->m_pWinClipboard ), m_XTransferable);
+ }
+ catch(RuntimeException&)
+ {
+ OSL_ENSURE( sal_False, "RuntimeException caught" );
+ }
+}
diff --git a/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx b/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx
new file mode 100644
index 000000000000..394b835c3612
--- /dev/null
+++ b/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _XNOTIFYINGDATAOBJECT_HXX_
+#define _XNOTIFYINGDATAOBJECT_HXX_
+
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <objidl.h>
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <systools/win32/comtools.hxx>
+
+/*--------------------------------------------------------------------------
+ To implement the lostOwnership mechanism cleanly we need this wrapper
+ object
+----------------------------------------------------------------------------*/
+
+// forward
+class CWinClipbImpl;
+
+class CXNotifyingDataObject : public IDataObject
+{
+public:
+ CXNotifyingDataObject(
+ const IDataObjectPtr& aIDataObject,
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable,
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::clipboard::XClipboardOwner >& aXClipOwner,
+ CWinClipbImpl* theWinClipImpl );
+
+ virtual ~CXNotifyingDataObject() {}
+
+ //-----------------------------------------------------------------
+ // ole interface implementation
+ //-----------------------------------------------------------------
+
+ //IUnknown interface methods
+ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ // IDataObject interface methods
+ STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc );
+ STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut );
+ STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease );
+ STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc );
+ STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection );
+ STDMETHODIMP DUnadvise( DWORD dwConnection );
+ STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise );
+
+ operator IDataObject*( );
+
+private:
+ void SAL_CALL lostOwnership( );
+
+private:
+ sal_Int32 m_nRefCnt;
+ IDataObjectPtr m_aIDataObject;
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > m_XTransferable;
+ const com::sun::star::uno::Reference< com::sun::star::datatransfer::clipboard::XClipboardOwner > m_XClipboardOwner;
+ CWinClipbImpl* m_pWinClipImpl;
+
+ friend class CWinClipbImpl;
+};
+
+#endif
diff --git a/dtrans/source/win32/dtobj/XTDataObject.cxx b/dtrans/source/win32/dtobj/XTDataObject.cxx
new file mode 100644
index 000000000000..e17a931d7380
--- /dev/null
+++ b/dtrans/source/win32/dtobj/XTDataObject.cxx
@@ -0,0 +1,848 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dtrans.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <osl/diagnose.h>
+
+#ifndef _TXDATAOBJECT_HXX_
+#include "XTDataObject.hxx"
+#endif
+#include <com/sun/star/datatransfer/dataflavor.hpp>
+#include "..\misc\ImplHelper.hxx"
+#include "DTransHelper.hxx"
+#include "TxtCnvtHlp.hxx"
+#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
+#include "FmtFilter.hxx"
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#pragma warning(disable:4917)
+#endif
+#include <windows.h>
+#include <shlobj.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#ifdef __MINGW32__
+#define __uuidof(I) IID_##I
+#endif
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::datatransfer::clipboard;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace rtl;
+
+//------------------------------------------------------------------------
+// a helper class that will be thrown by the function validateFormatEtc
+//------------------------------------------------------------------------
+
+class CInvalidFormatEtcException
+{
+public:
+ HRESULT m_hr;
+ CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {};
+};
+
+//------------------------------------------------------------------------
+// ctor
+//------------------------------------------------------------------------
+
+CXTDataObject::CXTDataObject( const Reference< XMultiServiceFactory >& aServiceManager,
+ const Reference< XTransferable >& aXTransferable ) :
+ m_nRefCnt( 0 ),
+ m_SrvMgr( aServiceManager ),
+ m_XTransferable( aXTransferable ),
+ m_DataFormatTranslator( aServiceManager ),
+ m_bFormatEtcContainerInitialized( sal_False ),
+ m_FormatRegistrar( m_SrvMgr, m_DataFormatTranslator )
+{
+}
+
+//------------------------------------------------------------------------
+// IUnknown->QueryInterface
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+
+ *ppvObject = NULL;
+ if ( ( __uuidof( IUnknown ) == iid ) ||
+ ( __uuidof( IDataObject ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ ( (LPUNKNOWN)*ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IUnknown->AddRef
+//------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
+{
+ return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
+}
+
+//------------------------------------------------------------------------
+// IUnknown->Release
+//------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CXTDataObject::Release( )
+{
+ ULONG nRefCnt =
+ static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
+
+ if ( 0 == nRefCnt )
+ delete this;
+
+ return nRefCnt;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
+{
+ if ( !(pFormatetc && pmedium) )
+ return E_INVALIDARG;
+
+ try
+ {
+ // prepare data transfer
+ invalidateStgMedium( *pmedium );
+ validateFormatEtc( pFormatetc );
+
+ // handle locale request, because locale is a artificial format for us
+ if ( CF_LOCALE == pFormatetc->cfFormat )
+ renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium );
+ else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
+ renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium );
+ else
+ renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium );
+ }
+ catch(UnsupportedFlavorException&)
+ {
+ HRESULT hr = DV_E_FORMATETC;
+
+ if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) )
+ hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium );
+
+ return hr;
+ }
+ catch( CInvalidFormatEtcException& ex )
+ {
+ return ex.m_hr;
+ }
+ catch( CStgTransferHelper::CStgTransferException& ex )
+ {
+ return translateStgExceptionCode( ex.m_hr );
+ }
+ catch(...)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+// inline
+void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium(
+ const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize,
+ sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium )
+{
+ OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer),
+ "Memory size less than number of bytes to transfer" );
+
+ CStgTransferHelper stgTransfHelper( AUTO_INIT );
+
+ // setup storage size
+ if ( nInitStgSize > 0 )
+ stgTransfHelper.init( nInitStgSize, GHND );
+
+#if OSL_DEBUG_LEVEL > 0
+ sal_uInt32 nBytesWritten = 0;
+ stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten );
+ OSL_ASSERT( nBytesWritten == nBytesToTransfer );
+#else
+ stgTransfHelper.write( lpStorage, nBytesToTransfer );
+#endif
+
+ setupStgMedium( fetc, stgTransfHelper, stgmedium );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+//inline
+void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium(
+ FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
+ {
+ LCID lcid = m_FormatRegistrar.getSynthesizedLocale( );
+ renderDataAndSetupStgMedium(
+ reinterpret_cast< sal_Int8* >( &lcid ),
+ fetc,
+ 0,
+ sizeof( LCID ),
+ stgmedium );
+ }
+ else
+ throw CInvalidFormatEtcException( DV_E_FORMATETC );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+//inline
+void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium(
+ FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
+
+ Any aAny = m_XTransferable->getTransferData( aFlavor );
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ {
+ OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
+ throw UnsupportedFlavorException( );
+ }
+
+ OUString aText;
+ aAny >>= aText;
+
+ sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode );
+
+ // to be sure there is an ending 0
+ sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode );
+
+ renderDataAndSetupStgMedium(
+ reinterpret_cast< const sal_Int8* >( aText.getStr( ) ),
+ fetc,
+ nRequiredMemSize,
+ nBytesToTransfer,
+ stgmedium );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+//inline
+void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium(
+ FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
+
+ Any aAny = m_XTransferable->getTransferData( aFlavor );
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ {
+ OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
+ throw UnsupportedFlavorException( );
+ }
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ throw UnsupportedFlavorException( );
+
+ Sequence< sal_Int8 > clipDataStream;
+ aAny >>= clipDataStream;
+
+ sal_uInt32 nRequiredMemSize = 0;
+ if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
+ nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1;
+
+ // prepare data for transmision
+ if ( CF_DIB == fetc.cfFormat )
+ clipDataStream = OOBmpToWinDIB( clipDataStream );
+
+ if ( CF_METAFILEPICT == fetc.cfFormat )
+ {
+ stgmedium.tymed = TYMED_MFPICT;
+ stgmedium.hMetaFilePict = OOMFPictToWinMFPict( clipDataStream );
+ stgmedium.pUnkForRelease = NULL;
+ }
+ else if( CF_ENHMETAFILE == fetc.cfFormat )
+ {
+ stgmedium.tymed = TYMED_ENHMF;
+ stgmedium.hMetaFilePict = OOMFPictToWinENHMFPict( clipDataStream );
+ stgmedium.pUnkForRelease = NULL;
+ }
+ else
+ renderDataAndSetupStgMedium(
+ clipDataStream.getArray( ),
+ fetc,
+ nRequiredMemSize,
+ clipDataStream.getLength( ),
+ stgmedium );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ HRESULT hr = S_OK;
+
+ try
+ {
+ if ( CF_UNICODETEXT == fetc.cfFormat )
+ // the transferable seems to have only text
+ renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium );
+ else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
+ // the transferable seems to have only unicode text
+ renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium );
+ else
+ // the transferable seems to have only text/html
+ renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium );
+ }
+ catch(UnsupportedFlavorException&)
+ {
+ hr = DV_E_FORMATETC;
+ }
+ catch( CInvalidFormatEtcException& )
+ {
+ OSL_ENSURE( sal_False, "Unexpected exception" );
+ }
+ catch( CStgTransferHelper::CStgTransferException& ex )
+ {
+ return translateStgExceptionCode( ex.m_hr );
+ }
+ catch(...)
+ {
+ hr = E_UNEXPECTED;
+ }
+
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// the transferable must have only text, so we will synthesize unicode text
+//------------------------------------------------------------------------
+
+void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat );
+
+ Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) );
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ {
+ OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
+ throw UnsupportedFlavorException( );
+ }
+
+ Sequence< sal_Int8 > aText;
+ aAny >>= aText;
+
+ CStgTransferHelper stgTransfHelper;
+
+ MultiByteToWideCharEx(
+ m_FormatRegistrar.getRegisteredTextCodePage( ),
+ reinterpret_cast< char* >( aText.getArray( ) ),
+ aText.getLength( ),
+ stgTransfHelper );
+
+ setupStgMedium( fetc, stgTransfHelper, stgmedium );
+}
+
+//------------------------------------------------------------------------
+// the transferable must have only unicode text so we will sythesize text
+//------------------------------------------------------------------------
+
+void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) );
+
+ DataFlavor aFlavor = formatEtcToDataFlavor(
+ m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
+
+ Any aAny = m_XTransferable->getTransferData( aFlavor );
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ {
+ OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
+ throw UnsupportedFlavorException( );
+ }
+
+ OUString aUnicodeText;
+ aAny >>= aUnicodeText;
+
+ CStgTransferHelper stgTransfHelper;
+
+ WideCharToMultiByteEx(
+ GetACP( ),
+ reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ),
+ aUnicodeText.getLength( ),
+ stgTransfHelper );
+
+ setupStgMedium( fetc, stgTransfHelper, stgmedium );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
+{
+ OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) );
+
+ DataFlavor aFlavor;
+
+ // creating a DataFlavor on the fly
+ aFlavor.MimeType = OUString::createFromAscii( "text/html" );
+ aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 );
+
+ Any aAny = m_XTransferable->getTransferData( aFlavor );
+
+ // unfortunately not all transferables fulfill the
+ // spec. an do throw an UnsupportedFlavorException
+ // so we must check the any
+ if ( !aAny.hasValue( ) )
+ {
+ OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
+ throw UnsupportedFlavorException( );
+ }
+
+ Sequence< sal_Int8 > aTextHtmlSequence;
+ aAny >>= aTextHtmlSequence;
+
+ Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence );
+
+ sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( );
+
+ renderDataAndSetupStgMedium(
+ reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ),
+ fetc,
+ 0,
+ nBytesToTransfer,
+ stgmedium );
+}
+
+//------------------------------------------------------------------------
+// IDataObject->EnumFormatEtc
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::EnumFormatEtc(
+ DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
+{
+ if ( NULL == ppenumFormatetc )
+ return E_INVALIDARG;
+
+ if ( DATADIR_SET == dwDirection )
+ return E_NOTIMPL;
+
+ *ppenumFormatetc = NULL;
+
+ InitializeFormatEtcContainer( );
+
+ HRESULT hr;
+ if ( DATADIR_GET == dwDirection )
+ {
+ *ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer );
+ if ( NULL != *ppenumFormatetc )
+ static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
+
+ hr = ( NULL != *ppenumFormatetc ) ? S_OK : E_OUTOFMEMORY;
+ }
+ else
+ hr = E_INVALIDARG;
+
+ return hr;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->QueryGetData
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
+{
+ if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) )
+ return E_INVALIDARG;
+
+ InitializeFormatEtcContainer( );
+
+ return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->GetDataHere
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->GetCanonicalFormatEtc
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->SetData
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->DAdvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->DUnadvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// IDataObject->EnumDAdvise
+//------------------------------------------------------------------------
+
+STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
+{
+ return E_NOTIMPL;
+}
+
+//------------------------------------------------------------------------
+// for our convenience
+//------------------------------------------------------------------------
+
+CXTDataObject::operator IDataObject*( )
+{
+ return static_cast< IDataObject* >( this );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const
+{
+ DataFlavor aFlavor;
+
+ if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
+ aFlavor =
+ m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) );
+ else
+ aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc );
+
+ if ( !aFlavor.MimeType.getLength( ) )
+ throw UnsupportedFlavorException( );
+
+ return aFlavor;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const
+{
+ OSL_ASSERT( lpFormatEtc );
+
+ if ( lpFormatEtc->lindex != -1 )
+ throw CInvalidFormatEtcException( DV_E_LINDEX );
+
+ if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) &&
+ !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) )
+ throw CInvalidFormatEtcException( DV_E_DVASPECT );
+
+ if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) &&
+ !(lpFormatEtc->tymed & TYMED_ISTREAM) &&
+ !(lpFormatEtc->tymed & TYMED_MFPICT) &&
+ !(lpFormatEtc->tymed & TYMED_ENHMF) )
+ throw CInvalidFormatEtcException( DV_E_TYMED );
+
+ if ( lpFormatEtc->cfFormat == CF_METAFILEPICT &&
+ !(lpFormatEtc->tymed & TYMED_MFPICT) )
+ throw CInvalidFormatEtcException( DV_E_TYMED );
+
+ if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE &&
+ !(lpFormatEtc->tymed & TYMED_ENHMF) )
+ throw CInvalidFormatEtcException( DV_E_TYMED );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+//inline
+void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc,
+ CStgTransferHelper& stgTransHlp,
+ STGMEDIUM& stgmedium )
+{
+ stgmedium.pUnkForRelease = NULL;
+
+ if ( fetc.cfFormat == CF_METAFILEPICT )
+ {
+ stgmedium.tymed = TYMED_MFPICT;
+ stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) );
+ }
+ else if ( fetc.cfFormat == CF_ENHMETAFILE )
+ {
+ stgmedium.tymed = TYMED_ENHMF;
+ stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) );
+ }
+ else if ( fetc.tymed & TYMED_HGLOBAL )
+ {
+ stgmedium.tymed = TYMED_HGLOBAL;
+ stgmedium.hGlobal = stgTransHlp.getHGlobal( );
+ }
+ else if ( fetc.tymed & TYMED_ISTREAM )
+ {
+ stgmedium.tymed = TYMED_ISTREAM;
+ stgTransHlp.getIStream( &stgmedium.pstm );
+ }
+ else
+ OSL_ASSERT( sal_False );
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const
+{
+ stgmedium.tymed = TYMED_NULL;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline
+HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const
+{
+ HRESULT hrTransl;
+
+ switch( hr )
+ {
+ case STG_E_MEDIUMFULL:
+ hrTransl = hr;
+ break;
+
+ default:
+ hrTransl = E_UNEXPECTED;
+ break;
+ }
+
+ return hrTransl;
+}
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( )
+{
+ if ( !m_bFormatEtcContainerInitialized )
+ {
+ m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer );
+ m_bFormatEtcContainerInitialized = sal_True;
+ }
+}
+
+//============================================================================
+// CEnumFormatEtc
+//============================================================================
+
+//----------------------------------------------------------------------------
+// ctor
+//----------------------------------------------------------------------------
+
+CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) :
+ m_nRefCnt( 0 ),
+ m_lpUnkOuter( lpUnkOuter ),
+ m_FormatEtcContainer( aFormatEtcContainer )
+{
+ Reset( );
+}
+
+//----------------------------------------------------------------------------
+// IUnknown->QueryInterface
+//----------------------------------------------------------------------------
+
+STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+
+ *ppvObject = NULL;
+
+ if ( ( __uuidof( IUnknown ) == iid ) ||
+ ( __uuidof( IEnumFORMATETC ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+//----------------------------------------------------------------------------
+// IUnknown->AddRef
+//----------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
+{
+ // keep the dataobject alive
+ m_lpUnkOuter->AddRef( );
+ return InterlockedIncrement( &m_nRefCnt );
+}
+
+//----------------------------------------------------------------------------
+// IUnknown->Release
+//----------------------------------------------------------------------------
+
+STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
+{
+ // release the outer dataobject
+ m_lpUnkOuter->Release( );
+
+ ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
+ if ( 0 == nRefCnt )
+ delete this;
+
+ return nRefCnt;
+}
+
+//----------------------------------------------------------------------------
+// IEnumFORMATETC->Next
+//----------------------------------------------------------------------------
+
+STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched )
+{
+ if ( ( nRequested < 1 ) ||
+ (( nRequested > 1 ) && ( NULL == lpFetched )) ||
+ IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) )
+ return E_INVALIDARG;
+
+ sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested );
+
+ if ( NULL != lpFetched )
+ *lpFetched = nFetched;
+
+ return (nFetched == nRequested) ? S_OK : S_FALSE;
+}
+
+//----------------------------------------------------------------------------
+// IEnumFORMATETC->Skip
+//----------------------------------------------------------------------------
+
+STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
+{
+ return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE;
+}
+
+//----------------------------------------------------------------------------
+// IEnumFORMATETC->Reset
+//----------------------------------------------------------------------------
+
+STDMETHODIMP CEnumFormatEtc::Reset( )
+{
+ m_FormatEtcContainer.beginEnumFormatEtc( );
+ return S_OK;
+}
+
+//----------------------------------------------------------------------------
+// IEnumFORMATETC->Clone
+//----------------------------------------------------------------------------
+
+STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
+{
+ if ( NULL == ppenum )
+ return E_INVALIDARG;
+
+ *ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer );
+ if ( NULL != ppenum )
+ static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
+
+ return ( NULL != *ppenum ) ? S_OK : E_OUTOFMEMORY;
+}
diff --git a/dtrans/source/win32/dtobj/XTDataObject.hxx b/dtrans/source/win32/dtobj/XTDataObject.hxx
new file mode 100644
index 000000000000..b7b20af56ac7
--- /dev/null
+++ b/dtrans/source/win32/dtobj/XTDataObject.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _XTDATAOBJECT_HXX_
+#define _XTDATAOBJECT_HXX_
+
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+
+#ifndef _DATAFORMATTRANSLATOR_HXX_
+#include "DataFmtTransl.hxx"
+#endif
+
+#ifndef _FETCLIST_HXX_
+#include "FEtcList.hxx"
+#endif
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <ole2.h>
+#include <objidl.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+/*--------------------------------------------------------------------------
+ - the function principle of the windows clipboard:
+ a data provider offers all formats he can deliver on the clipboard
+ a clipboard client ask for the available formats on the clipboard
+ and decides if there is a format he can use
+ if there is one, he requests the data in this format
+
+ - This class inherits from IDataObject an so can be placed on the
+ OleClipboard. The class wrapps a transferable object which is the
+ original DataSource
+ - DataFlavors offerd by this transferable will be translated into
+ appropriate clipboard formats
+ - if the transferable contains text data always text and unicodetext
+ will be offered or vice versa
+ - text data will be automaticaly converted between text und unicode text
+ - although the transferable may support text in different charsets
+ (codepages) only text in one codepage can be offered by the clipboard
+
+----------------------------------------------------------------------------*/
+
+class CStgTransferHelper;
+
+class CXTDataObject : public IDataObject
+{
+public:
+ CXTDataObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& aXTransferable );
+ virtual ~CXTDataObject() {}
+
+ //-----------------------------------------------------------------
+ // ole interface implementation
+ //-----------------------------------------------------------------
+
+ //IUnknown interface methods
+ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ // IDataObject interface methods
+ STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc );
+ STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut );
+ STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease );
+ STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc );
+ STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection );
+ STDMETHODIMP DUnadvise( DWORD dwConnection );
+ STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise );
+
+ operator IDataObject*( );
+
+private:
+ com::sun::star::datatransfer::DataFlavor SAL_CALL formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const;
+
+ void SAL_CALL renderDataAndSetupStgMedium( const sal_Int8* lpStorage,
+ const FORMATETC& fetc,
+ sal_uInt32 nInitStgSize,
+ sal_uInt32 nBytesToTransfer,
+ STGMEDIUM& stgmedium );
+
+ void SAL_CALL renderLocaleAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+ void SAL_CALL renderUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+ void SAL_CALL renderAnyDataAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+
+ HRESULT SAL_CALL renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+ void SAL_CALL renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+ void SAL_CALL renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+ void SAL_CALL renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium );
+
+ void SAL_CALL setupStgMedium( const FORMATETC& fetc,
+ CStgTransferHelper& stgTransHlp,
+ STGMEDIUM& stgmedium );
+
+ void validateFormatEtc( LPFORMATETC lpFormatEtc ) const;
+ void SAL_CALL invalidateStgMedium( STGMEDIUM& stgmedium ) const;
+
+ HRESULT SAL_CALL translateStgExceptionCode( HRESULT hr ) const;
+
+ inline void SAL_CALL InitializeFormatEtcContainer( );
+
+private:
+ LONG m_nRefCnt;
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr;
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > m_XTransferable;
+ CFormatEtcContainer m_FormatEtcContainer;
+ sal_Bool m_bFormatEtcContainerInitialized;
+ CDataFormatTranslator m_DataFormatTranslator;
+ CFormatRegistrar m_FormatRegistrar;
+};
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+class CEnumFormatEtc : public IEnumFORMATETC
+{
+public:
+ CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer );
+ virtual ~CEnumFormatEtc() {}
+
+ // IUnknown
+ STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppvObject );
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ //IEnumFORMATETC
+ STDMETHODIMP Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched );
+ STDMETHODIMP Skip( ULONG celt );
+ STDMETHODIMP Reset( );
+ STDMETHODIMP Clone( IEnumFORMATETC** ppenum );
+
+private:
+ LONG m_nRefCnt;
+ LPUNKNOWN m_lpUnkOuter;
+ CFormatEtcContainer m_FormatEtcContainer;
+};
+
+typedef CEnumFormatEtc *PCEnumFormatEtc;
+
+#endif
diff --git a/dtrans/source/win32/dtobj/makefile.mk b/dtrans/source/win32/dtobj/makefile.mk
new file mode 100644
index 000000000000..5aea2b133dc1
--- /dev/null
+++ b/dtrans/source/win32/dtobj/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=dtrans
+TARGET=dtobjfact
+ENABLE_EXCEPTIONS=TRUE
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+#-DUNICODE -D_UNICODE
+.IF "$(COM)"!="GCC"
+CFLAGS+=-GR -Ob0
+.ENDIF
+
+SLOFILES=$(SLO)$/DtObjFactory.obj\
+ $(SLO)$/APNDataObject.obj\
+ $(SLO)$/DOTransferable.obj\
+ $(SLO)$/DTransHelper.obj\
+ $(SLO)$/XTDataObject.obj\
+ $(SLO)$/TxtCnvtHlp.obj\
+ $(SLO)$/DataFmtTransl.obj\
+ $(SLO)$/FmtFilter.obj\
+ $(SLO)$/FetcList.obj\
+ $(SLO)$/Fetc.obj\
+ $(SLO)$/XNotifyingDataObject.obj
+
+LIB1TARGET=$(SLB)$/$(TARGET).lib
+.IF "$(COM)"!="GCC"
+LIB1OBJFILES=$(SLOFILES)
+.ELSE
+LIB1OBJFILES=$(SLO)$/DtObjFactory.obj\
+ $(SLO)$/APNDataObject.obj\
+ $(SLO)$/DOTransferable.obj\
+ $(SLO)$/DTransHelper.obj\
+ $(SLO)$/XTDataObject.obj\
+ $(SLO)$/TxtCnvtHlp.obj\
+ $(SLO)$/DataFmtTransl.obj\
+ $(SLO)$/FmtFilter.obj\
+ $(SLO)$/FetcList.obj\
+ $(SLO)$/Fetc.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk