basic/source/sbx/sbxscan.cxx | 34 ++-- i18npool/inc/cclass_unicode.hxx | 5 i18npool/inc/collatorImpl.hxx | 4 i18npool/inc/numberformatcode.hxx | 4 i18npool/inc/transliterationImpl.hxx | 4 i18npool/source/characterclassification/cclass_unicode_parser.cxx | 22 ++ i18npool/source/collator/collatorImpl.cxx | 4 i18npool/source/localedata/LocaleNode.cxx | 19 +- i18npool/source/localedata/data/ar_DZ.xml | 1 i18npool/source/localedata/data/ar_EG.xml | 1 i18npool/source/localedata/data/ar_LB.xml | 1 i18npool/source/localedata/data/ar_SA.xml | 1 i18npool/source/localedata/data/ar_TN.xml | 1 i18npool/source/localedata/data/fa_IR.xml | 1 i18npool/source/localedata/data/locale.dtd | 3 i18npool/source/numberformatcode/numberformatcode.cxx | 4 i18npool/source/transliteration/transliterationImpl.cxx | 4 include/svl/zforlist.hxx | 7 include/unotools/localedatawrapper.hxx | 74 +++++++++- offapi/com/sun/star/i18n/LocaleItem.idl | 12 + sc/inc/stringutil.hxx | 3 sc/qa/unit/ucalc.cxx | 1 sc/source/core/data/column3.cxx | 12 - sc/source/core/data/table3.cxx | 2 sc/source/core/tool/compiler.cxx | 17 +- sc/source/core/tool/formulaopt.cxx | 8 - sc/source/core/tool/stringutil.cxx | 6 sc/source/ui/cctrl/editfield.cxx | 7 sc/source/ui/docshell/docsh6.cxx | 4 sc/source/ui/miscdlgs/solveroptions.cxx | 8 - sc/source/ui/sidebar/AlignmentPropertyPanel.cxx | 3 svl/source/numbers/zforfind.cxx | 15 +- svl/source/numbers/zforlist.cxx | 13 + svx/source/sidebar/possize/PosSizePropertyPanel.cxx | 3 svx/source/sidebar/shadow/ShadowPropertyPanel.cxx | 3 svx/source/svdraw/svdomeas.cxx | 9 - sw/source/core/bastyp/calc.cxx | 5 sw/source/core/doc/docsort.cxx | 5 unotools/source/i18n/localedatawrapper.cxx | 58 ++++++- vcl/source/control/field.cxx | 3 vcl/source/control/longcurr.cxx | 3 41 files changed, 293 insertions(+), 101 deletions(-)
New commits: commit 89e0a9183e7b21596bcd5504b104bf816f1d3ef3 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:27:44 2017 +0200 Resolves: tdf#81671 add DecimalSeparatorAlternative to ar-* and fa-IR In locales that use 'Ù«' U+066B ARABIC DECIMAL SEPARATOR additionally have '.' normal dot as input separator. Change-Id: Icb3f42374776e3fc65af3270abaca26ea5b24082 diff --git a/i18npool/source/localedata/data/ar_DZ.xml b/i18npool/source/localedata/data/ar_DZ.xml index 16362ced8c01..4cb4d155018b 100644 --- a/i18npool/source/localedata/data/ar_DZ.xml +++ b/i18npool/source/localedata/data/ar_DZ.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Â </ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>Ù«</Time100SecSeparator> <ListSeparator>;</ListSeparator> diff --git a/i18npool/source/localedata/data/ar_EG.xml b/i18npool/source/localedata/data/ar_EG.xml index 4dfe9bec8ff1..5bcb4b689c30 100644 --- a/i18npool/source/localedata/data/ar_EG.xml +++ b/i18npool/source/localedata/data/ar_EG.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Ù¬</ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>.</Time100SecSeparator> <ListSeparator>;</ListSeparator> diff --git a/i18npool/source/localedata/data/ar_LB.xml b/i18npool/source/localedata/data/ar_LB.xml index 9499dfb8ba48..64ac706e8fa4 100644 --- a/i18npool/source/localedata/data/ar_LB.xml +++ b/i18npool/source/localedata/data/ar_LB.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Ù¬</ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>.</Time100SecSeparator> <ListSeparator>;</ListSeparator> diff --git a/i18npool/source/localedata/data/ar_SA.xml b/i18npool/source/localedata/data/ar_SA.xml index 05f0fb81edb3..f7970ffedd30 100644 --- a/i18npool/source/localedata/data/ar_SA.xml +++ b/i18npool/source/localedata/data/ar_SA.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Ù¬</ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>.</Time100SecSeparator> <ListSeparator>;</ListSeparator> diff --git a/i18npool/source/localedata/data/ar_TN.xml b/i18npool/source/localedata/data/ar_TN.xml index 014f77524603..ae37a4b84c0f 100644 --- a/i18npool/source/localedata/data/ar_TN.xml +++ b/i18npool/source/localedata/data/ar_TN.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Ù¬</ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>.</Time100SecSeparator> <ListSeparator>;</ListSeparator> diff --git a/i18npool/source/localedata/data/fa_IR.xml b/i18npool/source/localedata/data/fa_IR.xml index 04b9ac8ffc3a..10157072450e 100644 --- a/i18npool/source/localedata/data/fa_IR.xml +++ b/i18npool/source/localedata/data/fa_IR.xml @@ -33,6 +33,7 @@ <DateSeparator>/</DateSeparator> <ThousandSeparator>Ù¬</ThousandSeparator> <DecimalSeparator>Ù«</DecimalSeparator> + <DecimalSeparatorAlternative>.</DecimalSeparatorAlternative> <TimeSeparator>:</TimeSeparator> <Time100SecSeparator>Ù«</Time100SecSeparator> <ListSeparator>;</ListSeparator> commit 92933ed580628c4e4cf539fc9fd90faaf51e05e6 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:24:01 2017 +0200 Define optional <Separators><DecimalSeparatorAlternative>, tdf#81671 Change-Id: I13d49463aa2fa9975b77d4ee62fcadc36b8317ae diff --git a/i18npool/source/localedata/data/locale.dtd b/i18npool/source/localedata/data/locale.dtd index 377df12b9bb8..53736783dd44 100644 --- a/i18npool/source/localedata/data/locale.dtd +++ b/i18npool/source/localedata/data/locale.dtd @@ -436,10 +436,11 @@ <!ATTLIST LC_CTYPE %RefLocale;> <!ATTLIST LC_CTYPE %UNOModule;> -<!ELEMENT Separators (DateSeparator, ThousandSeparator, DecimalSeparator, TimeSeparator, Time100SecSeparator, ListSeparator, LongDateDayOfWeekSeparator, LongDateDaySeparator, LongDateMonthSeparator, LongDateYearSeparator)> +<!ELEMENT Separators (DateSeparator, ThousandSeparator, DecimalSeparator, DecimalSeparatorAlternative?, TimeSeparator, Time100SecSeparator, ListSeparator, LongDateDayOfWeekSeparator, LongDateDaySeparator, LongDateMonthSeparator, LongDateYearSeparator)> <!ELEMENT DateSeparator (#PCDATA)> <!ELEMENT ThousandSeparator (#PCDATA)> <!ELEMENT DecimalSeparator (#PCDATA)> +<!ELEMENT DecimalSeparatorAlternative (#PCDATA)> <!ELEMENT TimeSeparator (#PCDATA)> <!ELEMENT Time100SecSeparator (#PCDATA)> <!ELEMENT ListSeparator (#PCDATA)> commit f285f3134378cb9a31f02200991e3fc44ca79419 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:22:21 2017 +0200 Parse/gen optional <DecimalSeparatorAlternative> in locale data, tdf#81671 Change-Id: I2781040c76e7c3dbfb4eedc7830a1f24b4c56b46 diff --git a/i18npool/source/localedata/LocaleNode.cxx b/i18npool/source/localedata/LocaleNode.cxx index 2c0134448343..25b87d8c03a3 100644 --- a/i18npool/source/localedata/LocaleNode.cxx +++ b/i18npool/source/localedata/LocaleNode.cxx @@ -227,7 +227,7 @@ OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of, OUString aVal; if (pNode) aVal = pNode->getValue(); - else + else if (nMinLen >= 0) // -1: optional => empty, 0: must be present, empty { ++nError; fprintf( stderr, "Error: node NULL pointer for parameter %s.\n", @@ -246,12 +246,15 @@ OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of, OSTR( aVal)); } else if (nLen > nMaxLen && nMaxLen >= 0) + { + ++nError; fprintf( stderr, - "Warning: more than %ld character%s (%ld) in %s %s not supported by application.\n", + "Error: more than %ld character%s (%ld) in %s '%s' not supported by application.\n", sal::static_int_cast< long >(nMaxLen), (nMaxLen > 1 ? "s" : ""), sal::static_int_cast< long >(nLen), (pNode ? OSTR( pNode->getName()) : ""), OSTR( aVal)); + } return aVal; } @@ -262,7 +265,7 @@ OUString LocaleNode::writeParameterCheckLen( const OFileWriter &of, { OUString aVal; const LocaleNode * pNode = findNode( pNodeName); - if (pNode) + if (pNode || nMinLen < 0) aVal = writeParameterCheckLen( of, pParameterName, pNode, nMinLen, nMaxLen); else { @@ -377,6 +380,8 @@ void LCCTYPENode::generateCode (const OFileWriter &of) const writeParameterCheckLen( of, "ThousandSeparator", "thousandSeparator", 1, 1); aDecSep = writeParameterCheckLen( of, "DecimalSeparator", "decimalSeparator", 1, 1); + OUString aDecSepAlt = + writeParameterCheckLen( of, "DecimalSeparatorAlternative", "decimalSeparatorAlternative", -1, 1); OUString aTimeSep = writeParameterCheckLen( of, "TimeSeparator", "timeSeparator", 1, 1); OUString aTime100Sep = @@ -414,13 +419,16 @@ void LCCTYPENode::generateCode (const OFileWriter &of) const fprintf( stderr, "Warning: %s\n", "LongDateYearSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, 2007May 9\"."); - int nSavErr = nError; int nWarn = 0; if (aDateSep == aTimeSep) incError( "DateSeparator equals TimeSeparator."); if (aDecSep == aThoSep) incError( "DecimalSeparator equals ThousandSeparator."); + if (aDecSepAlt == aThoSep) + incError( "DecimalSeparatorAlternative equals ThousandSeparator."); + if (aDecSepAlt == aDecSep) + incError( "DecimalSeparatorAlternative equals DecimalSeparator, it must not be specified then."); if ( aThoSep == " " ) incError( "ThousandSeparator is an ' ' ordinary space, this should be a non-breaking space U+00A0 instead."); if (aListSep == aDecSep) @@ -572,7 +580,8 @@ void LCCTYPENode::generateCode (const OFileWriter &of) const of.writeAsciiString("\tLongDateDayOfWeekSeparator,\n"); of.writeAsciiString("\tLongDateDaySeparator,\n"); of.writeAsciiString("\tLongDateMonthSeparator,\n"); - of.writeAsciiString("\tLongDateYearSeparator\n"); + of.writeAsciiString("\tLongDateYearSeparator,\n"); + of.writeAsciiString("\tdecimalSeparatorAlternative\n"); of.writeAsciiString("};\n\n"); of.writeFunction("getLocaleItem_", "SAL_N_ELEMENTS(LCType)", "LCType"); } commit 940808a512ff637f161cc3eb1de0362b2f95318c Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:19:35 2017 +0200 Handle decimalSeparatorAlternative, tdf#81671 Change-Id: I3a3d3b0683ea46cff5c023e911977ce5b2f5f032 diff --git a/vcl/source/control/longcurr.cxx b/vcl/source/control/longcurr.cxx index 8dd0ec192870..805da72f1eea 100644 --- a/vcl/source/control/longcurr.cxx +++ b/vcl/source/control/longcurr.cxx @@ -109,6 +109,7 @@ bool ImplNumericProcessKeyInput( const KeyEvent& rKEvt, ((cChar >= '0') && (cChar <= '9')) || (bThousandSep && string::equals(rLocaleDataWrapper.getNumThousandSep(), cChar)) || (string::equals(rLocaleDataWrapper.getNumDecimalSep(), cChar) ) || + (string::equals(rLocaleDataWrapper.getNumDecimalSepAlt(), cChar) ) || (cChar == '-')); } } @@ -132,6 +133,8 @@ bool ImplNumericGetValue( const OUString& rStr, BigInt& rValue, // Find decimal sign's position nDecPos = aStr.indexOf( rLocaleDataWrapper.getNumDecimalSep() ); + if (nDecPos < 0 && !rLocaleDataWrapper.getNumDecimalSepAlt().isEmpty()) + nDecPos = aStr.indexOf( rLocaleDataWrapper.getNumDecimalSepAlt() ); if ( nDecPos != -1 ) { commit 03cf4eaaaf22a70386d4f8557f92dc00e57586c7 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:19:14 2017 +0200 Handle decimalSeparatorAlternative, tdf#81671 Change-Id: Ica696322bfeea641452e73fd49bf89c33b6d4d96 diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx index 76786223b122..220da283ba86 100644 --- a/vcl/source/control/field.cxx +++ b/vcl/source/control/field.cxx @@ -72,6 +72,7 @@ bool ImplNumericProcessKeyInput( const KeyEvent& rKEvt, ((cChar >= '0') && (cChar <= '9')) || string::equals(rLocaleDataWrappper.getNumDecimalSep(), cChar) || (bThousandSep && string::equals(rLocaleDataWrappper.getNumThousandSep(), cChar)) || + string::equals(rLocaleDataWrappper.getNumDecimalSepAlt(), cChar) || (cChar == '-')); } } @@ -97,6 +98,8 @@ bool ImplNumericGetValue( const OUString& rStr, sal_Int64& rValue, // find position of decimal point nDecPos = aStr.indexOf( rLocaleDataWrappper.getNumDecimalSep() ); + if (nDecPos < 0 && !rLocaleDataWrappper.getNumDecimalSepAlt().isEmpty()) + nDecPos = aStr.indexOf( rLocaleDataWrappper.getNumDecimalSepAlt() ); // find position of fraction nFracDivPos = aStr.indexOf( '/' ); commit 7c5b9247c4425f1b733b62e365f15cf390c4bb63 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:18:10 2017 +0200 Handle decimalSeparatorAlternative in TakeRepresentation, tdf#81671 Change-Id: I552cb14fcb048d6c7da9043704c9941686a30993 diff --git a/svx/source/svdraw/svdomeas.cxx b/svx/source/svdraw/svdomeas.cxx index 5e472c7bc277..81eee47621f7 100644 --- a/svx/source/svdraw/svdomeas.cxx +++ b/svx/source/svdraw/svdomeas.cxx @@ -130,9 +130,12 @@ OUString SdrMeasureObj::TakeRepresentation(SdrMeasureFieldKind eMeasureFieldKind aStr = "?"; } - sal_Unicode cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]); + SvtSysLocale aSysLocale; + const LocaleDataWrapper& rLocaleDataWrapper = aSysLocale.GetLocaleData(); + sal_Unicode cDec(rLocaleDataWrapper.getNumDecimalSep()[0]); + sal_Unicode cDecAlt(rLocaleDataWrapper.getNumDecimalSepAlt().toChar()); - if(aStr.indexOf(cDec) != -1) + if(aStr.indexOf(cDec) != -1 || (cDecAlt && aStr.indexOf(cDecAlt) != -1)) { sal_Int32 nLen2(aStr.getLength() - 1); @@ -142,7 +145,7 @@ OUString SdrMeasureObj::TakeRepresentation(SdrMeasureFieldKind eMeasureFieldKind nLen2--; } - if(aStr[nLen2] == cDec) + if(aStr[nLen2] == cDec || (cDecAlt && aStr[nLen2] == cDecAlt)) { aStr = aStr.copy(0, nLen2); nLen2--; commit 7cf453c78ce67f17661bfc74d1df6073cfc9d2ad Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:16:53 2017 +0200 Use LocaleDataWrapper::stringToDouble() in StrToDouble, tdf#81671 Change-Id: I7c791d8d133b830b146a4a9c6869bf27609167b6 diff --git a/sw/source/core/doc/docsort.cxx b/sw/source/core/doc/docsort.cxx index c0111810e7c2..26cdcc41a19f 100644 --- a/sw/source/core/doc/docsort.cxx +++ b/sw/source/core/doc/docsort.cxx @@ -112,10 +112,7 @@ double SwSortElement::StrToDouble( const OUString& rStr ) rtl_math_ConversionStatus eStatus; sal_Int32 nEnd; - double nRet = ::rtl::math::stringToDouble( rStr, - pLclData->getNumDecimalSep()[0], - pLclData->getNumThousandSep()[0], - &eStatus, &nEnd ); + double nRet = pLclData->stringToDouble( rStr, true, &eStatus, &nEnd ); if( rtl_math_ConversionStatus_Ok != eStatus || nEnd == 0 ) nRet = 0.0; commit 2c2d57585407acda2ea57c07dab98b5a23b37940 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:15:46 2017 +0200 Use LocaleDataWrapper::stringToDouble() in lcl_Str2Double, tdf#81671 Change-Id: Ife8f955e7f7a1c791c8bd0390981aae5fe9f82dc diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx index d906f97ca7ca..2e43e93b7947 100644 --- a/sw/source/core/bastyp/calc.cxx +++ b/sw/source/core/bastyp/calc.cxx @@ -1324,10 +1324,9 @@ namespace const sal_Unicode nCurrCmdPos = rCommandPos; rtl_math_ConversionStatus eStatus; const sal_Unicode* pEnd; - rVal = rtl_math_uStringToDouble( rCommand.getStr() + rCommandPos, + rVal = pLclData->stringToDouble( rCommand.getStr() + rCommandPos, rCommand.getStr() + rCommand.getLength(), - pLclData->getNumDecimalSep()[0], - pLclData->getNumThousandSep()[0], + true, &eStatus, &pEnd ); rCommandPos = static_cast<sal_Int32>(pEnd - rCommand.getStr()); commit 29dd087619ee089268fa16771f46f82a1feaa468 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:13:39 2017 +0200 Use LocaleDataWrapper::stringToDouble() in ShadowPropertyPanel, tdf#81671 Change-Id: I3e8f0a4a75c55543a1b6f6e9470cfd7aeb80e603 diff --git a/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx b/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx index ccad5be1d498..6a94f810056c 100644 --- a/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx +++ b/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx @@ -53,10 +53,9 @@ sal_uInt32 ParseText(OUString const & sTmp) return 0; const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); - const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0]; rtl_math_ConversionStatus eStatus; - double fTmp = rtl::math::stringToDouble( sTmp, cSep, 0, &eStatus); + double fTmp = rLocaleWrapper.stringToDouble( sTmp, false, &eStatus, nullptr); if (eStatus != rtl_math_ConversionStatus_Ok) return 0; commit fb5fc8256e79a3185c92c782733a78a18eafabeb Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:12:56 2017 +0200 Use LocaleDataWrapper::stringToDouble() in PosSizePropertyPanel, tdf#81671 Change-Id: Ice64297dff19f653383b1936d7f47c692df0baf8 diff --git a/svx/source/sidebar/possize/PosSizePropertyPanel.cxx b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx index 3895b2a41208..64012a7af1cf 100644 --- a/svx/source/sidebar/possize/PosSizePropertyPanel.cxx +++ b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx @@ -430,7 +430,6 @@ IMPL_LINK_NOARG( PosSizePropertyPanel, AngleModifiedHdl, Edit&, void ) return; const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); - const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0]; // Do not check that the entire string was parsed up to its end, there may // be a degree symbol following the number. Note that this also means that @@ -438,7 +437,7 @@ IMPL_LINK_NOARG( PosSizePropertyPanel, AngleModifiedHdl, Edit&, void ) /* TODO: we could check for the degree symbol stop if there are no other * cases with different symbol characters in any language? */ rtl_math_ConversionStatus eStatus; - double fTmp = rtl::math::stringToDouble( sTmp, cSep, 0, &eStatus); + double fTmp = rLocaleWrapper.stringToDouble( sTmp, false, &eStatus, nullptr); if (eStatus != rtl_math_ConversionStatus_Ok) return; commit b962def146376dcb48dd93f045fd703489c283e3 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:12:17 2017 +0200 Use LocaleDataWrapper::stringToDouble() in AlignmentPropertyPanel, tdf#81671 Change-Id: I49619f763f3046e94b0bd5d5226e628409310871 diff --git a/sc/source/ui/sidebar/AlignmentPropertyPanel.cxx b/sc/source/ui/sidebar/AlignmentPropertyPanel.cxx index a00e4bcb06eb..cdb79078bb79 100644 --- a/sc/source/ui/sidebar/AlignmentPropertyPanel.cxx +++ b/sc/source/ui/sidebar/AlignmentPropertyPanel.cxx @@ -164,7 +164,6 @@ IMPL_LINK_NOARG( AlignmentPropertyPanel, AngleModifiedHdl, Edit&, void ) return; const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); - const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0]; // Do not check that the entire string was parsed up to its end, there may // be a degree symbol following the number. Note that this also means that @@ -172,7 +171,7 @@ IMPL_LINK_NOARG( AlignmentPropertyPanel, AngleModifiedHdl, Edit&, void ) /* TODO: we could check for the degree symbol stop if there are no other * cases with different symbol characters in any language? */ rtl_math_ConversionStatus eStatus; - double fTmp = rtl::math::stringToDouble( sTmp, cSep, 0, &eStatus); + double fTmp = rLocaleWrapper.stringToDouble( sTmp, false, &eStatus, nullptr); if (eStatus != rtl_math_ConversionStatus_Ok) return; commit 6c0e05ece7bd6e2ecae63fdb4cd73b1f9eaf7ed4 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:11:25 2017 +0200 Use LocaleDataWrapper::stringToDouble() in ScSolverValueDialog, tdf#81671 Change-Id: I6b29ab335c0d2e66804421cb90a6684b747c5035 diff --git a/sc/source/ui/miscdlgs/solveroptions.cxx b/sc/source/ui/miscdlgs/solveroptions.cxx index 03bda551f857..59f00ed46851 100644 --- a/sc/source/ui/miscdlgs/solveroptions.cxx +++ b/sc/source/ui/miscdlgs/solveroptions.cxx @@ -467,12 +467,10 @@ double ScSolverValueDialog::GetValue() const { OUString aInput = m_pEdValue->GetText(); - const LocaleDataWrapper* pLocaleData = ScGlobal::GetpLocaleData(); rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; - double fValue = rtl::math::stringToDouble( aInput, - pLocaleData->getNumDecimalSep()[0], - pLocaleData->getNumThousandSep()[0], - &eStatus ); + sal_Int32 nParseEnd = 0; + double fValue = ScGlobal::GetpLocaleData()->stringToDouble( aInput, true, &eStatus, &nParseEnd); + /* TODO: shouldn't there be some error checking? */ return fValue; } commit 9ccdd3f9e1878f31ccd71b099fe926c20e1a92aa Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:10:24 2017 +0200 Use LocaleDataWrapper::stringToDouble() in ScDoubleField::GetValue, tdf#81671 Change-Id: I7ce956a6a08b9b5befd100e2b0030fc2d4787749 diff --git a/sc/source/ui/cctrl/editfield.cxx b/sc/source/ui/cctrl/editfield.cxx index a516e45c8356..25d3c43888da 100644 --- a/sc/source/ui/cctrl/editfield.cxx +++ b/sc/source/ui/cctrl/editfield.cxx @@ -34,11 +34,6 @@ sal_Unicode lclGetDecSep() return ScGlobal::GetpLocaleData()->getNumDecimalSep()[0]; } -sal_Unicode lclGetGroupSep() -{ - return ScGlobal::GetpLocaleData()->getNumThousandSep()[0]; -} - } // namespace ScDoubleField::ScDoubleField( vcl::Window* pParent, WinBits nStyle ) : @@ -60,7 +55,7 @@ bool ScDoubleField::GetValue( double& rfValue ) const { rtl_math_ConversionStatus eStatus; sal_Int32 nEnd; - rfValue = rtl::math::stringToDouble( aStr, lclGetDecSep(), lclGetGroupSep(), &eStatus, &nEnd ); + rfValue = ScGlobal::GetpLocaleData()->stringToDouble( aStr, true, &eStatus, &nEnd ); bOk = (eStatus == rtl_math_ConversionStatus_Ok) && (nEnd == aStr.getLength() ); } return bOk; commit 7616e1c18869cda8a924e26337e3f1c83cbb7efe Author: Eike Rathke <[email protected]> Date: Fri Oct 27 18:00:32 2017 +0200 LocaleDataWrapper::stringToDouble() w/ decimalSeparatorAlternative, tdf#81671 To be used instead of rtl::math::stringToDouble() if locale dependent separators are involved. Change-Id: I54359c981901dc57b3d9312b0bfd2f2a14fccb33 diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx index a5f1988f1db4..02b416250adc 100644 --- a/include/unotools/localedatawrapper.hxx +++ b/include/unotools/localedatawrapper.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/i18n/LocaleItem.hpp> #include <com/sun/star/i18n/reservedWords.hpp> #include <rtl/ustring.hxx> +#include <rtl/math.h> #include <i18nlangtag/languagetag.hxx> #include <unotools/readwritemutexguard.hxx> #include <unotools/unotoolsdllapi.h> @@ -240,6 +241,64 @@ public: const OUString& getLongDateYearSep() const { return getOneLocaleItem( css::i18n::LocaleItem::LONG_DATE_YEAR_SEPARATOR ); } + /** A wrapper around rtl::math::stringToDouble() using the locale dependent + decimal separator, group separator, and if needed decimal separator + alternative. + + The decimal separator is tried first, if the conversion does not match + the entire string then the decimal separator alternative is tried if it + occurs in the string and was the reason to stop. + + Leading blanks are skipped, trailing blanks are not skipped. The number + is parsed up to the first non-floating point number character, same as + rtl::math::stringToDouble() does. The caller is responsible for proper + error checking and end comparison. + + @param rString + The string to parse as floating point number. + @param bUseGroupSep + Whether group separator is used/accepted during parsing. + @param pStatus + Pointer to receive the conversion status as in + rtl::math::stringToDouble(). + @param pParseEnd + Pointer to receive the parse end (exclusive) as in + rtl::math::stringToDouble(). + @return The floating point number as parsed. + */ + double stringToDouble( const OUString& rString, bool bUseGroupSep, + rtl_math_ConversionStatus* pStatus, sal_Int32* pParseEnd ) const; + + /** A wrapper around rtl_math_uStringToDouble() using the locale dependent + decimal separator, group separator, and if needed decimal separator + alternative. + + The decimal separator is tried first, if the conversion does not match + the entire string then the decimal separator alternative is tried if it + occurs in the string and was the reason to stop. + + Leading blanks are skipped, trailing blanks are not skipped. The number + is parsed up to the first non-floating point number character, same as + rtl_math_uStringToDouble() does. The caller is responsible for proper + error checking and end comparison. + + @param pBegin + The string position to start parsing a floating point number. + @param pEnd + The string position to stop parsing, exclusive. + @param bUseGroupSep + Whether group separator is used/accepted during parsing. + @param pStatus + Pointer to receive the conversion status as in + rtl_math_uStringToDouble(). + @param pParseEnd + Pointer to receive the parse end (exclusive) as in + rtl_math_uStringToDouble(). + @return The floating point number as parsed. + */ + double stringToDouble( const sal_Unicode* pBegin, const sal_Unicode* pEnd, bool bUseGroupSep, + rtl_math_ConversionStatus* pStatus, const sal_Unicode** ppParseEnd ) const; + // currency const OUString& getCurrSymbol() const; const OUString& getCurrBankSymbol() const; diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index 52269c291fcc..2f125f6b8e14 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -41,6 +41,7 @@ #include <rtl/ustrbuf.hxx> #include <osl/diagnose.h> #include <sal/macros.h> +#include <rtl/math.hxx> static const sal_uInt16 nCurrFormatInvalid = 0xffff; static const sal_uInt16 nCurrFormatDefault = 0; @@ -1747,6 +1748,46 @@ OUString LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals, return aNumber; } +// --- number parsing ------------------------------------------------- + +double LocaleDataWrapper::stringToDouble( const OUString& rString, bool bUseGroupSep, + rtl_math_ConversionStatus* pStatus, sal_Int32* pParseEnd ) const +{ + const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0); + rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; + sal_Int32 nParseEnd = 0; + double fValue = rtl::math::stringToDouble( rString, getNumDecimalSep()[0], cGroupSep, &eStatus, &nParseEnd); + bool bTryAlt = (nParseEnd < rString.getLength() && !getNumDecimalSepAlt().isEmpty() && + rString[nParseEnd] == getNumDecimalSepAlt().toChar()); + // Try re-parsing with alternative if that was the reason to stop. + if (bTryAlt) + fValue = rtl::math::stringToDouble( rString, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &nParseEnd); + if (pStatus) + *pStatus = eStatus; + if (pParseEnd) + *pParseEnd = nParseEnd; + return fValue; +} + +double LocaleDataWrapper::stringToDouble( const sal_Unicode* pBegin, const sal_Unicode* pEnd, bool bUseGroupSep, + rtl_math_ConversionStatus* pStatus, const sal_Unicode** ppParseEnd ) const +{ + const sal_Unicode cGroupSep = (bUseGroupSep ? getNumThousandSep()[0] : 0); + rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; + const sal_Unicode* pParseEnd = nullptr; + double fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSep()[0], cGroupSep, &eStatus, &pParseEnd); + bool bTryAlt = (pParseEnd < pEnd && !getNumDecimalSepAlt().isEmpty() && + *pParseEnd == getNumDecimalSepAlt().toChar()); + // Try re-parsing with alternative if that was the reason to stop. + if (bTryAlt) + fValue = rtl_math_uStringToDouble( pBegin, pEnd, getNumDecimalSepAlt().toChar(), cGroupSep, &eStatus, &pParseEnd); + if (pStatus) + *pStatus = eStatus; + if (ppParseEnd) + *ppParseEnd = pParseEnd; + return fValue; +} + // --- mixed ---------------------------------------------------------- LanguageTag LocaleDataWrapper::getLoadedLanguageTag() const commit dc520c7759fde6e765afece23b78b5ca6dece5b1 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 17:56:19 2017 +0200 Handle decimalSeparatorAlternative in BASIC ImpScan,..., tdf#81671 Change-Id: I73ff2bf624ba7c8d88c9419a109c340806bd31f5 diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx index a0be80e6383a..093595800450 100644 --- a/basic/source/sbx/sbxscan.cxx +++ b/basic/source/sbx/sbxscan.cxx @@ -51,12 +51,13 @@ #include <o3tl/make_unique.hxx> -void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep ) +void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep, sal_Unicode& rcDecimalSepAlt ) { SvtSysLocale aSysLocale; const LocaleDataWrapper& rData = aSysLocale.GetLocaleData(); rcDecimalSep = rData.getNumDecimalSep()[0]; rcThousandSep = rData.getNumThousandSep()[0]; + rcDecimalSepAlt = rData.getNumDecimalSepAlt().toChar(); } @@ -84,18 +85,22 @@ bool ImpStrChr( const sal_Unicode* p, sal_Unicode c ) ErrCode ImpScan( const OUString& rWSrc, double& nVal, SbxDataType& rType, sal_uInt16* pLen, bool bAllowIntntl, bool bOnlyIntntl ) { - sal_Unicode cIntntlDecSep, cIntntlGrpSep; + sal_Unicode cIntntlDecSep, cIntntlGrpSep, cIntntlDecSepAlt; sal_Unicode cNonIntntlDecSep = '.'; if( bAllowIntntl || bOnlyIntntl ) { - ImpGetIntntlSep( cIntntlDecSep, cIntntlGrpSep ); + ImpGetIntntlSep( cIntntlDecSep, cIntntlGrpSep, cIntntlDecSepAlt ); if( bOnlyIntntl ) cNonIntntlDecSep = cIntntlDecSep; + // Ensure that the decimal separator alternative is really one. + if (cIntntlDecSepAlt && cIntntlDecSepAlt == cNonIntntlDecSep) + cIntntlDecSepAlt = 0; } else { cIntntlDecSep = cNonIntntlDecSep; cIntntlGrpSep = 0; // no group separator accepted in non-i18n + cIntntlDecSepAlt = 0; } const sal_Unicode* const pStart = rWSrc.getStr(); @@ -113,7 +118,8 @@ ErrCode ImpScan( const OUString& rWSrc, double& nVal, SbxDataType& rType, bMinus = true; } if( rtl::isAsciiDigit( *p ) || ((*p == cNonIntntlDecSep || *p == cIntntlDecSep || - (cIntntlDecSep && *p == cIntntlGrpSep)) && rtl::isAsciiDigit( *(p+1) ))) + (cIntntlDecSep && *p == cIntntlGrpSep) || (cIntntlDecSepAlt && *p == cIntntlDecSepAlt)) && + rtl::isAsciiDigit( *(p+1) ))) { short exp = 0; short decsep = 0; @@ -123,6 +129,8 @@ ErrCode ImpScan( const OUString& rWSrc, double& nVal, SbxDataType& rType, aSearchStr.append(cNonIntntlDecSep); if( cIntntlDecSep != cNonIntntlDecSep ) aSearchStr.append(cIntntlDecSep); + if( cIntntlDecSepAlt && cIntntlDecSepAlt != cNonIntntlDecSep ) + aSearchStr.append(cIntntlDecSepAlt); if( bOnlyIntntl ) aSearchStr.append(cIntntlGrpSep); const sal_Unicode* const pSearchStr = aSearchStr.getStr(); @@ -135,7 +143,7 @@ ErrCode ImpScan( const OUString& rWSrc, double& nVal, SbxDataType& rType, p++; continue; } - if( *p == cNonIntntlDecSep || *p == cIntntlDecSep ) + if( *p == cNonIntntlDecSep || *p == cIntntlDecSep || (cIntntlDecSepAlt && *p == cIntntlDecSepAlt) ) { // Use the separator that is passed to stringToDouble() aBuf[ p - pStart ] = cIntntlDecSep; @@ -318,8 +326,8 @@ static void myftoa( double nNum, char * pBuf, short nPrec, short nExpWidth, short nDec; // number of positions before decimal point int i; - sal_Unicode cDecimalSep, cThousandSep; - ImpGetIntntlSep( cDecimalSep, cThousandSep ); + sal_Unicode cDecimalSep, cThousandSep, cDecimalSepAlt; + ImpGetIntntlSep( cDecimalSep, cThousandSep, cDecimalSepAlt ); if( cForceThousandSep ) cThousandSep = cForceThousandSep; @@ -429,8 +437,8 @@ void ImpCvtNum( double nNum, short nPrec, OUString& rRes, bool bCoreString ) char *q; char cBuf[ 40 ], *p = cBuf; - sal_Unicode cDecimalSep, cThousandSep; - ImpGetIntntlSep( cDecimalSep, cThousandSep ); + sal_Unicode cDecimalSep, cThousandSep, cDecimalSepAlt; + ImpGetIntntlSep( cDecimalSep, cThousandSep, cDecimalSepAlt ); if( bCoreString ) cDecimalSep = '.'; @@ -468,13 +476,15 @@ bool ImpConvStringExt( OUString& rSrc, SbxDataType eTargetType ) case SbxDOUBLE: case SbxCURRENCY: { - sal_Unicode cDecimalSep, cThousandSep; - ImpGetIntntlSep( cDecimalSep, cThousandSep ); + sal_Unicode cDecimalSep, cThousandSep, cDecimalSepAlt; + ImpGetIntntlSep( cDecimalSep, cThousandSep, cDecimalSepAlt ); aNewString = rSrc; - if( cDecimalSep != '.' ) + if( cDecimalSep != '.' || (cDecimalSepAlt && cDecimalSepAlt != '.') ) { sal_Int32 nPos = aNewString.indexOf( cDecimalSep ); + if( nPos == -1 && cDecimalSepAlt ) + nPos = aNewString.indexOf( cDecimalSepAlt ); if( nPos != -1 ) { sal_Unicode* pStr = const_cast<sal_Unicode*>(aNewString.getStr()); commit dcf0877cd04280e598943ecfe299cf7360971056 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:35:37 2017 +0200 Handle decimalSeparatorAlternative in SvNumberFormatter parsing, tdf#81671 Change-Id: Ic10aa36805ec4214f7ac54529fb391cf1e390a70 diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx index 0d82b6d6d4b4..969d0007380a 100644 --- a/include/svl/zforlist.hxx +++ b/include/svl/zforlist.hxx @@ -821,6 +821,7 @@ private: // cached locale data items needed almost any time OUString aDecimalSep; + OUString aDecimalSepAlt; OUString aThousandSep; OUString aDateSep; @@ -958,11 +959,17 @@ public: // return the corresponding decimal separator const OUString& GetNumDecimalSep() const; + // return the corresponding decimal separator alternative + const OUString& GetNumDecimalSepAlt() const; + // return the corresponding group (AKA thousand) separator const OUString& GetNumThousandSep() const; // return the corresponding date separator const OUString& GetDateSep() const; + + // checks for decimal separator and optional alternative + bool IsDecimalSep( const OUString& rStr ) const; }; #endif // INCLUDED_SVL_ZFORLIST_HXX diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx index 83c37af79c2e..5f717108f263 100644 --- a/svl/source/numbers/zforfind.cxx +++ b/svl/source/numbers/zforfind.cxx @@ -794,6 +794,12 @@ inline bool ImpSvNumberInputScan::GetDecSep( const OUString& rString, sal_Int32& nPos = nPos + rSep.getLength(); return true; } + const OUString& rSepAlt = pFormatter->GetNumDecimalSepAlt(); + if ( !rSepAlt.isEmpty() && rString.match( rSepAlt, nPos) ) + { + nPos = nPos + rSepAlt.getLength(); + return true; + } } return false; } @@ -3121,7 +3127,7 @@ bool ImpSvNumberInputScan::IsNumberFormatMain( const OUString& rString, / if (eSetType == css::util::NumberFormat::FRACTION) // Fraction 1 = 1/1 { if (i >= nStringsCnt || // no end string nor decimal separator - sStrArray[i] == pFormatter->GetNumDecimalSep()) + pFormatter->IsDecimalSep( sStrArray[i])) { eScannedType = css::util::NumberFormat::FRACTION; nMatchedAllStrings &= ~nMatchedVirgin; @@ -3144,7 +3150,7 @@ bool ImpSvNumberInputScan::IsNumberFormatMain( const OUString& rString, / eScannedType == css::util::NumberFormat::UNDEFINED && // not date or currency nDecPos == 0 && // no previous decimal separator (i >= nStringsCnt || // no end string nor decimal separator - sStrArray[i] == pFormatter->GetNumDecimalSep()) + pFormatter->IsDecimalSep( sStrArray[i])) ) { eScannedType = css::util::NumberFormat::FRACTION; @@ -3490,6 +3496,11 @@ void ImpSvNumberInputScan::ChangeIntl() sal_Unicode cDecSep = pFormatter->GetNumDecimalSep()[0]; bDecSepInDateSeps = ( cDecSep == '-' || cDecSep == pFormatter->GetDateSep()[0] ); + if (!bDecSepInDateSeps) + { + sal_Unicode cDecSepAlt = pFormatter->GetNumDecimalSepAlt().toChar(); + bDecSepInDateSeps = cDecSepAlt && (cDecSepAlt == '-' || cDecSepAlt == pFormatter->GetDateSep()[0]); + } bTextInitialized = false; aUpperCurrSymbol.clear(); InvalidateDateAcceptancePatterns(); diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx index 94912797057c..f4c236827a01 100644 --- a/svl/source/numbers/zforlist.cxx +++ b/svl/source/numbers/zforlist.cxx @@ -307,6 +307,7 @@ void SvNumberFormatter::ImpConstruct( LanguageType eLang ) // cached locale data items const LocaleDataWrapper* pLoc = GetLocaleData(); aDecimalSep = pLoc->getNumDecimalSep(); + aDecimalSepAlt = pLoc->getNumDecimalSepAlt(); aThousandSep = pLoc->getNumThousandSep(); aDateSep = pLoc->getDateSep(); @@ -338,6 +339,7 @@ void SvNumberFormatter::ChangeIntl(LanguageType eLnge) // cached locale data items, initialize BEFORE calling ChangeIntl below const LocaleDataWrapper* pLoc = GetLocaleData(); aDecimalSep = pLoc->getNumDecimalSep(); + aDecimalSepAlt = pLoc->getNumDecimalSepAlt(); aThousandSep = pLoc->getNumThousandSep(); aDateSep = pLoc->getDateSep(); @@ -537,10 +539,21 @@ const NativeNumberWrapper* SvNumberFormatter::GetNatNum() const { return xNatNum const OUString& SvNumberFormatter::GetNumDecimalSep() const { return aDecimalSep; } +const OUString& SvNumberFormatter::GetNumDecimalSepAlt() const { return aDecimalSepAlt; } + const OUString& SvNumberFormatter::GetNumThousandSep() const { return aThousandSep; } const OUString& SvNumberFormatter::GetDateSep() const { return aDateSep; } +bool SvNumberFormatter::IsDecimalSep( const OUString& rStr ) const +{ + if (rStr == GetNumDecimalSep()) + return true; + if (GetNumDecimalSepAlt().isEmpty()) + return false; + return rStr == GetNumDecimalSepAlt(); +} + bool SvNumberFormatter::IsTextFormat(sal_uInt32 F_Index) const { const SvNumberformat* pFormat = GetFormatEntry(F_Index); commit 5ab5243068ff0e023da35633922f140688c7fcbd Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:31:29 2017 +0200 Check decimalSeparatorAlternative in CheckConfigOptions(), tdf#81671 Change-Id: I5281a6e63e1cff8ae47f1b79eb4fdb5e7eaa074b diff --git a/sc/source/ui/docshell/docsh6.cxx b/sc/source/ui/docshell/docsh6.cxx index 9ec7631aa749..6b611373cd05 100644 --- a/sc/source/ui/docshell/docsh6.cxx +++ b/sc/source/ui/docshell/docsh6.cxx @@ -476,6 +476,7 @@ void ScDocShell::CheckConfigOptions() return; OUString aDecSep = ScGlobal::GetpLocaleData()->getNumDecimalSep(); + OUString aDecSepAlt = ScGlobal::GetpLocaleData()->getNumDecimalSepAlt(); ScModule* pScMod = SC_MOD(); const ScFormulaOptions& rOpt=pScMod->GetFormulaOptions(); @@ -483,7 +484,8 @@ void ScDocShell::CheckConfigOptions() const OUString& aSepArrRow = rOpt.GetFormulaSepArrayRow(); const OUString& aSepArrCol = rOpt.GetFormulaSepArrayCol(); - if (aDecSep == aSepArg || aDecSep == aSepArrRow || aDecSep == aSepArrCol) + if (aDecSep == aSepArg || aDecSep == aSepArrRow || aDecSep == aSepArrCol || + aDecSepAlt == aSepArg || aDecSepAlt == aSepArrRow || aDecSepAlt == aSepArrCol) { // One of arg separators conflicts with the current decimal // separator. Reset them to default. commit 0ce0999fa2ace834558f9e79053df60b60623950 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:28:52 2017 +0200 Check decimalSeparatorAlternative in GetDefaultFormulaSeparators(), tdf#81671 Change-Id: Idf413d1e9db4f63bd90888f1dfc6a5d9455e47cb diff --git a/sc/source/core/tool/formulaopt.cxx b/sc/source/core/tool/formulaopt.cxx index 2271d8801164..5fba1d82661b 100644 --- a/sc/source/core/tool/formulaopt.cxx +++ b/sc/source/core/tool/formulaopt.cxx @@ -88,13 +88,19 @@ void ScFormulaOptions::GetDefaultFormulaSeparators( sal_Unicode cDecSep = rDecSep[0]; sal_Unicode cListSep = rListSep[0]; + sal_Unicode cDecSepAlt = rLocaleData.getNumDecimalSepAlt().toChar(); // usually 0 (empty) // Excel by default uses system's list separator as the parameter // separator, which in English locales is a comma. However, OOo's list // separator value is set to ';' for all English locales. Because of this // discrepancy, we will hardcode the separator value here, for now. - if (cDecSep == '.') + // Similar for decimal separator alternative. + // However, if the decimal separator alternative is '.' and the decimal + // separator is ',' this makes no sense, fall back to ';' in that case. + if (cDecSep == '.' || (cDecSepAlt == '.' && cDecSep != ',')) cListSep = ','; + else if (cDecSep == ',' && cDecSepAlt == '.') + cListSep = ';'; // Special case for de_CH locale. if (rLocale.Language == "de" && rLocale.Country == "CH") commit ca214981553eb21a4276d07c76db0c37c234a11c Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:27:07 2017 +0200 Handle decimalSeparatorAlternative in ScColumn::ParseString(), tdf#81671 Change-Id: I9f708b28ee5fdb23217e75386a64ab86dacfd3c4 diff --git a/sc/inc/stringutil.hxx b/sc/inc/stringutil.hxx index bf4c519ab014..b28867f7f361 100644 --- a/sc/inc/stringutil.hxx +++ b/sc/inc/stringutil.hxx @@ -122,12 +122,13 @@ public: * @param rStr string to parse * @param dsep decimal separator * @param gsep group separator (aka thousands separator) + * @param dsepa decimal separator alternative, usually 0 * @param rVal value of successfully parsed number * * @return true if the string is a valid number, false otherwise. */ static bool parseSimpleNumber( - const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal); + const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal); static bool parseSimpleNumber( const char* p, size_t n, char dsep, char gsep, double& rVal); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index db7bb49bff27..f03bb90fd470 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1641,6 +1641,7 @@ void Test::testCSV() bool bResult = ScStringUtil::parseSimpleNumber (aStr, aTests[i].eSep == English ? '.' : ',', aTests[i].eSep == English ? ',' : '.', + 0, nValue); CPPUNIT_ASSERT_EQUAL_MESSAGE ("CSV numeric detection failure", aTests[i].bResult, bResult); CPPUNIT_ASSERT_EQUAL_MESSAGE ("CSV numeric value failure", aTests[i].nValue, nValue); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 001d8d320485..646210a8e679 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1806,13 +1806,15 @@ bool ScColumn::ParseString( const LocaleDataItem2& aLocaleItem = pLocale->getLocaleItem(); const OUString& rDecSep = aLocaleItem.decimalSeparator; const OUString& rGroupSep = aLocaleItem.thousandSeparator; - if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1) + const OUString& rDecSepAlt = aLocaleItem.decimalSeparatorAlternative; + if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1 || rDecSepAlt.getLength() > 1) break; sal_Unicode dsep = rDecSep[0]; sal_Unicode gsep = rGroupSep[0]; + sal_Unicode dsepa = rDecSepAlt.toChar(); - if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal)) + if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, dsepa, nVal)) break; rCell.set(nVal); diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx index 94f49e0fef70..8ac5a3a6a0d0 100644 --- a/sc/source/core/tool/stringutil.cxx +++ b/sc/source/core/tool/stringutil.cxx @@ -49,7 +49,7 @@ void ScSetStringParam::setNumericInput() } bool ScStringUtil::parseSimpleNumber( - const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal) + const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double& rVal) { // Actually almost the entire pre-check is unnecessary and we could call // rtl::math::stringToDouble() just after having exchanged ascii space with @@ -110,7 +110,7 @@ bool ScStringUtil::parseSimpleNumber( haveSeenDigit = true; ++nDigitCount; } - else if (c == dsep) + else if (c == dsep || (dsepa && c == dsepa)) { // this is a decimal separator. @@ -125,7 +125,7 @@ bool ScStringUtil::parseSimpleNumber( nPosDSep = i; nPosGSep = -1; - aBuf.append(c); + aBuf.append(dsep); // append the separator that is parsed in stringToDouble() below nDigitCount = 0; } else if (c == gsep) commit c1a47f1a51360f4afed094c1f87790fafb95e103 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:12:58 2017 +0200 Handle decimalSeparatorAlternative in ScCompiler, tdf#81671 Change-Id: I7471f0fb237e29a6f4e8bdd3405cd3b831673ca6 diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index cd8760b6bde6..3844e80008e0 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2018,8 +2018,8 @@ sal_Int32 ScCompiler::NextSymbol(bool bInArray) sal_Unicode cSep = mxSymbols->getSymbolChar( ocSep); sal_Unicode cArrayColSep = mxSymbols->getSymbolChar( ocArrayColSep); sal_Unicode cArrayRowSep = mxSymbols->getSymbolChar( ocArrayRowSep); - sal_Unicode cDecSep = (mxSymbols->isEnglish() ? '.' : - ScGlobal::pLocaleData->getNumDecimalSep()[0]); + sal_Unicode cDecSep = (mxSymbols->isEnglish() ? '.' : ScGlobal::pLocaleData->getNumDecimalSep()[0]); + sal_Unicode cDecSepAlt = (mxSymbols->isEnglish() ? 0 : ScGlobal::pLocaleData->getNumDecimalSepAlt().toChar()); // special symbols specific to address convention used sal_Unicode cSheetPrefix = pConv->getSpecialSymbol(ScCompiler::Convention::ABS_SHEET_PREFIX); @@ -2262,7 +2262,7 @@ Label_MaskStateMachine: SetError(FormulaError::StringOverflow); eState = ssStop; } - else if (c == cDecSep) + else if (c == cDecSep || (cDecSepAlt && c == cDecSepAlt)) { if (++nDecSeps > 1) { @@ -3202,10 +3202,17 @@ bool ScCompiler::IsReference( const OUString& rName, const OUString* pErrRef ) { // Has to be called before IsValue sal_Unicode ch1 = rName[0]; - sal_Unicode cDecSep = ( mxSymbols->isEnglish() ? '.' : - ScGlobal::pLocaleData->getNumDecimalSep()[0] ); + sal_Unicode cDecSep = ( mxSymbols->isEnglish() ? '.' : ScGlobal::pLocaleData->getNumDecimalSep()[0] ); if ( ch1 == cDecSep ) return false; + // Code further down checks only if cDecSep=='.' so simply obtaining the + // alternative decimal separator if it's not is sufficient. + if (cDecSep != '.') + { + cDecSep = ScGlobal::pLocaleData->getNumDecimalSepAlt().toChar(); + if ( ch1 == cDecSep ) + return false; + } // Who was that imbecile introducing '.' as the sheet name separator!?! if ( rtl::isAsciiDigit( ch1 ) && pConv->getSpecialSymbol( Convention::SHEET_SEPARATOR) == '.' ) { commit 21052ba2edeef9e16bf90fea62f007b1131c73c0 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 15:07:00 2017 +0200 Allow decimalSeparatorAlternative in cclass_unicode::parseText(), tdf#81671 Change-Id: I0469027951e68d3c08f40c236db3865edbdaa3e0 diff --git a/i18npool/inc/cclass_unicode.hxx b/i18npool/inc/cclass_unicode.hxx index d276347fa78c..b3390de4b6f1 100644 --- a/i18npool/inc/cclass_unicode.hxx +++ b/i18npool/inc/cclass_unicode.hxx @@ -138,6 +138,7 @@ private: ScanState eState; sal_Unicode cGroupSep; sal_Unicode cDecimalSep; + sal_Unicode cDecimalSepAlt; /// Get corresponding KParseTokens flag for a character static sal_Int32 getParseTokensType(sal_uInt32 c, bool isFirst); diff --git a/i18npool/source/characterclassification/cclass_unicode_parser.cxx b/i18npool/source/characterclassification/cclass_unicode_parser.cxx index 6e7279c229dc..1979135b8eca 100644 --- a/i18npool/source/characterclassification/cclass_unicode_parser.cxx +++ b/i18npool/source/characterclassification/cclass_unicode_parser.cxx @@ -433,18 +433,21 @@ void cclass_Unicode::initParserTable( const Locale& rLocale, sal_Int32 startChar // specials if( mxLocaleData.is() ) { - LocaleDataItem aItem = - mxLocaleData->getLocaleItem( aParserLocale ); + LocaleDataItem2 aItem = + mxLocaleData->getLocaleItem2( aParserLocale ); //!TODO: theoretically separators may be a string, adjustment would have to be //! done here and in parsing and in ::rtl::math::stringToDouble() cGroupSep = aItem.thousandSeparator[0]; cDecimalSep = aItem.decimalSeparator[0]; + cDecimalSepAlt = aItem.decimalSeparatorAlternative.toChar(); } if ( cGroupSep < nDefCnt ) pTable[cGroupSep] |= ParserFlags::VALUE; if ( cDecimalSep < nDefCnt ) pTable[cDecimalSep] |= ParserFlags::CHAR_VALUE | ParserFlags::VALUE; + if ( cDecimalSepAlt && cDecimalSepAlt < nDefCnt ) + pTable[cDecimalSepAlt] |= ParserFlags::CHAR_VALUE | ParserFlags::VALUE; // Modify characters according to KParseTokens definitions. { @@ -593,6 +596,8 @@ ParserFlags cclass_Unicode::getFlagsExtended(sal_uInt32 const c) return ParserFlags::VALUE; else if ( c == cDecimalSep ) return ParserFlags::CHAR_VALUE | ParserFlags::VALUE; + else if ( cDecimalSepAlt && c == cDecimalSepAlt ) + return ParserFlags::CHAR_VALUE | ParserFlags::VALUE; bool bStart = (eState == ssGetChar || eState == ssGetWordFirstChar || eState == ssRewindFromValue || eState == ssIgnoreLeadingInRewind); sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes); @@ -704,6 +709,7 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 bool bQuote = false; bool bMightBeWord = true; bool bMightBeWordLast = true; + bool bDecSepAltUsed = false; //! All the variables above (plus ParseResult) have to be resetted on ssRewindFromValue! sal_Int32 nextCharIndex(nPos); // == index of nextChar @@ -743,7 +749,7 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 else r.TokenType = KParseType::ASC_NUMBER; } - else if (current == cDecimalSep) + else if (current == cDecimalSep || (bDecSepAltUsed = (cDecimalSepAlt && current == cDecimalSep))) { if (nextChar) ++nDecSeps; @@ -812,7 +818,8 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 } if ( nMask & ParserFlags::VALUE ) { - if (current == cDecimalSep && ++nDecSeps > 1) + if ((current == cDecimalSep || (bDecSepAltUsed = (cDecimalSepAlt && current == cDecimalSepAlt))) && + ++nDecSeps > 1) { if (nCodePoints == 2) eState = ssRewindFromValue; @@ -954,6 +961,7 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 bQuote = false; bMightBeWord = true; bMightBeWordLast = true; + bDecSepAltUsed = false; } else { @@ -1001,7 +1009,7 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 if ( r.TokenType & KParseType::ASC_NUMBER ) { r.Value = rtl_math_uStringToDouble(rText.getStr() + nPos + r.LeadingWhiteSpace, - rText.getStr() + r.EndPos, cDecimalSep, cGroupSep, nullptr, nullptr); + rText.getStr() + r.EndPos, (bDecSepAltUsed ? cDecimalSepAlt : cDecimalSep), cGroupSep, nullptr, nullptr); if ( bMightBeWord ) r.TokenType |= KParseType::IDENTNAME; } commit 922a94f376d90c72315f86f2604924c142fca5be Author: Eike Rathke <[email protected]> Date: Fri Oct 27 14:52:43 2017 +0200 Add LocaleDataWrapper::getNumDecimalSepAlt(), tdf#81671 Change-Id: Id3a16004603685ef859506c2c6d86f8ff097c1d0 diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx index 398c990fe53b..a5f1988f1db4 100644 --- a/include/unotools/localedatawrapper.hxx +++ b/include/unotools/localedatawrapper.hxx @@ -65,7 +65,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper css::uno::Sequence< OUString > aDateAcceptancePatterns; css::uno::Sequence< sal_Int32 > aGrouping; // cached items - OUString aLocaleItem[css::i18n::LocaleItem::COUNT]; + OUString aLocaleItem[css::i18n::LocaleItem::COUNT2]; OUString aReservedWord[css::i18n::reservedWords::COUNT]; OUString aCurrSymbol; OUString aCurrBankSymbol; @@ -209,6 +209,8 @@ public: { return getOneLocaleItem( css::i18n::LocaleItem::THOUSAND_SEPARATOR ); } const OUString& getNumDecimalSep() const { return getOneLocaleItem( css::i18n::LocaleItem::DECIMAL_SEPARATOR ); } + const OUString& getNumDecimalSepAlt() const + { return getOneLocaleItem( css::i18n::LocaleItem::DECIMAL_SEPARATOR_ALTERNATIVE ); } const OUString& getTimeSep() const { return getOneLocaleItem( css::i18n::LocaleItem::TIME_SEPARATOR ); } const OUString& getTime100SecSep() const diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index d2552ffe4a82..52269c291fcc 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -355,7 +355,7 @@ std::vector< LanguageType > LocaleDataWrapper::getInstalledLanguageTypes() const OUString& LocaleDataWrapper::getOneLocaleItem( sal_Int16 nItem ) const { ::utl::ReadWriteGuard aGuard( aMutex ); - if ( nItem >= LocaleItem::COUNT ) + if ( nItem >= LocaleItem::COUNT2 ) { SAL_WARN( "unotools.i18n", "getOneLocaleItem: bounds" ); return aLocaleItem[0]; @@ -428,6 +428,9 @@ void LocaleDataWrapper::getOneLocaleItemImpl( sal_Int16 nItem ) case LocaleItem::LONG_DATE_YEAR_SEPARATOR : aLocaleItem[nItem] = aLocaleDataItem.LongDateYearSeparator; break; + case LocaleItem::DECIMAL_SEPARATOR_ALTERNATIVE : + aLocaleItem[nItem] = aLocaleDataItem.decimalSeparatorAlternative; + break; default: SAL_WARN( "unotools.i18n", "getOneLocaleItemImpl: which one?" ); } commit 51a7ae749de90485f3b15a3f935f0f11d5aeff5b Author: Eike Rathke <[email protected]> Date: Fri Oct 27 14:48:26 2017 +0200 Let LocaleDataWrapper::getLocaleItem() return LocaleDataItem2&, tdf#81671 Change-Id: I16cfe81dd3ce0c8c2e905d55bea13df134c7a398 diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx index be53b7558add..398c990fe53b 100644 --- a/include/unotools/localedatawrapper.hxx +++ b/include/unotools/localedatawrapper.hxx @@ -60,7 +60,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper LanguageTag maLanguageTag; std::shared_ptr< css::i18n::Calendar2 > xDefaultCalendar; std::shared_ptr< css::i18n::Calendar2 > xSecondaryCalendar; - css::i18n::LocaleDataItem aLocaleDataItem; + css::i18n::LocaleDataItem2 aLocaleDataItem; css::uno::Sequence< OUString > aReservedWordSeq; css::uno::Sequence< OUString > aDateAcceptancePatterns; css::uno::Sequence< sal_Int32 > aGrouping; @@ -82,7 +82,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper { bool operator()(const css::lang::Locale& rLocale1, const css::lang::Locale& rLocale2) const; }; - mutable std::map<css::lang::Locale, css::i18n::LocaleDataItem, Locale_Compare> maDataItemCache; + mutable std::map<css::lang::Locale, css::i18n::LocaleDataItem2, Locale_Compare> maDataItemCache; // whenever Locale changes void invalidateData(); @@ -144,7 +144,8 @@ public: // Wrapper implementations of service LocaleData css::i18n::LanguageCountryInfo getLanguageCountryInfo() const; - const css::i18n::LocaleDataItem& getLocaleItem() const; + /// NOTE: this wraps XLocaleData5::getLocaleItem2() in fact. + const css::i18n::LocaleDataItem2& getLocaleItem() const; /// NOTE: this wraps XLocaleData3::getAllCalendars2() in fact. css::uno::Sequence< css::i18n::Calendar2 > getAllCalendars() const; /// NOTE: this wraps XLocaleData2::getAllCurrencies2() in fact. diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 847e6f84d355..001d8d320485 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -49,7 +49,7 @@ #include <listenercontext.hxx> #include <filterentries.hxx> -#include <com/sun/star/i18n/LocaleDataItem.hpp> +#include <com/sun/star/i18n/LocaleDataItem2.hpp> #include <memory> @@ -64,7 +64,7 @@ #include <cstdio> -using ::com::sun::star::i18n::LocaleDataItem; +using ::com::sun::star::i18n::LocaleDataItem2; using namespace formula; @@ -1803,7 +1803,7 @@ bool ScColumn::ParseString( if (!pLocale) break; - const LocaleDataItem& aLocaleItem = pLocale->getLocaleItem(); + const LocaleDataItem2& aLocaleItem = pLocale->getLocaleItem(); const OUString& rDecSep = aLocaleItem.decimalSeparator; const OUString& rGroupSep = aLocaleItem.thousandSeparator; if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1) diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 6347e24086ef..fba985e7d28d 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -99,7 +99,7 @@ using namespace ::com::sun::star::i18n; bool SplitString( const OUString &sWhole, OUString &sPrefix, OUString &sSuffix, double &fNum ) { - i18n::LocaleDataItem aLocaleItem = ScGlobal::pLocaleData->getLocaleItem(); + i18n::LocaleDataItem2 aLocaleItem = ScGlobal::pLocaleData->getLocaleItem(); // Get prefix element OUString sUser = "-"; diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index 77940997ace6..d2552ffe4a82 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -173,7 +173,7 @@ css::i18n::LanguageCountryInfo LocaleDataWrapper::getLanguageCountryInfo() const return css::i18n::LanguageCountryInfo(); } -const css::i18n::LocaleDataItem& LocaleDataWrapper::getLocaleItem() const +const css::i18n::LocaleDataItem2& LocaleDataWrapper::getLocaleItem() const { { ::utl::ReadWriteGuard aGuard( aMutex ); @@ -188,7 +188,7 @@ const css::i18n::LocaleDataItem& LocaleDataWrapper::getLocaleItem() const ::utl::ReadWriteGuard aGuard( aMutex ); const css::lang::Locale& rLocal = getMyLocale(); - css::i18n::LocaleDataItem aItem = xLD->getLocaleItem( rLocal ); + css::i18n::LocaleDataItem2 aItem = xLD->getLocaleItem2( rLocal ); auto aRet = maDataItemCache.insert(std::make_pair(rLocal, aItem)); assert(aRet.second); return aRet.first->second; @@ -197,7 +197,7 @@ const css::i18n::LocaleDataItem& LocaleDataWrapper::getLocaleItem() const { SAL_WARN( "unotools.i18n", "getLocaleItem: Exception caught " << e ); } - static css::i18n::LocaleDataItem aEmptyItem; + static css::i18n::LocaleDataItem2 aEmptyItem; return aEmptyItem; } commit 2c1ab132685bee9251901be38e113e129c2c3fce Author: Eike Rathke <[email protected]> Date: Fri Oct 27 13:10:11 2017 +0200 Instanciate XLocaleData5 in all internal interfaces, tdf#81671 Change-Id: I71ab5008be930efdd3ba944b020554b9d65ed729 diff --git a/i18npool/inc/cclass_unicode.hxx b/i18npool/inc/cclass_unicode.hxx index 8e2fe1c445c8..d276347fa78c 100644 --- a/i18npool/inc/cclass_unicode.hxx +++ b/i18npool/inc/cclass_unicode.hxx @@ -21,7 +21,7 @@ #include <com/sun/star/i18n/XNativeNumberSupplier.hpp> #include <com/sun/star/i18n/XCharacterClassification.hpp> -#include <com/sun/star/i18n/XLocaleData4.hpp> +#include <com/sun/star/i18n/XLocaleData5.hpp> #include <cppuhelper/implbase.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -126,7 +126,7 @@ private: /// used for parser only css::lang::Locale aParserLocale; - css::uno::Reference < css::i18n::XLocaleData4 > mxLocaleData; + css::uno::Reference < css::i18n::XLocaleData5 > mxLocaleData; css::uno::Reference < css::i18n::XNativeNumberSupplier > xNatNumSup; OUString aStartChars; OUString aContChars; diff --git a/i18npool/inc/collatorImpl.hxx b/i18npool/inc/collatorImpl.hxx index b6f9dd25f791..47641a25f3a5 100644 --- a/i18npool/inc/collatorImpl.hxx +++ b/i18npool/inc/collatorImpl.hxx @@ -21,7 +21,7 @@ #include <comphelper/processfactory.hxx> #include <com/sun/star/uno/Reference.h> -#include <com/sun/star/i18n/XLocaleData4.hpp> +#include <com/sun/star/i18n/XLocaleData5.hpp> #include <com/sun/star/i18n/XCollator.hpp> #include <com/sun/star/lang/Locale.hpp> #include <cppuhelper/weak.hxx> @@ -94,7 +94,7 @@ private: // Service Factory css::uno::Reference < css::uno::XComponentContext > m_xContext; // lang::Locale Data - css::uno::Reference < css::i18n::XLocaleData4 > mxLocaleData; + css::uno::Reference < css::i18n::XLocaleData5 > mxLocaleData; /// @throws css::uno::RuntimeException bool SAL_CALL createCollator(const css::lang::Locale& rLocale, const OUString& serviceName, diff --git a/i18npool/inc/numberformatcode.hxx b/i18npool/inc/numberformatcode.hxx index d74231fc1560..a9c4a67c8b51 100644 --- a/i18npool/inc/numberformatcode.hxx +++ b/i18npool/inc/numberformatcode.hxx @@ -25,7 +25,7 @@ #include <cppuhelper/implbase.hxx> #include <com/sun/star/i18n/XNumberFormatCode.hpp> -#include <com/sun/star/i18n/XLocaleData4.hpp> +#include <com/sun/star/i18n/XLocaleData5.hpp> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -55,7 +55,7 @@ public: private: osl::Mutex maMutex; - css::uno::Reference < css::i18n::XLocaleData4 > m_xLocaleData; + css::uno::Reference < css::i18n::XLocaleData5 > m_xLocaleData; typedef std::pair< css::lang::Locale, css::uno::Sequence< css::i18n::FormatElement > > FormatElementCacheItem; std::deque < FormatElementCacheItem > m_aFormatElementCache; diff --git a/i18npool/inc/transliterationImpl.hxx b/i18npool/inc/transliterationImpl.hxx index c5e83b254885..0d70de37bfd2 100644 --- a/i18npool/inc/transliterationImpl.hxx +++ b/i18npool/inc/transliterationImpl.hxx @@ -19,7 +19,7 @@ #ifndef INCLUDED_I18NPOOL_INC_TRANSLITERATIONIMPL_HXX #define INCLUDED_I18NPOOL_INC_TRANSLITERATIONIMPL_HXX -#include <com/sun/star/i18n/XLocaleData4.hpp> +#include <com/sun/star/i18n/XLocaleData5.hpp> #include <com/sun/star/i18n/XExtendedTransliteration.hpp> #include <cppuhelper/implbase.hxx> #include <com/sun/star/uno/XComponentContext.hpp> @@ -87,7 +87,7 @@ private: sal_Int16 numCascade; bool caseignoreOnly; css::uno::Reference< css::uno::XComponentContext > mxContext; - css::uno::Reference< css::i18n::XLocaleData4 > mxLocaledata; + css::uno::Reference< css::i18n::XLocaleData5 > mxLocaledata; css::uno::Reference< css::i18n::XExtendedTransliteration > caseignore; /// @throws css::uno::RuntimeException diff --git a/i18npool/source/characterclassification/cclass_unicode_parser.cxx b/i18npool/source/characterclassification/cclass_unicode_parser.cxx index dc3d0775586d..6e7279c229dc 100644 --- a/i18npool/source/characterclassification/cclass_unicode_parser.cxx +++ b/i18npool/source/characterclassification/cclass_unicode_parser.cxx @@ -25,7 +25,7 @@ #include <com/sun/star/i18n/KParseTokens.hpp> #include <com/sun/star/i18n/KParseType.hpp> #include <com/sun/star/i18n/UnicodeType.hpp> -#include <com/sun/star/i18n/LocaleData.hpp> +#include <com/sun/star/i18n/LocaleData2.hpp> #include <com/sun/star/i18n/NativeNumberMode.hpp> #include <com/sun/star/i18n/NativeNumberSupplier.hpp> #include <comphelper/processfactory.hxx> @@ -381,7 +381,7 @@ bool cclass_Unicode::setupInternational( const Locale& rLocale ) } if ( !mxLocaleData.is() ) { - mxLocaleData.set( LocaleData::create(m_xContext) ); + mxLocaleData.set( LocaleData2::create(m_xContext) ); } return bChanged; } diff --git a/i18npool/source/collator/collatorImpl.cxx b/i18npool/source/collator/collatorImpl.cxx index 258ee9f6ec66..fd9b1f1bb053 100644 --- a/i18npool/source/collator/collatorImpl.cxx +++ b/i18npool/source/collator/collatorImpl.cxx @@ -20,7 +20,7 @@ #include <collatorImpl.hxx> #include <localedata.hxx> #include <com/sun/star/i18n/CollatorOptions.hpp> -#include <com/sun/star/i18n/LocaleData.hpp> +#include <com/sun/star/i18n/LocaleData2.hpp> #include <rtl/ustrbuf.hxx> #include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> @@ -34,7 +34,7 @@ namespace i18npool { CollatorImpl::CollatorImpl( const Reference < XComponentContext >& rxContext ) : m_xContext(rxContext) { - mxLocaleData.set( LocaleData::create(rxContext) ); + mxLocaleData.set( LocaleData2::create(rxContext) ); cachedItem = nullptr; } diff --git a/i18npool/source/numberformatcode/numberformatcode.cxx b/i18npool/source/numberformatcode/numberformatcode.cxx index 5fd2af898363..1ffafe63fa8c 100644 --- a/i18npool/source/numberformatcode/numberformatcode.cxx +++ b/i18npool/source/numberformatcode/numberformatcode.cxx @@ -20,13 +20,13 @@ #include <numberformatcode.hxx> #include <com/sun/star/i18n/KNumberFormatUsage.hpp> #include <com/sun/star/i18n/KNumberFormatType.hpp> -#include <com/sun/star/i18n/LocaleData.hpp> +#include <com/sun/star/i18n/LocaleData2.hpp> #include <cppuhelper/supportsservice.hxx> NumberFormatCodeMapper::NumberFormatCodeMapper( const css::uno::Reference < css::uno::XComponentContext >& rxContext ) { - m_xLocaleData.set( css::i18n::LocaleData::create( rxContext ) ); + m_xLocaleData.set( css::i18n::LocaleData2::create( rxContext ) ); } diff --git a/i18npool/source/transliteration/transliterationImpl.cxx b/i18npool/source/transliteration/transliterationImpl.cxx index 9fb298aef29d..456b8793c1ab 100644 --- a/i18npool/source/transliteration/transliterationImpl.cxx +++ b/i18npool/source/transliteration/transliterationImpl.cxx @@ -21,7 +21,7 @@ #include <transliterationImpl.hxx> #include <servicename.hxx> -#include <com/sun/star/i18n/LocaleData.hpp> +#include <com/sun/star/i18n/LocaleData2.hpp> #include <com/sun/star/i18n/TransliterationType.hpp> #include <com/sun/star/i18n/TransliterationModulesExtra.hpp> #include <com/sun/star/lang/XComponent.hpp> @@ -140,7 +140,7 @@ TransliterationImpl::TransliterationImpl(const Reference <XComponentContext>& xC numCascade = 0; caseignoreOnly = true; - mxLocaledata.set(LocaleData::create(xContext)); + mxLocaledata.set(LocaleData2::create(xContext)); } TransliterationImpl::~TransliterationImpl() commit ad1bf2ce2612ffb025c8ef9967018db53527a796 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 12:15:57 2017 +0200 Supersede with XLocaleData5, LocaleData2, tdf#81671 Change-Id: I17332be77f9c66c4fcfb7e3f3144ec624b804f94 diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx index a5d675988a75..be53b7558add 100644 --- a/include/unotools/localedatawrapper.hxx +++ b/include/unotools/localedatawrapper.hxx @@ -20,7 +20,7 @@ #ifndef INCLUDED_UNOTOOLS_LOCALEDATAWRAPPER_HXX #define INCLUDED_UNOTOOLS_LOCALEDATAWRAPPER_HXX -#include <com/sun/star/i18n/XLocaleData4.hpp> +#include <com/sun/star/i18n/XLocaleData5.hpp> #include <com/sun/star/i18n/LocaleItem.hpp> #include <com/sun/star/i18n/reservedWords.hpp> #include <rtl/ustring.hxx> @@ -56,7 +56,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper static sal_uInt8 nLocaleDataChecking; // 0:=dontknow, 1:=yes, 2:=no css::uno::Reference< css::uno::XComponentContext > m_xContext; - css::uno::Reference< css::i18n::XLocaleData4 > xLD; + css::uno::Reference< css::i18n::XLocaleData5 > xLD; LanguageTag maLanguageTag; std::shared_ptr< css::i18n::Calendar2 > xDefaultCalendar; std::shared_ptr< css::i18n::Calendar2 > xSecondaryCalendar; diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index 3ae1ac104f70..77940997ace6 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -30,7 +30,7 @@ #include <com/sun/star/i18n/KNumberFormatUsage.hpp> #include <com/sun/star/i18n/KNumberFormatType.hpp> -#include <com/sun/star/i18n/LocaleData.hpp> +#include <com/sun/star/i18n/LocaleData2.hpp> #include <com/sun/star/i18n/CalendarFieldIndex.hpp> #include <com/sun/star/i18n/CalendarDisplayIndex.hpp> #include <com/sun/star/i18n/NumberFormatIndex.hpp> @@ -85,7 +85,7 @@ LocaleDataWrapper::LocaleDataWrapper( ) : m_xContext( rxContext ), - xLD( LocaleData::create(rxContext) ), + xLD( LocaleData2::create(rxContext) ), maLanguageTag( rLanguageTag ), bLocaleDataItemValid( false ), bReservedWordValid( false ), @@ -99,7 +99,7 @@ LocaleDataWrapper::LocaleDataWrapper( ) : m_xContext( comphelper::getProcessComponentContext() ), - xLD( LocaleData::create(m_xContext) ), + xLD( LocaleData2::create(m_xContext) ), maLanguageTag( rLanguageTag ), bLocaleDataItemValid( false ), bReservedWordValid( false ), commit 281a84bd33d1c34d51c4a933d395f17bd36190c6 Author: Eike Rathke <[email protected]> Date: Fri Oct 27 12:04:35 2017 +0200 New LocaleItem::DECIMAL_SEPARATOR_ALTERNATIVE, tdf#81671 Change-Id: I1817d917621ccc3c81468132c558f9faa8c4ec4c diff --git a/offapi/com/sun/star/i18n/LocaleItem.idl b/offapi/com/sun/star/i18n/LocaleItem.idl index 97f6d586a667..6c3af39f9685 100644 --- a/offapi/com/sun/star/i18n/LocaleItem.idl +++ b/offapi/com/sun/star/i18n/LocaleItem.idl @@ -74,11 +74,17 @@ published constants LocaleItem /// @see com::sun::star::i18n::LocaleDataItem::LongDateYearSeparator const short LONG_DATE_YEAR_SEPARATOR = 16; - //! New values may be inserted here if locale data provides them. - //! Do not forget to adjust the COUNT value. - /// count of items available const short COUNT = 17; + + /// @see com::sun::star::i18n::LocaleDataItem2::decimalSeparatorAlternative + const short DECIMAL_SEPARATOR_ALTERNATIVE = 17; + + /// count of items available + const short COUNT2 = 18; + + //! New values may be appended here if locale data provides them. + //! Do not forget to introduce a new COUNTx value. };
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
