summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-01-30 17:56:53 +0100
committerMiklos Vajna <vmiklos@collabora.com>2020-01-30 22:20:43 +0100
commitae5f469d3893de73850ccc369dbf426a4acd8f15 (patch)
tree86582ebf1cc827cfc9ed32fcd880021dc89bb933
parent27740793367369c043721697955666be3a1ccda9 (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.cxx7
-rw-r--r--sw/source/filter/ww8/docxexport.cxx55
-rw-r--r--sw/source/filter/ww8/docxexport.hxx3
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();