include/oox/ole/vbaproject.hxx                  |    4 +
 oox/source/core/filterdetect.cxx                |    9 --
 oox/source/ole/vbaproject.cxx                   |   14 ++++
 sw/source/filter/ww8/docxexport.cxx             |   61 ++++++-------------
 writerfilter/inc/ooxml/OOXMLDocument.hxx        |    3 
 writerfilter/source/filter/WriterFilter.cxx     |   11 ++-
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx |   74 ------------------------
 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx |    4 -
 writerfilter/source/ooxml/OOXMLStreamImpl.cxx   |   23 ++++++-
 writerfilter/source/ooxml/OOXMLStreamImpl.hxx   |    3 
 10 files changed, 69 insertions(+), 137 deletions(-)

New commits:
commit 0129c2cd9dd95355412b194c595f4b986403ba1e
Author: Miklos Vajna <[email protected]>
Date:   Wed Jun 7 14:49:38 2017 +0200

    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.
    
    Change-Id: I4085e4dba24475e6fd555e5f34fe7ad0f305c57d
    Reviewed-on: https://gerrit.libreoffice.org/38504
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins <[email protected]>

diff --git a/include/oox/ole/vbaproject.hxx b/include/oox/ole/vbaproject.hxx
index 3f0e2b0fccfc..4e6aacf24ad6 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 ed94ca5a5770..991b3d86a585 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -163,14 +163,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 e915ba78ea10..c38adc9c3777 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/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index f95aa0cb3a82..24a388ec1ab6 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1287,51 +1287,30 @@ void DocxExport::WriteVBA()
         m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), 
"http://schemas.microsoft.com/office/2006/relationships/vbaProject";, 
"vbaProject.bin");
     }
 
-    uno::Reference<beans::XPropertySet> 
xPropertySet(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
-    if (!xPropertySet.is())
+    OUString aDataName("_MS_VBA_Macros_XML");
+    if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
         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)
+    uno::Reference<io::XStream> 
xDataStream(xDocumentStorage->openStreamElement(aDataName, nOpenMode), 
uno::UNO_QUERY);
+    if (xDataStream.is())
     {
-        if (rProperty.Name == "OOXVBA")
-            rProperty.Value >>= aVBA;
-    }
-    if (!aVBA.hasElements())
-        return;
+        // Then the data stream, which wants to work with an already set
+        // xProjectStream.
+        std::unique_ptr<SvStream> 
pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
 
-    for (const auto& rProperty : aVBA)
-    {
-        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");
-        }
+        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");
     }
 }
 
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx 
b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 009aeba949cc..c7241f946311 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 };
+        FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, 
ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, 
FOOTER, HEADER, VBADATA };
     typedef std::shared_ptr<OOXMLStream> Pointer_t;
 
     virtual ~OOXMLStream() {}
@@ -229,7 +229,6 @@ 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 55c70e11eabc..df23ef38bb0c 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -236,9 +236,6 @@ 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));
@@ -257,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/OOXMLDocumentImpl.cxx 
b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index c6095737d6ba..3213d690dce8 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -39,7 +39,6 @@
 #include <svx/dialogs.hrc>
 #include <comphelper/sequence.hxx>
 #include <unotools/mediadescriptor.hxx>
-#include <comphelper/propertysequence.hxx>
 
 #include <iostream>
 #include "sfx2/objsh.hxx"
@@ -497,9 +496,6 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
 
         resolveActiveXStream(rStream);
 
-        if (!mbIsSubstream)
-            preserveVBA();
-
         resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
         resolveFastSubStream(rStream, OOXMLStream::STYLES);
         resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
@@ -811,71 +807,6 @@ 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(
-    {
-        {"DataStream", uno::makeAny(xDataStream)}
-    });
-}
-
 void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
 {
     // Resolving all ActiveX[n].xml files from ActiveX folder.
@@ -1015,11 +946,6 @@ 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 1922e225e168..e8bca30237ce 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -54,8 +54,6 @@ class OOXMLDocumentImpl : public OOXMLDocument
     css::uno::Reference<css::io::XInputStream> mxEmbeddings;
     css::uno::Sequence < css::beans::PropertyValue > mxEmbeddingsList;
     std::vector<css::beans::PropertyValue> aEmbeddings;
-    /// List of VBA-related streams.
-    css::uno::Sequence<css::beans::PropertyValue> maVBA;
     bool mbIsSubstream;
     bool mbSkipImages;
     /// How many paragraphs equal to 1 percent?
@@ -94,7 +92,6 @@ 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;
@@ -140,7 +137,6 @@ 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.cxx 
b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 9530654dcf3c..ddb89f17b528 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -172,6 +172,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;
@@ -182,6 +183,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;
@@ -416,8 +421,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;
 }
 
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx 
b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
index cb0276d84649..aff8189b7396 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
@@ -80,9 +80,6 @@ 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
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to