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