sw/qa/extras/ooxmlexport/data/tdf147861_customField.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx               |   19 +++++++++++
 sw/qa/extras/ooxmlexport/ooxmlexport8.cxx                |    2 -
 writerfilter/source/dmapper/DomainMapper_Impl.cxx        |   25 ++++++++++++++-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx        |    4 ++
 5 files changed, 48 insertions(+), 2 deletions(-)

New commits:
commit 0bb206bb444bebc7726bdda4c8955de9934eb160
Author:     Justin Luth <[email protected]>
AuthorDate: Sat Mar 12 11:11:01 2022 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Apr 1 17:12:02 2022 +0200

    tdf#147861 writerfilter: use GetFieldResult, not current DocProperty
    
    Import DOCX and RTF DocProperty fields as "fixed" if the displayed
    text does not match the File - Properties - Custom variable's content.
    
    Otherwise LO will automatically update the field and show the wrong
    contents (because MS Word requires the user to manually refresh via F9).
    
    (cherry picked from commit c4cb1d1dd581a5f120d9cf8b1d4274ec38f3eabe)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
    
    Change-Id: Id5d3d0794e81b13465c5e824f1e994f563e62c1c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132401
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf147861_customField.docx 
b/sw/qa/extras/ooxmlexport/data/tdf147861_customField.docx
new file mode 100644
index 000000000000..70071fa7e8a3
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf147861_customField.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index be2f031c51d6..ee875f24acb9 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -21,6 +21,7 @@
 #include <officecfg/Office/Common.hxx>
 
 #include <swmodeltestbase.hxx>
+#include <unotxdoc.hxx>
 
 constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/ooxmlexport/data/";
 
@@ -51,6 +52,24 @@ DECLARE_OOXMLEXPORT_TEST(testTdf135164_cancelledNumbering, 
"tdf135164_cancelledN
     CPPUNIT_ASSERT_EQUAL(OUString("i"), getProperty<OUString>(xPara, 
"ListLabelString"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf147861_customField, 
"tdf147861_customField.docx")
+{
+    // These should each be specific values, not a shared DocProperty
+    getParagraph(1, "CustomEditedTitle"); // edited
+    // A couple of nulls at the end of the string thwarted all attemps at an 
"equals" comparison.
+    CPPUNIT_ASSERT(getParagraph(2)->getString().startsWith(" INSERT Custom 
Title here"));
+    getParagraph(3, "My Title"); // edited
+
+    // Verify that these are fields, and not just plain text
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, 
uno::UNO_QUERY);
+    auto xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
+    uno::Reference<text::XTextField> xField(xFields->nextElement(), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("CustomEditedTitle"), 
xField->getPresentation(false));
+    // The " (fixed)" part is unnecessary, but it must be consistent across a 
round-trip
+    CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), 
xField->getPresentation(true));
+}
+
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf135906, "tdf135906.docx")
 {
     // just test round-tripping. The document was exported as corrupt and 
didn't re-load.
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index 59d713fdfb04..c65d279739ba 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -147,7 +147,7 @@ DECLARE_OOXMLEXPORT_TEST(testN751117, "n751117.docx")
 DECLARE_OOXMLEXPORT_TEST(testFdo74745, "fdo74745.docx")
 {
     uno::Reference<text::XTextRange > paragraph = getParagraph(3);
-    CPPUNIT_ASSERT_EQUAL(OUString("09/02/14"), paragraph->getString());
+    CPPUNIT_ASSERT_EQUAL(OUString("09/02/2014"), paragraph->getString());
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo81486, "fdo81486.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index df943fb1dda7..2e1d13d5de17 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4723,6 +4723,11 @@ void 
FieldContext::SetTextField(uno::Reference<text::XTextField> const& xTextFie
     m_xTextField = xTextField;
 }
 
+void FieldContext::CacheVariableValue(const uno::Any& rAny)
+{
+        rAny >>= m_sVariableValue;
+}
+
 void FieldContext::AppendCommand(std::u16string_view rPart)
 {
     m_sCommand += rPart;
@@ -5356,6 +5361,9 @@ void DomainMapper_Impl::handleAuthor
             }
         }
     }
+    else
+        
pContext->CacheVariableValue(xUserDefinedProps->getPropertyValue(rFirstParam));
+
     OUString sServiceName("com.sun.star.text.TextField.");
     bool bIsCustomField = false;
     if(sFieldServiceName.isEmpty())
@@ -6975,7 +6983,22 @@ void DomainMapper_Impl::SetFieldResult(OUString const& 
rResult)
                             getPropertyName(bHasContent && sValue.isEmpty()? 
PROP_CONTENT : PROP_CURRENT_PRESENTATION),
                          uno::makeAny( rResult ));
 
-                    if (xServiceInfo->supportsService(
+                    // LO always automatically updates a DocInfo field from 
the File-Properties-Custom Prop
+                    // while MS Word requires the user to manually refresh the 
field (with F9).
+                    // In other words, Word lets the field to be out of sync 
with the controlling variable.
+                    // Marking as FIXEDFLD solves the automatic replacement 
problem, but of course prevents
+                    // Writer from making any changes, even on an F9 refresh.
+                    OUString sVariable = pContext->GetVariableValue();
+                    if (rResult.getLength() != sVariable.getLength())
+                    {
+                        sal_Int32 nLen = sVariable.indexOf('\x0');
+                        if (nLen >= 0)
+                            sVariable = sVariable.copy(0, nLen);
+                    }
+                    bool bCustomFixedField = rResult != sVariable &&
+                        
xServiceInfo->supportsService("com.sun.star.text.TextField.DocInfo.Custom");
+
+                    if (bCustomFixedField || xServiceInfo->supportsService(
                             
"com.sun.star.text.TextField.DocInfo.CreateDateTime"))
                     {
                         // Creation time is const, don't try to update it.
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 3b5827aff7ae..c65a03520a15 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -174,6 +174,7 @@ class FieldContext : public virtual SvRefBase
 
     OUString m_sCommand;
     OUString m_sResult;
+    OUString m_sVariableValue;
     std::optional<FieldId> m_eFieldId;
     bool m_bFieldLocked;
 
@@ -209,6 +210,9 @@ public:
     void AppendResult(std::u16string_view rResult) { m_sResult += rResult; }
     const OUString&  GetResult() const { return m_sResult; }
 
+    void CacheVariableValue(const css::uno::Any& rAny);
+    const OUString& GetVariableValue() { return m_sVariableValue; }
+
     void                    SetCommandCompleted() { m_bFieldCommandCompleted = 
true; }
     bool                    IsCommandCompleted() const { return 
m_bFieldCommandCompleted;    }
 

Reply via email to