[Libreoffice-commits] core.git: sw/qa sw/source writerfilter/Library_writerfilter.mk writerfilter/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 17 21:31:03 UTC 2020


 sw/qa/extras/ooxmlexport/data/tdf123386.docx      |binary
 sw/qa/extras/ooxmlexport/data/tdf123389.docx      |binary
 sw/qa/extras/ooxmlexport/data/tdf133647.docx      |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx          |   46 ++++++++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx      |   35 ++++++++++++++--
 writerfilter/Library_writerfilter.mk              |    6 +-
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |    8 +++
 writerfilter/source/dmapper/PropertyIds.cxx       |    2 
 writerfilter/source/dmapper/PropertyIds.hxx       |    2 
 9 files changed, 91 insertions(+), 8 deletions(-)

New commits:
commit 82189fdc93ac337e1de3379d678eca6b7654e6fc
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Mon Aug 17 14:00:54 2020 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Mon Aug 17 23:30:21 2020 +0200

    tdf133647 tdf123386 tdf123389 fix DOCX table formula export
    
    Keep original DOCX table formula during round-trip
    using grab-bagging.
    
    This is a temporary solution until fixing formula export
    and a proposed solution for formula cannot be converted.
    
    Follow-up of commit 68e74bdf63e992666016c790e8e4cfd5b28d6abe
    (tdf133647 tdf123386 tdf123389 Improved .docx table formula import).
    
    Change-Id: Ia4759e250c06e9cc0495fb0b57fccd1ee1f50da9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100872
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf123386.docx b/sw/qa/extras/ooxmlexport/data/tdf123386.docx
new file mode 100644
index 000000000000..1278068ddedf
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf123386.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf123389.docx b/sw/qa/extras/ooxmlexport/data/tdf123389.docx
new file mode 100644
index 000000000000..4245464b820d
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf123389.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf133647.docx b/sw/qa/extras/ooxmlexport/data/tdf133647.docx
new file mode 100644
index 000000000000..fb525446c7fc
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf133647.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 017fa21a6dec..e0ce31a44d1b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -1009,6 +1009,52 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133163, "tdf133163.fodt")
     assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", " = SUM(A1:A3)");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf133647, "tdf133647.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport();
