xref: /trunk/main/dtrans/source/win32/dtobj/DataFmtTransl.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 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dtrans.hxx"
30 
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
34 #include "DataFmtTransl.hxx"
35 #include <rtl/string.hxx>
36 #include <osl/diagnose.h>
37 #include <rtl/tencinfo.h>
38 #include "..\misc\ImplHelper.hxx"
39 #include "..\misc\WinClip.hxx"
40 #include "MimeAttrib.hxx"
41 #include "DTransHelper.hxx"
42 #include <rtl/string.h>
43 #include "Fetc.hxx"
44 
45 #if defined _MSC_VER
46 #pragma warning(push,1)
47 #pragma warning(disable:4917)
48 #endif
49 #include <windows.h>
50 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
51 #include <olestd.h>
52 #endif
53 #include <shlobj.h>
54 #if defined _MSC_VER
55 #pragma warning(pop)
56 #endif
57 
58 
59 //------------------------------------------------------------------------
60 // namespace directives
61 //------------------------------------------------------------------------
62 
63 using namespace rtl;
64 using namespace std;
65 using namespace com::sun::star::uno;
66 using namespace com::sun::star::datatransfer;
67 using namespace com::sun::star::lang;
68 
69 //------------------------------------------------------------------------
70 // const
71 //------------------------------------------------------------------------
72 
73 const Type       CPPUTYPE_SALINT32   = getCppuType((sal_Int32*)0);
74 const Type       CPPUTYPE_SALINT8    = getCppuType((sal_Int8*)0);
75 const Type       CPPUTYPE_OUSTRING   = getCppuType((OUString*)0);
76 const Type       CPPUTYPE_SEQSALINT8 = getCppuType((Sequence< sal_Int8>*)0);
77 const sal_Int32  MAX_CLIPFORMAT_NAME = 256;
78 
79 const OUString TEXT_PLAIN_CHARSET   = OUString::createFromAscii( "text/plain;charset=" );
80 const OUString HPNAME_OEM_ANSI_TEXT = OUString::createFromAscii( "OEM/ANSI Text" );
81 
82 const OUString HTML_FORMAT_NAME_WINDOWS = OUString::createFromAscii( "HTML Format" );
83 const OUString HTML_FORMAT_NAME_SOFFICE = OUString::createFromAscii( "HTML (HyperText Markup Language)" );
84 
85 //------------------------------------------------------------------------
86 //
87 //------------------------------------------------------------------------
88 
89 CDataFormatTranslator::CDataFormatTranslator( const Reference< XMultiServiceFactory >& aServiceManager ) :
90     m_SrvMgr( aServiceManager )
91 {
92     m_XDataFormatTranslator = Reference< XDataFormatTranslator >(
93         m_SrvMgr->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.DataFormatTranslator" ) ), UNO_QUERY );
94 }
95 
96 //------------------------------------------------------------------------
97 //
98 //------------------------------------------------------------------------
99 
100 CFormatEtc CDataFormatTranslator::getFormatEtcFromDataFlavor( const DataFlavor& aDataFlavor ) const
101 {
102     sal_Int32 cf = CF_INVALID;
103 
104     try
105     {
106         if( m_XDataFormatTranslator.is( ) )
107         {
108             Any aFormat = m_XDataFormatTranslator->getSystemDataTypeFromDataFlavor( aDataFlavor );
109 
110             if ( aFormat.hasValue( ) )
111             {
112                 if ( aFormat.getValueType( ) == CPPUTYPE_SALINT32 )
113                 {
114                     aFormat >>= cf;
115                     OSL_ENSURE( CF_INVALID != cf, "Invalid Clipboard format delivered" );
116                 }
117                 else if ( aFormat.getValueType( ) == CPPUTYPE_OUSTRING )
118                 {
119                     OUString aClipFmtName;
120                     aFormat >>= aClipFmtName;
121 
122                     OSL_ASSERT( aClipFmtName.getLength( ) );
123                     cf = RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) );
124 
125                     OSL_ENSURE( CF_INVALID != cf, "RegisterClipboardFormat failed" );
126                 }
127                 else
128                     OSL_ENSURE( sal_False, "Wrong Any-Type detected" );
129             }
130         }
131     }
132     catch( ... )
133     {
134         OSL_ENSURE( sal_False, "Unexpected error" );
135     }
136 
137     return sal::static_int_cast<CFormatEtc>(getFormatEtcForClipformat( sal::static_int_cast<CLIPFORMAT>(cf) ));
138 }
139 
140 //------------------------------------------------------------------------
141 //
142 //------------------------------------------------------------------------
143 
144 DataFlavor CDataFormatTranslator::getDataFlavorFromFormatEtc( const FORMATETC& aFormatEtc, LCID lcid ) const
145 {
146     DataFlavor aFlavor;
147 
148     try
149     {
150         CLIPFORMAT aClipformat = aFormatEtc.cfFormat;
151 
152         Any aAny;
153         aAny <<= static_cast< sal_Int32 >( aClipformat );
154 
155         if ( isOemOrAnsiTextFormat( aClipformat ) )
156         {
157             aFlavor.MimeType             = TEXT_PLAIN_CHARSET;
158             aFlavor.MimeType            += getTextCharsetFromLCID( lcid, aClipformat );
159 
160             aFlavor.HumanPresentableName = HPNAME_OEM_ANSI_TEXT;
161             aFlavor.DataType             = CPPUTYPE_SEQSALINT8;
162         }
163         else if ( CF_INVALID != aClipformat )
164         {
165             if ( m_XDataFormatTranslator.is( ) )
166             {
167                 aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny );
168 
169                 if ( !aFlavor.MimeType.getLength( ) )
170                 {
171                     // lookup of DataFlavor from clipboard format id
172                     // failed, so we try to resolve via clipboard
173                     // format name
174                     OUString clipFormatName = getClipboardFormatName( aClipformat );
175 
176                     // if we could not get a clipboard format name an
177                     // error must have occured or it is a standard
178                     // clipboard format that we don't translate, e.g.
179                     // CF_BITMAP (the office only uses CF_DIB)
180                     if ( clipFormatName.getLength( ) )
181                     {
182                         aAny <<= clipFormatName;
183                         aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny );
184                     }
185                 }
186             }
187         }
188     }
189     catch( ... )
190     {
191         OSL_ENSURE( sal_False, "Unexpected error" );
192     }
193 
194     return aFlavor;
195 }
196 
197 //------------------------------------------------------------------------
198 //
199 //------------------------------------------------------------------------
200 
201 CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformatName( const OUString& aClipFmtName ) const
202 {
203     // check parameter
204     if ( !aClipFmtName.getLength( ) )
205         return CFormatEtc( CF_INVALID );
206 
207     CLIPFORMAT cf = sal::static_int_cast<CLIPFORMAT>(RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) ));
208     return getFormatEtcForClipformat( cf );
209 }
210 
211 //------------------------------------------------------------------------
212 //
213 //------------------------------------------------------------------------
214 
215 OUString CDataFormatTranslator::getClipboardFormatName( CLIPFORMAT aClipformat ) const
216 {
217     OSL_PRECOND( CF_INVALID != aClipformat, "Invalid clipboard format" );
218 
219     sal_Unicode wBuff[ MAX_CLIPFORMAT_NAME ];
220     sal_Int32   nLen = GetClipboardFormatNameW( aClipformat, reinterpret_cast<LPWSTR>(wBuff), MAX_CLIPFORMAT_NAME );
221 
222     return OUString( wBuff, nLen );
223 }
224 
225 //------------------------------------------------------------------------
226 //
227 //------------------------------------------------------------------------
228 
229 CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformat( CLIPFORMAT cf ) const
230 {
231     CFormatEtc fetc( cf, TYMED_NULL, NULL, DVASPECT_CONTENT );
232 
233     switch( cf )
234     {
235     case CF_METAFILEPICT:
236         fetc.setTymed( TYMED_MFPICT );
237         break;
238 
239     case CF_ENHMETAFILE:
240         fetc.setTymed( TYMED_ENHMF );
241         break;
242 
243     default:
244         fetc.setTymed( TYMED_HGLOBAL /*| TYMED_ISTREAM*/ );
245     }
246 
247     /*
248         hack: in order to paste urls copied by Internet Explorer
249         with "copy link" we set the lindex member to 0
250         but if we really want to support CFSTR_FILECONTENT and
251         the accompany format CFSTR_FILEDESCRIPTOR (FileGroupDescriptor)
252         the client of the clipboard service has to provide a id
253         of which FileContents it wants to paste
254         see MSDN: "Handling Shell Data Transfer Scenarios"
255     */
256     if ( cf == RegisterClipboardFormatA( CFSTR_FILECONTENTS ) )
257          fetc.setLindex( 0 );
258 
259     return fetc;
260 }
261 
262 //------------------------------------------------------------------------
263 //
264 //------------------------------------------------------------------------
265 
266 sal_Bool SAL_CALL CDataFormatTranslator::isOemOrAnsiTextFormat( CLIPFORMAT cf ) const
267 {
268     return ( (cf == CF_TEXT) || (cf == CF_OEMTEXT) );
269 }
270 
271 //------------------------------------------------------------------------
272 //
273 //------------------------------------------------------------------------
274 
275 sal_Bool SAL_CALL CDataFormatTranslator::isUnicodeTextFormat( CLIPFORMAT cf ) const
276 {
277     return ( cf == CF_UNICODETEXT );
278 }
279 
280 //------------------------------------------------------------------------
281 //
282 //------------------------------------------------------------------------
283 
284 sal_Bool SAL_CALL CDataFormatTranslator::isTextFormat( CLIPFORMAT cf ) const
285 {
286     return ( isOemOrAnsiTextFormat( cf ) || isUnicodeTextFormat( cf ) );
287 }
288 
289 //------------------------------------------------------------------------
290 //
291 //------------------------------------------------------------------------
292 
293 sal_Bool SAL_CALL CDataFormatTranslator::isHTMLFormat( CLIPFORMAT cf ) const
294 {
295     OUString clipFormatName = getClipboardFormatName( cf );
296     return ( clipFormatName == HTML_FORMAT_NAME_WINDOWS );
297 }
298 
299 //------------------------------------------------------------------------
300 //
301 //------------------------------------------------------------------------
302 
303 sal_Bool SAL_CALL CDataFormatTranslator::isTextHtmlFormat( CLIPFORMAT cf ) const
304 {
305     OUString clipFormatName = getClipboardFormatName( cf );
306     return ( clipFormatName.equalsIgnoreAsciiCase( HTML_FORMAT_NAME_SOFFICE ) );
307 }
308 
309 //------------------------------------------------------------------------
310 //
311 //------------------------------------------------------------------------
312 
313 OUString SAL_CALL CDataFormatTranslator::getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const
314 {
315     OSL_ASSERT( isOemOrAnsiTextFormat( aClipformat ) );
316 
317     OUString charset;
318     if ( CF_TEXT == aClipformat )
319     {
320         charset = getMimeCharsetFromLocaleId(
321                     lcid,
322                     LOCALE_IDEFAULTANSICODEPAGE,
323                     PRE_WINDOWS_CODEPAGE );
324     }
325     else if ( CF_OEMTEXT == aClipformat )
326     {
327         charset = getMimeCharsetFromLocaleId(
328                     lcid,
329                     LOCALE_IDEFAULTCODEPAGE,
330                     PRE_OEM_CODEPAGE );
331     }
332     else // CF_UNICODE
333         OSL_ASSERT( sal_False );
334 
335     return charset;
336 }
337