xref: /AOO41X/main/dtrans/source/win32/dtobj/XTDataObject.cxx (revision 48123e16153c92857455f9e7a0d17cc19307983f)
1*48123e16SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*48123e16SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*48123e16SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*48123e16SAndrew Rist  * distributed with this work for additional information
6*48123e16SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*48123e16SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*48123e16SAndrew Rist  * "License"); you may not use this file except in compliance
9*48123e16SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*48123e16SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*48123e16SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*48123e16SAndrew Rist  * software distributed under the License is distributed on an
15*48123e16SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*48123e16SAndrew Rist  * KIND, either express or implied.  See the License for the
17*48123e16SAndrew Rist  * specific language governing permissions and limitations
18*48123e16SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*48123e16SAndrew Rist  *************************************************************/
21*48123e16SAndrew Rist 
22*48123e16SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir // includes
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir #include <osl/diagnose.h>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #ifndef _TXDATAOBJECT_HXX_
33cdf0e10cSrcweir #include "XTDataObject.hxx"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include <com/sun/star/datatransfer/DataFlavor.hpp>
36cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
37cdf0e10cSrcweir #include "DTransHelper.hxx"
38cdf0e10cSrcweir #include "TxtCnvtHlp.hxx"
39cdf0e10cSrcweir #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
40cdf0e10cSrcweir #include "FmtFilter.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #if defined _MSC_VER
43cdf0e10cSrcweir #pragma warning(push,1)
44cdf0e10cSrcweir #pragma warning(disable:4917)
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir #include <windows.h>
47cdf0e10cSrcweir #include <shlobj.h>
48cdf0e10cSrcweir #if defined _MSC_VER
49cdf0e10cSrcweir #pragma warning(pop)
50cdf0e10cSrcweir #endif
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #ifdef __MINGW32__
53cdf0e10cSrcweir #define __uuidof(I) IID_##I
54cdf0e10cSrcweir #endif
55cdf0e10cSrcweir 
56cdf0e10cSrcweir //------------------------------------------------------------------------
57cdf0e10cSrcweir // namespace directives
58cdf0e10cSrcweir //------------------------------------------------------------------------
59cdf0e10cSrcweir 
60cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
61cdf0e10cSrcweir using namespace com::sun::star::datatransfer::clipboard;
62cdf0e10cSrcweir using namespace com::sun::star::uno;
63cdf0e10cSrcweir using namespace com::sun::star::lang;
64cdf0e10cSrcweir using namespace rtl;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //------------------------------------------------------------------------
67cdf0e10cSrcweir // a helper class that will be thrown by the function validateFormatEtc
68cdf0e10cSrcweir //------------------------------------------------------------------------
69cdf0e10cSrcweir 
70cdf0e10cSrcweir class CInvalidFormatEtcException
71cdf0e10cSrcweir {
72cdf0e10cSrcweir public:
73cdf0e10cSrcweir 	HRESULT m_hr;
74cdf0e10cSrcweir 	CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {};
75cdf0e10cSrcweir };
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //------------------------------------------------------------------------
78cdf0e10cSrcweir // ctor
79cdf0e10cSrcweir //------------------------------------------------------------------------
80cdf0e10cSrcweir 
81cdf0e10cSrcweir CXTDataObject::CXTDataObject( const Reference< XMultiServiceFactory >& aServiceManager,
82cdf0e10cSrcweir 							  const Reference< XTransferable >& aXTransferable ) :
83cdf0e10cSrcweir 	m_nRefCnt( 0 ),
84cdf0e10cSrcweir 	m_SrvMgr( aServiceManager ),
85cdf0e10cSrcweir 	m_XTransferable( aXTransferable ),
86cdf0e10cSrcweir 	m_DataFormatTranslator( aServiceManager ),
87cdf0e10cSrcweir     m_bFormatEtcContainerInitialized( sal_False ),
88cdf0e10cSrcweir 	m_FormatRegistrar( m_SrvMgr, m_DataFormatTranslator )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir //------------------------------------------------------------------------
93cdf0e10cSrcweir // IUnknown->QueryInterface
94cdf0e10cSrcweir //------------------------------------------------------------------------
95cdf0e10cSrcweir 
96cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	if ( NULL == ppvObject )
99cdf0e10cSrcweir 		return E_INVALIDARG;
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	*ppvObject = NULL;
104cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) ||
105cdf0e10cSrcweir 		 ( __uuidof( IDataObject ) == iid ) )
106cdf0e10cSrcweir 	{
107cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
108cdf0e10cSrcweir 		( (LPUNKNOWN)*ppvObject )->AddRef( );
109cdf0e10cSrcweir 		hr = S_OK;
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	return hr;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
115cdf0e10cSrcweir //------------------------------------------------------------------------
116cdf0e10cSrcweir // IUnknown->AddRef
117cdf0e10cSrcweir //------------------------------------------------------------------------
118cdf0e10cSrcweir 
119cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir //------------------------------------------------------------------------
125cdf0e10cSrcweir // IUnknown->Release
126cdf0e10cSrcweir //------------------------------------------------------------------------
127cdf0e10cSrcweir 
128cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::Release( )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	ULONG nRefCnt =
131cdf0e10cSrcweir 		static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	if ( 0 == nRefCnt )
134cdf0e10cSrcweir 		delete this;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	return nRefCnt;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir //------------------------------------------------------------------------
140cdf0e10cSrcweir //
141cdf0e10cSrcweir //------------------------------------------------------------------------
142cdf0e10cSrcweir 
143cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir 	if ( !(pFormatetc && pmedium) )
146cdf0e10cSrcweir 		return E_INVALIDARG;
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	try
149cdf0e10cSrcweir 	{
150cdf0e10cSrcweir 		// prepare data transfer
151cdf0e10cSrcweir 		invalidateStgMedium( *pmedium );
152cdf0e10cSrcweir 		validateFormatEtc( pFormatetc );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 		// handle locale request, because locale is a artificial format for us
155cdf0e10cSrcweir 		if ( CF_LOCALE == pFormatetc->cfFormat )
156cdf0e10cSrcweir 			renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium );
157cdf0e10cSrcweir 		else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
158cdf0e10cSrcweir 			renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium );
159cdf0e10cSrcweir 		else
160cdf0e10cSrcweir 			renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium );
161cdf0e10cSrcweir 	}
162cdf0e10cSrcweir 	catch(UnsupportedFlavorException&)
163cdf0e10cSrcweir 	{
164cdf0e10cSrcweir 		HRESULT hr = DV_E_FORMATETC;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 		if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) )
167cdf0e10cSrcweir 			hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		return hr;
170cdf0e10cSrcweir 	}
171cdf0e10cSrcweir 	catch( CInvalidFormatEtcException& ex )
172cdf0e10cSrcweir 	{
173cdf0e10cSrcweir 		return ex.m_hr;
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 	catch( CStgTransferHelper::CStgTransferException& ex )
176cdf0e10cSrcweir 	{
177cdf0e10cSrcweir 		return translateStgExceptionCode( ex.m_hr );
178cdf0e10cSrcweir 	}
179cdf0e10cSrcweir 	catch(...)
180cdf0e10cSrcweir 	{
181cdf0e10cSrcweir 		return E_UNEXPECTED;
182cdf0e10cSrcweir 	}
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	return S_OK;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir //------------------------------------------------------------------------
188cdf0e10cSrcweir //
189cdf0e10cSrcweir //------------------------------------------------------------------------
190cdf0e10cSrcweir 
191cdf0e10cSrcweir // inline
192cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium(
193cdf0e10cSrcweir 	const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize,
194cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir 	OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer),
197cdf0e10cSrcweir 		         "Memory size less than number of bytes to transfer" );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper( AUTO_INIT );
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	// setup storage size
202cdf0e10cSrcweir 	if ( nInitStgSize > 0 )
203cdf0e10cSrcweir 		stgTransfHelper.init( nInitStgSize, GHND );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
206cdf0e10cSrcweir     sal_uInt32 nBytesWritten = 0;
207cdf0e10cSrcweir     stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten );
208cdf0e10cSrcweir     OSL_ASSERT( nBytesWritten == nBytesToTransfer );
209cdf0e10cSrcweir #else
210cdf0e10cSrcweir     stgTransfHelper.write( lpStorage, nBytesToTransfer );
211cdf0e10cSrcweir #endif
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir //------------------------------------------------------------------------
217cdf0e10cSrcweir //
218cdf0e10cSrcweir //------------------------------------------------------------------------
219cdf0e10cSrcweir 
220cdf0e10cSrcweir //inline
221cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium(
222cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
225cdf0e10cSrcweir 	{
226cdf0e10cSrcweir 		LCID lcid = m_FormatRegistrar.getSynthesizedLocale( );
227cdf0e10cSrcweir 		renderDataAndSetupStgMedium(
228cdf0e10cSrcweir 			reinterpret_cast< sal_Int8* >( &lcid ),
229cdf0e10cSrcweir 			fetc,
230cdf0e10cSrcweir 			0,
231cdf0e10cSrcweir 			sizeof( LCID ),
232cdf0e10cSrcweir 			stgmedium );
233cdf0e10cSrcweir 	}
234cdf0e10cSrcweir 	else
235cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_FORMATETC );
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir //------------------------------------------------------------------------
239cdf0e10cSrcweir //
240cdf0e10cSrcweir //------------------------------------------------------------------------
241cdf0e10cSrcweir 
242cdf0e10cSrcweir //inline
243cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium(
244cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
251cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
252cdf0e10cSrcweir 	// so we must check the any
253cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
256cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
257cdf0e10cSrcweir 	}
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 	OUString aText;
260cdf0e10cSrcweir 	aAny >>= aText;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode );
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 	// to be sure there is an ending 0
265cdf0e10cSrcweir 	sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode );
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	renderDataAndSetupStgMedium(
268cdf0e10cSrcweir 		reinterpret_cast< const sal_Int8* >( aText.getStr( ) ),
269cdf0e10cSrcweir 		fetc,
270cdf0e10cSrcweir 		nRequiredMemSize,
271cdf0e10cSrcweir 		nBytesToTransfer,
272cdf0e10cSrcweir 		stgmedium );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir //------------------------------------------------------------------------
276cdf0e10cSrcweir //
277cdf0e10cSrcweir //------------------------------------------------------------------------
278cdf0e10cSrcweir 
279cdf0e10cSrcweir //inline
280cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium(
281cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
282cdf0e10cSrcweir {
283cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
288cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
289cdf0e10cSrcweir 	// so we must check the any
290cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
291cdf0e10cSrcweir 	{
292cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
293cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
294cdf0e10cSrcweir 	}
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
297cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
298cdf0e10cSrcweir 	// so we must check the any
299cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
300cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 	Sequence< sal_Int8 > clipDataStream;
303cdf0e10cSrcweir 	aAny >>= clipDataStream;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	sal_uInt32 nRequiredMemSize = 0;
306cdf0e10cSrcweir 	if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
307cdf0e10cSrcweir 		nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	// prepare data for transmision
310cdf0e10cSrcweir 	if ( CF_DIB == fetc.cfFormat )
311cdf0e10cSrcweir 		clipDataStream = OOBmpToWinDIB( clipDataStream );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 	if ( CF_METAFILEPICT == fetc.cfFormat )
314cdf0e10cSrcweir 	{
315cdf0e10cSrcweir 		stgmedium.tymed          = TYMED_MFPICT;
316cdf0e10cSrcweir 		stgmedium.hMetaFilePict  = OOMFPictToWinMFPict( clipDataStream );
317cdf0e10cSrcweir 		stgmedium.pUnkForRelease = NULL;
318cdf0e10cSrcweir 	}
319cdf0e10cSrcweir 	else if( CF_ENHMETAFILE	== fetc.cfFormat )
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		stgmedium.tymed          = TYMED_ENHMF;
322cdf0e10cSrcweir 		stgmedium.hMetaFilePict  = OOMFPictToWinENHMFPict( clipDataStream );
323cdf0e10cSrcweir 		stgmedium.pUnkForRelease = NULL;
324cdf0e10cSrcweir 	}
325cdf0e10cSrcweir 	else
326cdf0e10cSrcweir 		renderDataAndSetupStgMedium(
327cdf0e10cSrcweir 			clipDataStream.getArray( ),
328cdf0e10cSrcweir 			fetc,
329cdf0e10cSrcweir 			nRequiredMemSize,
330cdf0e10cSrcweir 			clipDataStream.getLength( ),
331cdf0e10cSrcweir 			stgmedium );
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir //------------------------------------------------------------------------
335cdf0e10cSrcweir //
336cdf0e10cSrcweir //------------------------------------------------------------------------
337cdf0e10cSrcweir 
338cdf0e10cSrcweir HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	HRESULT hr = S_OK;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 	try
343cdf0e10cSrcweir 	{
344cdf0e10cSrcweir 		if ( CF_UNICODETEXT == fetc.cfFormat )
345cdf0e10cSrcweir 			// the transferable seems to have only text
346cdf0e10cSrcweir 			renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium );
347cdf0e10cSrcweir 		else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
348cdf0e10cSrcweir 			// the transferable seems to have only unicode text
349cdf0e10cSrcweir 			renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium );
350cdf0e10cSrcweir 		else
351cdf0e10cSrcweir 			// the transferable seems to have only text/html
352cdf0e10cSrcweir 			renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium );
353cdf0e10cSrcweir 	}
354cdf0e10cSrcweir 	catch(UnsupportedFlavorException&)
355cdf0e10cSrcweir 	{
356cdf0e10cSrcweir 		hr = DV_E_FORMATETC;
357cdf0e10cSrcweir 	}
358cdf0e10cSrcweir 	catch( CInvalidFormatEtcException& )
359cdf0e10cSrcweir 	{
360cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Unexpected exception" );
361cdf0e10cSrcweir 	}
362cdf0e10cSrcweir 	catch( CStgTransferHelper::CStgTransferException& ex )
363cdf0e10cSrcweir 	{
364cdf0e10cSrcweir 		return translateStgExceptionCode( ex.m_hr );
365cdf0e10cSrcweir 	}
366cdf0e10cSrcweir 	catch(...)
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir 		hr = E_UNEXPECTED;
369cdf0e10cSrcweir 	}
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	return hr;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir //------------------------------------------------------------------------
375cdf0e10cSrcweir // the transferable must have only text, so we will synthesize unicode text
376cdf0e10cSrcweir //------------------------------------------------------------------------
377cdf0e10cSrcweir 
378cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir 	OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat );
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
385cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
386cdf0e10cSrcweir 	// so we must check the any
387cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
388cdf0e10cSrcweir 	{
389cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
390cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
391cdf0e10cSrcweir 	}
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 	Sequence< sal_Int8 > aText;
394cdf0e10cSrcweir 	aAny >>= aText;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	MultiByteToWideCharEx(
399cdf0e10cSrcweir 		m_FormatRegistrar.getRegisteredTextCodePage( ),
400cdf0e10cSrcweir 		reinterpret_cast< char* >( aText.getArray( ) ),
401cdf0e10cSrcweir 		aText.getLength( ),
402cdf0e10cSrcweir 		stgTransfHelper );
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir //------------------------------------------------------------------------
408cdf0e10cSrcweir // the transferable must have only unicode text so we will sythesize text
409cdf0e10cSrcweir //------------------------------------------------------------------------
410cdf0e10cSrcweir 
411cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir 	OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) );
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor(
416cdf0e10cSrcweir 		m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
421cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
422cdf0e10cSrcweir 	// so we must check the any
423cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
424cdf0e10cSrcweir 	{
425cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
426cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
427cdf0e10cSrcweir 	}
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 	OUString aUnicodeText;
430cdf0e10cSrcweir 	aAny >>= aUnicodeText;
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 	WideCharToMultiByteEx(
435cdf0e10cSrcweir 		GetACP( ),
436cdf0e10cSrcweir 		reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ),
437cdf0e10cSrcweir 		aUnicodeText.getLength( ),
438cdf0e10cSrcweir 		stgTransfHelper );
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir //------------------------------------------------------------------------
444cdf0e10cSrcweir //
445cdf0e10cSrcweir //------------------------------------------------------------------------
446cdf0e10cSrcweir 
447cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir 	OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) );
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 	DataFlavor aFlavor;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 	// creating a DataFlavor on the fly
454cdf0e10cSrcweir 	aFlavor.MimeType = OUString::createFromAscii( "text/html" );
455cdf0e10cSrcweir 	aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 );
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
460cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
461cdf0e10cSrcweir 	// so we must check the any
462cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
463cdf0e10cSrcweir 	{
464cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
465cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
466cdf0e10cSrcweir 	}
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	Sequence< sal_Int8 > aTextHtmlSequence;
469cdf0e10cSrcweir 	aAny >>= aTextHtmlSequence;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir 	Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence );
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	renderDataAndSetupStgMedium(
476cdf0e10cSrcweir 		reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ),
477cdf0e10cSrcweir 		fetc,
478cdf0e10cSrcweir 		0,
479cdf0e10cSrcweir 		nBytesToTransfer,
480cdf0e10cSrcweir 		stgmedium );
481cdf0e10cSrcweir }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir //------------------------------------------------------------------------
484cdf0e10cSrcweir // IDataObject->EnumFormatEtc
485cdf0e10cSrcweir //------------------------------------------------------------------------
486cdf0e10cSrcweir 
487cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumFormatEtc(
488cdf0e10cSrcweir 	DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir 	if ( NULL == ppenumFormatetc )
491cdf0e10cSrcweir 		return E_INVALIDARG;
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 	if ( DATADIR_SET == dwDirection )
494cdf0e10cSrcweir 		return E_NOTIMPL;
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 	*ppenumFormatetc = NULL;
497cdf0e10cSrcweir 
498cdf0e10cSrcweir     InitializeFormatEtcContainer( );
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 	HRESULT hr;
501cdf0e10cSrcweir 	if ( DATADIR_GET == dwDirection )
502cdf0e10cSrcweir 	{
503cdf0e10cSrcweir 		*ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer );
504cdf0e10cSrcweir 		if ( NULL != *ppenumFormatetc )
505cdf0e10cSrcweir 			static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 		hr = ( NULL != *ppenumFormatetc ) ? S_OK : E_OUTOFMEMORY;
508cdf0e10cSrcweir 	}
509cdf0e10cSrcweir 	else
510cdf0e10cSrcweir 		hr = E_INVALIDARG;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 	return hr;
513cdf0e10cSrcweir }
514cdf0e10cSrcweir 
515cdf0e10cSrcweir //------------------------------------------------------------------------
516cdf0e10cSrcweir // IDataObject->QueryGetData
517cdf0e10cSrcweir //------------------------------------------------------------------------
518cdf0e10cSrcweir 
519cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir 	if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) )
522cdf0e10cSrcweir 		return E_INVALIDARG;
523cdf0e10cSrcweir 
524cdf0e10cSrcweir     InitializeFormatEtcContainer( );
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 	return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir 
529cdf0e10cSrcweir //------------------------------------------------------------------------
530cdf0e10cSrcweir // IDataObject->GetDataHere
531cdf0e10cSrcweir //------------------------------------------------------------------------
532cdf0e10cSrcweir 
533cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir 	return E_NOTIMPL;
536cdf0e10cSrcweir }
537cdf0e10cSrcweir 
538cdf0e10cSrcweir //------------------------------------------------------------------------
539cdf0e10cSrcweir // IDataObject->GetCanonicalFormatEtc
540cdf0e10cSrcweir //------------------------------------------------------------------------
541cdf0e10cSrcweir 
542cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
543cdf0e10cSrcweir {
544cdf0e10cSrcweir 	return E_NOTIMPL;
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir //------------------------------------------------------------------------
548cdf0e10cSrcweir // IDataObject->SetData
549cdf0e10cSrcweir //------------------------------------------------------------------------
550cdf0e10cSrcweir 
551cdf0e10cSrcweir STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir 	return E_NOTIMPL;
554cdf0e10cSrcweir }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir //------------------------------------------------------------------------
557cdf0e10cSrcweir // IDataObject->DAdvise
558cdf0e10cSrcweir //------------------------------------------------------------------------
559cdf0e10cSrcweir 
560cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
561cdf0e10cSrcweir {
562cdf0e10cSrcweir 	return E_NOTIMPL;
563cdf0e10cSrcweir }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir //------------------------------------------------------------------------
566cdf0e10cSrcweir // IDataObject->DUnadvise
567cdf0e10cSrcweir //------------------------------------------------------------------------
568cdf0e10cSrcweir 
569cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
570cdf0e10cSrcweir {
571cdf0e10cSrcweir 	return E_NOTIMPL;
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir //------------------------------------------------------------------------
575cdf0e10cSrcweir // IDataObject->EnumDAdvise
576cdf0e10cSrcweir //------------------------------------------------------------------------
577cdf0e10cSrcweir 
578cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir 	return E_NOTIMPL;
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir //------------------------------------------------------------------------
584cdf0e10cSrcweir // for our convenience
585cdf0e10cSrcweir //------------------------------------------------------------------------
586cdf0e10cSrcweir 
587cdf0e10cSrcweir CXTDataObject::operator IDataObject*( )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir 	return static_cast< IDataObject* >( this );
590cdf0e10cSrcweir }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir //------------------------------------------------------------------------
593cdf0e10cSrcweir //
594cdf0e10cSrcweir //------------------------------------------------------------------------
595cdf0e10cSrcweir 
596cdf0e10cSrcweir inline
597cdf0e10cSrcweir DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const
598cdf0e10cSrcweir {
599cdf0e10cSrcweir 	DataFlavor aFlavor;
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 	if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
602cdf0e10cSrcweir 		aFlavor =
603cdf0e10cSrcweir 			m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) );
604cdf0e10cSrcweir 	else
605cdf0e10cSrcweir 		aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc );
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 	if ( !aFlavor.MimeType.getLength( ) )
608cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	return aFlavor;
611cdf0e10cSrcweir }
612cdf0e10cSrcweir 
613cdf0e10cSrcweir //------------------------------------------------------------------------
614cdf0e10cSrcweir //
615cdf0e10cSrcweir //------------------------------------------------------------------------
616cdf0e10cSrcweir 
617cdf0e10cSrcweir inline
618cdf0e10cSrcweir void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const
619cdf0e10cSrcweir {
620cdf0e10cSrcweir 	OSL_ASSERT( lpFormatEtc );
621cdf0e10cSrcweir 
622cdf0e10cSrcweir 	if ( lpFormatEtc->lindex != -1 )
623cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_LINDEX );
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 	if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) &&
626cdf0e10cSrcweir 		 !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) )
627cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_DVASPECT );
628cdf0e10cSrcweir 
629cdf0e10cSrcweir 	if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) &&
630cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ISTREAM) &&
631cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_MFPICT) &&
632cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ENHMF) )
633cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	if ( lpFormatEtc->cfFormat == CF_METAFILEPICT &&
636cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_MFPICT) )
637cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
638cdf0e10cSrcweir 
639cdf0e10cSrcweir 	if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE &&
640cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ENHMF) )
641cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir //------------------------------------------------------------------------
645cdf0e10cSrcweir //
646cdf0e10cSrcweir //------------------------------------------------------------------------
647cdf0e10cSrcweir 
648cdf0e10cSrcweir //inline
649cdf0e10cSrcweir void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc,
650cdf0e10cSrcweir 											 CStgTransferHelper& stgTransHlp,
651cdf0e10cSrcweir 											 STGMEDIUM& stgmedium )
652cdf0e10cSrcweir {
653cdf0e10cSrcweir 	stgmedium.pUnkForRelease = NULL;
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 	if ( fetc.cfFormat == CF_METAFILEPICT )
656cdf0e10cSrcweir 	{
657cdf0e10cSrcweir 		stgmedium.tymed         = TYMED_MFPICT;
658cdf0e10cSrcweir 		stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) );
659cdf0e10cSrcweir 	}
660cdf0e10cSrcweir 	else if ( fetc.cfFormat == CF_ENHMETAFILE )
661cdf0e10cSrcweir 	{
662cdf0e10cSrcweir 		stgmedium.tymed        = TYMED_ENHMF;
663cdf0e10cSrcweir 		stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) );
664cdf0e10cSrcweir 	}
665cdf0e10cSrcweir 	else if ( fetc.tymed & TYMED_HGLOBAL )
666cdf0e10cSrcweir 	{
667cdf0e10cSrcweir 		stgmedium.tymed   = TYMED_HGLOBAL;
668cdf0e10cSrcweir 		stgmedium.hGlobal = stgTransHlp.getHGlobal( );
669cdf0e10cSrcweir 	}
670cdf0e10cSrcweir 	else if ( fetc.tymed & TYMED_ISTREAM )
671cdf0e10cSrcweir 	{
672cdf0e10cSrcweir 		stgmedium.tymed = TYMED_ISTREAM;
673cdf0e10cSrcweir 		stgTransHlp.getIStream( &stgmedium.pstm );
674cdf0e10cSrcweir 	}
675cdf0e10cSrcweir 	else
676cdf0e10cSrcweir 		OSL_ASSERT( sal_False );
677cdf0e10cSrcweir }
678cdf0e10cSrcweir 
679cdf0e10cSrcweir //------------------------------------------------------------------------
680cdf0e10cSrcweir //
681cdf0e10cSrcweir //------------------------------------------------------------------------
682cdf0e10cSrcweir 
683cdf0e10cSrcweir inline
684cdf0e10cSrcweir void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const
685cdf0e10cSrcweir {
686cdf0e10cSrcweir 	stgmedium.tymed = TYMED_NULL;
687cdf0e10cSrcweir }
688cdf0e10cSrcweir 
689cdf0e10cSrcweir //------------------------------------------------------------------------
690cdf0e10cSrcweir //
691cdf0e10cSrcweir //------------------------------------------------------------------------
692cdf0e10cSrcweir 
693cdf0e10cSrcweir inline
694cdf0e10cSrcweir HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const
695cdf0e10cSrcweir {
696cdf0e10cSrcweir 	HRESULT hrTransl;
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	switch( hr )
699cdf0e10cSrcweir 	{
700cdf0e10cSrcweir 	case STG_E_MEDIUMFULL:
701cdf0e10cSrcweir 		hrTransl = hr;
702cdf0e10cSrcweir 		break;
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 	default:
705cdf0e10cSrcweir 		hrTransl = E_UNEXPECTED;
706cdf0e10cSrcweir 		break;
707cdf0e10cSrcweir 	}
708cdf0e10cSrcweir 
709cdf0e10cSrcweir 	return hrTransl;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir //------------------------------------------------------------------------
713cdf0e10cSrcweir //
714cdf0e10cSrcweir //------------------------------------------------------------------------
715cdf0e10cSrcweir 
716cdf0e10cSrcweir inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( )
717cdf0e10cSrcweir {
718cdf0e10cSrcweir     if ( !m_bFormatEtcContainerInitialized )
719cdf0e10cSrcweir     {
720cdf0e10cSrcweir         m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer );
721cdf0e10cSrcweir         m_bFormatEtcContainerInitialized = sal_True;
722cdf0e10cSrcweir     }
723cdf0e10cSrcweir }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir //============================================================================
726cdf0e10cSrcweir // CEnumFormatEtc
727cdf0e10cSrcweir //============================================================================
728cdf0e10cSrcweir 
729cdf0e10cSrcweir //----------------------------------------------------------------------------
730cdf0e10cSrcweir // ctor
731cdf0e10cSrcweir //----------------------------------------------------------------------------
732cdf0e10cSrcweir 
733cdf0e10cSrcweir CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) :
734cdf0e10cSrcweir 	m_nRefCnt( 0 ),
735cdf0e10cSrcweir 	m_lpUnkOuter( lpUnkOuter ),
736cdf0e10cSrcweir 	m_FormatEtcContainer( aFormatEtcContainer )
737cdf0e10cSrcweir {
738cdf0e10cSrcweir 	Reset( );
739cdf0e10cSrcweir }
740cdf0e10cSrcweir 
741cdf0e10cSrcweir //----------------------------------------------------------------------------
742cdf0e10cSrcweir // IUnknown->QueryInterface
743cdf0e10cSrcweir //----------------------------------------------------------------------------
744cdf0e10cSrcweir 
745cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
746cdf0e10cSrcweir {
747cdf0e10cSrcweir 	if ( NULL == ppvObject )
748cdf0e10cSrcweir 		return E_INVALIDARG;
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	*ppvObject = NULL;
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) ||
755cdf0e10cSrcweir 		 ( __uuidof( IEnumFORMATETC ) == iid ) )
756cdf0e10cSrcweir 	{
757cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
758cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
759cdf0e10cSrcweir 		hr = S_OK;
760cdf0e10cSrcweir 	}
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 	return hr;
763cdf0e10cSrcweir }
764cdf0e10cSrcweir 
765cdf0e10cSrcweir //----------------------------------------------------------------------------
766cdf0e10cSrcweir // IUnknown->AddRef
767cdf0e10cSrcweir //----------------------------------------------------------------------------
768cdf0e10cSrcweir 
769cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
770cdf0e10cSrcweir {
771cdf0e10cSrcweir 	// keep the dataobject alive
772cdf0e10cSrcweir 	m_lpUnkOuter->AddRef( );
773cdf0e10cSrcweir 	return InterlockedIncrement( &m_nRefCnt );
774cdf0e10cSrcweir }
775cdf0e10cSrcweir 
776cdf0e10cSrcweir //----------------------------------------------------------------------------
777cdf0e10cSrcweir // IUnknown->Release
778cdf0e10cSrcweir //----------------------------------------------------------------------------
779cdf0e10cSrcweir 
780cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
781cdf0e10cSrcweir {
782cdf0e10cSrcweir 	// release the outer dataobject
783cdf0e10cSrcweir 	m_lpUnkOuter->Release( );
784cdf0e10cSrcweir 
785cdf0e10cSrcweir 	ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
786cdf0e10cSrcweir 	if ( 0 == nRefCnt )
787cdf0e10cSrcweir 		delete this;
788cdf0e10cSrcweir 
789cdf0e10cSrcweir 	return nRefCnt;
790cdf0e10cSrcweir }
791cdf0e10cSrcweir 
792cdf0e10cSrcweir //----------------------------------------------------------------------------
793cdf0e10cSrcweir // IEnumFORMATETC->Next
794cdf0e10cSrcweir //----------------------------------------------------------------------------
795cdf0e10cSrcweir 
796cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir 	if ( ( nRequested < 1 ) ||
799cdf0e10cSrcweir 		 (( nRequested > 1 ) && ( NULL == lpFetched )) ||
800cdf0e10cSrcweir 		 IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) )
801cdf0e10cSrcweir 		return E_INVALIDARG;
802cdf0e10cSrcweir 
803cdf0e10cSrcweir 	sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested );
804cdf0e10cSrcweir 
805cdf0e10cSrcweir 	if ( NULL != lpFetched )
806cdf0e10cSrcweir 		*lpFetched = nFetched;
807cdf0e10cSrcweir 
808cdf0e10cSrcweir 	return (nFetched == nRequested) ? S_OK : S_FALSE;
809cdf0e10cSrcweir }
810cdf0e10cSrcweir 
811cdf0e10cSrcweir //----------------------------------------------------------------------------
812cdf0e10cSrcweir // IEnumFORMATETC->Skip
813cdf0e10cSrcweir //----------------------------------------------------------------------------
814cdf0e10cSrcweir 
815cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir 	return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE;
818cdf0e10cSrcweir }
819cdf0e10cSrcweir 
820cdf0e10cSrcweir //----------------------------------------------------------------------------
821cdf0e10cSrcweir // IEnumFORMATETC->Reset
822cdf0e10cSrcweir //----------------------------------------------------------------------------
823cdf0e10cSrcweir 
824cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Reset( )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir 	m_FormatEtcContainer.beginEnumFormatEtc( );
827cdf0e10cSrcweir 	return S_OK;
828cdf0e10cSrcweir }
829cdf0e10cSrcweir 
830cdf0e10cSrcweir //----------------------------------------------------------------------------
831cdf0e10cSrcweir // IEnumFORMATETC->Clone
832cdf0e10cSrcweir //----------------------------------------------------------------------------
833cdf0e10cSrcweir 
834cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
835cdf0e10cSrcweir {
836cdf0e10cSrcweir 	if ( NULL == ppenum )
837cdf0e10cSrcweir 		return E_INVALIDARG;
838cdf0e10cSrcweir 
839cdf0e10cSrcweir 	*ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer );
840cdf0e10cSrcweir 	if ( NULL != ppenum )
841cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir 	return ( NULL != *ppenum ) ? S_OK : E_OUTOFMEMORY;
844cdf0e10cSrcweir }
845