xref: /AOO41X/main/dtrans/source/win32/dtobj/DOTransferable.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //------------------------------------------------------------------------
32*cdf0e10cSrcweir // includes
33*cdf0e10cSrcweir //------------------------------------------------------------------------
34*cdf0e10cSrcweir #include <sal/types.h>
35*cdf0e10cSrcweir #include <rtl/process.h>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #ifndef _DOWRAPPERTRANSFERABLE_HXX_
38*cdf0e10cSrcweir #include "DOTransferable.hxx"
39*cdf0e10cSrcweir #endif
40*cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
41*cdf0e10cSrcweir #include "..\misc\WinClip.hxx"
42*cdf0e10cSrcweir #include "DTransHelper.hxx"
43*cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
44*cdf0e10cSrcweir #include "TxtCnvtHlp.hxx"
45*cdf0e10cSrcweir #include "MimeAttrib.hxx"
46*cdf0e10cSrcweir #include "FmtFilter.hxx"
47*cdf0e10cSrcweir #include "Fetc.hxx"
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #if(_MSC_VER < 1300) && !defined(__MINGW32__)
51*cdf0e10cSrcweir #include <olestd.h>
52*cdf0e10cSrcweir #endif
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #define STR2(x) #x
55*cdf0e10cSrcweir #define STR(x) STR2(x)
56*cdf0e10cSrcweir #define PRAGMA_MSG( msg ) message( __FILE__ "(" STR(__LINE__) "): " #msg )
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir //------------------------------------------------------------------------
59*cdf0e10cSrcweir // namespace directives
60*cdf0e10cSrcweir //------------------------------------------------------------------------
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir using namespace rtl;
63*cdf0e10cSrcweir using namespace std;
64*cdf0e10cSrcweir using namespace osl;
65*cdf0e10cSrcweir using namespace cppu;
66*cdf0e10cSrcweir using namespace com::sun::star::uno;
67*cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
68*cdf0e10cSrcweir using namespace com::sun::star::io;
69*cdf0e10cSrcweir using namespace com::sun::star::lang;
70*cdf0e10cSrcweir using namespace com::sun::star::container;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir //------------------------------------------------------------------------
73*cdf0e10cSrcweir //
74*cdf0e10cSrcweir //------------------------------------------------------------------------
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir namespace
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir 	const Type CPPUTYPE_SEQINT8  = getCppuType( ( Sequence< sal_Int8 >* )0 );
79*cdf0e10cSrcweir 	const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 	inline
82*cdf0e10cSrcweir 	sal_Bool isValidFlavor( const DataFlavor& aFlavor )
83*cdf0e10cSrcweir 	{
84*cdf0e10cSrcweir 		return ( aFlavor.MimeType.getLength( ) &&
85*cdf0e10cSrcweir 				 ( ( aFlavor.DataType ==  CPPUTYPE_SEQINT8 ) ||
86*cdf0e10cSrcweir 				 ( aFlavor.DataType == CPPUTYPE_OUSTRING ) ) );
87*cdf0e10cSrcweir 	}
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir } // end namespace
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir //------------------------------------------------------------------------
93*cdf0e10cSrcweir // ctor
94*cdf0e10cSrcweir //------------------------------------------------------------------------
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir CDOTransferable::CDOTransferable(
97*cdf0e10cSrcweir 	const Reference< XMultiServiceFactory >& ServiceManager, IDataObjectPtr rDataObject ) :
98*cdf0e10cSrcweir 	m_rDataObject( rDataObject ),
99*cdf0e10cSrcweir 	m_SrvMgr( ServiceManager ),
100*cdf0e10cSrcweir 	m_DataFormatTranslator( m_SrvMgr ),
101*cdf0e10cSrcweir 	m_bUnicodeRegistered( sal_False ),
102*cdf0e10cSrcweir 	m_TxtFormatOnClipboard( CF_INVALID )
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir }
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir //------------------------------------------------------------------------
107*cdf0e10cSrcweir //
108*cdf0e10cSrcweir //------------------------------------------------------------------------
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir Any SAL_CALL CDOTransferable::getTransferData( const DataFlavor& aFlavor )
111*cdf0e10cSrcweir 		throw( UnsupportedFlavorException, IOException, RuntimeException )
112*cdf0e10cSrcweir {
113*cdf0e10cSrcweir 	OSL_ASSERT( isValidFlavor( aFlavor ) );
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir 	MutexGuard aGuard( m_aMutex );
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 	//------------------------------------------------
118*cdf0e10cSrcweir 	// convert dataflavor to formatetc
119*cdf0e10cSrcweir 	//------------------------------------------------
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 	CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor );
122*cdf0e10cSrcweir 	OSL_ASSERT( CF_INVALID != fetc.getClipformat() );
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 	//------------------------------------------------
125*cdf0e10cSrcweir 	//	get the data from clipboard in a byte stream
126*cdf0e10cSrcweir 	//------------------------------------------------
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir 	ByteSequence_t clipDataStream;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 	try
131*cdf0e10cSrcweir 	{
132*cdf0e10cSrcweir 		clipDataStream = getClipboardData( fetc );
133*cdf0e10cSrcweir 	}
134*cdf0e10cSrcweir 	catch( UnsupportedFlavorException& )
135*cdf0e10cSrcweir 	{
136*cdf0e10cSrcweir 		if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat( ) ) &&
137*cdf0e10cSrcweir 			 m_bUnicodeRegistered )
138*cdf0e10cSrcweir 		{
139*cdf0e10cSrcweir 			 OUString aUnicodeText = synthesizeUnicodeText( );
140*cdf0e10cSrcweir 			 Any aAny = makeAny( aUnicodeText );
141*cdf0e10cSrcweir 			 return aAny;
142*cdf0e10cSrcweir 		}
143*cdf0e10cSrcweir 		else
144*cdf0e10cSrcweir 			throw; // pass through exception
145*cdf0e10cSrcweir 	}
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 	//------------------------------------------------
148*cdf0e10cSrcweir 	// return the data as any
149*cdf0e10cSrcweir 	//------------------------------------------------
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir 	return byteStreamToAny( clipDataStream, aFlavor.DataType );
152*cdf0e10cSrcweir }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir //------------------------------------------------------------------------
155*cdf0e10cSrcweir // getTransferDataFlavors
156*cdf0e10cSrcweir //------------------------------------------------------------------------
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir Sequence< DataFlavor > SAL_CALL CDOTransferable::getTransferDataFlavors(  )
159*cdf0e10cSrcweir 	throw( RuntimeException )
160*cdf0e10cSrcweir {
161*cdf0e10cSrcweir 	return m_FlavorList;
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir //------------------------------------------------------------------------
165*cdf0e10cSrcweir // isDataFlavorSupported
166*cdf0e10cSrcweir // returns true if we find a DataFlavor with the same MimeType and
167*cdf0e10cSrcweir // DataType
168*cdf0e10cSrcweir //------------------------------------------------------------------------
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
171*cdf0e10cSrcweir 	throw( RuntimeException )
172*cdf0e10cSrcweir {
173*cdf0e10cSrcweir 	OSL_ASSERT( isValidFlavor( aFlavor ) );
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 	for ( sal_Int32 i = 0; i < m_FlavorList.getLength( ); i++ )
176*cdf0e10cSrcweir 		if ( compareDataFlavors( aFlavor, m_FlavorList[i] ) )
177*cdf0e10cSrcweir 			return sal_True;
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 	return sal_False;
180*cdf0e10cSrcweir }
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir //------------------------------------------------------------------------
183*cdf0e10cSrcweir // helper function
184*cdf0e10cSrcweir // the list of datafalvors currently on the clipboard will be initialized
185*cdf0e10cSrcweir // only once; if the client of this Transferable will hold a reference
186*cdf0e10cSrcweir // to it und the underlying clipboard content changes, the client does
187*cdf0e10cSrcweir // possible operate on a invalid list
188*cdf0e10cSrcweir // if there is only text on the clipboard we will also offer unicode text
189*cdf0e10cSrcweir // an synthesize this format on the fly if requested, to accomplish this
190*cdf0e10cSrcweir // we save the first offered text format which we will later use for the
191*cdf0e10cSrcweir // conversion
192*cdf0e10cSrcweir //------------------------------------------------------------------------
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir void SAL_CALL CDOTransferable::initFlavorList( )
195*cdf0e10cSrcweir {
196*cdf0e10cSrcweir 	IEnumFORMATETCPtr pEnumFormatEtc;
197*cdf0e10cSrcweir 	HRESULT hr = m_rDataObject->EnumFormatEtc( DATADIR_GET, &pEnumFormatEtc );
198*cdf0e10cSrcweir 	if ( SUCCEEDED( hr ) )
199*cdf0e10cSrcweir 	{
200*cdf0e10cSrcweir 		pEnumFormatEtc->Reset( );
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 		FORMATETC fetc;
203*cdf0e10cSrcweir 		while ( S_FALSE != pEnumFormatEtc->Next( 1, &fetc, NULL ) )
204*cdf0e10cSrcweir 		{
205*cdf0e10cSrcweir 			// we use locales only to determine the
206*cdf0e10cSrcweir 			// charset if there is text on the cliboard
207*cdf0e10cSrcweir 			// we don't offer this format
208*cdf0e10cSrcweir 			if ( CF_LOCALE == fetc.cfFormat )
209*cdf0e10cSrcweir 				continue;
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 			DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir 			// if text or oemtext is offered we also pretend to have unicode text
214*cdf0e10cSrcweir 			if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) &&
215*cdf0e10cSrcweir 				 !m_bUnicodeRegistered )
216*cdf0e10cSrcweir 			{
217*cdf0e10cSrcweir 				addSupportedFlavor( aFlavor );
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 				m_TxtFormatOnClipboard = fetc.cfFormat;
220*cdf0e10cSrcweir 				m_bUnicodeRegistered   = sal_True;
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 				// register unicode text as accompany format
223*cdf0e10cSrcweir 				aFlavor = formatEtcToDataFlavor(
224*cdf0e10cSrcweir 					m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
225*cdf0e10cSrcweir 				addSupportedFlavor( aFlavor );
226*cdf0e10cSrcweir 			}
227*cdf0e10cSrcweir 			else if ( (CF_UNICODETEXT == fetc.cfFormat) && !m_bUnicodeRegistered )
228*cdf0e10cSrcweir 			{
229*cdf0e10cSrcweir 				addSupportedFlavor( aFlavor );
230*cdf0e10cSrcweir 				m_bUnicodeRegistered = sal_True;
231*cdf0e10cSrcweir 			}
232*cdf0e10cSrcweir 			else
233*cdf0e10cSrcweir 				addSupportedFlavor( aFlavor );
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 			// see MSDN IEnumFORMATETC
236*cdf0e10cSrcweir 			CoTaskMemFree( fetc.ptd );
237*cdf0e10cSrcweir 		}
238*cdf0e10cSrcweir 	}
239*cdf0e10cSrcweir }
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir //------------------------------------------------------------------------
242*cdf0e10cSrcweir //
243*cdf0e10cSrcweir //------------------------------------------------------------------------
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir inline
246*cdf0e10cSrcweir void SAL_CALL CDOTransferable::addSupportedFlavor( const DataFlavor& aFlavor )
247*cdf0e10cSrcweir {
248*cdf0e10cSrcweir 	// we ignore all formats that couldn't be translated
249*cdf0e10cSrcweir 	if ( aFlavor.MimeType.getLength( ) )
250*cdf0e10cSrcweir 	{
251*cdf0e10cSrcweir 		OSL_ASSERT( isValidFlavor( aFlavor ) );
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir 		m_FlavorList.realloc( m_FlavorList.getLength( ) + 1 );
254*cdf0e10cSrcweir 		m_FlavorList[m_FlavorList.getLength( ) - 1] = aFlavor;
255*cdf0e10cSrcweir 	}
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir //------------------------------------------------------------------------
259*cdf0e10cSrcweir // helper function
260*cdf0e10cSrcweir //------------------------------------------------------------------------
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir //inline
263*cdf0e10cSrcweir DataFlavor SAL_CALL CDOTransferable::formatEtcToDataFlavor( const FORMATETC& aFormatEtc )
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir 	DataFlavor aFlavor;
266*cdf0e10cSrcweir 	LCID lcid = 0;
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir 	// for non-unicode text format we must provid a locale to get
269*cdf0e10cSrcweir 	// the character-set of the text, if there is no locale on the
270*cdf0e10cSrcweir 	// clipboard we assume the text is in a charset appropriate for
271*cdf0e10cSrcweir 	// the current thread locale
272*cdf0e10cSrcweir 	if ( (CF_TEXT == aFormatEtc.cfFormat) || (CF_OEMTEXT == aFormatEtc.cfFormat) )
273*cdf0e10cSrcweir 		lcid = getLocaleFromClipboard( );
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 	return m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, lcid );
276*cdf0e10cSrcweir }
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir //------------------------------------------------------------------------
279*cdf0e10cSrcweir // returns the current locale on clipboard; if there is no locale on
280*cdf0e10cSrcweir // clipboard the function returns the current thread locale
281*cdf0e10cSrcweir //------------------------------------------------------------------------
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir LCID SAL_CALL CDOTransferable::getLocaleFromClipboard( )
284*cdf0e10cSrcweir {
285*cdf0e10cSrcweir 	LCID lcid = GetThreadLocale( );
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 	try
288*cdf0e10cSrcweir 	{
289*cdf0e10cSrcweir 		CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE );
290*cdf0e10cSrcweir 		ByteSequence_t aLCIDSeq = getClipboardData( fetc );
291*cdf0e10cSrcweir 		lcid = *(reinterpret_cast<LCID*>( aLCIDSeq.getArray( ) ) );
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		// because of a Win95/98 Bug; there the high word
294*cdf0e10cSrcweir 		// of a locale has the same value as the
295*cdf0e10cSrcweir 		// low word e.g. 0x07040704 that's not right
296*cdf0e10cSrcweir 		// correct is 0x00000704
297*cdf0e10cSrcweir 		lcid &= 0x0000FFFF;
298*cdf0e10cSrcweir 	}
299*cdf0e10cSrcweir 	catch(...)
300*cdf0e10cSrcweir 	{
301*cdf0e10cSrcweir 		// we take the default locale
302*cdf0e10cSrcweir 	}
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 	return lcid;
305*cdf0e10cSrcweir }
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir //------------------------------------------------------------------------
308*cdf0e10cSrcweir // i think it's not necessary to call ReleaseStgMedium
309*cdf0e10cSrcweir // in case of failures because nothing should have been
310*cdf0e10cSrcweir // allocated etc.
311*cdf0e10cSrcweir //------------------------------------------------------------------------
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir CDOTransferable::ByteSequence_t SAL_CALL CDOTransferable::getClipboardData( CFormatEtc& aFormatEtc )
314*cdf0e10cSrcweir {
315*cdf0e10cSrcweir 	STGMEDIUM stgmedium;
316*cdf0e10cSrcweir 	HRESULT hr = m_rDataObject->GetData( aFormatEtc, &stgmedium );
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir 	// in case of failure to get a WMF metafile handle, try to get a memory block
319*cdf0e10cSrcweir 	if( FAILED( hr ) &&
320*cdf0e10cSrcweir 	    ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) &&
321*cdf0e10cSrcweir 	    ( TYMED_MFPICT == aFormatEtc.getTymed() ) )
322*cdf0e10cSrcweir 	{
323*cdf0e10cSrcweir         CFormatEtc aTempFormat( aFormatEtc );
324*cdf0e10cSrcweir 	    aTempFormat.setTymed( TYMED_HGLOBAL );
325*cdf0e10cSrcweir 	    hr = m_rDataObject->GetData( aTempFormat, &stgmedium );
326*cdf0e10cSrcweir 	}
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir 	if ( FAILED( hr ) )
329*cdf0e10cSrcweir 	{
330*cdf0e10cSrcweir 		OSL_ASSERT( (hr != E_INVALIDARG) &&
331*cdf0e10cSrcweir 			        (hr != DV_E_DVASPECT) &&
332*cdf0e10cSrcweir 					(hr != DV_E_LINDEX) &&
333*cdf0e10cSrcweir 					(hr != DV_E_TYMED) );
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 		if ( DV_E_FORMATETC == hr )
336*cdf0e10cSrcweir 			throw UnsupportedFlavorException( );
337*cdf0e10cSrcweir 		else if ( STG_E_MEDIUMFULL == hr )
338*cdf0e10cSrcweir 			throw IOException( );
339*cdf0e10cSrcweir 		else
340*cdf0e10cSrcweir 			throw RuntimeException( );
341*cdf0e10cSrcweir 	}
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir 	ByteSequence_t byteStream;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir 	try
346*cdf0e10cSrcweir 	{
347*cdf0e10cSrcweir 		if ( CF_ENHMETAFILE == aFormatEtc.getClipformat() )
348*cdf0e10cSrcweir 			byteStream = WinENHMFPictToOOMFPict( stgmedium.hEnhMetaFile );
349*cdf0e10cSrcweir         else if (CF_HDROP == aFormatEtc.getClipformat())
350*cdf0e10cSrcweir 			byteStream = CF_HDROPToFileList(stgmedium.hGlobal);
351*cdf0e10cSrcweir         else if ( CF_BITMAP == aFormatEtc.getClipformat() )
352*cdf0e10cSrcweir         {
353*cdf0e10cSrcweir             byteStream = WinBITMAPToOOBMP(stgmedium.hBitmap);
354*cdf0e10cSrcweir             if( aFormatEtc.getTymed() == TYMED_GDI &&
355*cdf0e10cSrcweir                 ! stgmedium.pUnkForRelease )
356*cdf0e10cSrcweir             {
357*cdf0e10cSrcweir                 DeleteObject(stgmedium.hBitmap);
358*cdf0e10cSrcweir             }
359*cdf0e10cSrcweir         }
360*cdf0e10cSrcweir 		else
361*cdf0e10cSrcweir 		{
362*cdf0e10cSrcweir 			clipDataToByteStream( aFormatEtc.getClipformat( ), stgmedium, byteStream );
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir 			// format conversion if necessary
365*cdf0e10cSrcweir 			if ( CF_DIB == aFormatEtc.getClipformat() )
366*cdf0e10cSrcweir 				byteStream = WinDIBToOOBMP( byteStream );
367*cdf0e10cSrcweir 			else if ( CF_METAFILEPICT == aFormatEtc.getClipformat() )
368*cdf0e10cSrcweir 				byteStream = WinMFPictToOOMFPict( byteStream );
369*cdf0e10cSrcweir 		}
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 		ReleaseStgMedium( &stgmedium );
372*cdf0e10cSrcweir 	}
373*cdf0e10cSrcweir 	catch( CStgTransferHelper::CStgTransferException& )
374*cdf0e10cSrcweir 	{
375*cdf0e10cSrcweir 		ReleaseStgMedium( &stgmedium );
376*cdf0e10cSrcweir 		throw IOException( );
377*cdf0e10cSrcweir 	}
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir 	return byteStream;
380*cdf0e10cSrcweir }
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir //------------------------------------------------------------------------
383*cdf0e10cSrcweir //
384*cdf0e10cSrcweir //------------------------------------------------------------------------
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir OUString SAL_CALL CDOTransferable::synthesizeUnicodeText( )
387*cdf0e10cSrcweir {
388*cdf0e10cSrcweir 	ByteSequence_t aTextSequence;
389*cdf0e10cSrcweir 	CFormatEtc	   fetc;
390*cdf0e10cSrcweir 	LCID		   lcid = getLocaleFromClipboard( );
391*cdf0e10cSrcweir 	sal_uInt32	   cpForTxtCnvt = 0;
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir 	if ( CF_TEXT == m_TxtFormatOnClipboard )
394*cdf0e10cSrcweir 	{
395*cdf0e10cSrcweir 		fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT );
396*cdf0e10cSrcweir 		aTextSequence = getClipboardData( fetc );
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir 		// determine the codepage used for text conversion
399*cdf0e10cSrcweir 		cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTANSICODEPAGE ).toInt32( );
400*cdf0e10cSrcweir 	}
401*cdf0e10cSrcweir 	else if ( CF_OEMTEXT == m_TxtFormatOnClipboard )
402*cdf0e10cSrcweir 	{
403*cdf0e10cSrcweir 		fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT );
404*cdf0e10cSrcweir 		aTextSequence = getClipboardData( fetc );
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 		// determine the codepage used for text conversion
407*cdf0e10cSrcweir 		cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTCODEPAGE ).toInt32( );
408*cdf0e10cSrcweir 	}
409*cdf0e10cSrcweir 	else
410*cdf0e10cSrcweir 		OSL_ASSERT( sal_False );
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir 	CStgTransferHelper stgTransferHelper;
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir 	// convert the text
415*cdf0e10cSrcweir 	MultiByteToWideCharEx( cpForTxtCnvt,
416*cdf0e10cSrcweir 						   reinterpret_cast<char*>( aTextSequence.getArray( ) ),
417*cdf0e10cSrcweir                            sal::static_int_cast<sal_uInt32>(-1), // Huh ?
418*cdf0e10cSrcweir                            stgTransferHelper,
419*cdf0e10cSrcweir                            sal_False);
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 	CRawHGlobalPtr	ptrHGlob(stgTransferHelper);
422*cdf0e10cSrcweir 	sal_Unicode*	pWChar = reinterpret_cast<sal_Unicode*>(ptrHGlob.GetMemPtr());
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 	return OUString(pWChar);
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir //------------------------------------------------------------------------
428*cdf0e10cSrcweir //
429*cdf0e10cSrcweir //------------------------------------------------------------------------
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir void CDOTransferable::clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence )
432*cdf0e10cSrcweir {
433*cdf0e10cSrcweir 	CStgTransferHelper memTransferHelper;
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	switch( stgmedium.tymed )
436*cdf0e10cSrcweir 	{
437*cdf0e10cSrcweir 	case TYMED_HGLOBAL:
438*cdf0e10cSrcweir 		memTransferHelper.init( stgmedium.hGlobal );
439*cdf0e10cSrcweir 		break;
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir 	case TYMED_MFPICT:
442*cdf0e10cSrcweir 		memTransferHelper.init( stgmedium.hMetaFilePict );
443*cdf0e10cSrcweir 		break;
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir 	case TYMED_ENHMF:
446*cdf0e10cSrcweir 		memTransferHelper.init( stgmedium.hEnhMetaFile );
447*cdf0e10cSrcweir 		break;
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir 	case TYMED_ISTREAM:
450*cdf0e10cSrcweir 		#ifdef _MSC_VER
451*cdf0e10cSrcweir 		#pragma PRAGMA_MSG( Has to be implemented )
452*cdf0e10cSrcweir 		#endif
453*cdf0e10cSrcweir 		break;
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir 	default:
456*cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
457*cdf0e10cSrcweir 		break;
458*cdf0e10cSrcweir 	}
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir 	int nMemSize = memTransferHelper.memSize( cf );
461*cdf0e10cSrcweir 	aByteSequence.realloc( nMemSize );
462*cdf0e10cSrcweir 	memTransferHelper.read( aByteSequence.getArray( ), nMemSize );
463*cdf0e10cSrcweir }
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir //------------------------------------------------------------------------
466*cdf0e10cSrcweir //
467*cdf0e10cSrcweir //------------------------------------------------------------------------
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir inline
470*cdf0e10cSrcweir Any CDOTransferable::byteStreamToAny( ByteSequence_t& aByteStream, const Type& aRequestedDataType )
471*cdf0e10cSrcweir {
472*cdf0e10cSrcweir 	Any aAny;
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir 	if ( aRequestedDataType == CPPUTYPE_OUSTRING )
475*cdf0e10cSrcweir 	{
476*cdf0e10cSrcweir 		OUString str = byteStreamToOUString( aByteStream );
477*cdf0e10cSrcweir 		aAny = makeAny(	str );
478*cdf0e10cSrcweir 	}
479*cdf0e10cSrcweir 	else
480*cdf0e10cSrcweir 		aAny = makeAny( aByteStream );
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 	return aAny;
483*cdf0e10cSrcweir }
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir //------------------------------------------------------------------------
486*cdf0e10cSrcweir //
487*cdf0e10cSrcweir //------------------------------------------------------------------------
488*cdf0e10cSrcweir 
489*cdf0e10cSrcweir inline
490*cdf0e10cSrcweir OUString CDOTransferable::byteStreamToOUString( ByteSequence_t& aByteStream )
491*cdf0e10cSrcweir {
492*cdf0e10cSrcweir 	sal_Int32 nWChars;
493*cdf0e10cSrcweir 	sal_Int32 nMemSize = aByteStream.getLength( );
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 	// if there is a trailing L"\0" substract 1 from length
496*cdf0e10cSrcweir 	if ( 0 == aByteStream[ aByteStream.getLength( ) - 2 ] &&
497*cdf0e10cSrcweir 		 0 == aByteStream[ aByteStream.getLength( ) - 1 ] )
498*cdf0e10cSrcweir 		nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) ) - 1;
499*cdf0e10cSrcweir 	else
500*cdf0e10cSrcweir 		nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) );
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir 	return OUString( reinterpret_cast< sal_Unicode* >( aByteStream.getArray( ) ), nWChars );
503*cdf0e10cSrcweir }
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir //------------------------------------------------------------------------
506*cdf0e10cSrcweir //
507*cdf0e10cSrcweir //------------------------------------------------------------------------
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::compareDataFlavors(
510*cdf0e10cSrcweir 	const DataFlavor& lhs, const DataFlavor& rhs )
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir 	if ( !m_rXMimeCntFactory.is( ) )
513*cdf0e10cSrcweir 	{
514*cdf0e10cSrcweir 		m_rXMimeCntFactory = Reference< XMimeContentTypeFactory >( m_SrvMgr->createInstance(
515*cdf0e10cSrcweir 			OUString::createFromAscii( "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY );
516*cdf0e10cSrcweir 	}
517*cdf0e10cSrcweir 	OSL_ASSERT( m_rXMimeCntFactory.is( ) );
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir 	try
522*cdf0e10cSrcweir 	{
523*cdf0e10cSrcweir 		Reference< XMimeContentType > xLhs( m_rXMimeCntFactory->createMimeContentType( lhs.MimeType ) );
524*cdf0e10cSrcweir 		Reference< XMimeContentType > xRhs( m_rXMimeCntFactory->createMimeContentType( rhs.MimeType ) );
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir 		if ( cmpFullMediaType( xLhs, xRhs ) )
527*cdf0e10cSrcweir 		{
528*cdf0e10cSrcweir 			bRet = cmpAllContentTypeParameter( xLhs, xRhs );
529*cdf0e10cSrcweir 		}
530*cdf0e10cSrcweir 	}
531*cdf0e10cSrcweir 	catch( IllegalArgumentException& )
532*cdf0e10cSrcweir 	{
533*cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Invalid content type detected" );
534*cdf0e10cSrcweir 		bRet = sal_False;
535*cdf0e10cSrcweir 	}
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 	return bRet;
538*cdf0e10cSrcweir }
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir //------------------------------------------------------------------------
541*cdf0e10cSrcweir //
542*cdf0e10cSrcweir //------------------------------------------------------------------------
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::cmpFullMediaType(
545*cdf0e10cSrcweir 	const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
546*cdf0e10cSrcweir {
547*cdf0e10cSrcweir 	return xLhs->getFullMediaType().equalsIgnoreAsciiCase( xRhs->getFullMediaType( ) );
548*cdf0e10cSrcweir }
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir //------------------------------------------------------------------------
551*cdf0e10cSrcweir //
552*cdf0e10cSrcweir //------------------------------------------------------------------------
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::cmpAllContentTypeParameter(
555*cdf0e10cSrcweir 	const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
556*cdf0e10cSrcweir {
557*cdf0e10cSrcweir 	Sequence< OUString > xLhsFlavors = xLhs->getParameters( );
558*cdf0e10cSrcweir 	Sequence< OUString > xRhsFlavors = xRhs->getParameters( );
559*cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir 	try
562*cdf0e10cSrcweir 	{
563*cdf0e10cSrcweir 		if ( xLhsFlavors.getLength( ) == xRhsFlavors.getLength( ) )
564*cdf0e10cSrcweir 		{
565*cdf0e10cSrcweir 			OUString pLhs;
566*cdf0e10cSrcweir 			OUString pRhs;
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 			for ( sal_Int32 i = 0; i < xLhsFlavors.getLength( ); i++ )
569*cdf0e10cSrcweir 			{
570*cdf0e10cSrcweir 				pLhs = xLhs->getParameterValue( xLhsFlavors[i] );
571*cdf0e10cSrcweir 				pRhs = xRhs->getParameterValue( xLhsFlavors[i] );
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir 				if ( !pLhs.equalsIgnoreAsciiCase( pRhs ) )
574*cdf0e10cSrcweir 				{
575*cdf0e10cSrcweir 					bRet = sal_False;
576*cdf0e10cSrcweir 					break;
577*cdf0e10cSrcweir 				}
578*cdf0e10cSrcweir 			}
579*cdf0e10cSrcweir 		}
580*cdf0e10cSrcweir 		else
581*cdf0e10cSrcweir 			bRet = sal_False;
582*cdf0e10cSrcweir 	}
583*cdf0e10cSrcweir 	catch( NoSuchElementException& )
584*cdf0e10cSrcweir 	{
585*cdf0e10cSrcweir 		bRet = sal_False;
586*cdf0e10cSrcweir 	}
587*cdf0e10cSrcweir 	catch( IllegalArgumentException& )
588*cdf0e10cSrcweir 	{
589*cdf0e10cSrcweir 		bRet = sal_False;
590*cdf0e10cSrcweir 	}
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir 	return bRet;
593*cdf0e10cSrcweir }
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir ::com::sun::star::uno::Any SAL_CALL CDOTransferable::getData( const Sequence< sal_Int8>& aProcessId  )
596*cdf0e10cSrcweir 		throw (::com::sun::star::uno::RuntimeException)
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir 	Any retVal;
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 	sal_uInt8 * arProcCaller= (sal_uInt8*)(sal_Int8*) aProcessId.getConstArray();
601*cdf0e10cSrcweir 	sal_uInt8 arId[16];
602*cdf0e10cSrcweir 	rtl_getGlobalProcessId(arId);
603*cdf0e10cSrcweir 	if( ! memcmp( arId, arProcCaller,16))
604*cdf0e10cSrcweir 	{
605*cdf0e10cSrcweir 		if (m_rDataObject.is())
606*cdf0e10cSrcweir 		{
607*cdf0e10cSrcweir 			IDataObject* pObj= m_rDataObject.get();
608*cdf0e10cSrcweir 			pObj->AddRef();
609*cdf0e10cSrcweir 			retVal.setValue( &pObj, getCppuType((sal_uInt32*)0));
610*cdf0e10cSrcweir 		}
611*cdf0e10cSrcweir 	}
612*cdf0e10cSrcweir 	return retVal;
613*cdf0e10cSrcweir }
614*cdf0e10cSrcweir 
615