1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "DataFmtTransl.hxx"
21 #include <rtl/string.hxx>
22 #include <osl/diagnose.h>
23 #include <rtl/tencinfo.h>
24 #include "ImplHelper.hxx"
25 #include "WinClip.hxx"
26 #include "MimeAttrib.hxx"
27 #include "DTransHelper.hxx"
28 #include <rtl/string.h>
29 #include <o3tl/char16_t2wchar_t.hxx>
31 #include <com/sun/star/datatransfer/DataFormatTranslator.hpp>
33 #if !defined WIN32_LEAN_AND_MEAN
34 # define WIN32_LEAN_AND_MEAN
40 using namespace com::sun::star::uno
;
41 using namespace com::sun::star::datatransfer
;
42 using namespace com::sun::star::lang
;
44 const Type CPPUTYPE_SALINT32
= cppu::UnoType
<sal_Int32
>::get();
45 const Type CPPUTYPE_SALINT8
= cppu::UnoType
<sal_Int8
>::get();
46 const Type CPPUTYPE_OUSTRING
= cppu::UnoType
<OUString
>::get();
47 const Type CPPUTYPE_SEQSALINT8
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
48 const sal_Int32 MAX_CLIPFORMAT_NAME
= 256;
50 CDataFormatTranslator::CDataFormatTranslator( const Reference
< XComponentContext
>& rxContext
)
52 m_XDataFormatTranslator
= DataFormatTranslator::create( rxContext
);
55 CFormatEtc
CDataFormatTranslator::getFormatEtcFromDataFlavor( const DataFlavor
& aDataFlavor
) const
57 sal_Int32 cf
= CF_INVALID
;
61 if( m_XDataFormatTranslator
.is( ) )
63 Any aFormat
= m_XDataFormatTranslator
->getSystemDataTypeFromDataFlavor( aDataFlavor
);
65 if ( aFormat
.hasValue( ) )
67 if ( aFormat
.getValueType( ) == CPPUTYPE_SALINT32
)
70 OSL_ENSURE( CF_INVALID
!= cf
, "Invalid Clipboard format delivered" );
72 else if ( aFormat
.getValueType( ) == CPPUTYPE_OUSTRING
)
74 OUString aClipFmtName
;
75 aFormat
>>= aClipFmtName
;
77 OSL_ASSERT( aClipFmtName
.getLength( ) );
78 cf
= RegisterClipboardFormatW( o3tl::toW(aClipFmtName
.getStr( )) );
80 OSL_ENSURE( CF_INVALID
!= cf
, "RegisterClipboardFormat failed" );
83 OSL_FAIL( "Wrong Any-Type detected" );
89 OSL_FAIL( "Unexpected error" );
92 return sal::static_int_cast
<CFormatEtc
>(getFormatEtcForClipformat( sal::static_int_cast
<CLIPFORMAT
>(cf
) ));
95 DataFlavor
CDataFormatTranslator::getDataFlavorFromFormatEtc(sal_uInt32 cfFormat
, LCID lcid
) const
101 CLIPFORMAT aClipformat
= cfFormat
;
104 aAny
<<= static_cast< sal_Int32
>( aClipformat
);
106 if ( isOemOrAnsiTextFormat( aClipformat
) )
108 aFlavor
.MimeType
= "text/plain;charset=";
109 aFlavor
.MimeType
+= getTextCharsetFromLCID( lcid
, aClipformat
);
111 aFlavor
.HumanPresentableName
= "OEM/ANSI Text";
112 aFlavor
.DataType
= CPPUTYPE_SEQSALINT8
;
114 else if ( CF_INVALID
!= aClipformat
)
116 if ( m_XDataFormatTranslator
.is( ) )
118 aFlavor
= m_XDataFormatTranslator
->getDataFlavorFromSystemDataType( aAny
);
120 if ( !aFlavor
.MimeType
.getLength( ) )
122 // lookup of DataFlavor from clipboard format id
123 // failed, so we try to resolve via clipboard
125 OUString clipFormatName
= getClipboardFormatName( aClipformat
);
127 // if we could not get a clipboard format name an
128 // error must have occurred or it is a standard
129 // clipboard format that we don't translate, e.g.
130 // CF_BITMAP (the office only uses CF_DIB)
131 if ( clipFormatName
.getLength( ) )
133 aAny
<<= clipFormatName
;
134 aFlavor
= m_XDataFormatTranslator
->getDataFlavorFromSystemDataType( aAny
);
142 OSL_FAIL( "Unexpected error" );
148 CFormatEtc
CDataFormatTranslator::getFormatEtcForClipformatName( const OUString
& aClipFmtName
)
151 if ( !aClipFmtName
.getLength( ) )
152 return CFormatEtc( CF_INVALID
);
154 CLIPFORMAT cf
= sal::static_int_cast
<CLIPFORMAT
>(RegisterClipboardFormatW( o3tl::toW(aClipFmtName
.getStr( )) ));
155 return getFormatEtcForClipformat( cf
);
158 OUString
CDataFormatTranslator::getClipboardFormatName( CLIPFORMAT aClipformat
)
160 OSL_PRECOND( CF_INVALID
!= aClipformat
, "Invalid clipboard format" );
162 sal_Unicode wBuff
[ MAX_CLIPFORMAT_NAME
+ 1 ]; // Null terminator isn't counted, apparently.
163 sal_Int32 nLen
= GetClipboardFormatNameW( aClipformat
, o3tl::toW(wBuff
), MAX_CLIPFORMAT_NAME
);
165 return OUString( wBuff
, nLen
);
168 CFormatEtc
CDataFormatTranslator::getFormatEtcForClipformat( CLIPFORMAT cf
)
170 CFormatEtc
fetc( cf
, TYMED_NULL
, nullptr, DVASPECT_CONTENT
);
174 case CF_METAFILEPICT
:
175 fetc
.setTymed( TYMED_MFPICT
);
179 fetc
.setTymed( TYMED_ENHMF
);
183 fetc
.setTymed( TYMED_HGLOBAL
/*| TYMED_ISTREAM*/ );
187 hack: in order to paste urls copied by Internet Explorer
188 with "copy link" we set the lindex member to 0
189 but if we really want to support CFSTR_FILECONTENT and
190 the accompany format CFSTR_FILEDESCRIPTOR (FileGroupDescriptor)
191 the client of the clipboard service has to provide a id
192 of which FileContents it wants to paste
193 see MSDN: "Handling Shell Data Transfer Scenarios"
195 if ( cf
== RegisterClipboardFormat( CFSTR_FILECONTENTS
) )
201 bool CDataFormatTranslator::isOemOrAnsiTextFormat( CLIPFORMAT cf
)
203 return ( (cf
== CF_TEXT
) || (cf
== CF_OEMTEXT
) );
206 bool CDataFormatTranslator::isUnicodeTextFormat( CLIPFORMAT cf
)
208 return ( cf
== CF_UNICODETEXT
);
211 bool CDataFormatTranslator::isTextFormat( CLIPFORMAT cf
)
213 return ( isOemOrAnsiTextFormat( cf
) || isUnicodeTextFormat( cf
) );
216 bool CDataFormatTranslator::isHTMLFormat( CLIPFORMAT cf
)
218 OUString clipFormatName
= getClipboardFormatName( cf
);
219 return ( clipFormatName
== "HTML Format" );
222 bool CDataFormatTranslator::isTextHtmlFormat( CLIPFORMAT cf
)
224 OUString clipFormatName
= getClipboardFormatName( cf
);
225 return clipFormatName
.equalsIgnoreAsciiCase( "HTML (HyperText Markup Language)" );
228 OUString
CDataFormatTranslator::getTextCharsetFromLCID( LCID lcid
, CLIPFORMAT aClipformat
)
230 OSL_ASSERT( isOemOrAnsiTextFormat( aClipformat
) );
233 if ( CF_TEXT
== aClipformat
)
235 charset
= getMimeCharsetFromLocaleId(
237 LOCALE_IDEFAULTANSICODEPAGE
,
238 PRE_WINDOWS_CODEPAGE
);
240 else if ( CF_OEMTEXT
== aClipformat
)
242 charset
= getMimeCharsetFromLocaleId(
244 LOCALE_IDEFAULTCODEPAGE
,
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */