[Libreoffice-commits] core.git: sw/qa sw/source writerfilter/inc writerfilter/source

sushil_shinde sushil.shinde at synerzip.com
Thu Nov 14 08:50:29 PST 2013


 sw/qa/extras/ooxmlexport/data/activex.docx      |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx        |   28 ++++++++++++
 sw/source/filter/ww8/docxexport.cxx             |   44 ++++++++++++++++++
 sw/source/filter/ww8/docxexport.hxx             |    3 +
 writerfilter/inc/ooxml/OOXMLDocument.hxx        |    3 -
 writerfilter/source/filter/ImportFilter.cxx     |   30 ++++++++++++
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx |   56 ++++++++++++++++++++++++
 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx |    3 +
 writerfilter/source/ooxml/OOXMLStreamImpl.cxx   |    6 ++
 9 files changed, 171 insertions(+), 2 deletions(-)

New commits:
commit f4714220903cbd657fbb4d103fb5293f5b8f7cf8
Author: sushil_shinde <sushil.shinde at synerzip.com>
Date:   Tue Nov 12 20:29:00 2013 +0530

    [docx] activeX files saved in InteropGrabBag and exported.
    
      The XDocuments representing the DOM of an OOXML's activex document
      is stored as the PropertyValue "OOXActiveX" into the "InteropGraBag".
    
      Added mxActiveXDomList object which holds xDocument for each
      activeX.xml from activeX folder.
    
      This changeset stores only activeX[n].xml files.
      Relationship files (example activeX.bin) from activex are not stored
      yet. (Working on it.)
    
    Reviewed on:
    	https://gerrit.libreoffice.org/6654
    
    Change-Id: I658e361211e1446ed095a73b0422da0c4f74df1c

diff --git a/sw/qa/extras/ooxmlexport/data/activex.docx b/sw/qa/extras/ooxmlexport/data/activex.docx
new file mode 100644
index 0000000..e7c15e8
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/activex.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index b622cb2..ce9a0a9 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -1587,6 +1587,34 @@ DECLARE_OOXML_TEST(testCustomXmlGrabBag, "customxml.docx")
    CPPUNIT_ASSERT(CustomXml); // Grab Bag has all the expected elements
 }
 
+DECLARE_OOXML_TEST(testActiveXGrabBag, "activex.docx")
+{
+   // The problem was that activeX.xml files were missing from docx file after saving file.
+   // This test case tests whether activex files grabbagged properly in correct object.
+
+   uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+   uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
+   uno::Sequence<beans::PropertyValue> aGrabBag(0);
+   xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag;
+   CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
+   bool bActiveX = sal_False;
+   for(int i = 0; i < aGrabBag.getLength(); ++i)
+   {
+       if (aGrabBag[i].Name == "OOXActiveX")
+       {
+           bActiveX = sal_True;
+           uno::Reference<xml::dom::XDocument> aActiveXDom;
+           uno::Sequence<uno::Reference<xml::dom::XDocument> > aActiveXDomList;
+           CPPUNIT_ASSERT(aGrabBag[i].Value >>= aActiveXDomList); // PropertyValue of proper type
+           sal_Int32 length = aActiveXDomList.getLength();
+           CPPUNIT_ASSERT_EQUAL(sal_Int32(5), length);
+           aActiveXDom = aActiveXDomList[0];
+           CPPUNIT_ASSERT(aActiveXDom.get()); // Reference not empty
+       }
+   }
+   CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements
+}
+
 DECLARE_OOXML_TEST(testFdo69644, "fdo69644.docx")
 {
     // The problem was that the exporter exported the table definition
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 2df1a60..9053d6b 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -353,6 +353,8 @@ void DocxExport::ExportDocument_Impl()
 
     WriteCustomXml();
 
+    WriteActiveX();
+
     delete pStyles, pStyles = NULL;
     delete m_pSections, m_pSections = NULL;
 }
@@ -855,6 +857,48 @@ void DocxExport::WriteCustomXml()
     }
 }
 
+void DocxExport::WriteActiveX()
+{
+    uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
+
+    uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
+    OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
+    if ( !xPropSetInfo->hasPropertyByName( pName ) )
+        return;
+
+    uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist;
+    uno::Sequence< beans::PropertyValue > propList;
+    xPropSet->getPropertyValue( pName ) >>= propList;
+    for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
+    {
+        OUString propName = propList[nProp].Name;
+        if ( propName == "OOXActiveX" )
+        {
+             propList[nProp].Value >>= activeXDomlist;
+             break;
+        }
+    }
+
+    for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++)
+    {
+        uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j];
+
+        if ( activeXDom.is() )
+        {
+            m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+                    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control",
+                    "activeX/activeX"+OUString::number((j+1))+".xml" );
+
+            uno::Reference< xml::sax::XSAXSerializable > serializer( activeXDom, uno::UNO_QUERY );
+            uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
+            writer->setOutputStream( GetFilter().openFragmentStream( "word/activeX/activeX"+OUString::number((j+1))+".xml",
+                "application/vnd.ms-office.activeX+xml" ) );
+            serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
+                uno::Sequence< beans::StringPair >() );
+         }
+     }
+}
+
 VMLExport& DocxExport::VMLExporter()
 {
     return *m_pVMLExport;
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 8c2f958..3815459 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -210,6 +210,9 @@ private:
     /// Write customXml/item[n].xml and customXml/itemProps[n].xml
     void WriteCustomXml();
 
+    /// Write word/activeX/activeX[n].xml
+    void WriteActiveX();
+
     /// All xml namespaces to be used at the top of any text .xml file (main doc, headers, footers,...)
     sax_fastparser::XFastAttributeListRef MainXmlNamespaces( sax_fastparser::FSHelperPtr serializer );
 
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 91d9adc..e75cf62 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -76,7 +76,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream
 {
 public:
     enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING,
-        FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, SETTINGS, VBAPROJECT };
+        FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, SETTINGS, VBAPROJECT };
     typedef boost::shared_ptr<OOXMLStream> Pointer_t;
 
     virtual ~OOXMLStream() {}
@@ -244,6 +244,7 @@ public:
     virtual void setThemeDom( uno::Reference<xml::dom::XDocument> xThemeDom ) = 0;
     virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0;
     virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0;
+    virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList( ) = 0;
 };
 
 
diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx
index b7bcfb9..f29e7ec 100644
--- a/writerfilter/source/filter/ImportFilter.cxx
+++ b/writerfilter/source/filter/ImportFilter.cxx
@@ -187,6 +187,36 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes
             SAL_WARN("writerfilter","Failed to save custom xml dom to documents grab bag");
         }
 
+        // Adding the saved ActiveX DOM to the document's grab bag
+        try
+        {
+            uno::Reference<beans::XPropertySet> xDocProps(m_xDstDoc, uno::UNO_QUERY);
+            if (xDocProps.is())
+            {
+                uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
+
+                const OUString aGrabBagPropName = "InteropGrabBag";
+                if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) )
+                {
+                    uno::Sequence<beans::PropertyValue> aGrabBag;
+
+                    // We want to keep the previous items
+                    xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
+                    sal_Int32 length = aGrabBag.getLength();
+                    aGrabBag.realloc(length+1);
+
+                    beans::PropertyValue* pValue = aGrabBag.getArray();
+                    pValue[length].Name = "OOXActiveX";
+                    pValue[length].Value = uno::makeAny( pDocument->getActiveXDomList() );
+                    xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) );
+                 }
+             }
+         }
+         catch(const uno::Exception&)
+         {
+             SAL_WARN("writerfilter","Failed to save ActiveX dom to documents grab bag");
+         }
+
         writerfilter::ooxml::OOXMLStream::Pointer_t  pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT ));
         oox::StorageRef xVbaPrjStrg( new ::oox::ole::OleStorage( m_xContext, pVBAProjectStream->getDocumentStream(), false ) );
         if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index c29ac5d..d71c339 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -431,6 +431,8 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
         // Custom xml's are handled as part of grab bag.
         resolveCustomXmlStream(rStream);
 
