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; }