1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DataFmtTransl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include "DataFmtTransl.hxx"
38 #include <rtl/string.hxx>
39 #include <osl/diagnose.h>
40 #include <rtl/tencinfo.h>
41 #include "..\misc\ImplHelper.hxx"
42 #include "..\misc\WinClip.hxx"
43 #include "MimeAttrib.hxx"
44 #include "DTransHelper.hxx"
45 #include <rtl/string.h>
49 #pragma warning(push,1)
50 #pragma warning(disable:4917)
53 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
62 //------------------------------------------------------------------------
63 // namespace directives
64 //------------------------------------------------------------------------
68 using namespace com::sun::star::uno
;
69 using namespace com::sun::star::datatransfer
;
70 using namespace com::sun::star::lang
;
72 //------------------------------------------------------------------------
74 //------------------------------------------------------------------------
76 const Type CPPUTYPE_SALINT32
= getCppuType((sal_Int32
*)0);
77 const Type CPPUTYPE_SALINT8
= getCppuType((sal_Int8
*)0);
78 const Type CPPUTYPE_OUSTRING
= getCppuType((OUString
*)0);
79 const Type CPPUTYPE_SEQSALINT8
= getCppuType((Sequence
< sal_Int8
>*)0);
80 const sal_Int32 MAX_CLIPFORMAT_NAME
= 256;
82 const OUString TEXT_PLAIN_CHARSET
= OUString::createFromAscii( "text/plain;charset=" );
83 const OUString HPNAME_OEM_ANSI_TEXT
= OUString::createFromAscii( "OEM/ANSI Text" );
85 const OUString HTML_FORMAT_NAME_WINDOWS
= OUString::createFromAscii( "HTML Format" );
86 const OUString HTML_FORMAT_NAME_SOFFICE
= OUString::createFromAscii( "HTML (HyperText Markup Language)" );
88 //------------------------------------------------------------------------
90 //------------------------------------------------------------------------
92 CDataFormatTranslator::CDataFormatTranslator( const Reference
< XMultiServiceFactory
>& aServiceManager
) :
93 m_SrvMgr( aServiceManager
)
95 m_XDataFormatTranslator
= Reference
< XDataFormatTranslator
>(
96 m_SrvMgr
->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.DataFormatTranslator" ) ), UNO_QUERY
);
99 //------------------------------------------------------------------------
101 //------------------------------------------------------------------------
103 CFormatEtc
CDataFormatTranslator::getFormatEtcFromDataFlavor( const DataFlavor
& aDataFlavor
) const
105 sal_Int32 cf
= CF_INVALID
;
109 if( m_XDataFormatTranslator
.is( ) )
111 Any aFormat
= m_XDataFormatTranslator
->getSystemDataTypeFromDataFlavor( aDataFlavor
);
113 if ( aFormat
.hasValue( ) )
115 if ( aFormat
.getValueType( ) == CPPUTYPE_SALINT32
)
118 OSL_ENSURE( CF_INVALID
!= cf
, "Invalid Clipboard format delivered" );
120 else if ( aFormat
.getValueType( ) == CPPUTYPE_OUSTRING
)
122 OUString aClipFmtName
;
123 aFormat
>>= aClipFmtName
;
125 OSL_ASSERT( aClipFmtName
.getLength( ) );
126 cf
= RegisterClipboardFormatW( reinterpret_cast<LPCWSTR
>(aClipFmtName
.getStr( )) );
128 OSL_ENSURE( CF_INVALID
!= cf
, "RegisterClipboardFormat failed" );
131 OSL_ENSURE( sal_False
, "Wrong Any-Type detected" );
137 OSL_ENSURE( sal_False
, "Unexpected error" );
140 return sal::static_int_cast
<CFormatEtc
>(getFormatEtcForClipformat( sal::static_int_cast
<CLIPFORMAT
>(cf
) ));
143 //------------------------------------------------------------------------
145 //------------------------------------------------------------------------
147 DataFlavor
CDataFormatTranslator::getDataFlavorFromFormatEtc( const FORMATETC
& aFormatEtc
, LCID lcid
) const
153 CLIPFORMAT aClipformat
= aFormatEtc
.cfFormat
;
156 aAny
<<= static_cast< sal_Int32
>( aClipformat
);
158 if ( isOemOrAnsiTextFormat( aClipformat
) )
160 aFlavor
.MimeType
= TEXT_PLAIN_CHARSET
;
161 aFlavor
.MimeType
+= getTextCharsetFromLCID( lcid
, aClipformat
);
163 aFlavor
.HumanPresentableName
= HPNAME_OEM_ANSI_TEXT
;
164 aFlavor
.DataType
= CPPUTYPE_SEQSALINT8
;
166 else if ( CF_INVALID
!= aClipformat
)
168 if ( m_XDataFormatTranslator
.is( ) )
170 aFlavor
= m_XDataFormatTranslator
->getDataFlavorFromSystemDataType( aAny
);
172 if ( !aFlavor
.MimeType
.getLength( ) )
174 // lookup of DataFlavor from clipboard format id
175 // failed, so we try to resolve via clipboard
177 OUString clipFormatName
= getClipboardFormatName( aClipformat
);
179 // if we could not get a clipboard format name an
180 // error must have occured or it is a standard
181 // clipboard format that we don't translate, e.g.
182 // CF_BITMAP (the office only uses CF_DIB)
183 if ( clipFormatName
.getLength( ) )
185 aAny
<<= clipFormatName
;
186 aFlavor
= m_XDataFormatTranslator
->getDataFlavorFromSystemDataType( aAny
);
194 OSL_ENSURE( sal_False
, "Unexpected error" );
200 //------------------------------------------------------------------------
202 //------------------------------------------------------------------------
204 CFormatEtc SAL_CALL
CDataFormatTranslator::getFormatEtcForClipformatName( const OUString
& aClipFmtName
) const
207 if ( !aClipFmtName
.getLength( ) )
208 return CFormatEtc( CF_INVALID
);
210 CLIPFORMAT cf
= sal::static_int_cast
<CLIPFORMAT
>(RegisterClipboardFormatW( reinterpret_cast<LPCWSTR
>(aClipFmtName
.getStr( )) ));
211 return getFormatEtcForClipformat( cf
);
214 //------------------------------------------------------------------------
216 //------------------------------------------------------------------------
218 OUString
CDataFormatTranslator::getClipboardFormatName( CLIPFORMAT aClipformat
) const
220 OSL_PRECOND( CF_INVALID
!= aClipformat
, "Invalid clipboard format" );
222 sal_Unicode wBuff
[ MAX_CLIPFORMAT_NAME
];
223 sal_Int32 nLen
= GetClipboardFormatNameW( aClipformat
, reinterpret_cast<LPWSTR
>(wBuff
), MAX_CLIPFORMAT_NAME
);
225 return OUString( wBuff
, nLen
);
228 //------------------------------------------------------------------------
230 //------------------------------------------------------------------------
232 CFormatEtc SAL_CALL
CDataFormatTranslator::getFormatEtcForClipformat( CLIPFORMAT cf
) const
234 CFormatEtc
fetc( cf
, TYMED_NULL
, NULL
, DVASPECT_CONTENT
);
238 case CF_METAFILEPICT
:
239 fetc
.setTymed( TYMED_MFPICT
);
243 fetc
.setTymed( TYMED_ENHMF
);
247 fetc
.setTymed( TYMED_HGLOBAL
/*| TYMED_ISTREAM*/ );
251 hack: in order to paste urls copied by Internet Explorer
252 with "copy link" we set the lindex member to 0
253 but if we really want to support CFSTR_FILECONTENT and
254 the accompany format CFSTR_FILEDESCRIPTOR (FileGroupDescriptor)
255 the client of the clipboard service has to provide a id
256 of which FileContents it wants to paste
257 see MSDN: "Handling Shell Data Transfer Scenarios"
259 if ( cf
== RegisterClipboardFormatA( CFSTR_FILECONTENTS
) )
265 //------------------------------------------------------------------------
267 //------------------------------------------------------------------------
269 sal_Bool SAL_CALL
CDataFormatTranslator::isOemOrAnsiTextFormat( CLIPFORMAT cf
) const
271 return ( (cf
== CF_TEXT
) || (cf
== CF_OEMTEXT
) );
274 //------------------------------------------------------------------------
276 //------------------------------------------------------------------------
278 sal_Bool SAL_CALL
CDataFormatTranslator::isUnicodeTextFormat( CLIPFORMAT cf
) const
280 return ( cf
== CF_UNICODETEXT
);
283 //------------------------------------------------------------------------
285 //------------------------------------------------------------------------
287 sal_Bool SAL_CALL
CDataFormatTranslator::isTextFormat( CLIPFORMAT cf
) const
289 return ( isOemOrAnsiTextFormat( cf
) || isUnicodeTextFormat( cf
) );
292 //------------------------------------------------------------------------
294 //------------------------------------------------------------------------
296 sal_Bool SAL_CALL
CDataFormatTranslator::isHTMLFormat( CLIPFORMAT cf
) const
298 OUString clipFormatName
= getClipboardFormatName( cf
);
299 return ( clipFormatName
== HTML_FORMAT_NAME_WINDOWS
);
302 //------------------------------------------------------------------------
304 //------------------------------------------------------------------------
306 sal_Bool SAL_CALL
CDataFormatTranslator::isTextHtmlFormat( CLIPFORMAT cf
) const
308 OUString clipFormatName
= getClipboardFormatName( cf
);
309 return ( clipFormatName
.equalsIgnoreAsciiCase( HTML_FORMAT_NAME_SOFFICE
) );
312 //------------------------------------------------------------------------
314 //------------------------------------------------------------------------
316 OUString SAL_CALL
CDataFormatTranslator::getTextCharsetFromLCID( LCID lcid
, CLIPFORMAT aClipformat
) const
318 OSL_ASSERT( isOemOrAnsiTextFormat( aClipformat
) );
321 if ( CF_TEXT
== aClipformat
)
323 charset
= getMimeCharsetFromLocaleId(
325 LOCALE_IDEFAULTANSICODEPAGE
,
326 PRE_WINDOWS_CODEPAGE
);
328 else if ( CF_OEMTEXT
== aClipformat
)
330 charset
= getMimeCharsetFromLocaleId(
332 LOCALE_IDEFAULTCODEPAGE
,
336 OSL_ASSERT( sal_False
);