diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-01-30 17:56:53 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-01-30 22:20:43 +0100 |
commit | ae5f469d3893de73850ccc369dbf426a4acd8f15 (patch) | |
tree | 86582ebf1cc827cfc9ed32fcd880021dc89bb933 | |
parent | 27740793367369c043721697955666be3a1ccda9 (diff) |
DOCX export: write document variables
This means that in case a user field is exported to DOCX and the user
updates the field, the result will be still correct, not empty.
Change-Id: I2b52292c70aa6f597f92af95e16c773839247efa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87748
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport14.cxx | 7 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 55 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.hxx | 3 |
3 files changed, 65 insertions, 0 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx index b79850140144..b8069d9f84df 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx @@ -301,6 +301,7 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField) utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text"); xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + validate(maTempFile.GetFileName(), test::OOXML); mbExported = true; xmlDocPtr pXmlDoc = parseExport("word/document.xml"); CPPUNIT_ASSERT(pXmlDoc); @@ -309,6 +310,12 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField) // exported as <w:t>User Field foo = bar</w:t>. assertXPathContent(pXmlDoc, "//w:p/w:r[2]/w:instrText", " DOCVARIABLE foo "); assertXPathContent(pXmlDoc, "//w:p/w:r[4]/w:t", "bar"); + + // Make sure that not only the variables, but also their values are written. + pXmlDoc = parseExport("word/settings.xml"); + CPPUNIT_ASSERT(pXmlDoc); + assertXPath(pXmlDoc, "//w:docVars/w:docVar", "name", "foo"); + assertXPath(pXmlDoc, "//w:docVars/w:docVar", "val", "bar"); } DECLARE_OOXMLEXPORT_TEST(testTdf124367, "tdf124367.docx") diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 526d100768c8..992a97d69103 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/xml/sax/Writer.hpp> #include <com/sun/star/awt/XControlModel.hpp> #include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <oox/token/namespaces.hxx> #include <oox/token/tokens.hxx> @@ -887,6 +888,58 @@ void DocxExport::WriteProperties( ) m_pFilter->exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly ); } +void DocxExport::WriteDocVars(const sax_fastparser::FSHelperPtr& pFS) +{ + SwDocShell* pDocShell = m_pDoc->GetDocShell(); + if (!pDocShell) + { + return; + } + + uno::Reference<text::XTextFieldsSupplier> xModel(pDocShell->GetModel(), uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xTextFieldMasters = xModel->getTextFieldMasters(); + uno::Sequence<rtl::OUString> aMasterNames = xTextFieldMasters->getElementNames(); + if (!aMasterNames.hasElements()) + { + return; + } + + // Only write docVars if there will be at least a single docVar. + bool bStarted = false; + const OUStringLiteral aPrefix("com.sun.star.text.fieldmaster.User."); + for (const auto& rMasterName : std::as_const(aMasterNames)) + { + if (!rMasterName.startsWith(aPrefix)) + { + // Not a user field. + continue; + } + + uno::Reference<beans::XPropertySet> xField; + xTextFieldMasters->getByName(rMasterName) >>= xField; + if (!xField.is()) + { + continue; + } + + OUString aKey = rMasterName.copy(aPrefix.getLength()); + OUString aValue; + xField->getPropertyValue("Content") >>= aValue; + if (!bStarted) + { + bStarted = true; + pFS->startElementNS(XML_w, XML_docVars); + } + pFS->singleElementNS(XML_w, XML_docVar, FSNS(XML_w, XML_name), aKey.toUtf8(), + FSNS(XML_w, XML_val), aValue.toUtf8()); + } + + if (bStarted) + { + pFS->endElementNS(XML_w, XML_docVars); + } +} + void DocxExport::WriteSettings() { SwViewShell *pViewShell(m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()); @@ -1151,6 +1204,8 @@ void DocxExport::WriteSettings() } } + WriteDocVars(pFS); + // Protect form // Section-specific write protection if (! hasProtectionProperties) diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index 00b908dc7efa..f659cd1244f4 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -245,6 +245,9 @@ private: /// Write word/settings.xml void WriteSettings(); + /// Writes the <w:docVars> part of settings.xml + void WriteDocVars(const sax_fastparser::FSHelperPtr& pFS); + /// Write word/theme/theme1.xml void WriteTheme(); |