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 )

Reply via email to