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