sc/source/ui/dbgui/scuiasciiopt.cxx | 297 +++++++++++++----------------------- 1 file changed, 109 insertions(+), 188 deletions(-)
New commits: commit 70ad1d0c86cffc567b05b903ee83844a189c0d26 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Jun 4 14:40:18 2025 +0500 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jun 9 11:14:50 2025 +0200 Related: tdf#166208 Avoid C-style array and fixed index madness Here we deal with conditional length and set of elements in the two sequences (names, values). This required a complex logic to handle them; and all the changes required accurate synchronization both in the code, and with the schema. An example of a confusion from this is commit 19f3b72f34c487dc97d582712d21734a7e055fd5, which increased the size of the sequence returned from lcl_CreatePropertiesNames. Instead, use ConfigItem::GetNodeNames to get the defined names from schema. This unifies the code for all eCall cases, by only reading and writing those values that exist in the respective config node's schema. Change-Id: I90fdaa603bb12dc554a4c2947dd7f3415af31f24 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186236 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit e8027d47d516e74b0631d99c584bc7bb301a3efb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186244 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx index b35cf24ba7fb..05d3f6ac9c33 100644 --- a/sc/source/ui/dbgui/scuiasciiopt.cxx +++ b/sc/source/ui/dbgui/scuiasciiopt.cxx @@ -38,6 +38,7 @@ #include <osl/diagnose.h> #include <vcl/svapp.hxx> #include <comphelper/lok.hxx> +#include <comphelper/sequence.hxx> #include <o3tl/string_view.hxx> #include <unicode/ucsdet.h> @@ -59,30 +60,6 @@ using namespace com::sun::star::uno; namespace { -// Defines - CSV Import Preserve Options -// For usage of index order see lcl_CreatePropertiesNames() below. -enum CSVImportOptionsIndex -{ - CSVIO_MergeDelimiters = 0, - CSVIO_Separators, - CSVIO_TextSeparators, - CSVIO_FixedWidth, - CSVIO_RemoveSpace, - CSVIO_EvaluateFormulas, - CSVIO_SeparatorType, - // Settings for *all* dialog invocations above. - // Settings not for SC_TEXTTOCOLUMNS below. - CSVIO_FromRow, - CSVIO_Text2ColSkipEmptyCells = CSVIO_FromRow, - CSVIO_CharSet, - CSVIO_QuotedAsText, - CSVIO_DetectSpecialNum, - CSVIO_DetectScientificNum, - CSVIO_Language, - // Plus one not for SC_IMPORTFILE. - CSVIO_PasteSkipEmptyCells -}; - enum SeparatorType { FIXED, @@ -95,33 +72,20 @@ enum SeparatorType // Config items for all three paths are defined in // officecfg/registry/schema/org/openoffice/Office/Calc.xcs // If not, options are neither loaded nor saved. -const ::std::vector<OUString> CSVImportOptionNames = -{ - u"MergeDelimiters"_ustr, - u"Separators"_ustr, - u"TextSeparators"_ustr, - u"FixedWidth"_ustr, - u"RemoveSpace"_ustr, - u"EvaluateFormulas"_ustr, - u"SeparatorType"_ustr, - u"FromRow"_ustr, - u"CharSet"_ustr, - u"QuotedFieldAsText"_ustr, - u"DetectSpecialNumbers"_ustr, - u"DetectScientificNumbers"_ustr, - u"Language"_ustr, - u"SkipEmptyCells"_ustr -}; -constexpr OUStringLiteral aSep_Path = u"Office.Calc/Dialogs/CSVImport"; -constexpr OUStringLiteral aSep_Path_Clpbrd = u"Office.Calc/Dialogs/ClipboardTextImport"; -constexpr OUStringLiteral aSep_Path_Text2Col = u"Office.Calc/Dialogs/TextToColumnsImport"; - -namespace { -CSVImportOptionsIndex getSkipEmptyCellsIndex( ScImportAsciiCall eCall ) -{ - return eCall == SC_TEXTTOCOLUMNS ? CSVIO_Text2ColSkipEmptyCells : CSVIO_PasteSkipEmptyCells; -} -} +constexpr OUString CSVIO_MergeDelimiters = u"MergeDelimiters"_ustr; +constexpr OUString CSVIO_Separators = u"Separators"_ustr; +constexpr OUString CSVIO_TextSeparators = u"TextSeparators"_ustr; +constexpr OUString CSVIO_FixedWidth = u"FixedWidth"_ustr; +constexpr OUString CSVIO_RemoveSpace = u"RemoveSpace"_ustr; +constexpr OUString CSVIO_EvaluateFormulas = u"EvaluateFormulas"_ustr; +constexpr OUString CSVIO_SeparatorType = u"SeparatorType"_ustr; +constexpr OUString CSVIO_FromRow = u"FromRow"_ustr; +constexpr OUString CSVIO_CharSet = u"CharSet"_ustr; +constexpr OUString CSVIO_QuotedAsText = u"QuotedFieldAsText"_ustr; +constexpr OUString CSVIO_DetectSpecialNum = u"DetectSpecialNumbers"_ustr; +constexpr OUString CSVIO_DetectScientificNum = u"DetectScientificNumbers"_ustr; +constexpr OUString CSVIO_Language = u"Language"_ustr; +constexpr OUString CSVIO_SkipEmptyCells = u"SkipEmptyCells"_ustr; static void lcl_FillCombo(weld::ComboBox& rCombo, std::u16string_view rList, sal_Unicode cSelect) { @@ -179,158 +143,115 @@ static sal_Unicode lcl_CharFromCombo(const weld::ComboBox& rCombo, std::u16strin return c; } -static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& rNames, ScImportAsciiCall eCall ) +static OUString lcl_GetConfigPath(ScImportAsciiCall eCall) { - sal_Int32 nProperties = 0; - switch(eCall) { case SC_IMPORTFILE: - rSepPath = aSep_Path; - nProperties = 13; - break; + return u"Office.Calc/Dialogs/CSVImport"_ustr; case SC_PASTETEXT: - rSepPath = aSep_Path_Clpbrd; - nProperties = 14; - break; + return u"Office.Calc/Dialogs/ClipboardTextImport"_ustr; case SC_TEXTTOCOLUMNS: default: - rSepPath = aSep_Path_Text2Col; - nProperties = 8; - break; - } - rNames.realloc( nProperties ); - OUString* pNames = rNames.getArray(); - pNames[ CSVIO_MergeDelimiters ] = CSVImportOptionNames[ CSVIO_MergeDelimiters ]; - pNames[ CSVIO_Separators ] = CSVImportOptionNames[ CSVIO_Separators ]; - pNames[ CSVIO_TextSeparators ] = CSVImportOptionNames[ CSVIO_TextSeparators ]; - pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ]; - pNames[ CSVIO_RemoveSpace ] = CSVImportOptionNames[ CSVIO_RemoveSpace ]; - pNames[ CSVIO_EvaluateFormulas ] = CSVImportOptionNames[ CSVIO_EvaluateFormulas ]; - pNames[ CSVIO_SeparatorType ] = CSVImportOptionNames[ CSVIO_SeparatorType ]; - if (eCall != SC_TEXTTOCOLUMNS) - { - pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ]; - pNames[ CSVIO_CharSet ] = CSVImportOptionNames[ CSVIO_CharSet ]; - pNames[ CSVIO_QuotedAsText ] = CSVImportOptionNames[ CSVIO_QuotedAsText ]; - pNames[ CSVIO_DetectSpecialNum ] = CSVImportOptionNames[ CSVIO_DetectSpecialNum ]; - pNames[ CSVIO_DetectScientificNum ] = CSVImportOptionNames[ CSVIO_DetectScientificNum ]; - pNames[ CSVIO_Language ] = CSVImportOptionNames[ CSVIO_Language ]; - } - if (eCall != SC_IMPORTFILE) - { - const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall); - assert( nSkipEmptyCells < rNames.getLength()); - pNames[ nSkipEmptyCells ] = CSVImportOptionNames[ CSVIO_PasteSkipEmptyCells ]; + return u"Office.Calc/Dialogs/TextToColumnsImport"_ustr; } } -static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators, +static void lcl_LoadSeparators(ScImportAsciiCall eCall, OUString& rFieldSeparators, OUString& rTextSeparators, bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum, bool& rDetectScientificNum, SeparatorType& rSepType, sal_Int32& rFromRow, sal_Int32& rCharSet, sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace, - bool& rEvaluateFormulas, ScImportAsciiCall eCall, bool& rBeforeDetection ) + bool& rEvaluateFormulas, bool& rBeforeDetection) { - Sequence<Any>aValues; - const Any *pProperties; - Sequence<OUString> aNames; - OUString aSepPath; - lcl_CreatePropertiesNames ( aSepPath, aNames, eCall); - ScLinkConfigItem aItem( aSepPath ); - aValues = aItem.GetProperties( aNames ); - pProperties = aValues.getConstArray(); - - if( pProperties[ CSVIO_MergeDelimiters ].hasValue() ) - rMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_MergeDelimiters ] ); - - if( pProperties[ CSVIO_RemoveSpace ].hasValue() ) - rRemoveSpace = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_RemoveSpace ] ); - - if( pProperties[ CSVIO_Separators ].hasValue() ) - pProperties[ CSVIO_Separators ] >>= rFieldSeparators; - - if( pProperties[ CSVIO_TextSeparators ].hasValue() ) - pProperties[ CSVIO_TextSeparators ] >>= rTextSeparators; + ScLinkConfigItem aItem(lcl_GetConfigPath(eCall)); + const Sequence<OUString> aNames = aItem.GetNodeNames({}); + const Sequence<Any> aValues = aItem.GetProperties(aNames); rBeforeDetection = true; - if( pProperties[ CSVIO_SeparatorType ].hasValue() ) - { - rBeforeDetection = false; - rSepType = static_cast<SeparatorType>(ScUnoHelpFunctions::GetInt16FromAny( pProperties[ CSVIO_SeparatorType ] )); - } - else if( pProperties[ CSVIO_FixedWidth ].hasValue() ) - rSepType = (ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_FixedWidth ] ) ? SeparatorType::FIXED : SeparatorType::DETECT_SEPARATOR); - - if( pProperties[ CSVIO_EvaluateFormulas ].hasValue() ) - rEvaluateFormulas = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_EvaluateFormulas ] ); - - if (eCall != SC_TEXTTOCOLUMNS) - { - if( pProperties[ CSVIO_FromRow ].hasValue() ) - pProperties[ CSVIO_FromRow ] >>= rFromRow; - - if( pProperties[ CSVIO_CharSet ].hasValue() ) - pProperties[ CSVIO_CharSet ] >>= rCharSet; - - if ( pProperties[ CSVIO_QuotedAsText ].hasValue() ) - pProperties[ CSVIO_QuotedAsText ] >>= rQuotedAsText; - if ( pProperties[ CSVIO_DetectSpecialNum ].hasValue() ) - pProperties[ CSVIO_DetectSpecialNum ] >>= rDetectSpecialNum; - - if ( pProperties[ CSVIO_DetectScientificNum ].hasValue() ) - pProperties[ CSVIO_DetectScientificNum ] >>= rDetectScientificNum; - - if ( pProperties[ CSVIO_Language ].hasValue() ) - pProperties[ CSVIO_Language ] >>= rLanguage; - } - if (eCall != SC_IMPORTFILE) - { - const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall); - assert( nSkipEmptyCells < aValues.getLength()); - if ( pProperties[nSkipEmptyCells].hasValue() ) - rSkipEmptyCells = ScUnoHelpFunctions::GetBoolFromAny( pProperties[nSkipEmptyCells] ); - } -} - -static void lcl_SaveSeparators( + for (sal_Int32 i = 0; i < aNames.getLength(); ++i) + { + const OUString& name = aNames[i]; + const Any& value = aValues[i]; + if (!value.hasValue()) + continue; + if (name == CSVIO_MergeDelimiters) + rMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny(value); + else if (name == CSVIO_RemoveSpace) + rRemoveSpace = ScUnoHelpFunctions::GetBoolFromAny(value); + else if (name == CSVIO_Separators) + value >>= rFieldSeparators; + else if (name == CSVIO_TextSeparators) + value >>= rTextSeparators; + else if (name == CSVIO_SeparatorType) + { + rBeforeDetection = false; + rSepType = static_cast<SeparatorType>(ScUnoHelpFunctions::GetInt16FromAny(value)); + } + else if (name == CSVIO_FixedWidth) + { + if (rBeforeDetection && ScUnoHelpFunctions::GetBoolFromAny(value)) + rSepType = SeparatorType::FIXED; + } + else if (name == CSVIO_EvaluateFormulas) + rEvaluateFormulas = ScUnoHelpFunctions::GetBoolFromAny(value); + else if (name == CSVIO_FromRow) + value >>= rFromRow; + else if (name == CSVIO_CharSet) + value >>= rCharSet; + else if (name == CSVIO_QuotedAsText) + value >>= rQuotedAsText; + else if (name == CSVIO_DetectSpecialNum) + value >>= rDetectSpecialNum; + else if (name == CSVIO_DetectScientificNum) + value >>= rDetectScientificNum; + else if (name == CSVIO_Language) + value >>= rLanguage; + else if (name == CSVIO_SkipEmptyCells) + rSkipEmptyCells = ScUnoHelpFunctions::GetBoolFromAny(value); + } +} + +static void lcl_SaveSeparators(ScImportAsciiCall eCall, const OUString& sFieldSeparators, const OUString& sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText, bool bDetectSpecialNum, bool bDetectScientificNum, SeparatorType rSepType, sal_Int32 nFromRow, - sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas, - ScImportAsciiCall eCall ) -{ - Sequence<Any> aValues; - Any *pProperties; - Sequence<OUString> aNames; - OUString aSepPath; - lcl_CreatePropertiesNames ( aSepPath, aNames, eCall ); - ScLinkConfigItem aItem( aSepPath ); - aValues = aItem.GetProperties( aNames ); - pProperties = aValues.getArray(); - - pProperties[ CSVIO_MergeDelimiters ] <<= bMergeDelimiters; - pProperties[ CSVIO_RemoveSpace ] <<= bRemoveSpace; - pProperties[ CSVIO_Separators ] <<= sFieldSeparators; - pProperties[ CSVIO_TextSeparators ] <<= sTextSeparators; - pProperties[ CSVIO_EvaluateFormulas ] <<= bEvaluateFormulas; - pProperties[ CSVIO_SeparatorType ] <<= static_cast<sal_Int16>(rSepType); - if (eCall != SC_TEXTTOCOLUMNS) - { - pProperties[ CSVIO_FromRow ] <<= nFromRow; - pProperties[ CSVIO_CharSet ] <<= nCharSet; - pProperties[ CSVIO_QuotedAsText ] <<= bQuotedAsText; - pProperties[ CSVIO_DetectSpecialNum ] <<= bDetectSpecialNum; - pProperties[ CSVIO_DetectScientificNum ] <<= bDetectScientificNum; - pProperties[ CSVIO_Language ] <<= nLanguage; - } - if (eCall != SC_IMPORTFILE) - { - const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall); - assert( nSkipEmptyCells < aValues.getLength()); - pProperties[ nSkipEmptyCells ] <<= bSkipEmptyCells; - } - - aItem.PutProperties(aNames, aValues); + sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas) +{ + ScLinkConfigItem aItem(lcl_GetConfigPath(eCall)); + std::unordered_map<OUString, Any> properties; + + for (const OUString& name : aItem.GetNodeNames({})) + { + if (name == CSVIO_MergeDelimiters) + properties[name] <<= bMergeDelimiters; + else if (name == CSVIO_RemoveSpace) + properties[name] <<= bRemoveSpace; + else if (name == CSVIO_Separators) + properties[name] <<= sFieldSeparators; + else if (name == CSVIO_TextSeparators) + properties[name] <<= sTextSeparators; + else if (name == CSVIO_EvaluateFormulas) + properties[name] <<= bEvaluateFormulas; + else if (name == CSVIO_SeparatorType) + properties[name] <<= static_cast<sal_Int16>(rSepType); + else if (name == CSVIO_FromRow) + properties[name] <<= nFromRow; + else if (name == CSVIO_CharSet) + properties[name] <<= nCharSet; + else if (name == CSVIO_QuotedAsText) + properties[name] <<= bQuotedAsText; + else if (name == CSVIO_DetectSpecialNum) + properties[name] <<= bDetectSpecialNum; + else if (name == CSVIO_DetectScientificNum) + properties[name] <<= bDetectScientificNum; + else if (name == CSVIO_Language) + properties[name] <<= nLanguage; + else if (name == CSVIO_SkipEmptyCells) + properties[name] <<= bSkipEmptyCells; + } + + aItem.PutProperties(comphelper::mapKeysToSequence(properties), + comphelper::mapValuesToSequence(properties)); } ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aDatName, @@ -409,9 +330,9 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD sal_Int32 nCharSet = -1; sal_Int32 nLanguage = 0; - lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters, + lcl_LoadSeparators ( meCall, sFieldSeparators, sTextSeparators, bMergeDelimiters, bQuotedFieldAsText, bDetectSpecialNum, bDetectScientificNum, eSepType, nFromRow, - nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, meCall, + nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, bBeforeDetection); maFieldSeparators = sFieldSeparators; @@ -682,14 +603,14 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) void ScImportAsciiDlg::SaveParameters() { - lcl_SaveSeparators( GetSeparators(), mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(), + lcl_SaveSeparators(meCall, GetSeparators(), mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(), mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(), mxCkbDetectScientificNumber->get_active(), mxRbFixed->get_active() ? FIXED : (mxRbDetectSep->get_active() ? DETECT_SEPARATOR : SEPARATOR), mxNfRow->get_value(), mxLbCharSet->get_active(), static_cast<sal_uInt16>(mxLbCustomLang->get_active_id()), mxCkbSkipEmptyCells->get_active(), mxCkbRemoveSpace->get_active(), - mxCkbEvaluateFormulas->get_active(), meCall ); + mxCkbEvaluateFormulas->get_active()); } void ScImportAsciiDlg::SetSeparators( sal_Unicode cSep )