1*f78e906fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f78e906fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f78e906fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f78e906fSAndrew Rist  * distributed with this work for additional information
6*f78e906fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f78e906fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f78e906fSAndrew Rist  * "License"); you may not use this file except in compliance
9*f78e906fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f78e906fSAndrew Rist  *
11*f78e906fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f78e906fSAndrew Rist  *
13*f78e906fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f78e906fSAndrew Rist  * software distributed under the License is distributed on an
15*f78e906fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f78e906fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*f78e906fSAndrew Rist  * specific language governing permissions and limitations
18*f78e906fSAndrew Rist  * under the License.
19*f78e906fSAndrew Rist  *
20*f78e906fSAndrew Rist  *************************************************************/
21*f78e906fSAndrew Rist 
22*f78e906fSAndrew Rist 
23cdf0e10cSrcweir #if defined(_MSC_VER) && (_MSC_VER > 1310)
24cdf0e10cSrcweir #pragma warning(disable : 4917 4555)
25cdf0e10cSrcweir #endif
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // actually this workaround should be in presys.h!
28cdf0e10cSrcweir //#define UINT64 USE_WIN_UINT64
29cdf0e10cSrcweir //#define INT64 USE_WIN_INT64
30cdf0e10cSrcweir //#define UINT32 USE_WIN_UINT32
31cdf0e10cSrcweir //#define INT32 USE_WIN_INT32
32cdf0e10cSrcweir 
33cdf0e10cSrcweir //#include <tools/presys.h>
34cdf0e10cSrcweir #include "embeddoc.hxx"
35cdf0e10cSrcweir //#include <tools/postsys.h>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir //#undef UINT64
38cdf0e10cSrcweir //#undef INT64
39cdf0e10cSrcweir //#undef UINT32
40cdf0e10cSrcweir //#undef INT32
41cdf0e10cSrcweir 
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <com/sun/star/uno/Any.h>
44cdf0e10cSrcweir #include <com/sun/star/uno/Exception.hpp>
45cdf0e10cSrcweir #include <com/sun/star/datatransfer/XTransferable.hpp>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <osl/thread.h>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace ::com::sun::star;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir //===============================================================================
53cdf0e10cSrcweir // EmbedDocument_Impl
54cdf0e10cSrcweir //===============================================================================
55cdf0e10cSrcweir 
56cdf0e10cSrcweir sal_uInt64 EmbedDocument_Impl::getMetaFileHandle_Impl( sal_Bool isEnhMeta )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir 	sal_uInt64 pResult = NULL;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 	uno::Reference< datatransfer::XTransferable > xTransferable( m_pDocHolder->GetDocument(), uno::UNO_QUERY );
61cdf0e10cSrcweir 	if ( xTransferable.is() )
62cdf0e10cSrcweir 	{
63cdf0e10cSrcweir 		uno::Sequence< sal_Int8 > aMetaBuffer;
64cdf0e10cSrcweir 		datatransfer::DataFlavor aFlavor;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 		if ( isEnhMeta )
67cdf0e10cSrcweir 		{
68cdf0e10cSrcweir 			aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
69cdf0e10cSrcweir 												"application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) );
70cdf0e10cSrcweir 			aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
71cdf0e10cSrcweir 		}
72cdf0e10cSrcweir 		else
73cdf0e10cSrcweir 		{
74cdf0e10cSrcweir 			aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
75cdf0e10cSrcweir 												"application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) );
76cdf0e10cSrcweir 			aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows GDIMetaFile" ) );
77cdf0e10cSrcweir 		}
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 		aFlavor.DataType = getCppuType( (const sal_uInt64*) 0 );
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 		uno::Any aAny = xTransferable->getTransferData( aFlavor );
82cdf0e10cSrcweir 		aAny >>= pResult;
83cdf0e10cSrcweir 	}
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 	return pResult;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir //-------------------------------------------------------------------------------
89cdf0e10cSrcweir // IDataObject
90cdf0e10cSrcweir 
91cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
92cdf0e10cSrcweir {
93cdf0e10cSrcweir 	if ( !pFormatetc )
94cdf0e10cSrcweir 		return DV_E_FORMATETC;
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	if ( !pMedium )
97cdf0e10cSrcweir 		return STG_E_MEDIUMFULL;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
100cdf0e10cSrcweir 	  || pFormatetc->dwAspect == DVASPECT_ICON
101cdf0e10cSrcweir 	  || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
102cdf0e10cSrcweir 		return DV_E_DVASPECT;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir 	if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
105cdf0e10cSrcweir 	{
106cdf0e10cSrcweir 		if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
107cdf0e10cSrcweir 			return DV_E_TYMED;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 		HENHMETAFILE hMeta = reinterpret_cast<HENHMETAFILE>( getMetaFileHandle_Impl( sal_True ) );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 		if ( hMeta )
112cdf0e10cSrcweir 		{
113cdf0e10cSrcweir 			pMedium->tymed = TYMED_ENHMF;
114cdf0e10cSrcweir 			pMedium->hEnhMetaFile = hMeta;
115cdf0e10cSrcweir 			pMedium->pUnkForRelease = NULL;
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 			return S_OK;
118cdf0e10cSrcweir 		}
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 		return STG_E_MEDIUMFULL;
121cdf0e10cSrcweir 	}
122cdf0e10cSrcweir 	else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
123cdf0e10cSrcweir 	{
124cdf0e10cSrcweir 	  	if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
125cdf0e10cSrcweir 			return DV_E_TYMED;
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 		HGLOBAL hMeta = reinterpret_cast<HGLOBAL>( getMetaFileHandle_Impl( sal_False ) );
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 		if ( hMeta )
130cdf0e10cSrcweir 		{
131cdf0e10cSrcweir 			pMedium->tymed = TYMED_MFPICT;
132cdf0e10cSrcweir 			pMedium->hMetaFilePict = hMeta;
133cdf0e10cSrcweir 			pMedium->pUnkForRelease = NULL;
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 			return S_OK;
136cdf0e10cSrcweir 		}
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 		return STG_E_MEDIUMFULL;
139cdf0e10cSrcweir 	}
140cdf0e10cSrcweir 	else
141cdf0e10cSrcweir 	{
142cdf0e10cSrcweir 		CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" );
143cdf0e10cSrcweir 		CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" );
144cdf0e10cSrcweir 		if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
145cdf0e10cSrcweir 		{
146cdf0e10cSrcweir 			if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
147cdf0e10cSrcweir 				return DV_E_TYMED;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 			CComPtr< IStorage > pNewStg;
150cdf0e10cSrcweir 			HRESULT hr = StgCreateDocfile( NULL, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, 0, &pNewStg );
151cdf0e10cSrcweir 			if ( FAILED( hr ) || !pNewStg ) return STG_E_MEDIUMFULL;
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 			hr = SaveTo_Impl( pNewStg );
154cdf0e10cSrcweir 			if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 			pMedium->tymed = TYMED_ISTORAGE;
157cdf0e10cSrcweir 			pMedium->pstg = pNewStg;
158cdf0e10cSrcweir 			pMedium->pstg->AddRef();
159cdf0e10cSrcweir 			pMedium->pUnkForRelease = ( IUnknown* )pNewStg;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 			return S_OK;
162cdf0e10cSrcweir 		}
163cdf0e10cSrcweir 	}
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 	return DV_E_FORMATETC;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir 	if ( !pFormatetc )
171cdf0e10cSrcweir 		return DV_E_FORMATETC;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	if ( !pMedium )
174cdf0e10cSrcweir 		return STG_E_MEDIUMFULL;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 	if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
177cdf0e10cSrcweir 	  || pFormatetc->dwAspect == DVASPECT_ICON
178cdf0e10cSrcweir 	  || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
179cdf0e10cSrcweir 		return DV_E_DVASPECT;
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 	CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" );
182cdf0e10cSrcweir 	CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" );
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
185cdf0e10cSrcweir 	{
186cdf0e10cSrcweir 		if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
187cdf0e10cSrcweir 			return DV_E_TYMED;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 		if ( !pMedium->pstg ) return STG_E_MEDIUMFULL;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 		HRESULT hr = SaveTo_Impl( pMedium->pstg );
192cdf0e10cSrcweir 		if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 		pMedium->tymed = TYMED_ISTORAGE;
195cdf0e10cSrcweir 		pMedium->pUnkForRelease = NULL;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 		return S_OK;
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 	return DV_E_FORMATETC;
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir 	if ( pFormatetc )
206cdf0e10cSrcweir 	{
207cdf0e10cSrcweir 		if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
208cdf0e10cSrcweir 		  || pFormatetc->dwAspect == DVASPECT_ICON
209cdf0e10cSrcweir 		  || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
210cdf0e10cSrcweir 			return DV_E_DVASPECT;
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 		if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
213cdf0e10cSrcweir 		{
214cdf0e10cSrcweir 			if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
215cdf0e10cSrcweir 				return DV_E_TYMED;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 			return S_OK;
218cdf0e10cSrcweir 		}
219cdf0e10cSrcweir 		else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
220cdf0e10cSrcweir 		{
221cdf0e10cSrcweir 	  		if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
222cdf0e10cSrcweir 				return DV_E_TYMED;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 			return S_OK;
225cdf0e10cSrcweir 		}
226cdf0e10cSrcweir 		else
227cdf0e10cSrcweir 		{
228cdf0e10cSrcweir 			CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" );
229cdf0e10cSrcweir 			CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" );
230cdf0e10cSrcweir 			if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
231cdf0e10cSrcweir 			{
232cdf0e10cSrcweir 				if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
233cdf0e10cSrcweir 					return DV_E_TYMED;
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 				return S_OK;
236cdf0e10cSrcweir 			}
237cdf0e10cSrcweir 		}
238cdf0e10cSrcweir 	}
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	return DV_E_FORMATETC;
241cdf0e10cSrcweir 
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir 	if ( !pFormatetcIn || !pFormatetcOut )
247cdf0e10cSrcweir 		return DV_E_FORMATETC;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 	pFormatetcOut->ptd = NULL;
250cdf0e10cSrcweir 	pFormatetcOut->cfFormat = pFormatetcIn->cfFormat;
251cdf0e10cSrcweir 	pFormatetcOut->dwAspect = DVASPECT_CONTENT;
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 	if ( pFormatetcIn->cfFormat == CF_ENHMETAFILE )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		pFormatetcOut->tymed = TYMED_ENHMF;
256cdf0e10cSrcweir 		return S_OK;
257cdf0e10cSrcweir 	}
258cdf0e10cSrcweir 	else if ( pFormatetcIn->cfFormat == CF_METAFILEPICT )
259cdf0e10cSrcweir 	{
260cdf0e10cSrcweir   		pFormatetcOut->tymed = TYMED_MFPICT;
261cdf0e10cSrcweir 		return S_OK;
262cdf0e10cSrcweir 	}
263cdf0e10cSrcweir 	else
264cdf0e10cSrcweir 	{
265cdf0e10cSrcweir 		CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" );
266cdf0e10cSrcweir 		CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" );
267cdf0e10cSrcweir 		if ( pFormatetcIn->cfFormat == cf_embSource || pFormatetcIn->cfFormat == cf_embObj )
268cdf0e10cSrcweir 		{
269cdf0e10cSrcweir 			pFormatetcOut->tymed = TYMED_ISTORAGE;
270cdf0e10cSrcweir 			return S_OK;
271cdf0e10cSrcweir 		}
272cdf0e10cSrcweir 	}
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	return DV_E_FORMATETC;
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * /*pFormatetc*/, STGMEDIUM * /*pMedium*/, BOOL /*fRelease*/ )
278cdf0e10cSrcweir {
279cdf0e10cSrcweir 	return E_NOTIMPL;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** /*ppFormatetc*/ )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir 	if ( dwDirection == DATADIR_GET )
285cdf0e10cSrcweir 		return OLE_S_USEREG;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	return E_NOTIMPL;
288cdf0e10cSrcweir }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection )
291cdf0e10cSrcweir {
292cdf0e10cSrcweir 	if ( !m_pDAdviseHolder )
293cdf0e10cSrcweir 		if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
294cdf0e10cSrcweir 			return E_OUTOFMEMORY;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	return m_pDAdviseHolder->Advise( (IDataObject*)this, pFormatetc, advf, pAdvSink, pdwConnection );
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::DUnadvise( DWORD dwConnection )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir 	if ( !m_pDAdviseHolder )
302cdf0e10cSrcweir 		if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
303cdf0e10cSrcweir 			return E_OUTOFMEMORY;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	return m_pDAdviseHolder->Unadvise( dwConnection );
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise )
309cdf0e10cSrcweir {
310cdf0e10cSrcweir 	if ( !m_pDAdviseHolder )
311cdf0e10cSrcweir 		if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
312cdf0e10cSrcweir 			return E_OUTOFMEMORY;
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	return m_pDAdviseHolder->EnumAdvise( ppenumAdvise );
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir // Fix strange warnings about some
318cdf0e10cSrcweir // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
319cdf0e10cSrcweir // warning C4505: 'xxx' : unreferenced local function has been removed
320cdf0e10cSrcweir #if defined(_MSC_VER)
321cdf0e10cSrcweir #pragma warning(disable: 4505)
322cdf0e10cSrcweir #endif
323