tdf#154131 Add Detect scientific number option

Add a sub case of Detect special numbers for import CSV (SC_IMPORTFILE),
paste unformated text (SC_PASTETEXT) and text to columns
(SC_TEXTTOCOLUMNS). Following cases are treated:
- If "Detect special numbers" is true, then "Detect scientific numbers"
  must be true and all special formats are treated (date, time,
scientific notation) in addition to basic decimal numbers.
- If "Detect special numbers" is false and "Detect scientific numbers" is
  true only scientific notation is treated in addition to basic decimal
numbers.
- If "Detect special numbers" and "Detect scientific numbers" are both
  false only basic decimal numbers are recognized as numbers. It is the
new case treated by this change
The new option bDetectScientificNumber is append to ASCII options

Change-Id: I73dff9f75d2c7b07ce155daa29dcc4ca9f288664
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152072
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index 7a18fb3..d282ca6 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -1032,6 +1032,13 @@
          </info>
          <value>false</value>
        </prop>
        <prop oor:name="DetectScientificNumbers" oor:type="xs:boolean" oor:nillable="false">
          <info>
            <desc>If true, Calc tries to detect numbers in scientific notation.</desc>
            <label>DetectScientificNumbers</label>
          </info>
          <value>true</value>
        </prop>
        <prop oor:name="Language" oor:type="xs:int" oor:nillable="false">
          <info>
            <desc>Language to use for CSV import.  This determines how the numbers are parsed.</desc>
@@ -1121,6 +1128,13 @@
          </info>
          <value>true</value>
        </prop>
        <prop oor:name="DetectScientificNumbers" oor:type="xs:boolean" oor:nillable="false">
          <info>
            <desc>If true, Calc tries to detect numbers in scientific notation.</desc>
            <label>DetectScientificNumbers</label>
          </info>
          <value>true</value>
        </prop>
        <prop oor:name="SkipEmptyCells" oor:type="xs:boolean" oor:nillable="false">
          <info>
            <desc>If true, Calc preserves previous content of cells when pasting empty ones. If false, Calc delete content of previous cells.</desc>
diff --git a/sc/inc/stringutil.hxx b/sc/inc/stringutil.hxx
index b2b58f6..3d930dd 100644
--- a/sc/inc/stringutil.hxx
+++ b/sc/inc/stringutil.hxx
@@ -70,11 +70,14 @@ struct SAL_WARN_UNUSED SC_DLLPUBLIC ScSetStringParam
    SvNumberFormatter* mpNumFormatter;

    /**
     * When true, we try to detect special number format (dates etc) from the
     * input string, when false, we only try to detect a basic decimal number
     * format.
     * Specify which number formats are detected:
     * mbDetectNumberFormat=true && mbDetectScientificNumberFormat=true : detect all special number formats : basic decimal number, date, scientific notation, etc
     * mbDetectNumberFormat=false && mbDetectScientificNumberFormat=true : detect scientific notation and basic decimal number, but not other special number formats (date etc)
     * mbDetectNumberFormat=false && mbDetectScientificNumberFormat=false : detect only basic decimal number, but not scientific notation or other special number formats (date etc)
     * Note: mbDetectNumberFormat=true && mbDetectScientificNumberFormat=false not allowed
     */
    bool mbDetectNumberFormat;
    bool mbDetectScientificNumberFormat;

    /**
     * Determine when to set the 'Text' number format to the cell where the
@@ -145,7 +148,7 @@ public:
     * @return true if the string is a valid number, false otherwise.
     */
    static bool parseSimpleNumber(
        const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal);
        const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal, bool bDetectScientificNumber = true);

    static bool parseSimpleNumber(
        const char* p, size_t n, char dsep, char gsep, double& rVal);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f615a02..5e1e66b 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2303,7 +2303,7 @@ bool ScColumn::ParseString(
                sal_Unicode gsep = rGroupSep[0];
                sal_Unicode dsepa = rDecSepAlt.toChar();

                if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, dsepa, nVal))
                if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, dsepa, nVal, aParam.mbDetectScientificNumberFormat))
                    break;

                rCell.set(nVal);
diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx
index 493f3fd..8a43638 100644
--- a/sc/source/core/tool/stringutil.cxx
+++ b/sc/source/core/tool/stringutil.cxx
@@ -28,6 +28,7 @@
ScSetStringParam::ScSetStringParam() :
    mpNumFormatter(nullptr),
    mbDetectNumberFormat(true),
    mbDetectScientificNumberFormat(true),
    meSetTextNumFormat(Never),
    mbHandleApostrophe(true),
    meStartListening(sc::SingleCellListening),
@@ -38,6 +39,7 @@ ScSetStringParam::ScSetStringParam() :
void ScSetStringParam::setTextInput()
{
    mbDetectNumberFormat = false;
    mbDetectScientificNumberFormat = false;
    mbHandleApostrophe = false;
    meSetTextNumFormat = Always;
}
@@ -45,12 +47,13 @@ void ScSetStringParam::setTextInput()
void ScSetStringParam::setNumericInput()
{
    mbDetectNumberFormat = true;
    mbDetectScientificNumberFormat = true;
    mbHandleApostrophe = true;
    meSetTextNumFormat = Never;
}

bool ScStringUtil::parseSimpleNumber(
    const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal)
    const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal, bool bDetectScientificNumber)
{
    // Actually almost the entire pre-check is unnecessary and we could call
    // rtl::math::stringToDouble() just after having exchanged ascii space with
@@ -165,7 +168,7 @@ bool ScStringUtil::parseSimpleNumber(
        {
            // this is an exponent designator.

            if (nPosExponent >= 0)
            if (nPosExponent >= 0 || !bDetectScientificNumber)
                // Only one exponent allowed.
                return false;

diff --git a/sc/source/ui/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx
index 20d1844..c9a4d88 100644
--- a/sc/source/ui/dbgui/asciiopt.cxx
+++ b/sc/source/ui/dbgui/asciiopt.cxx
@@ -33,6 +33,7 @@ ScAsciiOptions::ScAsciiOptions() :
    bRemoveSpace    ( false ),
    bQuotedFieldAsText(false),
    bDetectSpecialNumber(false),
    bDetectScientificNumber(true),
    bEvaluateFormulas(true),
    bSkipEmptyCells(false),
    bSaveAsShown(true),
@@ -196,6 +197,15 @@ void ScAsciiOptions::ReadFromString( std::u16string_view rString )

    // Token 13: include BOM.
    bIncludeBOM = nPos >= 0 && o3tl::getToken(rString, 0, ',', nPos) == u"true";

    // Token 14: Detect scientific numbers.
    if (nPos >= 0)
    {
        bDetectScientificNumber = o3tl::getToken(rString, 0, ',', nPos) == u"true";
    }
    else
        bDetectScientificNumber = true;    // default of versions that didn't add the parameter

}

OUString ScAsciiOptions::WriteToString() const
@@ -266,7 +276,9 @@ OUString ScAsciiOptions::WriteToString() const
               // Token 12: evaluate formulas in import
               OUString::boolean( bEvaluateFormulas ) + "," +
               // Token 13: include BOM
               OUString::boolean(bIncludeBOM)
               OUString::boolean(bIncludeBOM) + "," +
               // Token 14: Detect scientific numbers.
               OUString::boolean( bDetectScientificNumber )
            );
    return aOutStr.makeStringAndClear();
}
diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx
index 8fd50c1b..61fa2d6 100644
--- a/sc/source/ui/dbgui/scuiasciiopt.cxx
+++ b/sc/source/ui/dbgui/scuiasciiopt.cxx
@@ -74,6 +74,7 @@ enum CSVImportOptionsIndex
    CSVIO_CharSet,
    CSVIO_QuotedAsText,
    CSVIO_DetectSpecialNum,
    CSVIO_DetectScientificNum,
    CSVIO_Language,
    // Plus one not for SC_IMPORTFILE.
    CSVIO_PasteSkipEmptyCells
