summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-06-02 18:41:38 +0200
committerAndras Timar <andras.timar@collabora.com>2017-06-23 16:59:20 +0200
commit748ebf9573096d31a59cdbf5d1e65340d1d55cfa (patch)
tree0d71abae026686dc4fd9160a0b17244e98394eb4 /sw
parentde2d6e773212c983dc190d1d29d005de87df6ffd (diff)
Related: tdf#108269 DOCM filter: preserve VBA stream
This is a combination of 3 commits (initial support, then two refactor commits to not duplicate code.) 1st commit: 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). Reviewed-on: https://gerrit.libreoffice.org/38360 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit 8a59b30bb1af55f7afd8b98e4b60234f98d84c76) Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport9.cxx Change-Id: Iba24eea4c5bca8f743a53027c71ed2aae48f1934 2nd commit: Related: tdf#108269 DOCM filter: reuse oox code for VBA preservation With this, the project stream import is shared between DOCM and XLSM. Change-Id: I8fbffefc5acf28adea4875fa6bc4148a99b5ebef Reviewed-on: https://gerrit.libreoffice.org/38495 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit e4adb8d9e77bab353dda26375e11a6b7a456368f) 3rd commit: Related: tdf#108269 DOCM filter: reuse oox code for VBA data preservation Which means the DOCM-specific code to roundtrip VBA things (project, data) can be removed. The oox part has to be extended a bit, as at least for this DOCM bugdoc there is an XML relation of the binary data, while existing shared code assumed the full VBA project is just a single OLE blob. Reviewed-on: https://gerrit.libreoffice.org/38504 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 0129c2cd9dd95355412b194c595f4b986403ba1e) Conflicts: writerfilter/inc/ooxml/OOXMLDocument.hxx writerfilter/source/ooxml/OOXMLDocumentImpl.hxx Change-Id: I4085e4dba24475e6fd555e5f34fe7ad0f305c57d Reviewed-on: https://gerrit.libreoffice.org/38558 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf108269.docmbin0 -> 20187 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport9.cxx12
-rw-r--r--sw/source/filter/ww8/docxexport.cxx63
-rw-r--r--sw/source/filter/ww8/docxexport.hxx3
4 files changed, 78 insertions, 0 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf108269.docm b/sw/qa/extras/ooxmlexport/data/tdf108269.docm
new file mode 100644
index 000000000000..44e943531d30
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf108269.docm
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index ba0e5a207d21..aa73ed26ddad 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -90,6 +90,18 @@ DECLARE_SW_ROUNDTRIP_TEST(testBadDocm, "bad.docm", nullptr, DocmTest)
CPPUNIT_ASSERT_EQUAL(OUString("MS Word 2007 XML VBA"), pTextDoc->GetDocShell()->GetMedium()->GetFilter()->GetName());
}
+DECLARE_SW_ROUNDTRIP_TEST(testTdf108269, "tdf108269.docm", nullptr, DocmTest)
+{
+ if (!mbExported)
+ return;
+
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
+ // This failed: VBA streams were not roundtripped via the doc-level
+ // grab-bag.
+ CPPUNIT_ASSERT(xNameAccess->hasByName("word/vbaProject.bin"));
+ CPPUNIT_ASSERT(xNameAccess->hasByName("word/vbaData.xml"));
+}
+
DECLARE_OOXMLEXPORT_TEST(testTdf95031, "tdf95031.docx")
{
// This was 494, in-numbering paragraph's automating spacing was handled as visible spacing, while it should not.
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index b7cda742afb9..48b6e300ff92 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/frame/XModel.hpp>
@@ -75,6 +76,7 @@
#include <comphelper/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <vcl/font.hxx>
+#include <unotools/ucbstreamhelper.hxx>
using namespace sax_fastparser;
using namespace ::comphelper;
@@ -462,6 +464,8 @@ void DocxExport::ExportDocument_Impl()
WriteEmbeddings();
+ WriteVBA();
+
m_aLinkedTextboxesHelper.clear(); //final cleanup
delete m_pStyles;
m_pStyles = nullptr;
@@ -1247,6 +1251,65 @@ void DocxExport::WriteActiveX()
}
}
+void DocxExport::WriteVBA()
+{
+ uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+ if (!xStorageBasedDocument.is())
+ return;
+
+ uno::Reference<embed::XStorage> xDocumentStorage(xStorageBasedDocument->getDocumentStorage(), uno::UNO_QUERY);
+ OUString aMacrosName("_MS_VBA_Macros");
+ if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
+ return;
+
+ const sal_Int32 nOpenMode = embed::ElementModes::READ;
+ uno::Reference<io::XStream> xMacrosStream(xDocumentStorage->openStreamElement(aMacrosName, nOpenMode), uno::UNO_QUERY);
+ uno::Reference<io::XOutputStream> xProjectStream;
+ if (xMacrosStream.is())
+ {
+ // First handle the the project stream, this sets xProjectStream.
+ std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xMacrosStream));
+
+ 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");
+ }
+
+ OUString aDataName("_MS_VBA_Macros_XML");
+ if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
+ return;
+
+ uno::Reference<io::XStream> xDataStream(xDocumentStorage->openStreamElement(aDataName, nOpenMode), uno::UNO_QUERY);
+ if (xDataStream.is())
+ {
+ // Then the data stream, which wants to work with an already set
+ // xProjectStream.
+ std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
+
+ 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 );
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 65c9f9283730..3623c5718eeb 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -244,6 +244,9 @@ private:
/// Write word/embeddings/Worksheet[n].xlsx
void WriteEmbeddings();
+ /// Writes word/vbaProject.bin.
+ void WriteVBA();
+
/// return true if Page Layout is set as Mirrored
bool isMirroredMargin();