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
getMetaFileHandle_Impl(sal_Bool isEnhMeta)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
GetData(FORMATETC * pFormatetc,STGMEDIUM * pMedium)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
GetDataHere(FORMATETC * pFormatetc,STGMEDIUM * pMedium)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
QueryGetData(FORMATETC * pFormatetc)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
GetCanonicalFormatEtc(FORMATETC * pFormatetcIn,FORMATETC * pFormatetcOut)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
SetData(FORMATETC *,STGMEDIUM *,BOOL)277cdf0e10cSrcweir STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * /*pFormatetc*/, STGMEDIUM * /*pMedium*/, BOOL /*fRelease*/ )
278cdf0e10cSrcweir {
279cdf0e10cSrcweir return E_NOTIMPL;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir
EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC **)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
DAdvise(FORMATETC * pFormatetc,DWORD advf,IAdviseSink * pAdvSink,DWORD * pdwConnection)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
DUnadvise(DWORD dwConnection)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
EnumDAdvise(IEnumSTATDATA ** ppenumAdvise)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