+        resolveActiveXStream(rStream);
+
         resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
         resolveFastSubStream(rStream, OOXMLStream::STYLES);
         resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
@@ -511,6 +513,55 @@ void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream)
     }
 }
 
+void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
+{
+    // Resolving all ActiveX[n].xml files from ActiveX folder.
+    uno::Reference<embed::XRelationshipAccess> mxRelationshipAccess;
+    mxRelationshipAccess.set((*dynamic_cast<OOXMLStreamImpl *>(mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
+    if (mxRelationshipAccess.is())
+    {
+        OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control");
+        OUString sTarget("Target");
+        bool bFound = false;
+        sal_Int32 counter = 0;
+        uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
+                mxRelationshipAccess->getAllRelationships();
+        uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomListTemp(aSeqs.getLength());
+        for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
+        {
+            uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
+            for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
+            {
+                beans::StringPair aPair = aSeq[i];
+                // Need to resolve only ActiveX files from document relationships.
+                // Skipping other files.
+                if (aPair.Second.compareTo(sCustomType) == 0)
+                    bFound = true;
+                else if(aPair.First.compareTo(sTarget) == 0 && bFound)
+                {
+                    // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
+                    // to ensure ActiveX.xml target is visited in lcl_getTarget.
+                    customTarget = aPair.Second;
+                }
+            }
+            if(bFound)
+            {
+                uno::Reference<xml::dom::XDocument> activeXTemp = importSubStream(OOXMLStream::ACTIVEX);
+                // This will add all ActiveX[n].xml to grabbag list.
+                if(activeXTemp.is())
+                {
+                    mxActiveXDomListTemp[counter] = activeXTemp;
+                    counter++;
+                    resolveFastSubStream(rStream, OOXMLStream::ACTIVEX);
+                }
+                bFound = false;
+            }
+        }
+        mxActiveXDomListTemp.realloc(counter);
+        mxActiveXDomList = mxActiveXDomListTemp;
+    }
+}
+
 uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStreamForId(const OUString & rId)
 {
     OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId));
@@ -583,6 +634,11 @@ uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustom
     return mxCustomXmlDomPropsList;
 }
 
+uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getActiveXDomList( )
+{
+    return mxActiveXDomList;
+}
+
 OOXMLDocument *
 OOXMLDocumentFactory::createDocument
 (OOXMLStream::Pointer_t pStream)
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index 0751133..74c1006 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -45,6 +45,7 @@ class OOXMLDocumentImpl : public OOXMLDocument
     uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomList;
     uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsList;
     uno::Reference<xml::dom::XDocument> mxCustomXmlProsDom;
+    uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomList;
     bool mbIsSubstream;
 
 protected:
@@ -69,6 +70,7 @@ protected:
 
     void setIsSubstream( bool bSubstream ) { mbIsSubstream = bSubstream; };
     void resolveCustomXmlStream(Stream & rStream);
+    void resolveActiveXStream(Stream & rStream);
 
 public:
     OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream);
@@ -117,6 +119,7 @@ public:
     virtual uno::Reference<xml::dom::XDocument> getThemeDom();
     virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList();
     virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList();
+    virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList();
 };
 }}
 #endif // OOXML_DOCUMENT_IMPL_HXX
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 333df28..8b658c5 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -112,6 +112,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
     static OUString sThemeType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme");
     static OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml");
     static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps");
+    static OUString sActiveXType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control");
     static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings");
     static OUString sTarget("Target");
     static OUString sTargetMode("TargetMode");
@@ -155,6 +156,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
         case CUSTOMXMLPROPS:
             sStreamType = sCustomPropsType;
             break;
+        case ACTIVEX:
+            sStreamType = sActiveXType;
+            break;
         case SETTINGS:
             sStreamType = sSettingsType;
             break;
@@ -186,7 +190,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
                 else if (aPair.First.compareTo(sTarget) == 0)
                 {
                     // checking item[n].xml is not visited already.
-                    if(customTarget != aPair.Second && sStreamType == sCustomType)
+                    if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType))
                     {
                         bFound = false;
                     }


More information about the Libreoffice-commits mailing list