sw/qa/extras/ooxmlexport/data/tdf166102.fodt |   31 ++++++++++++++
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx     |   57 +++++++++++++++++++++++++--
 sw/source/filter/ww8/docxattributeoutput.cxx |   14 ++++--
 3 files changed, 94 insertions(+), 8 deletions(-)

New commits:
commit 9bbd80c06ed0b563184882873fbe129b245504e5
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Thu Apr 10 12:47:08 2025 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Apr 29 11:23:42 2025 +0200

    tdf#166102: replace < and > with parentheses
    
    =sum<A1:A3> was exported to =sumA1:A3 making the
    expression faulty
    
    I also tried replacing them with spaces but then it causes
    a Syntax error in Word after updating the field
    
    Change-Id: I25b42d0a06335a4e5d8c8df90e8cf30e191fe426
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183967
    Tested-by: Jenkins
    Tested-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    (cherry picked from commit 7f8602e4feac16b5d0f6b80b93d5be6378f0aa11)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184076
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf166102.fodt 
b/sw/qa/extras/ooxmlexport/data/tdf166102.fodt
new file mode 100644
index 000000000000..eb72a22c76da
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf166102.fodt
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer"; office:version="1.4" 
office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:body>
+  <office:text>
+   <table:table>
+    <table:table-column/>
+    <table:table-row>
+     <table:table-cell>
+      <text:p>1</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row>
+     <table:table-cell>
+      <text:p>2</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row>
+     <table:table-cell>
+      <text:p>3</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row>
+     <table:table-cell table:formula="ooow:sum&lt;A1:A3&gt;" 
office:value-type="float" office:value="6">
+      <text:p>6</text:p>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 64901fcf7359..c7501b7e331e 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -20,6 +20,7 @@
 #include <com/sun/star/text/TableColumnSeparator.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/text/XTextField.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
@@ -895,7 +896,20 @@ DECLARE_OOXMLEXPORT_TEST(testTdf44986, "tdf44986.docx")
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf118682)
 {
-    loadAndSave("tdf118682.fodt");
+    loadAndReload("tdf118682.fodt");
+
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
+
+    uno::Reference<text::XTextField> 
xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(u"(<A1>)+(<A2>)"_ustr, 
xEnumerationAccess1->getPresentation(true).trim());
+    CPPUNIT_ASSERT_EQUAL(u"3"_ustr, 
xEnumerationAccess1->getPresentation(false).trim());
+
+    uno::Reference<text::XTextField> 
xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(u"SUM(<A1:A3>)"_ustr, 
xEnumerationAccess2->getPresentation(true).trim());
+    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, 
xEnumerationAccess2->getPresentation(false).trim());
+
     // Support cell references in table formulas
     xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
 
@@ -904,13 +918,26 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf118682)
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3);
 
     // Cell references were parenthesized: <A1>+<A2> and SUM(<A1:A3>)
-    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", u" =A1+A2");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", u" =(A1)+(A2)");
     assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", u" 
=SUM(A1:A3)");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf133163)
 {
-    loadAndSave("tdf133163.fodt");
+    loadAndReload("tdf133163.fodt");
+
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
+
+    uno::Reference<text::XTextField> 
xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(u"(<A1>)+(<A2>)"_ustr, 
xEnumerationAccess1->getPresentation(true).trim());
+    CPPUNIT_ASSERT_EQUAL(u"3"_ustr, 
xEnumerationAccess1->getPresentation(false).trim());
+
+    uno::Reference<text::XTextField> 
xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(u"SUM(<A1:A3>)"_ustr, 
xEnumerationAccess2->getPresentation(true).trim());
+    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, 
xEnumerationAccess2->getPresentation(false).trim());
+
     xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
 
     // Formula cells were completely missing.
@@ -918,10 +945,32 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf133163)
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3);
 
     // Cell references were parenthesized: <A1>+<A2> and SUM(<A1:A3>)
-    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", u" =A1+A2");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", u" =(A1)+(A2)");
     assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", u" 
=SUM(A1:A3)");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf166102)
+{
+    loadAndReload("tdf166102.fodt");
+
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
+
+    uno::Reference<text::XTextField> 
xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(u"sum(<A1:A3>)"_ustr, 
xEnumerationAccess1->getPresentation(true).trim());
+    CPPUNIT_ASSERT_EQUAL(u"6"_ustr, 
xEnumerationAccess1->getPresentation(false).trim());
+
+    xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
+
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3);
+
+    // Without the fix in place, this test would have failed with
+    // - Expected:  =sum(A1:A3)
+    // - Actual  :  =sumA1:A3
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", u" 
=sum(A1:A3)");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf133647)
 {
     loadAndSave("tdf133647.docx");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 04089b7b86e6..f0966736bed8 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3073,12 +3073,18 @@ void DocxAttributeOutput::CmdField_Impl( const 
SwTextNode* pNode, sal_Int32 nPos
             {
                 UErrorCode nErr(U_ZERO_ERROR);
                 icu::UnicodeString sInput(sToken.getStr());
-                // remove < and > around cell references, e.g. <A1> to A1, 
<A1:B2> to A1:B2
+                // replace < and > around cell references with parentheses
+                // e.g. "<A1>" to "(A1)", "<A1:B2>" to "(A1:B2)"
                 icu::RegexMatcher 
aMatcher("<([A-Z]{1,3}[0-9]+(:[A-Z]{1,3}[0-9]+)?)>", sInput, 0, nErr);
-                sInput = aMatcher.replaceAll(icu::UnicodeString("$1"), nErr);
+                sInput = aMatcher.replaceAll(icu::UnicodeString("($1)"), nErr);
+
+                // In case the parenthesis has been doubled in the previous 
replaceAll, remove one of them
+                icu::RegexMatcher 
aMatcher2("[(]([(][A-Z]{1,3}[0-9]+(:[A-Z]{1,3}[0-9]+)?[)])[)]", sInput, 0, 
nErr);
+                sInput = aMatcher2.replaceAll(icu::UnicodeString("$1"), nErr);
+
                 // convert MEAN to AVERAGE
-                icu::RegexMatcher aMatcher2("\bMEAN\b", sInput, 
UREGEX_CASE_INSENSITIVE, nErr);
-                sToken = aMatcher2.replaceAll(icu::UnicodeString("AVERAGE"), 
nErr).getTerminatedBuffer();
+                icu::RegexMatcher aMatcher3("\bMEAN\b", sInput, 
UREGEX_CASE_INSENSITIVE, nErr);
+                sToken = aMatcher3.replaceAll(icu::UnicodeString("AVERAGE"), 
nErr).getTerminatedBuffer();
             }
         }
 

Reply via email to