diff options
-rw-r--r-- | connectivity/source/commontools/dbtools.cxx | 83 | ||||
-rw-r--r-- | connectivity/source/drivers/dbase/DTable.cxx | 43 | ||||
-rw-r--r-- | include/connectivity/dbtools.hxx | 45 | ||||
-rw-r--r-- | sc/CppunitTest_sc_ucalc.mk | 1 | ||||
-rw-r--r-- | sc/Library_sc.mk | 1 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh8.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/unoobj/filtuno.cxx | 140 |
7 files changed, 232 insertions, 85 deletions
diff --git a/connectivity/source/commontools/dbtools.cxx b/connectivity/source/commontools/dbtools.cxx index 97316e5e2536..fa34331d85f9 100644 --- a/connectivity/source/commontools/dbtools.cxx +++ b/connectivity/source/commontools/dbtools.cxx @@ -2026,6 +2026,89 @@ OSQLColumns::Vector::const_iterator find(OSQLColumns::Vector::const_iterator fir ++first; return first; } + +namespace dbase +{ + bool dbfDecodeCharset(rtl_TextEncoding &_out_encoding, sal_uInt8 nType, sal_uInt8 nCodepage) + { + switch (nType) + { + case dBaseIII: + case dBaseIV: + case dBaseV: + case VisualFoxPro: + case VisualFoxProAuto: + case dBaseFS: + case dBaseFSMemo: + case dBaseIVMemoSQL: + case dBaseIIIMemo: + case FoxProMemo: + { + if (nCodepage != 0x00) + { + auto eEncoding(RTL_TEXTENCODING_DONTKNOW); + switch(nCodepage) + { + case 0x01: eEncoding = RTL_TEXTENCODING_IBM_437; break; // DOS USA code page 437 + case 0x02: eEncoding = RTL_TEXTENCODING_IBM_850; break; // DOS Multilingual code page 850 + case 0x03: eEncoding = RTL_TEXTENCODING_MS_1252; break; // Windows ANSI code page 1252 + case 0x04: eEncoding = RTL_TEXTENCODING_APPLE_ROMAN; break; // Standard Macintosh + case 0x64: eEncoding = RTL_TEXTENCODING_IBM_852; break; // EE MS-DOS code page 852 + case 0x65: eEncoding = RTL_TEXTENCODING_IBM_866; break; // Russian MS-DOS code page 866 + case 0x66: eEncoding = RTL_TEXTENCODING_IBM_865; break; // Nordic MS-DOS code page 865 + case 0x67: eEncoding = RTL_TEXTENCODING_IBM_861; break; // Icelandic MS-DOS + //case 0x68: eEncoding = ; break; // Kamenicky (Czech) MS-DOS + //case 0x69: eEncoding = ; break; // Mazovia (Polish) MS-DOS + case 0x6A: eEncoding = RTL_TEXTENCODING_IBM_737; break; // Greek MS-DOS (437G) + case 0x6B: eEncoding = RTL_TEXTENCODING_IBM_857; break; // Turkish MS-DOS + case 0x6C: eEncoding = RTL_TEXTENCODING_IBM_863; break; // MS-DOS, Canada + case 0x78: eEncoding = RTL_TEXTENCODING_MS_950; break; // Windows, Traditional Chinese + case 0x79: eEncoding = RTL_TEXTENCODING_MS_949; break; // Windows, Korean (Hangul) + case 0x7A: eEncoding = RTL_TEXTENCODING_MS_936; break; // Windows, Simplified Chinese + case 0x7B: eEncoding = RTL_TEXTENCODING_MS_932; break; // Windows, Japanese (Shift-jis) + case 0x7C: eEncoding = RTL_TEXTENCODING_MS_874; break; // Windows, Thai + case 0x7D: eEncoding = RTL_TEXTENCODING_MS_1255; break; // Windows, Hebrew + case 0x7E: eEncoding = RTL_TEXTENCODING_MS_1256; break; // Windows, Arabic + case 0x96: eEncoding = RTL_TEXTENCODING_APPLE_CYRILLIC; break; // Russian Macintosh + case 0x97: eEncoding = RTL_TEXTENCODING_APPLE_CENTEURO; break; // Eastern European Macintosh + case 0x98: eEncoding = RTL_TEXTENCODING_APPLE_GREEK; break; // Greek Macintosh + case 0xC8: eEncoding = RTL_TEXTENCODING_MS_1250; break; // Windows EE code page 1250 + case 0xC9: eEncoding = RTL_TEXTENCODING_MS_1251; break; // Russian Windows + case 0xCA: eEncoding = RTL_TEXTENCODING_MS_1254; break; // Turkish Windows + case 0xCB: eEncoding = RTL_TEXTENCODING_MS_1253; break; // Greek Windows + case 0xCC: eEncoding = RTL_TEXTENCODING_MS_1257; break; // Windows, Baltic + } + if(eEncoding != RTL_TEXTENCODING_DONTKNOW) + { + _out_encoding = eEncoding; + return true; + } + } + } + } + return false; + } + + bool dbfReadCharset(rtl_TextEncoding &nCharSet, SvStream* dbf_Stream) + { + sal_uInt8 nType=0; + dbf_Stream->ReadUChar( nType ); + + dbf_Stream->Seek(STREAM_SEEK_TO_BEGIN + 29); + if (dbf_Stream->IsEof()) + { + return false; + } + else + { + sal_uInt8 nEncoding=0; + dbf_Stream->ReadUChar( nEncoding ); + return dbfDecodeCharset(nCharSet, nType, nEncoding); + } + } + +} + } //namespace connectivity /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx index 6da1f893e6fc..3e14a594bbb7 100644 --- a/connectivity/source/drivers/dbase/DTable.cxx +++ b/connectivity/source/drivers/dbase/DTable.cxx @@ -250,48 +250,9 @@ void ODbaseTable::readHeader() case dBaseIIIMemo: case FoxProMemo: m_pFileStream->SetEndian(SvStreamEndian::LITTLE); - // trailer[17] corresponds to language code, see DBFHeader def in connectivity/source/inc/dbase/DTable.hxx - if ( m_aHeader.trailer[17] != 0x00 && getConnection()->isTextEncodingDefaulted() ) + if( getConnection()->isTextEncodingDefaulted() && + !dbfDecodeCharset(m_eEncoding, nType, m_aHeader.trailer[17])) { - switch(m_aHeader.trailer[17]) - { - case 0x01: m_eEncoding = RTL_TEXTENCODING_IBM_437; break; // DOS USA code page 437 - case 0x02: m_eEncoding = RTL_TEXTENCODING_IBM_850; break; // DOS Multilingual code page 850 - case 0x03: m_eEncoding = RTL_TEXTENCODING_MS_1252; break; // Windows ANSI code page 1252 - case 0x04: m_eEncoding = RTL_TEXTENCODING_APPLE_ROMAN; break; // Standard Macintosh - case 0x64: m_eEncoding = RTL_TEXTENCODING_IBM_852; break; // EE MS-DOS code page 852 - case 0x65: m_eEncoding = RTL_TEXTENCODING_IBM_866; break; // Russian MS-DOS code page 866 - case 0x66: m_eEncoding = RTL_TEXTENCODING_IBM_865; break; // Nordic MS-DOS code page 865 - case 0x67: m_eEncoding = RTL_TEXTENCODING_IBM_861; break; // Icelandic MS-DOS - //case 0x68: m_eEncoding = ; break; // Kamenicky (Czech) MS-DOS - //case 0x69: m_eEncoding = ; break; // Mazovia (Polish) MS-DOS - case 0x6A: m_eEncoding = RTL_TEXTENCODING_IBM_737; break; // Greek MS-DOS (437G) - case 0x6B: m_eEncoding = RTL_TEXTENCODING_IBM_857; break; // Turkish MS-DOS - case 0x6C: m_eEncoding = RTL_TEXTENCODING_IBM_863; break; // MS-DOS, Canada - case 0x78: m_eEncoding = RTL_TEXTENCODING_MS_950; break; // Windows, Traditional Chinese - case 0x79: m_eEncoding = RTL_TEXTENCODING_MS_949; break; // Windows, Korean (Hangul) - case 0x7A: m_eEncoding = RTL_TEXTENCODING_MS_936; break; // Windows, Simplified Chinese - case 0x7B: m_eEncoding = RTL_TEXTENCODING_MS_932; break; // Windows, Japanese (Shift-jis) - case 0x7C: m_eEncoding = RTL_TEXTENCODING_MS_874; break; // Windows, Thai - case 0x7D: m_eEncoding = RTL_TEXTENCODING_MS_1255; break; // Windows, Hebrew - case 0x7E: m_eEncoding = RTL_TEXTENCODING_MS_1256; break; // Windows, Arabic - case 0x96: m_eEncoding = RTL_TEXTENCODING_APPLE_CYRILLIC; break; // Russian Macintosh - case 0x97: m_eEncoding = RTL_TEXTENCODING_APPLE_CENTEURO; break; // Eastern European Macintosh - case 0x98: m_eEncoding = RTL_TEXTENCODING_APPLE_GREEK; break; // Greek Macintosh - case 0xC8: m_eEncoding = RTL_TEXTENCODING_MS_1250; break; // Windows EE code page 1250 - case 0xC9: m_eEncoding = RTL_TEXTENCODING_MS_1251; break; // Russian Windows - case 0xCA: m_eEncoding = RTL_TEXTENCODING_MS_1254; break; // Turkish Windows - case 0xCB: m_eEncoding = RTL_TEXTENCODING_MS_1253; break; // Greek Windows - case 0xCC: m_eEncoding = RTL_TEXTENCODING_MS_1257; break; // Windows, Baltic - default: - // Default Encoding - m_eEncoding = RTL_TEXTENCODING_IBM_850; - break; - } - } - else - { - // Default Encoding m_eEncoding = RTL_TEXTENCODING_IBM_850; } break; diff --git a/include/connectivity/dbtools.hxx b/include/connectivity/dbtools.hxx index 7f4719bd41c8..4b493ee98267 100644 --- a/include/connectivity/dbtools.hxx +++ b/include/connectivity/dbtools.hxx @@ -27,6 +27,7 @@ #include <unotools/sharedunocomponent.hxx> #include <connectivity/dbtoolsdllapi.hxx> #include <connectivity/FValue.hxx> +#include <tools/stream.hxx> namespace com { namespace sun { namespace star { @@ -786,9 +787,51 @@ namespace dbtools OUStringBuffer& _out_rSQLPredicate ); - } // namespace dbtools +namespace connectivity::dbase +{ + enum DBFType { dBaseIII = 0x03, + dBaseIV = 0x04, + dBaseV = 0x05, + VisualFoxPro = 0x30, + VisualFoxProAuto = 0x31, // Visual FoxPro with AutoIncrement field + dBaseFS = 0x43, + dBaseFSMemo = 0xB3, + dBaseIIIMemo = 0x83, + dBaseIVMemo = 0x8B, + dBaseIVMemoSQL = 0x8E, + FoxProMemo = 0xF5 + }; + + /** decode a DBase file's codepage byte to a RTL charset + @param _out_nCharset + in case of success, the decoded RTL charset is written there. + else, this is not written to. + @param nType + the file's type byte + @param nCodepage + the file's codepage byte + @return + true if a RTL charset was successfully decoded and written to _out_nCharset + false if nothing was written to _out_nCharset + */ + OOO_DLLPUBLIC_DBTOOLS bool dbfDecodeCharset(rtl_TextEncoding &_out_nCharset, sal_uInt8 nType, sal_uInt8 nCodepage); + + /** decode a DBase file's codepage byte to a RTL charset + @param _out_nCharset + in case of success, the decoded RTL charset is written there. + else, this is not written to. + @param dbf_Stream + pointer to a SvStream encapsulating the DBase file. + The stream will be rewinded and read from. + No guarantee is made on its position afterwards. Caller must reposition it itself. + @return + true if a RTL charset was successfully decoded and written to _out_nCharset + false if nothing was written to _out_nCharset + */ + OOO_DLLPUBLIC_DBTOOLS bool dbfReadCharset(rtl_TextEncoding &nCharSet, SvStream* dbf_Stream); +} // namespace connectivity::dbase #endif // INCLUDED_CONNECTIVITY_DBTOOLS_HXX diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk index d918182a0c4f..d423f6c73a7b 100644 --- a/sc/CppunitTest_sc_ucalc.mk +++ b/sc/CppunitTest_sc_ucalc.mk @@ -45,6 +45,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_ucalc, \ comphelper \ cppu \ cppuhelper \ + dbtools \ drawinglayer \ editeng \ for \ diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 5b7d2fcf9275..c9f54638e62e 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -58,6 +58,7 @@ $(eval $(call gb_Library_use_libraries,sc,\ comphelper \ cppu \ cppuhelper \ + dbtools \ drawinglayer \ editeng \ for \ diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx index b21e6426e99b..5a676d24d029 100644 --- a/sc/source/ui/docshell/docsh8.cxx +++ b/sc/source/ui/docshell/docsh8.cxx @@ -301,10 +301,6 @@ ErrCode ScDocShell::DBaseImport( const OUString& rFullFileName, rtl_TextEncoding ErrCode nErr = ERRCODE_NONE; - // Try to get the Text Encoding from the driver - if( eCharSet == RTL_TEXTENCODING_IBM_850 ) - eCharSet = RTL_TEXTENCODING_DONTKNOW; - try { long i; diff --git a/sc/source/ui/unoobj/filtuno.cxx b/sc/source/ui/unoobj/filtuno.cxx index c0cc98782879..fd98a2cb590c 100644 --- a/sc/source/ui/unoobj/filtuno.cxx +++ b/sc/source/ui/unoobj/filtuno.cxx @@ -22,6 +22,7 @@ #include <vcl/msgbox.hxx> #include <vcl/svapp.hxx> #include <unotools/ucbstreamhelper.hxx> +#include <connectivity/dbtools.hxx> #include "editutil.hxx" #include "filtuno.hxx" @@ -44,6 +45,7 @@ using namespace com::sun::star; using namespace com::sun::star::uno; +using namespace connectivity::dbase; #define SCFILTEROPTIONSOBJ_SERVICE "com.sun.star.ui.dialogs.FilterOptionsDialog" #define SCFILTEROPTIONSOBJ_IMPLNAME "com.sun.star.comp.Calc.FilterOptionsDialog" @@ -59,44 +61,75 @@ SC_SIMPLE_SERVICE_INFO( ScFilterOptionsObj, SCFILTEROPTIONSOBJ_IMPLNAME, SCFILTE #define DBF_SEP_PATH_IMPORT "Office.Calc/Dialogs/DBFImport" #define DBF_SEP_PATH_EXPORT "Office.Calc/Dialogs/DBFExport" -static void load_CharSet( rtl_TextEncoding &nCharSet, bool bExport ) +namespace { - Sequence<Any> aValues; - const Any *pProperties; - Sequence<OUString> aNames { DBF_CHAR_SET }; - ScLinkConfigItem aItem( OUString::createFromAscii( - bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); - aValues = aItem.GetProperties( aNames ); - pProperties = aValues.getConstArray(); + enum class charsetSource + { + charset_from_file, + charset_from_user_setting, + charset_default + }; + // TODO: use DTable.hxx instead + enum DBFType { dBaseIII = 0x03, + dBaseIV = 0x04, + dBaseV = 0x05, + VisualFoxPro = 0x30, + VisualFoxProAuto = 0x31, // Visual FoxPro with AutoIncrement field + dBaseFS = 0x43, + dBaseFSMemo = 0xB3, + dBaseIIIMemo = 0x83, + dBaseIVMemo = 0x8B, + dBaseIVMemoSQL = 0x8E, + FoxProMemo = 0xF5 + }; + + charsetSource load_CharSet(rtl_TextEncoding &nCharSet, bool bExport, SvStream* dbf_Stream) + { + if (dbfReadCharset(nCharSet, dbf_Stream)) + { + return charsetSource::charset_from_file; + } - // Default choice - nCharSet = RTL_TEXTENCODING_IBM_850; + Sequence<Any> aValues; + const Any *pProperties; + Sequence<OUString> aNames { DBF_CHAR_SET }; + ScLinkConfigItem aItem( OUString::createFromAscii( + bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); - if( pProperties[0].hasValue() ) - { - sal_Int32 nChar = 0; - pProperties[0] >>= nChar; - if( nChar >= 0) + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getConstArray(); + + if( pProperties[0].hasValue() ) { - nCharSet = (rtl_TextEncoding) nChar; + sal_Int32 nChar = 0; + pProperties[0] >>= nChar; + if( nChar >= 0) + { + nCharSet = (rtl_TextEncoding) nChar; + return charsetSource::charset_from_user_setting; + } } + + // Default choice + nCharSet = RTL_TEXTENCODING_IBM_850; + return charsetSource::charset_default; } -} -static void save_CharSet( rtl_TextEncoding nCharSet, bool bExport ) -{ - Sequence<Any> aValues; - Any *pProperties; - Sequence<OUString> aNames { DBF_CHAR_SET }; - ScLinkConfigItem aItem( OUString::createFromAscii( - bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); + void save_CharSet( rtl_TextEncoding nCharSet, bool bExport ) + { + Sequence<Any> aValues; + Any *pProperties; + Sequence<OUString> aNames { DBF_CHAR_SET }; + ScLinkConfigItem aItem( OUString::createFromAscii( + bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); - aValues = aItem.GetProperties( aNames ); - pProperties = aValues.getArray(); - pProperties[0] <<= (sal_Int32) nCharSet; + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getArray(); + pProperties[0] <<= (sal_Int32) nCharSet; - aItem.PutProperties(aNames, aValues); + aItem.PutProperties(aNames, aValues); + } } ScFilterOptionsObj::ScFilterOptionsObj() : @@ -209,6 +242,7 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() { bool bDBEnc = false; bool bAscii = false; + bool skipDialog = false; sal_Unicode const cStrDel = '"'; sal_Unicode cAsciiDel = ';'; @@ -250,8 +284,20 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() // dBase import aTitle = ScGlobal::GetRscString( STR_IMPORT_DBF ); } - load_CharSet( eEncoding, bExport ); + + std::unique_ptr<SvStream> pInStream; + if ( xInputStream.is() ) + pInStream.reset(utl::UcbStreamHelper::CreateStream( xInputStream )); + switch(load_CharSet( eEncoding, bExport, pInStream.get())) + { + case charsetSource::charset_from_file: + skipDialog = true;break; + case charsetSource::charset_from_user_setting: + case charsetSource::charset_default: + break; + } bDBEnc = true; + // pInStream goes out of scope, the stream is automatically closed } else if ( aFilterString == ScDocShell::GetDifFilterName() ) { @@ -270,21 +316,37 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() } ScImportOptions aOptions( cAsciiDel, cStrDel, eEncoding); - - ScopedVclPtr<AbstractScImportOptionsDlg> pDlg(pFact->CreateScImportOptionsDlg( - bAscii, &aOptions, &aTitle, true/*bMultiByte*/, bDBEnc, - !bExport)); - OSL_ENSURE(pDlg, "Dialog create fail!"); - if ( pDlg->Execute() == RET_OK ) + if(skipDialog) + { + // TODO: check we are not missing some of the stuff that ScImportOptionsDlg::GetImportOptions + // (file sc/source/ui/dbgui/scuiimoptdlg.cxx) does + // that is, if the dialog sets options that are not selected by the user (!) + // then we are missing them here. + // Then we may need to rip them out of the dialog. + // Or we actually change the dialog to not display if skipDialog==true + // in that case, add an argument skipDialog to CreateScImportOptionsDlg + nRet = ui::dialogs::ExecutableDialogResults::OK; + } + else + { + ScopedVclPtr<AbstractScImportOptionsDlg> pDlg(pFact->CreateScImportOptionsDlg( + bAscii, &aOptions, &aTitle, true/*bMultiByte*/, + bDBEnc, !bExport)); + OSL_ENSURE(pDlg, "Dialog create fail!"); + if ( pDlg->Execute() == RET_OK ) + { + pDlg->SaveImportOptions(); + pDlg->GetImportOptions( aOptions ); + save_CharSet( aOptions.eCharSet, bExport ); + nRet = ui::dialogs::ExecutableDialogResults::OK; + } + } + if (nRet == ui::dialogs::ExecutableDialogResults::OK) { - pDlg->SaveImportOptions(); - pDlg->GetImportOptions( aOptions ); - save_CharSet( aOptions.eCharSet, bExport ); if ( bAscii ) aFilterOptions = aOptions.BuildString(); else aFilterOptions = aOptions.aStrFont; - nRet = ui::dialogs::ExecutableDialogResults::OK; } } |