diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-06-02 18:41:38 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-06-02 21:31:01 +0200 |
commit | 8a59b30bb1af55f7afd8b98e4b60234f98d84c76 (patch) | |
tree | d71bcd1ecfc93ccd1720d41f74edd9150c58fc8e /sw/source/filter/ww8/docxexport.cxx | |
parent | ecad6d749726dbb8c945f67fca3856cbd2ff4851 (diff) |
Related: tdf#108269 DOCM filter: preserve VBA stream
This means 2 new streams when roundtripping DOCM files that actually
have macros: word/vbaProject.bin and word/vbaData.xml (+ the relation
pointing to the second from the first).
Change-Id: Iba24eea4c5bca8f743a53027c71ed2aae48f1934
Reviewed-on: https://gerrit.libreoffice.org/38360
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'sw/source/filter/ww8/docxexport.cxx')
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 57432c9add87..a57eb02915c8 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -77,6 +77,7 @@ #include <comphelper/string.hxx> #include <rtl/ustrbuf.hxx> #include <vcl/font.hxx> +#include <unotools/ucbstreamhelper.hxx> using namespace sax_fastparser; using namespace ::comphelper; @@ -464,6 +465,8 @@ void DocxExport::ExportDocument_Impl() WriteEmbeddings(); + WriteVBA(); + m_aLinkedTextboxesHelper.clear(); //final cleanup delete m_pStyles; m_pStyles = nullptr; @@ -1251,6 +1254,78 @@ void DocxExport::WriteActiveX() } } +void DocxExport::WriteVBA() +{ + uno::Reference<beans::XPropertySet> xPropertySet(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY); + if (!xPropertySet.is()) + return; + + uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo(); + if (!xPropertySetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG)) + return; + + uno::Sequence<beans::PropertyValue> aGrabBag; + xPropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag; + uno::Sequence<beans::PropertyValue> aVBA; + for (const auto& rProperty : aGrabBag) + { + if (rProperty.Name == "OOXVBA") + rProperty.Value >>= aVBA; + } + if (!aVBA.hasElements()) + return; + + uno::Reference<io::XOutputStream> xProjectStream; + for (const auto& rProperty : aVBA) + { + if (rProperty.Name == "ProjectStream") + { + // First check for the project stream, this sets xProjectStream. + uno::Reference<io::XStream> xInputStream; + rProperty.Value >>= xInputStream; + if (!xInputStream.is()) + return; + std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xInputStream)); + + xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject"); + uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY); + if (!xOutputStream.is()) + return; + std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream)); + + // Write the stream. + pOut->WriteStream(*pIn); + + // Write the relationship. + m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin"); + } + else if (rProperty.Name == "DataStream") + { + // Then the data stream, which wants to work with an already set + // xProjectStream. + uno::Reference<io::XStream> xInputStream; + rProperty.Value >>= xInputStream; + if (!xInputStream.is()) + return; + std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xInputStream)); + + uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY); + if (!xOutputStream.is()) + return; + std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream)); + + // Write the stream. + pOut->WriteStream(*pIn); + + // Write the relationship. + if (!xProjectStream.is()) + return; + + m_pFilter->addRelation(xProjectStream, "http://schemas.microsoft.com/office/2006/relationships/wordVbaData", "vbaData.xml"); + } + } +} + void DocxExport::WriteEmbeddings() { uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); |