+    if (!pXmlDoc)
+        return;
+
+    // Keep original formula during round-trip
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(A1,B1)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(C1:D1)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(A1,5,B1:C1,6)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " = (1+2)*SUM(C1,D1)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " = 3*(2+SUM(A1:C1)+7)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " = 1+(SUM(1,2))");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " = (SUM(C1,5)*(2+7))*(3+SUM(1,B1))");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " = sum(a1,b1)");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf123386, "tdf123386.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport();
+    if (!pXmlDoc)
+        return;
+
+    // Keep original formula during round-trip
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " = A1 < 2");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = B1 > 1");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " = C1=3");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " = D1 <> 3");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND(A1=1,B1=2)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND((A1<1),(B1<>2))");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " = OR(A1=1,B1=2)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " = OR(TRUE,FALSE)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " = NOT(TRUE)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[12]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND(1,DEFINED(ABC1))");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf123389, "tdf123389.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport();
+    if (!pXmlDoc)
+        return;
+
+    // Keep original formula during round-trip
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " = ROUND(2.345,1)");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = ROUND(A1,2)");
+}
 
 DECLARE_OOXMLEXPORT_TEST(testTdf106953, "tdf106953.docx")
 {
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index fd3c9aeb360b..81760cc044ab 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2150,11 +2150,36 @@ void DocxAttributeOutput::CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos
             }
             else if ( rInfos.eType == ww::eEquals )
             {
-               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
-               icu::RegexMatcher aMatcher("<([A-Z]{1,3}[0-9]+(:[A-Z]{1,3}[0-9]+)?)>", sInput, 0, nErr);
-               sToken = aMatcher.replaceAll(icu::UnicodeString("$1"), nErr).getTerminatedBuffer();
+                // Use original OOXML formula, if it exists and its conversion hasn't been changed
+                bool bIsChanged = true;
+                if ( pNode->GetTableBox() )
+                {
+                    if ( const SfxGrabBagItem* pItem = pNode->GetTableBox()->GetFrameFormat()->GetAttrSet().GetItem<SfxGrabBagItem>(RES_FRMATR_GRABBAG) )
+                    {
+                        OUString sActualFormula = sToken.trim();
+                        const std::map<OUString, uno::Any>& rGrabBag = pItem->GetGrabBag();
+                        std::map<OUString, uno::Any>::const_iterator aStoredFormula = rGrabBag.find("CellFormulaConverted");
+                        if ( aStoredFormula != rGrabBag.end() && sActualFormula.indexOf('=') == 0 &&
+                                        sActualFormula.copy(1).trim() == aStoredFormula->second.get<OUString>().trim() )
+                        {
+                            aStoredFormula = rGrabBag.find("CellFormula");
+                            if ( aStoredFormula != rGrabBag.end() )
+                            {
+                                sToken = " = " + aStoredFormula->second.get<OUString>();
+                                bIsChanged = false;
+                            }
+                        }
+                    }
+                }
+
+                if ( bIsChanged )
+                {
+                    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
+                    icu::RegexMatcher aMatcher("<([A-Z]{1,3}[0-9]+(:[A-Z]{1,3}[0-9]+)?)>", sInput, 0, nErr);
+                    sToken = aMatcher.replaceAll(icu::UnicodeString("$1"), nErr).getTerminatedBuffer();
+                }
             }
 
             // Write the Field command
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index cbda03e9dcdd..add7c20bb2ea 100644
--- a/writerfilter/Library_writerfilter.mk
+++ b/writerfilter/Library_writerfilter.mk
@@ -51,9 +51,9 @@ $(eval $(call gb_Library_use_libraries,writerfilter,\
 
 $(eval $(call gb_Library_use_externals,writerfilter,\
 	boost_headers \
-    icui18n \
-    icuuc \
-    icu_headers \
+	icui18n \
+	icuuc \
+	icu_headers \
 	libxml2 \
 ))
 
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 4e8afddc8d50..1d23295fd759 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4286,6 +4286,14 @@ void DomainMapper_Impl::handleFieldFormula
     // we don't copy the = symbol from the command
     OUString formula = convertFieldFormula(command.copy(1));
 
+    // grab-bag the original and converted formula
+    if (getTableManager().isInTable())
+    {
+        TablePropertyMapPtr pPropMap(new TablePropertyMap());
+        pPropMap->Insert(PROP_CELL_FORMULA, uno::makeAny(command.copy(1)), true, CELL_GRAB_BAG);
+        pPropMap->Insert(PROP_CELL_FORMULA_CONVERTED, uno::makeAny(formula), true, CELL_GRAB_BAG);
+        getTableManager().cellProps(pPropMap);
+    }
     xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny(formula));
     xFieldProperties->setPropertyValue(getPropertyName(PROP_NUMBER_FORMAT), uno::makeAny(sal_Int32(0)));
     xFieldProperties->setPropertyValue("IsShowFormula", uno::makeAny(false));
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 7428097f0953..3aafab2c9354 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -355,6 +355,8 @@ OUString getPropertyName( PropertyIds eId )
         case PROP_DATATABLE_NAME: sName = "DataTableName"; break;
         case PROP_DATACOLUMN_NAME: sName = "DataColumnName"; break;
         case PROP_CHAR_TRANSPARENCE: sName = "CharTransparence"; break;
+        case PROP_CELL_FORMULA: sName = "CellFormula"; break;
+        case PROP_CELL_FORMULA_CONVERTED: sName = "CellFormulaConverted"; break;
     }
     assert(sName.getLength()>0);
     return sName;
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index c1c0e25698d6..5eed2297ff0d 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -357,6 +357,8 @@ enum PropertyIds
         ,PROP_DATATABLE_NAME
         ,PROP_DATACOLUMN_NAME
         ,PROP_CHAR_TRANSPARENCE
+        ,PROP_CELL_FORMULA
+        ,PROP_CELL_FORMULA_CONVERTED
     };
 
 //Returns the UNO string equivalent to eId.


More information about the Libreoffice-commits mailing list