i18npool/source/characterclassification/cclass_unicode_parser.cxx |   10 +-
 sw/qa/extras/uiwriter/data/tdf125154.odt                          |binary
 sw/qa/extras/uiwriter/uiwriter.cxx                                |   47 
++++++++++
 sw/source/core/bastyp/calc.cxx                                    |    2 
 4 files changed, 57 insertions(+), 2 deletions(-)

New commits:
commit 29f5742bc8ff36741baac5b71082b3daee70ac18
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Jun 13 17:15:07 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Jun 16 16:22:22 2023 +0200

    tdf#125154 i18npool,sw: fix group separators in numbers in formulas
    
    Commit 776f7e7463de3e97f3056712ee567f49a314829d changed cclass_Unicode
    to reject group separators in numbers by default, but users are
    complaining that the neat "5.000" numbers in their existing documents
    are now considered invalid.
    
    * in SwCalc, use GROUP_SEPARATOR_IN_NUMBER
    * in cclass_Unicode::parseText(), reject a group separator if it is not
      followed by at least 3 digits
    
    With this, a number from tdf#42518 "0.19" is still considered invalid,
    while "5.000" is now valid again.
    
    Change-Id: If86f2ed4c27be16f866d7f4cee00789344e9ee2e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153047
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/i18npool/source/characterclassification/cclass_unicode_parser.cxx 
b/i18npool/source/characterclassification/cclass_unicode_parser.cxx
index aed29ea1ce5b..9ed95e2f907a 100644
--- a/i18npool/source/characterclassification/cclass_unicode_parser.cxx
+++ b/i18npool/source/characterclassification/cclass_unicode_parser.cxx
@@ -827,8 +827,16 @@ void cclass_Unicode::parseText( ParseResult& r, const 
OUString& rText, sal_Int32
                 {
                     if (current == cGroupSep)
                     {
-                        if (getFlags(nextChar, eState) & 
ParserFlags::VALUE_DIGIT)
+                        // accept only if it is followed by 3 digits
+                        sal_Int32 tempIndex(index);
+                        sal_uInt32 const nextChar2((tempIndex < 
rText.getLength()) ? rText.iterateCodePoints(&tempIndex) : 0);
+                        sal_uInt32 const nextChar3((tempIndex < 
rText.getLength()) ? rText.iterateCodePoints(&tempIndex) : 0);
+                        if (getFlags(nextChar, eState) & 
ParserFlags::VALUE_DIGIT
+                            && getFlags(nextChar2, eState) & 
ParserFlags::VALUE_DIGIT
+                            && getFlags(nextChar3, eState) & 
ParserFlags::VALUE_DIGIT)
+                        {
                             nParseTokensType |= 
KParseTokens::GROUP_SEPARATOR_IN_NUMBER;
+                        }
                         else
                         {
                             // Trailing group separator character is not a
diff --git a/sw/qa/extras/uiwriter/data/tdf125154.odt 
b/sw/qa/extras/uiwriter/data/tdf125154.odt
new file mode 100644
index 000000000000..81dee2be72cf
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf125154.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index 4a84aeef9f44..58ebbcde09ff 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -375,6 +375,53 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkCopy)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFormulaNumberWithGroupSeparator)
+{
+    createSwDoc("tdf125154.odt");
+    dispatchCommand(mxComponent, ".uno:UpdateAll", {});
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->SttEndDoc(true);
+    SwField const* pField;
+
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("1000"), pField->GetFormula());
+    CPPUNIT_ASSERT_EQUAL(OUString("1.000"), pField->ExpandField(true, 
nullptr));
+    pWrtShell->GoNextCell();
+    CPPUNIT_ASSERT_EQUAL(OUString("10000"), 
pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+    pWrtShell->GoNextCell();
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("test"), pField->GetFormula());
+    CPPUNIT_ASSERT_EQUAL(OUString("1.000"), pField->ExpandField(true, 
nullptr));
+    pWrtShell->GoNextCell();
+    // the problem was that this was 0
+    CPPUNIT_ASSERT_EQUAL(OUString("10000"), 
pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+    pWrtShell->Down(false);
+    pWrtShell->SttPara(false);
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("1000*10%"), pField->GetFormula());
+    CPPUNIT_ASSERT_EQUAL(OUString("100"), pField->ExpandField(true, nullptr));
+    pWrtShell->Down(false);
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("5.000*10%"), pField->GetFormula());
+    // the problem was that this was 0
+    CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
+    pWrtShell->Down(false);
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("5.000*10%"), pField->GetFormula());
+    // the problem was that this was
+    CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
+    pWrtShell->Down(false);
+    pField = pWrtShell->GetCurField();
+    CPPUNIT_ASSERT_EQUAL(OUString("5000*10%"), pField->GetFormula());
+    CPPUNIT_ASSERT_EQUAL(OUString("500"), pField->ExpandField(true, nullptr));
+    pWrtShell->Down(false);
+    CPPUNIT_ASSERT_EQUAL(OUString(u"-100,00 €"), 
pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+    pWrtShell->GoNextCell();
+    // tdf#42518 the problem was that this was 1.900,00 €
+    CPPUNIT_ASSERT_EQUAL(OUString("** Expression is faulty **"), 
pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testInsertFileInInputFieldException)
 {
     createSwDoc();
diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx
index d6b09766fb40..62d300f60ba7 100644
--- a/sw/source/core/bastyp/calc.cxx
+++ b/sw/source/core/bastyp/calc.cxx
@@ -153,7 +153,7 @@ const sal_Int32 coStartFlags =
 
 // Continuing characters may be any alphanumeric, underscore, or dot.
 const sal_Int32 coContFlags =
-    ( coStartFlags | i18n::KParseTokens::ASC_DOT )
+    (coStartFlags | i18n::KParseTokens::ASC_DOT | 
i18n::KParseTokens::GROUP_SEPARATOR_IN_NUMBER)
         & ~i18n::KParseTokens::IGNORE_LEADING_WS;
 
 extern "C" {

Reply via email to