@@ -96,6 +97,7 @@ const ::std::vector<OUString> CSVImportOptionNames =
    "CharSet",
    "QuotedFieldAsText",
    "DetectSpecialNumbers",
    "DetectScientificNumbers",
    "Language",
    "SkipEmptyCells"
};
@@ -174,11 +176,11 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& 
    {
        case SC_IMPORTFILE:
            rSepPath = aSep_Path;
            nProperties = 11;
            nProperties = 12;
            break;
        case SC_PASTETEXT:
            rSepPath = aSep_Path_Clpbrd;
            nProperties = 12;
            nProperties = 13;
            break;
        case SC_TEXTTOCOLUMNS:
        default:
@@ -200,6 +202,7 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& 
        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)
@@ -211,7 +214,7 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& 
}

static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
                             bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum,
                             bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum, bool& rDetectScientificNum,
                             bool& rFixedWidth, sal_Int32& rFromRow, sal_Int32& rCharSet,
                             sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace,
                             bool& rEvaluateFormulas, ScImportAsciiCall eCall )
@@ -257,6 +260,9 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar
        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;
    }
@@ -271,7 +277,7 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar

static void lcl_SaveSeparators(
    const OUString& sFieldSeparators, const OUString& sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText,
    bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow,
    bool bDetectSpecialNum, bool bDetectScientificNum, bool bFixedWidth, sal_Int32 nFromRow,
    sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas,
    ScImportAsciiCall eCall )
{
@@ -296,6 +302,7 @@ static void lcl_SaveSeparators(
        pProperties[ CSVIO_CharSet ] <<= nCharSet;
        pProperties[ CSVIO_QuotedAsText ] <<= bQuotedAsText;
        pProperties[ CSVIO_DetectSpecialNum ] <<= bDetectSpecialNum;
        pProperties[ CSVIO_DetectScientificNum ] <<= bDetectScientificNum;
        pProperties[ CSVIO_Language ] <<= nLanguage;
    }
    if (eCall != SC_IMPORTFILE)
@@ -337,6 +344,7 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
    , mxCbTextSep(m_xBuilder->weld_combo_box("textdelimiter"))
    , mxCkbQuotedAsText(m_xBuilder->weld_check_button("quotedfieldastext"))
    , mxCkbDetectNumber(m_xBuilder->weld_check_button("detectspecialnumbers"))
    , mxCkbDetectScientificNumber(m_xBuilder->weld_check_button("detectscientificnumbers"))
    , mxCkbEvaluateFormulas(m_xBuilder->weld_check_button("evaluateformulas"))
    , mxCkbSkipEmptyCells(m_xBuilder->weld_check_button("skipemptycells"))
    , mxLbType(m_xBuilder->weld_combo_box("columntype"))
@@ -370,6 +378,7 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
    bool bFixedWidth = false;
    bool bQuotedFieldAsText = false;
    bool bDetectSpecialNum = true;
    bool bDetectScientificNum = true;
    bool bEvaluateFormulas = (meCall != SC_IMPORTFILE);
    bool bSkipEmptyCells = true;
    bool bRemoveSpace = false;
@@ -377,7 +386,7 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
    sal_Int32 nCharSet = -1;
    sal_Int32 nLanguage = 0;
    lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
                         bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow,
                         bQuotedFieldAsText, bDetectSpecialNum, bDetectScientificNum, bFixedWidth, nFromRow,
                         nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, meCall);
    // load from saved settings
    maFieldSeparators = sFieldSeparators;
@@ -389,7 +398,13 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
    if (bRemoveSpace)
        mxCkbRemoveSpace->set_active(true);
    if (bDetectSpecialNum)
    {
        mxCkbDetectNumber->set_active(true);
        bDetectScientificNum = true;
        mxCkbDetectScientificNumber->set_sensitive(false);
    }
    if (bDetectScientificNum)
        mxCkbDetectScientificNumber->set_active(true);
    if (bEvaluateFormulas)
        mxCkbEvaluateFormulas->set_active(true);
    if (bSkipEmptyCells)
