[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - include/oox oox/source sw/qa sw/source writerfilter/inc writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Fri Jun 23 14:59:40 UTC 2017
include/oox/ole/vbaproject.hxx | 4 +
oox/source/core/filterdetect.cxx | 9 ---
oox/source/ole/vbaproject.cxx | 14 +++++
sw/qa/extras/ooxmlexport/data/tdf108269.docm |binary
sw/qa/extras/ooxmlexport/ooxmlexport9.cxx | 12 ++++
sw/source/filter/ww8/docxexport.cxx | 63 ++++++++++++++++++++++++++
sw/source/filter/ww8/docxexport.hxx | 3 +
writerfilter/inc/ooxml/OOXMLDocument.hxx | 2
writerfilter/source/filter/WriterFilter.cxx | 8 +++
writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 23 ++++++++-
10 files changed, 127 insertions(+), 11 deletions(-)
New commits:
commit 748ebf9573096d31a59cdbf5d1e65340d1d55cfa
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Fri Jun 2 18:41:38 2017 +0200
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 at libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos at 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 at collabora.co.uk>
Tested-by: Jenkins <ci at 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 at collabora.co.uk>
Tested-by: Jenkins <ci at 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 at collabora.com>
Tested-by: Andras Timar <andras.timar at collabora.com>
diff --git a/include/oox/ole/vbaproject.hxx b/include/oox/ole/vbaproject.hxx
index c29a8eaa2ce0..e48d19a87959 100644
--- a/include/oox/ole/vbaproject.hxx
+++ b/include/oox/ole/vbaproject.hxx
@@ -37,6 +37,7 @@ namespace com { namespace sun { namespace star {
namespace script { namespace vba { class XVBAMacroResolver; } }
namespace uno { class XComponentContext; }
namespace uno { class XInterface; }
+ namespace io { class XInputStream; }
} } }
namespace oox {
@@ -130,6 +131,9 @@ public:
bool importVbaProject(
StorageBase& rVbaPrjStrg );
+ /// Imports VBA data for a VBA project, e.g. word/vbaData.xml.
+ void importVbaData(const css::uno::Reference<css::io::XInputStream>& xInputStream);
+
/** Reads vba module related information from the project streams */
void readVbaModules( StorageBase& rVbaPrjStrg );
/** Imports (and creates) vba modules and user forms from the vba project records previously read.
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index 8812e0c30c25..88d3926a2656 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -172,14 +172,7 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType, const OUString& rFileName )
{
- bool bDocm = false;
- OUString aDocmExtension = ".docm";
- if (rFileName.getLength() >= aDocmExtension.getLength())
- {
- OUString aExtension = rFileName.copy(rFileName.getLength() - aDocmExtension.getLength());
- // The file name ends with .docm, ignoring case.
- bDocm = aExtension.equalsIgnoreAsciiCase(aDocmExtension);
- }
+ bool bDocm = rFileName.endsWithIgnoreAsciiCase(".docm");
if( rContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" && !bDocm )
return OUString( "writer_MS_Word_2007" );
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index b520d652f8d6..029d946892bd 100644
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -32,6 +32,7 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <comphelper/configurationhelper.hxx>
#include <comphelper/string.hxx>
+#include <comphelper/storagehelper.hxx>
#include <osl/diagnose.h>
#include <rtl/tencinfo.h>
#include <rtl/ustrbuf.h>
@@ -49,6 +50,7 @@
namespace oox {
namespace ole {
+using namespace ::com::sun::star;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
@@ -182,6 +184,18 @@ void VbaProject::importVbaProject( StorageBase& rVbaPrjStrg, const GraphicHelper
}
}
+void VbaProject::importVbaData(const uno::Reference<io::XInputStream>& xInputStream)
+{
+ uno::Reference<document::XStorageBasedDocument> xStorageBasedDoc(mxDocModel, uno::UNO_QUERY);
+ uno::Reference<embed::XStorage> xDocStorage(xStorageBasedDoc->getDocumentStorage(), uno::UNO_QUERY);
+ {
+ const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE;
+ uno::Reference<io::XOutputStream> xDocStream(xDocStorage->openStreamElement("_MS_VBA_Macros_XML", nOpenMode), uno::UNO_QUERY);
+ comphelper::OStorageHelper::CopyInputToOutput(xInputStream, xDocStream);
+ }
+ uno::Reference<embed::XTransactedObject>(xDocStorage, uno::UNO_QUERY)->commit();
+}
+
void VbaProject::registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher )
{
OSL_ENSURE( rxAttacher.get(), "VbaProject::registerMacroAttacher - unexpected empty reference" );
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
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf108269.docm 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();
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index af060387d9a7..1b33336c8996 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -75,7 +75,7 @@ class OOXMLStream
{
public:
enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, WEBSETTINGS, FONTTABLE, NUMBERING,
- FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER, SIGNATURE };
+ FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER, SIGNATURE, VBADATA };
typedef std::shared_ptr<OOXMLStream> Pointer_t;
virtual ~OOXMLStream() {}
diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx
index b50a8f49743f..4a1ce7762e3c 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -254,6 +254,14 @@ sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& aDesc
oox::GraphicHelper gHelper(m_xContext, xFrame, xVbaPrjStrg);
aVbaProject.importVbaProject(*xVbaPrjStrg, gHelper);
+
+ writerfilter::ooxml::OOXMLStream::Pointer_t pVBADataStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBADATA));
+ if (pVBADataStream)
+ {
+ uno::Reference<io::XInputStream> xDataStream = pVBADataStream->getDocumentStream();
+ if (xDataStream.is())
+ aVbaProject.importVbaData(xDataStream);
+ }
}
pStream.reset();
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 16d7ae31100b..fe26b58cbe93 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -173,6 +173,7 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc
static const char sHeaderTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/header";
static const char sOleObjectTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/oleObject";
static const char sVBAProjectType[] = "http://schemas.microsoft.com/office/2006/relationships/vbaProject";
+ static const char sVBADataType[] = "http://schemas.microsoft.com/office/2006/relationships/wordVbaData";
OUString sStreamType;
OUString sStreamTypeStrict;
@@ -183,6 +184,10 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc
sStreamType = sVBAProjectType;
sStreamTypeStrict = sVBAProjectType;
break;
+ case VBADATA:
+ sStreamType = sVBADataType;
+ sStreamTypeStrict = sVBADataType;
+ break;
case DOCUMENT:
sStreamType = sDocumentType;
sStreamTypeStrict = sDocumentTypeStrict;
@@ -420,8 +425,22 @@ OOXMLDocumentFactory::createStream
(const OOXMLStream::Pointer_t& pStream, OOXMLStream::StreamType_t nStreamType)
{
OOXMLStream::Pointer_t pRet;
- if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
- pRet.reset(new OOXMLStreamImpl(*pImpl, nStreamType));
+
+ if (nStreamType != OOXMLStream::VBADATA)
+ {
+ if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
+ pRet.reset(new OOXMLStreamImpl(*pImpl, nStreamType));
+ }
+ else
+ {
+ // VBADATA is not a relation of the document, but of the VBAPROJECT stream.
+ if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
+ {
+ std::unique_ptr<OOXMLStreamImpl> pProject(new OOXMLStreamImpl(*pImpl, OOXMLStream::VBAPROJECT));
+ pRet.reset(new OOXMLStreamImpl(*pProject, OOXMLStream::VBADATA));
+ }
+ }
+
return pRet;
}
More information about the Libreoffice-commits
mailing list