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 c4cb1d1dd581a5f120d9cf8b1d4274ec38f3eabe
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Sat Mar 12 11:11:01 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Mar 25 13:48:12 2022 +0100

    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).
    
    Change-Id: Id5d3d0794e81b13465c5e824f1e994f563e62c1c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131415
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

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 a33da51048b8..bbc5ec25da07 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -18,6 +18,7 @@
 
 #include <queue>
 #include <swmodeltestbase.hxx>
+#include <unotxdoc.hxx>
 
 constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/ooxmlexport/data/";
 
@@ -48,6 +49,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));
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf135906)
 {
     loadAndReload("tdf135906.docx");
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index 3d0b23f9e71e..415138bc5e28 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -129,7 +129,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 a4d59a8b7fdb..a3d6a4f69498 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4792,6 +4792,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;
@@ -5425,6 +5430,9 @@ void DomainMapper_Impl::handleAuthor
             }
         }
     }
+    else
+        
pContext->CacheVariableValue(xUserDefinedProps->getPropertyValue(rFirstParam));
+
     OUString sServiceName("com.sun.star.text.TextField.");
     bool bIsCustomField = false;
     if(sFieldServiceName.isEmpty())
@@ -7044,7 +7052,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 869d0cdf1ece..f6c3f637de5d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -176,6 +176,7 @@ class FieldContext : public virtual SvRefBase
 
     OUString m_sCommand;
     OUString m_sResult;
+    OUString m_sVariableValue;
     std::optional<FieldId> m_eFieldId;
     bool m_bFieldLocked;
 
@@ -211,6 +212,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