sw/qa/extras/ooxmlexport/data/tdf150542.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport16.cxx | 21 +++++++++ writerfilter/source/dmapper/SettingsTable.cxx | 58 +++++++++++++++++++++++++- writerfilter/source/ooxml/model.xml | 3 + 4 files changed, 81 insertions(+), 1 deletion(-)
New commits: commit 184a805bc50c593cde950fb0b3253665cc748999 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Tue Mar 28 13:15:09 2023 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Tue Apr 4 08:54:46 2023 +0200 tdf#150542: DOCX import: support for document varibles Writer does insert document variables only if they are in document body as DOCVARIABLE fields. But ones given in settings.xml (w:docVars/w:docVar) were ignored. Moreover variables in settings should have priority and overwrite ones in fields. Word by default does show only field results, but refreshing field values will override values with ones from settings. Change-Id: I7103c90eef59ab18f8a25e616dcf8a8b1c6dcb08 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149646 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> (cherry picked from commit 992d86b1b67a6bd28bbf5e63b2d2406881f476b7) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149889 diff --git a/sw/qa/extras/ooxmlexport/data/tdf150542.docx b/sw/qa/extras/ooxmlexport/data/tdf150542.docx new file mode 100644 index 000000000000..3f115fa69370 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf150542.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx index d7dfbf73890e..044c6f3055fd 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx @@ -976,6 +976,27 @@ CPPUNIT_TEST_FIXTURE(Test, Test_ShadowDirection) "rotWithShape", "0"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf150542) +{ + loadAndSave("tdf150542.docx"); + + xmlDocUniquePtr pSettingsDoc = parseExport("word/settings.xml"); + // Ensure that all docvars from input are written back and with correct values. + // Order of document variables is not checked. So this can fail at some time if order is changed. + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[1]", "name", u"LocalChars\u00C1\u0072\u0076\u00ED\u007A\u0074\u0075\u0072\u006F\u0054\u00FC\u006B\u00F6\u0072\u0066\u00FA\u0072\u00F3\u0067\u00E9\u0070"); + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[1]", "val", u"Correct value (\u00E1\u0072\u0076\u00ED\u007A\u0074\u0075\u0072\u006F\u0020\u0074\u00FC\u006B\u00F6\u0072\u0066\u00FA\u0072\u00F3\u0067\u00E9\u0070)"); + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[2]", "name", "DocVar1"); + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[2]", "val", "DocVar1 Value"); + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[3]", "name", "DocVar3"); + assertXPath(pSettingsDoc, + "/w:settings/w:docVars/w:docVar[3]", "val", "DocVar3 Value"); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf139549) { loadAndSave("tdf139549.docx"); diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index 45dc67b9f43b..d24dae617c01 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -26,6 +26,8 @@ #include <rtl/ustring.hxx> #include <sfx2/zoomitem.hxx> +#include <com/sun/star/text/XDependentTextField.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertyState.hpp> @@ -95,6 +97,7 @@ struct SettingsTable_Impl bool m_bNoLeading = false; OUString m_sDecimalSymbol; OUString m_sListSeparator; + std::vector<std::pair<OUString, OUString>> m_aDocVars; uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps; @@ -136,7 +139,6 @@ struct SettingsTable_Impl , m_pThemeFontLangProps(3) , m_pCurrentCompatSetting(3) {} - }; SettingsTable::SettingsTable(const DomainMapper& rDomainMapper) @@ -187,6 +189,12 @@ void SettingsTable::lcl_attribute(Id nName, Value & val) case NS_ooxml::LN_CT_View_val: m_pImpl->m_nView = nIntValue; break; + case NS_ooxml::LN_CT_DocVar_name: + m_pImpl->m_aDocVars.back().first = sStringValue; + break; + case NS_ooxml::LN_CT_DocVar_val: + m_pImpl->m_aDocVars.back().second = sStringValue; + break; case NS_ooxml::LN_CT_CompatSetting_name: m_pImpl->m_pCurrentCompatSetting.getArray()[0] = comphelper::makePropertyValue("name", sStringValue); @@ -342,6 +350,25 @@ void SettingsTable::lcl_sprm(Sprm& rSprm) } } break; + case NS_ooxml::LN_CT_Settings_docVars: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties) + { + pProperties->resolve(*this); + } + } + break; + case NS_ooxml::LN_CT_DocVar: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties) + { + m_pImpl->m_aDocVars.push_back(std::make_pair(OUString(), OUString())); + pProperties->resolve(*this); + } + } + break; case NS_ooxml::LN_CT_Compat_noColumnBalance: m_pImpl->m_bNoColumnBalance = nIntValue; break; @@ -572,6 +599,35 @@ void SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& x } } + // Create or overwrite DocVars based on found in settings + if (m_pImpl->m_aDocVars.size()) + { + uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier(xDoc, uno::UNO_QUERY_THROW); + uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters(); + for (const auto& docVar : m_pImpl->m_aDocVars) + { + uno::Reference< beans::XPropertySet > xMaster; + OUString sFieldMasterService("com.sun.star.text.FieldMaster.User." + docVar.first); + + // Find or create Field Master + if (xFieldMasterAccess->hasByName(sFieldMasterService)) + { + xMaster.set(xFieldMasterAccess->getByName(sFieldMasterService), uno::UNO_QUERY_THROW); + } + else + { + xMaster.set(xTextFactory->createInstance("com.sun.star.text.FieldMaster.User"), uno::UNO_QUERY_THROW); + xMaster->setPropertyValue(getPropertyName(PROP_NAME), uno::Any(docVar.first)); + uno::Reference<text::XDependentTextField> xField( + xTextFactory->createInstance("com.sun.star.text.TextField.User"), + uno::UNO_QUERY); + xField->attachTextFieldMaster(xMaster); + } + + xMaster->setPropertyValue(getPropertyName(PROP_CONTENT), uno::Any(docVar.second)); + } + } + // Auto hyphenation: turns on hyphenation by default, <w:suppressAutoHyphens/> may still disable it at a paragraph level. // Situation is similar for RTF_WIDOWCTRL, which turns on widow / orphan control by default. if (!(m_pImpl->m_bAutoHyphenation || m_pImpl->m_bNoHyphenateCaps || m_pImpl->m_bWidowControl)) diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 158b764f355e..e33019b6db17 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -18808,6 +18808,9 @@ <attribute name="uri" tokenid="ooxml:CT_CompatSetting_uri"/> <attribute name="val" tokenid="ooxml:CT_CompatSetting_val"/> </resource> + <resource name="CT_DocVars" resource="Properties"> + <element name="docVar" tokenid="ooxml:CT_DocVar"/> + </resource> <resource name="CT_DocVar" resource="Properties"> <attribute name="name" tokenid="ooxml:CT_DocVar_name"/> <attribute name="val" tokenid="ooxml:CT_DocVar_val"/>