summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-06-02 18:41:38 +0200
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2017-06-07 04:49:22 +0200
commit35c3dfddf9933809525540d02484c2754510f6d9 (patch)
tree8201fe5d91bad88be3323c2924435395ed15c5fb /writerfilter
parent81451bb88855e575fc9a2f5c1e91254c15f07cb9 (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> (cherry picked from commit 8a59b30bb1af55f7afd8b98e4b60234f98d84c76) Reviewed-on: https://gerrit.libreoffice.org/38458 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/inc/ooxml/OOXMLDocument.hxx1
-rw-r--r--writerfilter/source/filter/WriterFilter.cxx3
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.cxx75
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.hxx4
-rw-r--r--writerfilter/source/ooxml/OOXMLStreamImpl.hxx3
5 files changed, 86 insertions, 0 deletions
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 27ecf84559b5..009aeba949cc 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -229,6 +229,7 @@ public:
virtual css::uno::Sequence<css::uno::Reference<css::xml::dom::XDocument> > getActiveXDomList( ) = 0;
virtual css::uno::Sequence<css::uno::Reference<css::io::XInputStream> > getActiveXBinList() = 0;
virtual css::uno::Sequence<css::beans::PropertyValue > getEmbeddingsList() = 0;
+ virtual css::uno::Sequence<css::beans::PropertyValue > getVBA() = 0;
};
diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx
index ff2586c7d3a3..55c70e11eabc 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -236,6 +236,9 @@ sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& aDesc
// Adding the saved embedding document to document's grab bag
aGrabBagProperties["OOXEmbeddings"] <<= pDocument->getEmbeddingsList();
+ if (pDocument->getVBA().hasElements())
+ aGrabBagProperties["OOXVBA"] <<= pDocument->getVBA();
+
putPropertiesToDocumentGrabBag(aGrabBagProperties);
writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT));
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index 089c0e2a8f26..550820be018e 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -39,6 +39,7 @@
#include <svx/dialogs.hrc>
#include <comphelper/sequence.hxx>
#include <unotools/mediadescriptor.hxx>
+#include <comphelper/propertysequence.hxx>
#include <iostream>
#include "sfx2/objsh.hxx"
@@ -496,6 +497,9 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
resolveActiveXStream(rStream);
+ if (!mbIsSubstream)
+ preserveVBA();
+
resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
resolveFastSubStream(rStream, OOXMLStream::STYLES);
resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
@@ -808,6 +812,72 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pS
mxEmbeddingsList = comphelper::containerToSequence(aEmbeddings);
}
+namespace
+{
+/// Returns the target string for rType in xRelationshipAccess.
+OUString getTypeTarget(const uno::Reference<embed::XRelationshipAccess>& xRelationshipAccess, const OUString& rType)
+{
+ uno::Sequence< uno::Sequence<beans::StringPair> > aRelations = xRelationshipAccess->getAllRelationships();
+ for (const auto& rRelation : aRelations)
+ {
+ OUString aType;
+ OUString aTarget;
+ for (const auto& rPair : rRelation)
+ {
+ if (rPair.First == "Type")
+ aType = rPair.Second;
+ else if (rPair.First == "Target")
+ aTarget = rPair.Second;
+ }
+
+ if (aType == rType)
+ return aTarget;
+ }
+
+ return OUString();
+}
+}
+
+void OOXMLDocumentImpl::preserveVBA()
+{
+ auto pOOXMLStream = dynamic_cast<OOXMLStreamImpl*>(mpStream.get());
+ if (!pOOXMLStream)
+ return;
+
+ uno::Reference<embed::XRelationshipAccess> xRelationshipAccess(pOOXMLStream->accessDocumentStream(), uno::UNO_QUERY);
+ if (!xRelationshipAccess.is())
+ return;
+
+ OUString aVBAStreamName = getTypeTarget(xRelationshipAccess, "http://schemas.microsoft.com/office/2006/relationships/vbaProject");
+ if (aVBAStreamName.isEmpty())
+ return;
+
+ uno::Reference<embed::XHierarchicalStorageAccess> xStorage(pOOXMLStream->getStorage(), uno::UNO_QUERY);
+ if (!xStorage.is())
+ return;
+
+ OUString aPath = pOOXMLStream->getPath();
+ uno::Reference<io::XStream> xStream(xStorage->openStreamElementByHierarchicalName(aPath + aVBAStreamName, embed::ElementModes::SEEKABLEREAD), uno::UNO_QUERY);
+ if (!xStream.is())
+ return;
+
+ xRelationshipAccess.set(xStream, uno::UNO_QUERY);
+ uno::Reference<io::XStream> xDataStream;
+ if (xRelationshipAccess.is())
+ {
+ // Check if there is a vbaData.xml for the vbaProject.bin.
+ OUString aVBAData = getTypeTarget(xRelationshipAccess, "http://schemas.microsoft.com/office/2006/relationships/wordVbaData");
+ if (!aVBAData.isEmpty())
+ xDataStream.set(xStorage->openStreamElementByHierarchicalName(aPath + aVBAData, embed::ElementModes::SEEKABLEREAD), uno::UNO_QUERY);
+ }
+
+ maVBA = comphelper::InitPropertySequence(
+ {
+ {"ProjectStream", uno::makeAny(xStream)},
+ {"DataStream", uno::makeAny(xDataStream)}
+ });
+}
+
void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
{
// Resolving all ActiveX[n].xml files from ActiveX folder.
@@ -947,6 +1017,11 @@ uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( )
return mxEmbeddingsList;
}
+uno::Sequence<beans::PropertyValue> OOXMLDocumentImpl::getVBA()
+{
+ return maVBA;
+}
+
OOXMLDocument *
OOXMLDocumentFactory::createDocument
(const OOXMLStream::Pointer_t& pStream,
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index 43bdeb651d78..c4245cae7b02 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -53,6 +53,8 @@ class OOXMLDocumentImpl : public OOXMLDocument
css::uno::Reference<css::io::XInputStream> mxActiveXBin;
css::uno::Reference<css::io::XInputStream> mxEmbeddings;
css::uno::Sequence < css::beans::PropertyValue > mxEmbeddingsList;
+ /// List of VBA-related streams.
+ css::uno::Sequence<css::beans::PropertyValue> maVBA;
bool mbIsSubstream;
bool mbSkipImages;
/// How many paragraphs equal to 1 percent?
@@ -91,6 +93,7 @@ protected:
void resolveActiveXStream(Stream & rStream);
void resolveGlossaryStream(Stream & rStream);
void resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pStream);
+ void preserveVBA();
public:
OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, const css::uno::Reference<css::task::XStatusIndicator>& xStatusIndicator, bool bSkipImages, const css::uno::Sequence<css::beans::PropertyValue>& rDescriptor);
virtual ~OOXMLDocumentImpl() override;
@@ -136,6 +139,7 @@ public:
virtual css::uno::Reference<css::xml::dom::XDocument> getGlossaryDocDom() override;
virtual css::uno::Sequence<css::uno::Sequence< css::uno::Any> > getGlossaryDomList() override;
virtual css::uno::Sequence<css::beans::PropertyValue > getEmbeddingsList() override;
+ virtual css::uno::Sequence<css::beans::PropertyValue> getVBA() override;
void incrementProgress();
bool IsSkipImages() { return mbSkipImages; };
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
index aff8189b7396..cb0276d84649 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
@@ -80,6 +80,9 @@ public:
// Giving access to mxDocumentStream. It is needed by resolving custom xml to get list of customxml's used in document.
const css::uno::Reference<css::io::XStream>& accessDocumentStream() { return mxDocumentStream;}
+
+ const css::uno::Reference<css::embed::XStorage>& getStorage() { return mxStorage; }
+ const OUString& getPath() { return msPath; }
};
}}
#endif // INCLUDED_WRITERFILTER_SOURCE_OOXML_OOXMLSTREAMIMPL_HXX