@@ -498,6 +513,7 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
    mxCkbAsOnce->connect_toggled( aSeparatorClickHdl );
    mxCkbQuotedAsText->connect_toggled( aSeparatorClickHdl );
    mxCkbDetectNumber->connect_toggled( aSeparatorClickHdl );
    mxCkbDetectScientificNumber->connect_toggled( aSeparatorClickHdl );
    mxCkbEvaluateFormulas->connect_toggled( aSeparatorClickHdl );
    mxCkbSkipEmptyCells->connect_toggled( aSeparatorClickHdl );
    mxCkbSpace->connect_toggled( aSeparatorClickHdl );
@@ -579,6 +595,8 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
        // Always detect special numbers for text-to-columns mode.
        mxCkbDetectNumber->set_active(true);
        mxCkbDetectNumber->set_sensitive(false);
        mxCkbDetectScientificNumber->set_active(true);
        mxCkbDetectScientificNumber->set_sensitive(false);
    }
    if (meCall == SC_IMPORTFILE)
    {
@@ -680,6 +698,7 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )

    rOpt.SetQuotedAsText(mxCkbQuotedAsText->get_active());
    rOpt.SetDetectSpecialNumber(mxCkbDetectNumber->get_active());
    rOpt.SetDetectScientificNumber(mxCkbDetectScientificNumber->get_active());
    rOpt.SetEvaluateFormulas(mxCkbEvaluateFormulas->get_active());
    rOpt.SetSkipEmptyCells(mxCkbSkipEmptyCells->get_active());
}
@@ -687,7 +706,7 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
void ScImportAsciiDlg::SaveParameters()
{
    lcl_SaveSeparators( maFieldSeparators, mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(),
                     mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(),
                     mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(), mxCkbDetectScientificNumber->get_active(),
                     mxRbFixed->get_active(),
                     mxNfRow->get_value(),
                     mxLbCharSet->get_active(),
@@ -823,6 +842,17 @@ void ScImportAsciiDlg::SeparatorHdl(const weld::Widget* pCtrl)
    OSL_ENSURE( pCtrl, "ScImportAsciiDlg::SeparatorHdl - missing sender" );
    OSL_ENSURE( !mxRbFixed->get_active(), "ScImportAsciiDlg::SeparatorHdl - not allowed in fixed width" );

    if (pCtrl == mxCkbDetectNumber.get())
    {
        if (mxCkbDetectNumber->get_active())
        {
            mxCkbDetectScientificNumber->set_active(true);
            mxCkbDetectScientificNumber->set_sensitive(false);
        }
        else
            mxCkbDetectScientificNumber->set_sensitive(true);
        return;
    }
    /*  #i41550# First update state of the controls. The GetSeparators()
        function needs final state of the check boxes. */
    if (pCtrl == mxCkbOther.get() && mxCkbOther->get_active())
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 5075084..c405fb2 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -1067,7 +1067,7 @@ bool ScImportExport::Text2Doc( SvStream& rStrm )
static bool lcl_PutString(
    ScDocumentImport& rDocImport, bool bUseDocImport,
    SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rStr, sal_uInt8 nColFormat,
    SvNumberFormatter* pFormatter, bool bDetectNumFormat, bool bEvaluateFormulas, bool bSkipEmptyCells,
    SvNumberFormatter* pFormatter, bool bDetectNumFormat, bool bDetectSciNumFormat, bool bEvaluateFormulas, bool bSkipEmptyCells,
    const ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
    const ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
{
@@ -1504,6 +1504,7 @@ static bool lcl_PutString(
        ScSetStringParam aParam;
        aParam.mpNumFormatter = pFormatter;
        aParam.mbDetectNumberFormat = bDetectNumFormat;
        aParam.mbDetectScientificNumberFormat = bDetectSciNumFormat;
        aParam.meSetTextNumFormat = ScSetStringParam::SpecialNumberOnly;
        aParam.mbHandleApostrophe = false;
        aParam.mbCheckLinkFormula = true;
@@ -1599,6 +1600,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
    LanguageType eDocLang = pExtOptions->GetLanguage();
    SvNumberFormatter aNumFormatter( comphelper::getProcessComponentContext(), eDocLang);
    bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber();
    bool bDetectSciNumFormat = pExtOptions->IsDetectScientificNumber();
    bool bEvaluateFormulas = pExtOptions->IsEvaluateFormulas();
    bool bSkipEmptyCells = pExtOptions->IsSkipEmptyCells();

@@ -1722,7 +1724,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )

                                bMultiLine |= lcl_PutString(
                                        aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
                                        &aNumFormatter, bDetectNumFormat, bEvaluateFormulas, bSkipEmptyCells,
                                        &aNumFormatter, bDetectNumFormat, bDetectSciNumFormat, bEvaluateFormulas, bSkipEmptyCells,
                                        aTransliteration, aCalendar,
                                        pEnglishTransliteration.get(), pEnglishCalendar.get());
                            }
@@ -1768,7 +1770,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )

                            bMultiLine |= lcl_PutString(
                                aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
                                &aNumFormatter, bDetectNumFormat, bEvaluateFormulas, bSkipEmptyCells,
                                &aNumFormatter, bDetectNumFormat, bDetectSciNumFormat, bEvaluateFormulas, bSkipEmptyCells,
                                aTransliteration, aCalendar,
                                pEnglishTransliteration.get(), pEnglishCalendar.get());
                        }
diff --git a/sc/source/ui/inc/asciiopt.hxx b/sc/source/ui/inc/asciiopt.hxx
index 60b9a14..6028b88 100644
--- a/sc/source/ui/inc/asciiopt.hxx
+++ b/sc/source/ui/inc/asciiopt.hxx
@@ -33,6 +33,7 @@ private:
    bool        bRemoveSpace;
    bool        bQuotedFieldAsText;
    bool        bDetectSpecialNumber;
    bool        bDetectScientificNumber;
    bool        bEvaluateFormulas;
    bool        bSkipEmptyCells;
    bool        bSaveAsShown;
@@ -60,6 +61,7 @@ public:
    bool                IsRemoveSpace() const   { return bRemoveSpace; }
    bool                IsQuotedAsText() const  { return bQuotedFieldAsText; }
    bool                IsDetectSpecialNumber() const { return bDetectSpecialNumber; }
    bool                IsDetectScientificNumber() const { return bDetectScientificNumber; }
    bool                IsEvaluateFormulas() const    { return bEvaluateFormulas; }
    bool                IsSkipEmptyCells() const      { return bSkipEmptyCells; }
    bool                GetIncludeBOM() const   { return bIncludeBOM; }
@@ -79,6 +81,7 @@ public:
    void    SetRemoveSpace( bool bSet )         { bRemoveSpace = bSet; }
    void    SetQuotedAsText(bool bSet)          { bQuotedFieldAsText = bSet; }
    void    SetDetectSpecialNumber(bool bSet)   { bDetectSpecialNumber = bSet; }
    void    SetDetectScientificNumber(bool bSet){ bDetectScientificNumber = bSet; }
    void    SetEvaluateFormulas(bool bSet)      { bEvaluateFormulas = bSet; }
    void    SetSkipEmptyCells(bool bSet)        { bSkipEmptyCells = bSet; }
    void    SetIncludeBOM(bool bVal)            { bIncludeBOM = bVal; }
diff --git a/sc/source/ui/inc/scuiasciiopt.hxx b/sc/source/ui/inc/scuiasciiopt.hxx
index 5649fb3..a96f2f59 100644
--- a/sc/source/ui/inc/scuiasciiopt.hxx
+++ b/sc/source/ui/inc/scuiasciiopt.hxx
@@ -71,6 +71,7 @@ class ScImportAsciiDlg : public weld::GenericDialogController

    std::unique_ptr<weld::CheckButton> mxCkbQuotedAsText;
    std::unique_ptr<weld::CheckButton> mxCkbDetectNumber;
    std::unique_ptr<weld::CheckButton> mxCkbDetectScientificNumber;
    std::unique_ptr<weld::CheckButton> mxCkbEvaluateFormulas;
    std::unique_ptr<weld::CheckButton> mxCkbSkipEmptyCells;

diff --git a/sc/uiconfig/scalc/ui/textimportcsv.ui b/sc/uiconfig/scalc/ui/textimportcsv.ui
index 91a84d9..8f1da18 100644
--- a/sc/uiconfig/scalc/ui/textimportcsv.ui
+++ b/sc/uiconfig/scalc/ui/textimportcsv.ui
@@ -579,7 +579,7 @@
                    <property name="spacing">6</property>
                    <property name="homogeneous">True</property>
                    <child>
                      <!-- n-columns=2 n-rows=2 -->
                      <!-- n-columns=3 n-rows=2 -->
                      <object class="GtkGrid" id="grid5">
                        <property name="visible">True</property>
                        <property name="can-focus">False</property>
@@ -659,6 +659,25 @@
                            </child>
                          </object>
                          <packing>
                            <property name="left-attach">2</property>
                            <property name="top-attach">0</property>
                          </packing>
                        </child>
                        <child>
                          <object class="GtkCheckButton" id="detectscientificnumbers">
                            <property name="label" translatable="yes" context="textimportcsv|detectspecialnumbers">Detect scientific num_bers</property>
                            <property name="visible">True</property>
                            <property name="can-focus">True</property>
                            <property name="receives-default">False</property>
                            <property name="use-underline">True</property>
                            <property name="draw-indicator">True</property>
                            <child internal-child="accessible">
                              <object class="AtkObject" id="detectscientificnumbers-atkobject">
                                <property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|detectscientificnumbers">When this option is enabled, Calc will automatically detect numbers in scientific notation in addition to basic decimal numbers.</property>
                              </object>
                            </child>
                          </object>
                          <packing>
                            <property name="left-attach">1</property>
                            <property name="top-attach">1</property>
                          </packing>
diff --git a/uitest/libreoffice/calc/csv_dialog.py b/uitest/libreoffice/calc/csv_dialog.py
index e15eea1..1313903 100644
--- a/uitest/libreoffice/calc/csv_dialog.py
+++ b/uitest/libreoffice/calc/csv_dialog.py
@@ -42,6 +42,21 @@ def load_csv_file(UITestCase, fileName, bUseDefaultOptions):
                if get_state_as_dict(xChild)['Selected'] == 'true':
                    xChild.executeAction("CLICK", tuple())
                UITestCase.assertEqual('false', get_state_as_dict(xChild)['Selected'])
                # tdf#154131
                if childName == 'detectspecialnumbers':
                    # if 'Detect special numbers' is false, 'Detect scientific numbers' can be modified
                    xDetectScientific = xDialog.getChild('detectscientificnumbers')
                    if get_state_as_dict(xDetectScientific)['Selected'] == 'false':
                        xDetectScientific.executeAction("CLICK", tuple())
                    UITestCase.assertEqual('true', get_state_as_dict(xDetectScientific)['Selected'])
                    xDetectScientific.executeAction("CLICK", tuple())
                    UITestCase.assertEqual('false', get_state_as_dict(xDetectScientific)['Selected'])
                    # if 'Detect special numbers' is true, 'Detect scientific numbers' is true and disabled
                    xChild.executeAction("CLICK", tuple())
                    UITestCase.assertEqual('true', get_state_as_dict(xChild)['Selected'])
                    UITestCase.assertEqual('true', get_state_as_dict(xDetectScientific)['Selected'])
                    UITestCase.assertEqual('false', get_state_as_dict(xDetectScientific)['Enabled'])
                    xChild.executeAction("CLICK", tuple())

            UITestCase.assertEqual('1', get_state_as_dict(xDialog.getChild("fromrow"))['Text'])