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