diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-06-02 18:41:38 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-06-23 16:59:20 +0200 |
commit | 748ebf9573096d31a59cdbf5d1e65340d1d55cfa (patch) | |
tree | 0d71abae026686dc4fd9160a0b17244e98394eb4 /sw | |
parent | de2d6e773212c983dc190d1d29d005de87df6ffd (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.docm | bin | 0 -> 20187 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport9.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 63 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.hxx | 3 |
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 Binary files differnew file mode 100644 index 000000000000..44e943531d30 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf108269.docm 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(); |