[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - writerfilter/qa writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Nov 16 14:22:37 UTC 2020


 writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx        |   22 ++++
 writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx |binary
 writerfilter/source/dmapper/DomainMapper_Impl.cxx                 |   48 +++++++---
 3 files changed, 56 insertions(+), 14 deletions(-)

New commits:
commit 4ed8d00c3e515cf38900294b26097a5281570000
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Nov 12 11:53:22 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Nov 16 15:22:03 2020 +0100

    DOCX import: fix lost cached result inside an IF field
    
    This builds on top of commit d09336fbdceaafd9320466b660a2b32a07dcc16a
    (tdf#125038 DOCX import: fix lost MERGEFIELD result inside an IF field,
    2019-10-31), and extends it for more cases.
    
    We know that DOCVARIABLE, FORMULA and IF fields inside an IF fields is
    not something Writer is capable of, so make sure we keep the cached
    result.
    
    (cherry picked from commit 6b15b6a6ab294e1d4a3a4bfb5ac81630aa08015c)
    
    Conflicts:
            writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
            writerfilter/source/dmapper/DomainMapper_Impl.cxx
    
    Change-Id: I20004f97c2073309c33594e5da6f8ba89ba278ba
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105937
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index d09a476dce4a..6eba76b0fd6a 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -18,6 +18,8 @@
 #include <com/sun/star/style/BreakType.hpp>
 
 #include <comphelper/processfactory.hxx>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
 
 using namespace ::com::sun::star;
 
@@ -143,6 +145,26 @@ CPPUNIT_TEST_FIXTURE(Test, testAltChunk)
     xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString("inner doc, first para"), xPara->getString());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFieldIfInsideIf)
+{
+    // Load a document with a field in a table cell: it contains an IF field with various nested
+    // fields.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "field-if-inside-if.docx";
+    getComponent() = loadFromDesktop(aURL);
+    uno::Reference<text::XTextTablesSupplier> xTextDocument(getComponent(), uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+
+    // Get the result of the topmost field.
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 0** Expression is faulty **2
+    // i.e. some of the inner fields escaped outside the outer field.
+    CPPUNIT_ASSERT_EQUAL(OUString("2"), xCell->getString());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx
new file mode 100644
index 000000000000..93aaab52d497
Binary files /dev/null and b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 22eb91ea9020..eb4c73762eef 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -204,7 +204,14 @@ static FieldContextPtr GetParentFieldContext(const std::deque<FieldContextPtr>&
 /// Decides if the pInner field inside pOuter is allowed in Writer core, depending on their type.
 static bool IsFieldNestingAllowed(const FieldContextPtr& pOuter, const FieldContextPtr& pInner)
 {
-    if (!pOuter->GetFieldId())
+    boost::optional<FieldId> oOuterFieldId = pOuter->GetFieldId();
+    if (!oOuterFieldId && pOuter->GetCommand().startsWith(" IF "))
+    {
+        // This will be FIELD_IF once the command is closed.
+        oOuterFieldId = FIELD_IF;
+    }
+
+    if (!oOuterFieldId)
     {
         return true;
     }
@@ -214,12 +221,15 @@ static bool IsFieldNestingAllowed(const FieldContextPtr& pOuter, const FieldCont
         return true;
     }
 
-    switch (pOuter->GetFieldId().get())
+    switch (oOuterFieldId.get())
     {
         case FIELD_IF:
         {
             switch (pInner->GetFieldId().get())
             {
+                case FIELD_DOCVARIABLE:
+                case FIELD_FORMULA:
+                case FIELD_IF:
                 case FIELD_MERGEFIELD:
                 {
                     return false;
@@ -5067,14 +5077,18 @@ void DomainMapper_Impl::CloseFieldCommand()
                     break;
                     case FIELD_DOCVARIABLE  :
                     {
-                        //create a user field and type
-                        uno::Reference< beans::XPropertySet > xMaster =
-                            FindOrCreateFieldMaster("com.sun.star.text.FieldMaster.User", sFirstParam);
-                        uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
-                        xDependentField->attachTextFieldMaster( xMaster );
-                        m_bSetUserFieldContent = true;
+                        if (bCreateField)
+                        {
+                            //create a user field and type
+                            uno::Reference<beans::XPropertySet> xMaster = FindOrCreateFieldMaster(
+                                "com.sun.star.text.FieldMaster.User", sFirstParam);
+                            uno::Reference<text::XDependentTextField> xDependentField(
+                                xFieldInterface, uno::UNO_QUERY_THROW);
+                            xDependentField->attachTextFieldMaster( xMaster );
+                            m_bSetUserFieldContent = true;
+                        }
+                        break;
                     }
-                    break;
                     case FIELD_EDITTIME     :
                         //it's a numbering type, no number format! SetNumberFormat( pContext->GetCommand(), xFieldProperties );
                     break;
@@ -5143,7 +5157,10 @@ void DomainMapper_Impl::CloseFieldCommand()
                     break;
                     case FIELD_FILESIZE     : break;
                     case FIELD_FORMULA :
-                        handleFieldFormula(pContext, xFieldProperties);
+                        if (bCreateField)
+                        {
+                            handleFieldFormula(pContext, xFieldProperties);
+                        }
                     break;
                     case FIELD_FORMCHECKBOX :
                     case FIELD_FORMDROPDOWN :
@@ -5694,8 +5711,8 @@ bool DomainMapper_Impl::IsFieldResultAsString()
         {
             if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back()))
             {
-                // Child field has no backing SwField, but the parent has: append is still possible.
-                bRet = pOuter->GetTextField().is();
+                // If nesting is not allowed, then the result can only be a string.
+                bRet = true;
             }
         }
     }
@@ -5714,8 +5731,11 @@ void DomainMapper_Impl::AppendFieldResult(OUString const& rString)
         {
             if (!IsFieldNestingAllowed(pOuter, pContext))
             {
-                // Child can't host the field result, forward to parent.
-                pOuter->AppendResult(rString);
+                if (pOuter->IsCommandCompleted())
+                {
+                    // Child can't host the field result, forward to parent.
+                    pOuter->AppendResult(rString);
+                }
                 return;
             }
         }


More information about the Libreoffice-commits mailing list