xref: /trunk/main/dtrans/source/win32/dtobj/DOTransferable.cxx (revision 48123e16153c92857455f9e7a0d17cc19307983f)
1*48123e16SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*48123e16SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*48123e16SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*48123e16SAndrew Rist  * distributed with this work for additional information
6*48123e16SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*48123e16SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*48123e16SAndrew Rist  * "License"); you may not use this file except in compliance
9*48123e16SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*48123e16SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*48123e16SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*48123e16SAndrew Rist  * software distributed under the License is distributed on an
15*48123e16SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*48123e16SAndrew Rist  * KIND, either express or implied.  See the License for the
17*48123e16SAndrew Rist  * specific language governing permissions and limitations
18*48123e16SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*48123e16SAndrew Rist  *************************************************************/
21*48123e16SAndrew Rist 
22*48123e16SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir // includes
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir #include <sal/types.h>
31cdf0e10cSrcweir #include <rtl/process.h>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #ifndef _DOWRAPPERTRANSFERABLE_HXX_
34cdf0e10cSrcweir #include "DOTransferable.hxx"
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
37cdf0e10cSrcweir #include "..\misc\WinClip.hxx"
38cdf0e10cSrcweir #include "DTransHelper.hxx"
39cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
40cdf0e10cSrcweir #include "TxtCnvtHlp.hxx"
41cdf0e10cSrcweir #include "MimeAttrib.hxx"
42cdf0e10cSrcweir #include "FmtFilter.hxx"
43cdf0e10cSrcweir #include "Fetc.hxx"
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #if(_MSC_VER < 1300) && !defined(__MINGW32__)
47cdf0e10cSrcweir #include <olestd.h>
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #define STR2(x) #x
51cdf0e10cSrcweir #define STR(x) STR2(x)
52cdf0e10cSrcweir #define PRAGMA_MSG( msg ) message( __FILE__ "(" STR(__LINE__) "): " #msg )
53cdf0e10cSrcweir 
54cdf0e10cSrcweir //------------------------------------------------------------------------
55cdf0e10cSrcweir // namespace directives
56cdf0e10cSrcweir //------------------------------------------------------------------------
57cdf0e10cSrcweir 
58cdf0e10cSrcweir using namespace rtl;
59cdf0e10cSrcweir using namespace std;
60cdf0e10cSrcweir using namespace osl;
61cdf0e10cSrcweir using namespace cppu;
62cdf0e10cSrcweir using namespace com::sun::star::uno;
63cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
64cdf0e10cSrcweir using namespace com::sun::star::io;
65cdf0e10cSrcweir using namespace com::sun::star::lang;
66cdf0e10cSrcweir using namespace com::sun::star::container;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir //------------------------------------------------------------------------
69cdf0e10cSrcweir //
70cdf0e10cSrcweir //------------------------------------------------------------------------
71cdf0e10cSrcweir 
72cdf0e10cSrcweir namespace
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     const Type CPPUTYPE_SEQINT8  = getCppuType( ( Sequence< sal_Int8 >* )0 );
75cdf0e10cSrcweir     const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     inline
78cdf0e10cSrcweir     sal_Bool isValidFlavor( const DataFlavor& aFlavor )
79cdf0e10cSrcweir     {
80cdf0e10cSrcweir         return ( aFlavor.MimeType.getLength( ) &&
81cdf0e10cSrcweir                  ( ( aFlavor.DataType ==  CPPUTYPE_SEQINT8 ) ||
82cdf0e10cSrcweir                  ( aFlavor.DataType == CPPUTYPE_OUSTRING ) ) );
83cdf0e10cSrcweir     }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir } // end namespace
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
88cdf0e10cSrcweir //------------------------------------------------------------------------
89cdf0e10cSrcweir // ctor
90cdf0e10cSrcweir //------------------------------------------------------------------------
91cdf0e10cSrcweir 
92cdf0e10cSrcweir CDOTransferable::CDOTransferable(
93cdf0e10cSrcweir     const Reference< XMultiServiceFactory >& ServiceManager, IDataObjectPtr rDataObject ) :
94cdf0e10cSrcweir     m_rDataObject( rDataObject ),
95cdf0e10cSrcweir     m_SrvMgr( ServiceManager ),
96cdf0e10cSrcweir     m_DataFormatTranslator( m_SrvMgr ),
97cdf0e10cSrcweir     m_bUnicodeRegistered( sal_False ),
98cdf0e10cSrcweir     m_TxtFormatOnClipboard( CF_INVALID )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir //------------------------------------------------------------------------
103cdf0e10cSrcweir //
104cdf0e10cSrcweir //------------------------------------------------------------------------
105cdf0e10cSrcweir 
106cdf0e10cSrcweir Any SAL_CALL CDOTransferable::getTransferData( const DataFlavor& aFlavor )
107cdf0e10cSrcweir         throw( UnsupportedFlavorException, IOException, RuntimeException )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     OSL_ASSERT( isValidFlavor( aFlavor ) );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     MutexGuard aGuard( m_aMutex );
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     //------------------------------------------------
114cdf0e10cSrcweir     // convert dataflavor to formatetc
115cdf0e10cSrcweir     //------------------------------------------------
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor );
118cdf0e10cSrcweir     OSL_ASSERT( CF_INVALID != fetc.getClipformat() );
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     //------------------------------------------------
121cdf0e10cSrcweir     //  get the data from clipboard in a byte stream
122cdf0e10cSrcweir     //------------------------------------------------
123cdf0e10cSrcweir 
124cdf0e10cSrcweir     ByteSequence_t clipDataStream;
125cdf0e10cSrcweir 
126cdf0e10cSrcweir     try
127cdf0e10cSrcweir     {
128cdf0e10cSrcweir         clipDataStream = getClipboardData( fetc );
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir     catch( UnsupportedFlavorException& )
131cdf0e10cSrcweir     {
132cdf0e10cSrcweir         if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat( ) ) &&
133cdf0e10cSrcweir              m_bUnicodeRegistered )
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir              OUString aUnicodeText = synthesizeUnicodeText( );
136cdf0e10cSrcweir              Any aAny = makeAny( aUnicodeText );
137cdf0e10cSrcweir              return aAny;
138cdf0e10cSrcweir         }
139cdf0e10cSrcweir         else
140cdf0e10cSrcweir             throw; // pass through exception
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir     //------------------------------------------------
144cdf0e10cSrcweir     // return the data as any
145cdf0e10cSrcweir     //------------------------------------------------
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     return byteStreamToAny( clipDataStream, aFlavor.DataType );
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir //------------------------------------------------------------------------
151cdf0e10cSrcweir // getTransferDataFlavors
152cdf0e10cSrcweir //------------------------------------------------------------------------
153cdf0e10cSrcweir 
154cdf0e10cSrcweir Sequence< DataFlavor > SAL_CALL CDOTransferable::getTransferDataFlavors(  )
155cdf0e10cSrcweir     throw( RuntimeException )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     return m_FlavorList;
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir //------------------------------------------------------------------------
161cdf0e10cSrcweir // isDataFlavorSupported
162cdf0e10cSrcweir // returns true if we find a DataFlavor with the same MimeType and
163cdf0e10cSrcweir // DataType
164cdf0e10cSrcweir //------------------------------------------------------------------------
165cdf0e10cSrcweir 
166cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
167cdf0e10cSrcweir     throw( RuntimeException )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     OSL_ASSERT( isValidFlavor( aFlavor ) );
170cdf0e10cSrcweir 
171cdf0e10cSrcweir     for ( sal_Int32 i = 0; i < m_FlavorList.getLength( ); i++ )
172cdf0e10cSrcweir         if ( compareDataFlavors( aFlavor, m_FlavorList[i] ) )
173cdf0e10cSrcweir             return sal_True;
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     return sal_False;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir //------------------------------------------------------------------------
179cdf0e10cSrcweir // helper function
180cdf0e10cSrcweir // the list of datafalvors currently on the clipboard will be initialized
181cdf0e10cSrcweir // only once; if the client of this Transferable will hold a reference
182cdf0e10cSrcweir // to it und the underlying clipboard content changes, the client does
183cdf0e10cSrcweir // possible operate on a invalid list
184cdf0e10cSrcweir // if there is only text on the clipboard we will also offer unicode text
185cdf0e10cSrcweir // an synthesize this format on the fly if requested, to accomplish this
186cdf0e10cSrcweir // we save the first offered text format which we will later use for the
187cdf0e10cSrcweir // conversion
188cdf0e10cSrcweir //------------------------------------------------------------------------
189cdf0e10cSrcweir 
190cdf0e10cSrcweir void SAL_CALL CDOTransferable::initFlavorList( )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     IEnumFORMATETCPtr pEnumFormatEtc;
193cdf0e10cSrcweir     HRESULT hr = m_rDataObject->EnumFormatEtc( DATADIR_GET, &pEnumFormatEtc );
194cdf0e10cSrcweir     if ( SUCCEEDED( hr ) )
195cdf0e10cSrcweir     {
196cdf0e10cSrcweir         pEnumFormatEtc->Reset( );
197cdf0e10cSrcweir 
198cdf0e10cSrcweir         FORMATETC fetc;
199cdf0e10cSrcweir         while ( S_FALSE != pEnumFormatEtc->Next( 1, &fetc, NULL ) )
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             // we use locales only to determine the
202cdf0e10cSrcweir             // charset if there is text on the cliboard
203cdf0e10cSrcweir             // we don't offer this format
204cdf0e10cSrcweir             if ( CF_LOCALE == fetc.cfFormat )
205cdf0e10cSrcweir                 continue;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir             DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
208cdf0e10cSrcweir 
209cdf0e10cSrcweir             // if text or oemtext is offered we also pretend to have unicode text
210cdf0e10cSrcweir             if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) &&
211cdf0e10cSrcweir                  !m_bUnicodeRegistered )
212cdf0e10cSrcweir             {
213cdf0e10cSrcweir                 addSupportedFlavor( aFlavor );
214cdf0e10cSrcweir 
215cdf0e10cSrcweir                 m_TxtFormatOnClipboard = fetc.cfFormat;
216cdf0e10cSrcweir                 m_bUnicodeRegistered   = sal_True;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir                 // register unicode text as accompany format
219cdf0e10cSrcweir                 aFlavor = formatEtcToDataFlavor(
220cdf0e10cSrcweir                     m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
221cdf0e10cSrcweir                 addSupportedFlavor( aFlavor );
222cdf0e10cSrcweir             }
223cdf0e10cSrcweir             else if ( (CF_UNICODETEXT == fetc.cfFormat) && !m_bUnicodeRegistered )
224cdf0e10cSrcweir             {
225cdf0e10cSrcweir                 addSupportedFlavor( aFlavor );
226cdf0e10cSrcweir                 m_bUnicodeRegistered = sal_True;
227cdf0e10cSrcweir             }
228cdf0e10cSrcweir             else
229cdf0e10cSrcweir                 addSupportedFlavor( aFlavor );
230cdf0e10cSrcweir 
231cdf0e10cSrcweir             // see MSDN IEnumFORMATETC
232cdf0e10cSrcweir             CoTaskMemFree( fetc.ptd );
233cdf0e10cSrcweir         }
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir //------------------------------------------------------------------------
238cdf0e10cSrcweir //
239cdf0e10cSrcweir //------------------------------------------------------------------------
240cdf0e10cSrcweir 
241cdf0e10cSrcweir inline
242cdf0e10cSrcweir void SAL_CALL CDOTransferable::addSupportedFlavor( const DataFlavor& aFlavor )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir     // we ignore all formats that couldn't be translated
245cdf0e10cSrcweir     if ( aFlavor.MimeType.getLength( ) )
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         OSL_ASSERT( isValidFlavor( aFlavor ) );
248cdf0e10cSrcweir 
249cdf0e10cSrcweir         m_FlavorList.realloc( m_FlavorList.getLength( ) + 1 );
250cdf0e10cSrcweir         m_FlavorList[m_FlavorList.getLength( ) - 1] = aFlavor;
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir //------------------------------------------------------------------------
255cdf0e10cSrcweir // helper function
256cdf0e10cSrcweir //------------------------------------------------------------------------
257cdf0e10cSrcweir 
258cdf0e10cSrcweir //inline
259cdf0e10cSrcweir DataFlavor SAL_CALL CDOTransferable::formatEtcToDataFlavor( const FORMATETC& aFormatEtc )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir     DataFlavor aFlavor;
262cdf0e10cSrcweir     LCID lcid = 0;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     // for non-unicode text format we must provid a locale to get
265cdf0e10cSrcweir     // the character-set of the text, if there is no locale on the
266cdf0e10cSrcweir     // clipboard we assume the text is in a charset appropriate for
267cdf0e10cSrcweir     // the current thread locale
268cdf0e10cSrcweir     if ( (CF_TEXT == aFormatEtc.cfFormat) || (CF_OEMTEXT == aFormatEtc.cfFormat) )
269cdf0e10cSrcweir         lcid = getLocaleFromClipboard( );
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     return m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, lcid );
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir //------------------------------------------------------------------------
275cdf0e10cSrcweir // returns the current locale on clipboard; if there is no locale on
276cdf0e10cSrcweir // clipboard the function returns the current thread locale
277cdf0e10cSrcweir //------------------------------------------------------------------------
278cdf0e10cSrcweir 
279cdf0e10cSrcweir LCID SAL_CALL CDOTransferable::getLocaleFromClipboard( )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     LCID lcid = GetThreadLocale( );
282cdf0e10cSrcweir 
283cdf0e10cSrcweir     try
284cdf0e10cSrcweir     {
285cdf0e10cSrcweir         CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE );
286cdf0e10cSrcweir         ByteSequence_t aLCIDSeq = getClipboardData( fetc );
287cdf0e10cSrcweir         lcid = *(reinterpret_cast<LCID*>( aLCIDSeq.getArray( ) ) );
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         // because of a Win95/98 Bug; there the high word
290cdf0e10cSrcweir         // of a locale has the same value as the
291cdf0e10cSrcweir         // low word e.g. 0x07040704 that's not right
292cdf0e10cSrcweir         // correct is 0x00000704
293cdf0e10cSrcweir         lcid &= 0x0000FFFF;
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir     catch(...)
296cdf0e10cSrcweir     {
297cdf0e10cSrcweir         // we take the default locale
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     return lcid;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir //------------------------------------------------------------------------
304cdf0e10cSrcweir // i think it's not necessary to call ReleaseStgMedium
305cdf0e10cSrcweir // in case of failures because nothing should have been
306cdf0e10cSrcweir // allocated etc.
307cdf0e10cSrcweir //------------------------------------------------------------------------
308cdf0e10cSrcweir 
309cdf0e10cSrcweir CDOTransferable::ByteSequence_t SAL_CALL CDOTransferable::getClipboardData( CFormatEtc& aFormatEtc )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir     STGMEDIUM stgmedium;
312cdf0e10cSrcweir     HRESULT hr = m_rDataObject->GetData( aFormatEtc, &stgmedium );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     // in case of failure to get a WMF metafile handle, try to get a memory block
315cdf0e10cSrcweir     if( FAILED( hr ) &&
316cdf0e10cSrcweir         ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) &&
317cdf0e10cSrcweir         ( TYMED_MFPICT == aFormatEtc.getTymed() ) )
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         CFormatEtc aTempFormat( aFormatEtc );
320cdf0e10cSrcweir         aTempFormat.setTymed( TYMED_HGLOBAL );
321cdf0e10cSrcweir         hr = m_rDataObject->GetData( aTempFormat, &stgmedium );
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     if ( FAILED( hr ) )
325cdf0e10cSrcweir     {
326cdf0e10cSrcweir         OSL_ASSERT( (hr != E_INVALIDARG) &&
327cdf0e10cSrcweir                     (hr != DV_E_DVASPECT) &&
328cdf0e10cSrcweir                     (hr != DV_E_LINDEX) &&
329cdf0e10cSrcweir                     (hr != DV_E_TYMED) );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         if ( DV_E_FORMATETC == hr )
332cdf0e10cSrcweir             throw UnsupportedFlavorException( );
333cdf0e10cSrcweir         else if ( STG_E_MEDIUMFULL == hr )
334cdf0e10cSrcweir             throw IOException( );
335cdf0e10cSrcweir         else
336cdf0e10cSrcweir             throw RuntimeException( );
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     ByteSequence_t byteStream;
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     try
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         if ( CF_ENHMETAFILE == aFormatEtc.getClipformat() )
344cdf0e10cSrcweir             byteStream = WinENHMFPictToOOMFPict( stgmedium.hEnhMetaFile );
345cdf0e10cSrcweir         else if (CF_HDROP == aFormatEtc.getClipformat())
346cdf0e10cSrcweir             byteStream = CF_HDROPToFileList(stgmedium.hGlobal);
347cdf0e10cSrcweir         else if ( CF_BITMAP == aFormatEtc.getClipformat() )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             byteStream = WinBITMAPToOOBMP(stgmedium.hBitmap);
350cdf0e10cSrcweir             if( aFormatEtc.getTymed() == TYMED_GDI &&
351cdf0e10cSrcweir                 ! stgmedium.pUnkForRelease )
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 DeleteObject(stgmedium.hBitmap);
354cdf0e10cSrcweir             }
355cdf0e10cSrcweir         }
356cdf0e10cSrcweir         else
357cdf0e10cSrcweir         {
358cdf0e10cSrcweir             clipDataToByteStream( aFormatEtc.getClipformat( ), stgmedium, byteStream );
359cdf0e10cSrcweir 
360cdf0e10cSrcweir             // format conversion if necessary
361cdf0e10cSrcweir             if ( CF_DIB == aFormatEtc.getClipformat() )
362cdf0e10cSrcweir                 byteStream = WinDIBToOOBMP( byteStream );
363cdf0e10cSrcweir             else if ( CF_METAFILEPICT == aFormatEtc.getClipformat() )
364cdf0e10cSrcweir                 byteStream = WinMFPictToOOMFPict( byteStream );
365cdf0e10cSrcweir         }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir         ReleaseStgMedium( &stgmedium );
368cdf0e10cSrcweir     }
369cdf0e10cSrcweir     catch( CStgTransferHelper::CStgTransferException& )
370cdf0e10cSrcweir     {
371cdf0e10cSrcweir         ReleaseStgMedium( &stgmedium );
372cdf0e10cSrcweir         throw IOException( );
373cdf0e10cSrcweir     }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     return byteStream;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir //------------------------------------------------------------------------
379cdf0e10cSrcweir //
380cdf0e10cSrcweir //------------------------------------------------------------------------
381cdf0e10cSrcweir 
382cdf0e10cSrcweir OUString SAL_CALL CDOTransferable::synthesizeUnicodeText( )
383cdf0e10cSrcweir {
384cdf0e10cSrcweir     ByteSequence_t aTextSequence;
385cdf0e10cSrcweir     CFormatEtc     fetc;
386cdf0e10cSrcweir     LCID           lcid = getLocaleFromClipboard( );
387cdf0e10cSrcweir     sal_uInt32     cpForTxtCnvt = 0;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir     if ( CF_TEXT == m_TxtFormatOnClipboard )
390cdf0e10cSrcweir     {
391cdf0e10cSrcweir         fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT );
392cdf0e10cSrcweir         aTextSequence = getClipboardData( fetc );
393cdf0e10cSrcweir 
394cdf0e10cSrcweir         // determine the codepage used for text conversion
395cdf0e10cSrcweir         cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTANSICODEPAGE ).toInt32( );
396cdf0e10cSrcweir     }
397cdf0e10cSrcweir     else if ( CF_OEMTEXT == m_TxtFormatOnClipboard )
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT );
400cdf0e10cSrcweir         aTextSequence = getClipboardData( fetc );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir         // determine the codepage used for text conversion
403cdf0e10cSrcweir         cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTCODEPAGE ).toInt32( );
404cdf0e10cSrcweir     }
405cdf0e10cSrcweir     else
406cdf0e10cSrcweir         OSL_ASSERT( sal_False );
407cdf0e10cSrcweir 
408cdf0e10cSrcweir     CStgTransferHelper stgTransferHelper;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     // convert the text
411cdf0e10cSrcweir     MultiByteToWideCharEx( cpForTxtCnvt,
412cdf0e10cSrcweir                            reinterpret_cast<char*>( aTextSequence.getArray( ) ),
413cdf0e10cSrcweir                            sal::static_int_cast<sal_uInt32>(-1), // Huh ?
414cdf0e10cSrcweir                            stgTransferHelper,
415cdf0e10cSrcweir                            sal_False);
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     CRawHGlobalPtr  ptrHGlob(stgTransferHelper);
418cdf0e10cSrcweir     sal_Unicode*    pWChar = reinterpret_cast<sal_Unicode*>(ptrHGlob.GetMemPtr());
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     return OUString(pWChar);
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir //------------------------------------------------------------------------
424cdf0e10cSrcweir //
425cdf0e10cSrcweir //------------------------------------------------------------------------
426cdf0e10cSrcweir 
427cdf0e10cSrcweir void CDOTransferable::clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence )
428cdf0e10cSrcweir {
429cdf0e10cSrcweir     CStgTransferHelper memTransferHelper;
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     switch( stgmedium.tymed )
432cdf0e10cSrcweir     {
433cdf0e10cSrcweir     case TYMED_HGLOBAL:
434cdf0e10cSrcweir         memTransferHelper.init( stgmedium.hGlobal );
435cdf0e10cSrcweir         break;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     case TYMED_MFPICT:
438cdf0e10cSrcweir         memTransferHelper.init( stgmedium.hMetaFilePict );
439cdf0e10cSrcweir         break;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     case TYMED_ENHMF:
442cdf0e10cSrcweir         memTransferHelper.init( stgmedium.hEnhMetaFile );
443cdf0e10cSrcweir         break;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     case TYMED_ISTREAM:
446cdf0e10cSrcweir         #ifdef _MSC_VER
447cdf0e10cSrcweir         #pragma PRAGMA_MSG( Has to be implemented )
448cdf0e10cSrcweir         #endif
449cdf0e10cSrcweir         break;
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     default:
452cdf0e10cSrcweir         throw UnsupportedFlavorException( );
453cdf0e10cSrcweir         break;
454cdf0e10cSrcweir     }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     int nMemSize = memTransferHelper.memSize( cf );
457cdf0e10cSrcweir     aByteSequence.realloc( nMemSize );
458cdf0e10cSrcweir     memTransferHelper.read( aByteSequence.getArray( ), nMemSize );
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
461cdf0e10cSrcweir //------------------------------------------------------------------------
462cdf0e10cSrcweir //
463cdf0e10cSrcweir //------------------------------------------------------------------------
464cdf0e10cSrcweir 
465cdf0e10cSrcweir inline
466cdf0e10cSrcweir Any CDOTransferable::byteStreamToAny( ByteSequence_t& aByteStream, const Type& aRequestedDataType )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     Any aAny;
469cdf0e10cSrcweir 
470cdf0e10cSrcweir     if ( aRequestedDataType == CPPUTYPE_OUSTRING )
471cdf0e10cSrcweir     {
472cdf0e10cSrcweir         OUString str = byteStreamToOUString( aByteStream );
473cdf0e10cSrcweir         aAny = makeAny( str );
474cdf0e10cSrcweir     }
475cdf0e10cSrcweir     else
476cdf0e10cSrcweir         aAny = makeAny( aByteStream );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir     return aAny;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir //------------------------------------------------------------------------
482cdf0e10cSrcweir //
483cdf0e10cSrcweir //------------------------------------------------------------------------
484cdf0e10cSrcweir 
485cdf0e10cSrcweir inline
486cdf0e10cSrcweir OUString CDOTransferable::byteStreamToOUString( ByteSequence_t& aByteStream )
487cdf0e10cSrcweir {
488cdf0e10cSrcweir     sal_Int32 nWChars;
489cdf0e10cSrcweir     sal_Int32 nMemSize = aByteStream.getLength( );
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     // if there is a trailing L"\0" substract 1 from length
492cdf0e10cSrcweir     if ( 0 == aByteStream[ aByteStream.getLength( ) - 2 ] &&
493cdf0e10cSrcweir          0 == aByteStream[ aByteStream.getLength( ) - 1 ] )
494cdf0e10cSrcweir         nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) ) - 1;
495cdf0e10cSrcweir     else
496cdf0e10cSrcweir         nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) );
497cdf0e10cSrcweir 
498cdf0e10cSrcweir     return OUString( reinterpret_cast< sal_Unicode* >( aByteStream.getArray( ) ), nWChars );
499cdf0e10cSrcweir }
500cdf0e10cSrcweir 
501cdf0e10cSrcweir //------------------------------------------------------------------------
502cdf0e10cSrcweir //
503cdf0e10cSrcweir //------------------------------------------------------------------------
504cdf0e10cSrcweir 
505cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::compareDataFlavors(
506cdf0e10cSrcweir     const DataFlavor& lhs, const DataFlavor& rhs )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir     if ( !m_rXMimeCntFactory.is( ) )
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         m_rXMimeCntFactory = Reference< XMimeContentTypeFactory >( m_SrvMgr->createInstance(
511cdf0e10cSrcweir             OUString::createFromAscii( "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY );
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir     OSL_ASSERT( m_rXMimeCntFactory.is( ) );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     sal_Bool bRet = sal_False;
516cdf0e10cSrcweir 
517cdf0e10cSrcweir     try
518cdf0e10cSrcweir     {
519cdf0e10cSrcweir         Reference< XMimeContentType > xLhs( m_rXMimeCntFactory->createMimeContentType( lhs.MimeType ) );
520cdf0e10cSrcweir         Reference< XMimeContentType > xRhs( m_rXMimeCntFactory->createMimeContentType( rhs.MimeType ) );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         if ( cmpFullMediaType( xLhs, xRhs ) )
523cdf0e10cSrcweir         {
524cdf0e10cSrcweir             bRet = cmpAllContentTypeParameter( xLhs, xRhs );
525cdf0e10cSrcweir         }
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir     catch( IllegalArgumentException& )
528cdf0e10cSrcweir     {
529cdf0e10cSrcweir         OSL_ENSURE( sal_False, "Invalid content type detected" );
530cdf0e10cSrcweir         bRet = sal_False;
531cdf0e10cSrcweir     }
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     return bRet;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir //------------------------------------------------------------------------
537cdf0e10cSrcweir //
538cdf0e10cSrcweir //------------------------------------------------------------------------
539cdf0e10cSrcweir 
540cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::cmpFullMediaType(
541cdf0e10cSrcweir     const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
542cdf0e10cSrcweir {
543cdf0e10cSrcweir     return xLhs->getFullMediaType().equalsIgnoreAsciiCase( xRhs->getFullMediaType( ) );
544cdf0e10cSrcweir }
545cdf0e10cSrcweir 
546cdf0e10cSrcweir //------------------------------------------------------------------------
547cdf0e10cSrcweir //
548cdf0e10cSrcweir //------------------------------------------------------------------------
549cdf0e10cSrcweir 
550cdf0e10cSrcweir sal_Bool SAL_CALL CDOTransferable::cmpAllContentTypeParameter(
551cdf0e10cSrcweir     const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const
552cdf0e10cSrcweir {
553cdf0e10cSrcweir     Sequence< OUString > xLhsFlavors = xLhs->getParameters( );
554cdf0e10cSrcweir     Sequence< OUString > xRhsFlavors = xRhs->getParameters( );
555cdf0e10cSrcweir     sal_Bool bRet = sal_True;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     try
558cdf0e10cSrcweir     {
559cdf0e10cSrcweir         if ( xLhsFlavors.getLength( ) == xRhsFlavors.getLength( ) )
560cdf0e10cSrcweir         {
561cdf0e10cSrcweir             OUString pLhs;
562cdf0e10cSrcweir             OUString pRhs;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir             for ( sal_Int32 i = 0; i < xLhsFlavors.getLength( ); i++ )
565cdf0e10cSrcweir             {
566cdf0e10cSrcweir                 pLhs = xLhs->getParameterValue( xLhsFlavors[i] );
567cdf0e10cSrcweir                 pRhs = xRhs->getParameterValue( xLhsFlavors[i] );
568cdf0e10cSrcweir 
569cdf0e10cSrcweir                 if ( !pLhs.equalsIgnoreAsciiCase( pRhs ) )
570cdf0e10cSrcweir                 {
571cdf0e10cSrcweir                     bRet = sal_False;
572cdf0e10cSrcweir                     break;
573cdf0e10cSrcweir                 }
574cdf0e10cSrcweir             }
575cdf0e10cSrcweir         }
576cdf0e10cSrcweir         else
577cdf0e10cSrcweir             bRet = sal_False;
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir     catch( NoSuchElementException& )
580cdf0e10cSrcweir     {
581cdf0e10cSrcweir         bRet = sal_False;
582cdf0e10cSrcweir     }
583cdf0e10cSrcweir     catch( IllegalArgumentException& )
584cdf0e10cSrcweir     {
585cdf0e10cSrcweir         bRet = sal_False;
586cdf0e10cSrcweir     }
587cdf0e10cSrcweir 
588cdf0e10cSrcweir     return bRet;
589cdf0e10cSrcweir }
590cdf0e10cSrcweir 
591cdf0e10cSrcweir ::com::sun::star::uno::Any SAL_CALL CDOTransferable::getData( const Sequence< sal_Int8>& aProcessId  )
592cdf0e10cSrcweir         throw (::com::sun::star::uno::RuntimeException)
593cdf0e10cSrcweir {
594cdf0e10cSrcweir     Any retVal;
595cdf0e10cSrcweir 
596cdf0e10cSrcweir     sal_uInt8 * arProcCaller= (sal_uInt8*)(sal_Int8*) aProcessId.getConstArray();
597cdf0e10cSrcweir     sal_uInt8 arId[16];
598cdf0e10cSrcweir     rtl_getGlobalProcessId(arId);
599cdf0e10cSrcweir     if( ! memcmp( arId, arProcCaller,16))
600cdf0e10cSrcweir     {
601cdf0e10cSrcweir         if (m_rDataObject.is())
602cdf0e10cSrcweir         {
603cdf0e10cSrcweir             IDataObject* pObj= m_rDataObject.get();
604cdf0e10cSrcweir             pObj->AddRef();
605cdf0e10cSrcweir             retVal.setValue( &pObj, getCppuType((sal_uInt32*)0));
606cdf0e10cSrcweir         }
607cdf0e10cSrcweir     }
608cdf0e10cSrcweir     return retVal;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir 
611