sw/qa/extras/ooxmlexport/data/tdf147861_customField.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport16.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 5f265a90b0c635826ca59a7726a85c639098e0bf
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Sat Mar 12 11:11:01 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Apr 1 08:34:03 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
            writerfilter/source/dmapper/DomainMapper_Impl.cxx
    
    Change-Id: Id5d3d0794e81b13465c5e824f1e994f563e62c1c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132347
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.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/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index d71c466258c3..042f4c825adb 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -19,6 +19,7 @@
 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextField.hpp>
 #include <comphelper/propertysequence.hxx>
 #include <editeng/escapementitem.hxx>
 #include <textboxhelper.hxx>
@@ -253,6 +254,24 @@ DECLARE_OOXMLEXPORT_TEST(testCommentDoneModel, 
"CommentDone.docx")
     }
 }
 
+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_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index f95920b7a9dc..523f4dda51fb 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -160,7 +160,7 @@ DECLARE_OOXMLEXPORT_TEST(testFdo49940, "fdo49940.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 accf1148f916..51b704b8a2e8 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4160,6 +4160,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(const OUString& rPart)
 {
     m_sCommand += rPart;
@@ -4793,6 +4798,9 @@ void DomainMapper_Impl::handleAuthor
             }
         }
     }
+    else
+        
pContext->CacheVariableValue(xUserDefinedProps->getPropertyValue(rFirstParam));
+
     OUString sServiceName("com.sun.star.text.TextField.");
     bool bIsCustomField = false;
     if(sFieldServiceName.isEmpty())
@@ -6406,7 +6414,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 8631e764a28c..3b97adab2006 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -159,6 +159,7 @@ class FieldContext : public virtual SvRefBase
 
     OUString m_sCommand;
     OUString m_sResult;
+    OUString m_sVariableValue;
     std::optional<FieldId> m_eFieldId;
     bool m_bFieldLocked;
 
@@ -194,6 +195,9 @@ public:
     void AppendResult(OUString const& 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