LibreOffice Module dtrans (master)  1
XTDataObject.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <osl/diagnose.h>
22 #include <o3tl/safeint.hxx>
23 
24 #include "XTDataObject.hxx"
25 #include <com/sun/star/datatransfer/DataFlavor.hpp>
26 #include "../misc/ImplHelper.hxx"
27 #include "DTransHelper.hxx"
28 #include "TxtCnvtHlp.hxx"
29 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
30 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
31 #include <com/sun/star/awt/AsyncCallback.hpp>
32 #include <com/sun/star/awt/XCallback.hpp>
33 #include "FmtFilter.hxx"
34 #include <cppuhelper/implbase.hxx>
35 
36 #if !defined WIN32_LEAN_AND_MEAN
37 # define WIN32_LEAN_AND_MEAN
38 #endif
39 #include <windows.h>
40 #include <shlobj.h>
41 
42 using namespace com::sun::star::datatransfer;
44 using namespace com::sun::star::uno;
45 using namespace com::sun::star::lang;
46 
47 namespace {
48 
49 void setupStgMedium( const FORMATETC& fetc,
50  CStgTransferHelper& stgTransHlp,
51  STGMEDIUM& stgmedium )
52 {
53  stgmedium.pUnkForRelease = nullptr;
54 
55  if ( fetc.cfFormat == CF_METAFILEPICT )
56  {
57  stgmedium.tymed = TYMED_MFPICT;
58  stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) );
59  }
60  else if ( fetc.cfFormat == CF_ENHMETAFILE )
61  {
62  stgmedium.tymed = TYMED_ENHMF;
63  stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) );
64  }
65  else if ( fetc.tymed & TYMED_HGLOBAL )
66  {
67  stgmedium.tymed = TYMED_HGLOBAL;
68  stgmedium.hGlobal = stgTransHlp.getHGlobal( );
69  }
70  else if ( fetc.tymed & TYMED_ISTREAM )
71  {
72  stgmedium.tymed = TYMED_ISTREAM;
73  stgTransHlp.getIStream( &stgmedium.pstm );
74  }
75  else
76  OSL_ASSERT( false );
77 }
78 
85 class AsyncDereference : public cppu::WeakImplHelper<css::awt::XCallback>
86 {
87  Reference<XTransferable> maTransferable;
88 
89 public:
90  AsyncDereference(css::uno::Reference<css::datatransfer::XTransferable> const & rTransferable)
91  : maTransferable(rTransferable)
92  {}
93 
94  virtual void SAL_CALL notify(css::uno::Any const &) override
95  {
96  maTransferable.set(nullptr);
97  }
98 };
99 
100 // a helper class that will be thrown by the function validateFormatEtc
101 
102 class CInvalidFormatEtcException
103 {
104 public:
105  HRESULT m_hr;
106  explicit CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {};
107 };
108 
109 void validateFormatEtc( LPFORMATETC lpFormatEtc )
110 {
111  OSL_ASSERT( lpFormatEtc );
112 
113  if ( lpFormatEtc->lindex != -1 )
114  throw CInvalidFormatEtcException( DV_E_LINDEX );
115 
116  if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) &&
117  !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) )
118  throw CInvalidFormatEtcException( DV_E_DVASPECT );
119 
120  if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) &&
121  !(lpFormatEtc->tymed & TYMED_ISTREAM) &&
122  !(lpFormatEtc->tymed & TYMED_MFPICT) &&
123  !(lpFormatEtc->tymed & TYMED_ENHMF) )
124  throw CInvalidFormatEtcException( DV_E_TYMED );
125 
126  if ( lpFormatEtc->cfFormat == CF_METAFILEPICT &&
127  !(lpFormatEtc->tymed & TYMED_MFPICT) )
128  throw CInvalidFormatEtcException( DV_E_TYMED );
129 
130  if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE &&
131  !(lpFormatEtc->tymed & TYMED_ENHMF) )
132  throw CInvalidFormatEtcException( DV_E_TYMED );
133 }
134 
135 void invalidateStgMedium( STGMEDIUM& stgmedium )
136 {
137  stgmedium.tymed = TYMED_NULL;
138 }
139 
140 HRESULT translateStgExceptionCode( HRESULT hr )
141 {
142  HRESULT hrTransl;
143 
144  switch( hr )
145  {
146  case STG_E_MEDIUMFULL:
147  hrTransl = hr;
148  break;
149 
150  default:
151  hrTransl = E_UNEXPECTED;
152  break;
153  }
154 
155  return hrTransl;
156 }
157 
158 // inline
159 void renderDataAndSetupStgMedium(
160  const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize,
161  sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium )
162 {
163  OSL_PRECOND( !nInitStgSize || (nInitStgSize >= nBytesToTransfer),
164  "Memory size less than number of bytes to transfer" );
165 
166  CStgTransferHelper stgTransfHelper( AUTO_INIT );
167 
168  // setup storage size
169  if ( nInitStgSize > 0 )
170  stgTransfHelper.init( nInitStgSize );
171 
172 #if OSL_DEBUG_LEVEL > 0
173  sal_uInt32 nBytesWritten = 0;
174  stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten );
175  OSL_ASSERT( nBytesWritten == nBytesToTransfer );
176 #else
177  stgTransfHelper.write( lpStorage, nBytesToTransfer );
178 #endif
179 
180  setupStgMedium( fetc, stgTransfHelper, stgmedium );
181 }
182 
183 }
184 
186  const Reference< XTransferable >& aXTransferable )
187  : m_nRefCnt( 0 )
188  , m_XTransferable( aXTransferable )
189  , m_XComponentContext( rxContext )
190  , m_bFormatEtcContainerInitialized( false )
191  , m_DataFormatTranslator( rxContext )
192  , m_FormatRegistrar( rxContext, m_DataFormatTranslator )
193 {
194 }
195 
197 {
198  css::awt::AsyncCallback::create(m_XComponentContext)->addCallback(
199  new AsyncDereference(m_XTransferable),
200  css::uno::Any());
201 }
202 
203 // IUnknown->QueryInterface
204 
205 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, void** ppvObject )
206 {
207  if ( nullptr == ppvObject )
208  return E_INVALIDARG;
209 
210  HRESULT hr = E_NOINTERFACE;
211 
212  *ppvObject = nullptr;
213  if ( ( __uuidof( IUnknown ) == iid ) ||
214  ( __uuidof( IDataObject ) == iid ) )
215  {
216  *ppvObject = static_cast< IUnknown* >( this );
217  static_cast<LPUNKNOWN>(*ppvObject)->AddRef( );
218  hr = S_OK;
219  }
220 
221  return hr;
222 }
223 
224 // IUnknown->AddRef
225 
226 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
227 {
228  return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
229 }
230 
231 // IUnknown->Release
232 
233 STDMETHODIMP_(ULONG) CXTDataObject::Release( )
234 {
235  ULONG nRefCnt =
236  static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
237 
238  if ( 0 == nRefCnt )
239  delete this;
240 
241  return nRefCnt;
242 }
243 
244 STDMETHODIMP CXTDataObject::GetData( FORMATETC * pFormatetc, STGMEDIUM * pmedium )
245 {
246  if ( !(pFormatetc && pmedium) )
247  return E_INVALIDARG;
248 
249  try
250  {
251  // prepare data transfer
252  invalidateStgMedium( *pmedium );
253  validateFormatEtc( pFormatetc );
254 
255  // handle locale request, because locale is an artificial format for us
256  if ( CF_LOCALE == pFormatetc->cfFormat )
257  renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium );
258  else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
259  renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium );
260  else
261  renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium );
262  }
263  catch(UnsupportedFlavorException&)
264  {
265  HRESULT hr = DV_E_FORMATETC;
266 
267  CFormatEtc aFormatetc(*pFormatetc);
269  hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium );
270 
271  return hr;
272  }
273  catch( CInvalidFormatEtcException& ex )
274  {
275  return ex.m_hr;
276  }
278  {
279  return translateStgExceptionCode( ex.m_hr );
280  }
281  catch(...)
282  {
283  return E_UNEXPECTED;
284  }
285 
286  return S_OK;
287 }
288 
289 //inline
291  FORMATETC const & fetc, STGMEDIUM& stgmedium )
292 {
294  throw CInvalidFormatEtcException( DV_E_FORMATETC );
296  renderDataAndSetupStgMedium(
297  reinterpret_cast< sal_Int8* >( &lcid ),
298  fetc,
299  0,
300  sizeof( LCID ),
301  stgmedium );
302 }
303 
305  FORMATETC const & fetc, STGMEDIUM& stgmedium )
306 {
307  DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
308 
309  Any aAny = m_XTransferable->getTransferData( aFlavor );
310 
311  // unfortunately not all transferables fulfill the
312  // spec. and do throw an UnsupportedFlavorException
313  // so we must check the any
314  if ( !aAny.hasValue( ) )
315  {
316  OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
317  throw UnsupportedFlavorException( );
318  }
319 
320  OUString aText;
321  aAny >>= aText;
322 
323  sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode );
324 
325  // to be sure there is an ending 0
326  sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode );
327 
328  renderDataAndSetupStgMedium(
329  reinterpret_cast< const sal_Int8* >( aText.getStr( ) ),
330  fetc,
331  nRequiredMemSize,
332  nBytesToTransfer,
333  stgmedium );
334 }
335 
337  FORMATETC& fetc, STGMEDIUM& stgmedium )
338 {
339  DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
340 
341  Any aAny = m_XTransferable->getTransferData( aFlavor );
342 
343  // unfortunately not all transferables fulfill the
344  // spec. and do throw an UnsupportedFlavorException
345  // so we must check the any
346  if ( !aAny.hasValue( ) )
347  {
348  OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
349  throw UnsupportedFlavorException( );
350  }
351 
352  // unfortunately not all transferables fulfill the
353  // spec. and do throw an UnsupportedFlavorException
354  // so we must check the any
355  if ( !aAny.hasValue( ) )
356  throw UnsupportedFlavorException( );
357 
358  Sequence< sal_Int8 > clipDataStream;
359  aAny >>= clipDataStream;
360 
361  sal_uInt32 nRequiredMemSize = 0;
362  if ( CDataFormatTranslator::isOemOrAnsiTextFormat( fetc.cfFormat ) )
363  nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1;
364 
365  // prepare data for transmission
366  // #i124085# DIBV5 should not happen for now, but keep as hint here
367  if ( CF_DIBV5 == fetc.cfFormat || CF_DIB == fetc.cfFormat )
368  {
369 #ifdef DBG_UTIL
370  if(CF_DIBV5 == fetc.cfFormat)
371  {
372  OSL_ENSURE(o3tl::make_unsigned(clipDataStream.getLength()) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV5HEADER)), "Wrong size on CF_DIBV5 data (!)");
373  }
374  else // CF_DIB == fetc.cfFormat
375  {
376  OSL_ENSURE(o3tl::make_unsigned(clipDataStream.getLength()) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)), "Wrong size on CF_DIB data (!)");
377  }
378 #endif
379 
380  // remove BITMAPFILEHEADER
381  clipDataStream = OOBmpToWinDIB( clipDataStream );
382  }
383 
384  if ( CF_METAFILEPICT == fetc.cfFormat )
385  {
386  stgmedium.tymed = TYMED_MFPICT;
387  stgmedium.hMetaFilePict = OOMFPictToWinMFPict( clipDataStream );
388  stgmedium.pUnkForRelease = nullptr;
389  }
390  else if( CF_ENHMETAFILE == fetc.cfFormat )
391  {
392  stgmedium.tymed = TYMED_ENHMF;
393  stgmedium.hMetaFilePict = OOMFPictToWinENHMFPict( clipDataStream );
394  stgmedium.pUnkForRelease = nullptr;
395  }
396  else
397  renderDataAndSetupStgMedium(
398  clipDataStream.getArray( ),
399  fetc,
400  nRequiredMemSize,
401  clipDataStream.getLength( ),
402  stgmedium );
403 }
404 
405 HRESULT CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
406 {
407  HRESULT hr = S_OK;
408 
409  try
410  {
411  if ( CF_UNICODETEXT == fetc.cfFormat )
412  // the transferable seems to have only text
414  else if ( CDataFormatTranslator::isOemOrAnsiTextFormat( fetc.cfFormat ) )
415  // the transferable seems to have only unicode text
416  renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium );
417  else
418  // the transferable seems to have only text/html
419  renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium );
420  }
421  catch(UnsupportedFlavorException&)
422  {
423  hr = DV_E_FORMATETC;
424  }
425  catch( CInvalidFormatEtcException& )
426  {
427  OSL_FAIL( "Unexpected exception" );
428  }
430  {
431  return translateStgExceptionCode( ex.m_hr );
432  }
433  catch(...)
434  {
435  hr = E_UNEXPECTED;
436  }
437 
438  return hr;
439 }
440 
441 // the transferable must have only text, so we will synthesize unicode text
442 
443 void CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC const & fetc, STGMEDIUM& stgmedium )
444 {
445  OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat );
446 
447  Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) );
448 
449  // unfortunately not all transferables fulfill the
450  // spec. and do throw an UnsupportedFlavorException
451  // so we must check the any
452  if ( !aAny.hasValue( ) )
453  {
454  OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
455  throw UnsupportedFlavorException( );
456  }
457 
458  Sequence< sal_Int8 > aText;
459  aAny >>= aText;
460 
461  CStgTransferHelper stgTransfHelper;
462 
465  reinterpret_cast< char* >( aText.getArray( ) ),
466  aText.getLength( ),
467  stgTransfHelper );
468 
469  setupStgMedium( fetc, stgTransfHelper, stgmedium );
470 }
471 
472 // the transferable must have only unicode text so we will synthesize text
473 
474 void CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
475 {
476  OSL_ASSERT( CDataFormatTranslator::isOemOrAnsiTextFormat( fetc.cfFormat ) );
477 
478  DataFlavor aFlavor = formatEtcToDataFlavor(
480 
481  Any aAny = m_XTransferable->getTransferData( aFlavor );
482 
483  // unfortunately not all transferables fulfill the
484  // spec. and do throw an UnsupportedFlavorException
485  // so we must check the any
486  if ( !aAny.hasValue( ) )
487  {
488  OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
489  throw UnsupportedFlavorException( );
490  }
491 
492  OUString aUnicodeText;
493  aAny >>= aUnicodeText;
494 
495  CStgTransferHelper stgTransfHelper;
496 
498  GetACP( ),
499  o3tl::toW( aUnicodeText.getStr( ) ),
500  aUnicodeText.getLength( ),
501  stgTransfHelper );
502 
503  setupStgMedium( fetc, stgTransfHelper, stgmedium );
504 }
505 
506 void CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
507 {
508  OSL_ASSERT( CDataFormatTranslator::isHTMLFormat( fetc.cfFormat ) );
509 
510  DataFlavor aFlavor;
511 
512  // creating a DataFlavor on the fly
513  aFlavor.MimeType = "text/html";
514  aFlavor.DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
515 
516  Any aAny = m_XTransferable->getTransferData( aFlavor );
517 
518  // unfortunately not all transferables fulfill the
519  // spec. and do throw an UnsupportedFlavorException
520  // so we must check the any
521  if ( !aAny.hasValue( ) )
522  {
523  OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
524  throw UnsupportedFlavorException( );
525  }
526 
527  Sequence< sal_Int8 > aTextHtmlSequence;
528  aAny >>= aTextHtmlSequence;
529 
530  Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence );
531 
532  sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( );
533 
534  renderDataAndSetupStgMedium(
535  reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ),
536  fetc,
537  0,
538  nBytesToTransfer,
539  stgmedium );
540 }
541 
542 // IDataObject->EnumFormatEtc
543 
545  DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
546 {
547  if ( nullptr == ppenumFormatetc )
548  return E_INVALIDARG;
549 
550  if ( DATADIR_SET == dwDirection )
551  return E_NOTIMPL;
552 
553  *ppenumFormatetc = nullptr;
554 
556 
557  HRESULT hr;
558  if ( DATADIR_GET == dwDirection )
559  {
560  *ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer );
561  static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
562 
563  hr = S_OK;
564  }
565  else
566  hr = E_INVALIDARG;
567 
568  return hr;
569 }
570 
571 // IDataObject->QueryGetData
572 
573 STDMETHODIMP CXTDataObject::QueryGetData( FORMATETC * pFormatetc )
574 {
575  if ( (nullptr == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) )
576  return E_INVALIDARG;
577 
579 
580  CFormatEtc aFormatetc(*pFormatetc);
581  return m_FormatEtcContainer.hasFormatEtc(aFormatetc) ? S_OK : S_FALSE;
582 }
583 
584 // IDataObject->GetDataHere
585 
586 STDMETHODIMP CXTDataObject::GetDataHere( FORMATETC *, STGMEDIUM * )
587 {
588  return E_NOTIMPL;
589 }
590 
591 // IDataObject->GetCanonicalFormatEtc
592 
593 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( FORMATETC *, FORMATETC * )
594 {
595  return E_NOTIMPL;
596 }
597 
598 // IDataObject->SetData
599 
600 STDMETHODIMP CXTDataObject::SetData( FORMATETC *, STGMEDIUM *, BOOL )
601 {
602  return E_NOTIMPL;
603 }
604 
605 // IDataObject->DAdvise
606 
607 STDMETHODIMP CXTDataObject::DAdvise( FORMATETC *, DWORD, IAdviseSink *, DWORD * )
608 {
609  return E_NOTIMPL;
610 }
611 
612 // IDataObject->DUnadvise
613 
614 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
615 {
616  return E_NOTIMPL;
617 }
618 
619 // IDataObject->EnumDAdvise
620 
621 STDMETHODIMP CXTDataObject::EnumDAdvise( IEnumSTATDATA ** )
622 {
623  return E_NOTIMPL;
624 }
625 
626 // for our convenience
627 
628 CXTDataObject::operator IDataObject*( )
629 {
630  return static_cast< IDataObject* >( this );
631 }
632 
633 inline
634 DataFlavor CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const
635 {
636  DataFlavor aFlavor;
637 
639  aFlavor =
641  else
642  aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc );
643 
644  if ( !aFlavor.MimeType.getLength( ) )
645  throw UnsupportedFlavorException( );
646 
647  return aFlavor;
648 }
649 
651 {
653  {
656  }
657 }
658 
659 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) :
660  m_nRefCnt( 0 ),
661  m_lpUnkOuter( lpUnkOuter ),
662  m_FormatEtcContainer( aFormatEtcContainer )
663 {
664  Reset( );
665 }
666 
667 // IUnknown->QueryInterface
668 
669 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, void** ppvObject )
670 {
671  if ( nullptr == ppvObject )
672  return E_INVALIDARG;
673 
674  HRESULT hr = E_NOINTERFACE;
675 
676  *ppvObject = nullptr;
677 
678  if ( ( __uuidof( IUnknown ) == iid ) ||
679  ( __uuidof( IEnumFORMATETC ) == iid ) )
680  {
681  *ppvObject = static_cast< IUnknown* >( this );
682  static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
683  hr = S_OK;
684  }
685 
686  return hr;
687 }
688 
689 // IUnknown->AddRef
690 
691 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
692 {
693  // keep the dataobject alive
694  m_lpUnkOuter->AddRef( );
695  return InterlockedIncrement( &m_nRefCnt );
696 }
697 
698 // IUnknown->Release
699 
700 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
701 {
702  // release the outer dataobject
703  m_lpUnkOuter->Release( );
704 
705  ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
706  if ( 0 == nRefCnt )
707  delete this;
708 
709  return nRefCnt;
710 }
711 
712 // IEnumFORMATETC->Next
713 
714 STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, FORMATETC * lpDest, ULONG* lpFetched )
715 {
716  if ( ( nRequested < 1 ) ||
717  (( nRequested > 1 ) && ( nullptr == lpFetched )) ||
718  IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) )
719  return E_INVALIDARG;
720 
721  sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested );
722 
723  if ( nullptr != lpFetched )
724  *lpFetched = nFetched;
725 
726  return (nFetched == nRequested) ? S_OK : S_FALSE;
727 }
728 
729 // IEnumFORMATETC->Skip
730 
731 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
732 {
733  return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE;
734 }
735 
736 // IEnumFORMATETC->Reset
737 
738 STDMETHODIMP CEnumFormatEtc::Reset( )
739 {
741  return S_OK;
742 }
743 
744 // IEnumFORMATETC->Clone
745 
746 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
747 {
748  if ( nullptr == ppenum )
749  return E_INVALIDARG;
750 
752  static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
753 
754  return S_OK;
755 }
756 
757 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pFormatectIn, FORMATETC *pFormatetcOut) override
STDMETHODIMP Reset() override
STDMETHODIMP DAdvise(FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) override
css::datatransfer::DataFlavor formatEtcToDataFlavor(const FORMATETC &aFormatEtc) const
STDMETHODIMP Next(ULONG nRequested, FORMATETC *lpDest, ULONG *lpFetched) override
CFormatRegistrar m_FormatRegistrar
int MultiByteToWideCharEx(UINT cp_src, LPCSTR lpMultiByteString, sal_uInt32 lenStr, CStgTransferHelper &refDTransHelper, BOOL bEnsureTrailingZero)
Definition: TxtCnvtHlp.cxx:58
static bool isSynthesizeableFormat(const CFormatEtc &aFormatEtc)
Definition: FetcList.cxx:244
signed char sal_Int8
void renderUnicodeAndSetupStgMedium(FORMATETC const &fetc, STGMEDIUM &stgmedium)
css::uno::Reference< css::datatransfer::XTransferable > m_XTransferable
HGLOBAL getHGlobal() const
STDMETHODIMP Skip(ULONG celt) override
HMETAFILEPICT OOMFPictToWinMFPict(Sequence< sal_Int8 > const &aOOMetaFilePict)
Definition: FmtFilter.cxx:148
bool hasFormatEtc(const CFormatEtc &fetc) const
Definition: FetcList.cxx:68
STDMETHODIMP GetDataHere(FORMATETC *pFormatetc, STGMEDIUM *pmedium) override
#define AUTO_INIT
int WideCharToMultiByteEx(UINT cp_dest, LPCWSTR lpWideCharString, sal_uInt32 lenStr, CStgTransferHelper &refDTransHelper, BOOL bEnsureTrailingZero)
Definition: TxtCnvtHlp.cxx:92
STDMETHODIMP Clone(IEnumFORMATETC **ppenum) override
HENHMETAFILE OOMFPictToWinENHMFPict(Sequence< sal_Int8 > const &aOOMetaFilePict)
Definition: FmtFilter.cxx:170
sal_uInt16 sal_Unicode
STDMETHODIMP GetData(FORMATETC *pFormatetc, STGMEDIUM *pmedium) override
const wchar_t *typedef BOOL
STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) override
void renderSynthesizedUnicodeAndSetupStgMedium(FORMATETC const &fetc, STGMEDIUM &stgmedium)
void getIStream(LPSTREAM *ppStream)
css::datatransfer::DataFlavor getDataFlavorFromFormatEtc(const FORMATETC &aFormatEtc, LCID lcid=GetThreadLocale()) const
CFormatEtcContainer m_FormatEtcContainer
STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) override
STDMETHODIMP QueryGetData(FORMATETC *pFormatetc) override
void beginEnumFormatEtc()
Definition: FetcList.cxx:81
static bool isHTMLFormat(CLIPFORMAT cf)
void renderAnyDataAndSetupStgMedium(FORMATETC &fetc, STGMEDIUM &stgmedium)
static CFormatEtc getFormatEtcForClipformat(CLIPFORMAT cf)
void renderSynthesizedTextAndSetupStgMedium(FORMATETC &fetc, STGMEDIUM &stgmedium)
static bool isOemOrAnsiTextFormat(CLIPFORMAT cf)
void InitializeFormatEtcContainer()
void RegisterFormats(const css::uno::Reference< css::datatransfer::XTransferable > &aXTransferable, CFormatEtcContainer &aFormatEtcContainer)
Definition: FetcList.cxx:143
STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc) override
LPUNKNOWN m_lpUnkOuter
static LCID getSynthesizedLocale()
Definition: FetcList.cxx:229
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Sequence< sal_Int8 > TextHtmlToHTMLFormat(Sequence< sal_Int8 > const &aTextHtml)
Definition: FmtFilter.cxx:244
bool hasSynthesizedLocale() const
Definition: FetcList.cxx:224
css::uno::Reference< css::uno::XComponentContext > m_XComponentContext
HRESULT renderSynthesizedFormatAndSetupStgMedium(FORMATETC &fetc, STGMEDIUM &stgmedium)
STDMETHODIMP DUnadvise(DWORD dwConnection) override
CFormatEtcContainer m_FormatEtcContainer
bool skipFormatEtc(sal_uInt32 aNum)
Definition: FetcList.cxx:104
STDMETHODIMP SetData(FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease) override
sal_uInt32 nextFormatEtc(LPFORMATETC lpFetc, sal_uInt32 aNum=1)
Definition: FetcList.cxx:86
virtual ~CXTDataObject()
CEnumFormatEtc(LPUNKNOWN lpUnkOuter, const CFormatEtcContainer &aFormatEtcContainer)
css::datatransfer::DataFlavor getRegisteredTextFlavor() const
Definition: FetcList.cxx:239
void renderSynthesizedHtmlAndSetupStgMedium(FORMATETC &fetc, STGMEDIUM &stgmedium)
STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise) override
void renderLocaleAndSetupStgMedium(FORMATETC const &fetc, STGMEDIUM &stgmedium)
Sequence< sal_Int8 > OOBmpToWinDIB(Sequence< sal_Int8 > &aOOBmp)
Definition: FmtFilter.cxx:212
bool m_bFormatEtcContainerInitialized
CXTDataObject()
Definition: XTDo.cxx:51
static sal_uInt32 getRegisteredTextCodePage()
Definition: FetcList.cxx:234
STDMETHODIMP_(ULONG) CXTDataObject
CDataFormatTranslator m_DataFormatTranslator