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<A1:A3>" 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(); } }