[Libreoffice-commits] core.git: include/oox oox/source sw/qa sw/source

Vinaya Mandke vinaya.mandke at synerzip.com
Wed Mar 5 01:14:11 PST 2014


 include/oox/drawingml/shape.hxx             |    3 
 oox/source/drawingml/diagram/diagram.cxx    |   15 ++++
 oox/source/drawingml/diagram/diagram.hxx    |    4 -
 oox/source/drawingml/shape.cxx              |   40 +++++++++++
 oox/source/shape/ShapeContextHandler.cxx    |   11 ++-
 sw/qa/extras/ooxmlexport/data/fdo74792.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx    |   24 ++++++
 sw/source/filter/ww8/docxsdrexport.cxx      |  101 ++++++++++++++++++++++++++--
 sw/source/filter/ww8/docxsdrexport.hxx      |    5 +
 9 files changed, 193 insertions(+), 10 deletions(-)

New commits:
commit 6536826f2f4c747582d60ed40b0418c6a67a9829
Author: Vinaya Mandke <vinaya.mandke at synerzip.com>
Date:   Tue Feb 25 13:13:11 2014 +0530

    fdo#74792 [DOCX] Grab-bag rels and images for SmartArt
    
    Added support to grab-bag rels and associated Images for
    data[i].xml, and drawing[i].xml.
    Added UT for the same
    
    Conflicts:
    	sw/qa/extras/ooxmlexport/ooxmlexport.cxx
    Reviewed on:
    	https://gerrit.libreoffice.org/8362
    
    Change-Id: I545825f67214f14037ab72b77764a07d575b8b5b

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index fa3f58c..7f3ba65 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -178,7 +178,8 @@ public:
     const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> &
                         getDiagramDoms() { return maDiagramDoms; }
     void                setDiagramDoms(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rDiagramDoms) { maDiagramDoms = rDiagramDoms; }
-
+    com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< com::sun::star::uno::Any > >resolveRelationshipsOfType(
+                                                                          core::XmlFilterBase& rFilter, OUString sFragment, OUString sType );
 protected:
 
     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index da439ea..4672a28 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -338,6 +338,9 @@ uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
 {
     sal_Int32 length = maMainDomMap.size();
 
+    if ( 0 < maDataRelsMap.getLength() )
+        ++length;
+
     uno::Sequence<beans::PropertyValue> aValue(length);
     beans::PropertyValue* pValue = aValue.getArray();
     for (DiagramDomMap::const_iterator i = maMainDomMap.begin();
@@ -349,6 +352,13 @@ uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
         ++pValue;
     }
 
+    if ( 0 < maDataRelsMap.getLength() )
+    {
+        pValue[0].Name = OUString("OOXDiagramDataRels");
+        pValue[0].Value = uno::makeAny ( maDataRelsMap );
+        ++pValue;
+    }
+
     return aValue;
 }
 
@@ -410,6 +420,11 @@ void loadDiagram( ShapePtr& pShape,
                        "OOXData",
                        pDiagram,
                        xRefDataModel);
+
+        pDiagram->getDataRelsMap() = pShape->resolveRelationshipsOfType( rFilter, xRefDataModel->getFragmentPath(),
+                                                           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" );
+
+
         // Pass the info to pShape
         for( ::std::vector<OUString>::const_iterator aIt = pData->getExtDrawings().begin(), aEnd = pData->getExtDrawings().end();
                 aIt != aEnd; ++aIt )
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index 031c66b..ae611c9 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -157,6 +157,7 @@ typedef boost::shared_ptr< LayoutNode > LayoutNodePtr;
 
 
 typedef std::map< OUString, uno::Reference<xml::dom::XDocument> > DiagramDomMap;
+typedef uno::Sequence< uno::Sequence< uno::Any > > DiagramRelsMap;
 
 
 
@@ -296,7 +297,7 @@ public:
     DiagramColorMap& getColors() { return maColors; }
     const DiagramColorMap& getColors() const { return maColors; }
     DiagramDomMap & getDomMap() { return maMainDomMap; }
-
+    DiagramRelsMap & getDataRelsMap() { return maDataRelsMap; }
     void addTo( const ShapePtr & pShape );
 
     uno::Sequence<beans::PropertyValue> getDomsAsPropertyValues() const;
@@ -308,6 +309,7 @@ private:
     DiagramColorMap                maColors;
     std::map< OUString, ShapePtr > maShapeMap;
     DiagramDomMap                  maMainDomMap;
+    DiagramRelsMap                 maDataRelsMap;
 };
 
 
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index ce1d3b6..3a2ebae 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1200,6 +1200,46 @@ void Shape::putPropertiesToGrabBag( const Sequence< PropertyValue >& aProperties
     }
 }
 
+uno::Sequence< uno::Sequence< uno::Any > >  Shape::resolveRelationshipsOfType(core::XmlFilterBase& rFilter, OUString sFragment, OUString sType )
+{
+    uno::Sequence< uno::Sequence< uno::Any > > xRelListTemp;
+    sal_Int32 counter = 0;
+
+    core::RelationsRef xRels = rFilter.importRelations( sFragment );
+    if ( xRels )
+    {
+        core::RelationsRef xImageRels = xRels->getRelationsFromType( sType );
+        if ( xImageRels )
+        {
+            xRelListTemp.realloc( xImageRels->size() );
+            for( ::std::map< OUString, core::Relation >::const_iterator aIt = xImageRels->begin(), aEnd = xImageRels->end(); aIt != aEnd; ++aIt )
+            {
+                uno::Sequence< uno::Any > diagramRelTuple (3);
+                // [0] => RID, [1] => InputStream [2] => extension
+                OUString sRelId = aIt->second.maId;
+
+                diagramRelTuple[0] = uno::makeAny ( sRelId );
+                OUString sTarget = xImageRels->getFragmentPathFromRelId( sRelId );
+
+                uno::Reference< io::XInputStream > xImageInputStrm( rFilter.openInputStream( sTarget ), uno::UNO_SET_THROW );
+                StreamDataSequence dataSeq;
+                if ( rFilter.importBinaryData( dataSeq, sTarget ) )
+                {
+                    diagramRelTuple[1] = uno::makeAny( dataSeq );
+                }
+
+                diagramRelTuple[2] = uno::makeAny( sTarget.copy( sTarget.lastIndexOf(".") ) );
+
+                xRelListTemp[counter] = diagramRelTuple;
+                ++counter;
+            }
+            xRelListTemp.realloc(counter);
+
+        }
+    }
+    return xRelListTemp;
+}
+
 } }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
index d97069b..dc20747 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -426,11 +426,20 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException, std::exception)
                     mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr));
 
                     uno::Sequence<beans::PropertyValue> aValue(mpShape->getDiagramDoms());
+                    uno::Sequence < uno::Any > diagramDrawing(2);
+                    // drawingValue[0] => dom, drawingValue[1] => Sequence of associated relationships
+
                     sal_Int32 length = aValue.getLength();
                     aValue.realloc(length+1);
+
+                    diagramDrawing[0] = uno::makeAny( mxFilterBase->importFragment( aFragmentPath ) );
+                    diagramDrawing[1] = uno::makeAny( pShapePtr->resolveRelationshipsOfType( *mxFilterBase, aFragmentPath,
+                            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" )  );
+
                     beans::PropertyValue* pValue = aValue.getArray();
                     pValue[length].Name = "OOXDrawing";
-                    pValue[length].Value = uno::makeAny( mxFilterBase->importFragment( aFragmentPath ) );
+                    pValue[length].Value = uno::makeAny( diagramDrawing );
+
                     pShapePtr->setDiagramDoms( aValue );
 
                     pShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() );
diff --git a/sw/qa/extras/ooxmlexport/data/fdo74792.docx b/sw/qa/extras/ooxmlexport/data/fdo74792.docx
new file mode 100644
index 0000000..3d00009
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/fdo74792.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index f885438..094519c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -1443,8 +1443,10 @@ DECLARE_OOXMLEXPORT_TEST(testSmartart, "smartart.docx")
       else if (aGrabBag[i].Name == "OOXDrawing")
       {
         bDrawing = sal_True;
+        uno::Sequence< uno::Any > diagramDrawing;
         uno::Reference<xml::dom::XDocument> aDrawingDom;
-        CPPUNIT_ASSERT(aGrabBag[i].Value >>= aDrawingDom); // PropertyValue of proper type
+        CPPUNIT_ASSERT(aGrabBag[i].Value >>= diagramDrawing);
+        CPPUNIT_ASSERT(diagramDrawing[0] >>= aDrawingDom); // PropertyValue of proper type
         CPPUNIT_ASSERT(aDrawingDom.get()); // Reference not empty
       }
     }
@@ -2940,6 +2942,26 @@ DECLARE_OOXMLEXPORT_TEST(testCompatSettingsForW14, "TextEffects_StylisticSets_Cn
     assertXPath(pXmlDoc, "/w:settings/w:compat/w:compatSetting[5]", "val", "1");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testFdo74792, "fdo74792.docx")
+{
+    /*
+     * fdo#74792 : The images associated with smart-art data[i].xml
+     * were not preserved on exporting to DOCX format
+     * Added support to grabbag the rels, with associated images.
+     */
+    xmlDocPtr pXmlDoc = parseExport("word/diagrams/_rels/data1.xml.rels");
+    if(!pXmlDoc)
+        return;
+    assertXPath(pXmlDoc,"/rels:Relationships/rels:Relationship", 4);
+    uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(
+                         comphelper::getComponentContext(m_xSFactory), m_aTempFile.GetURL());
+
+    //check that images are also saved
+    OUString sImageFile( "word/media/OOXDiagramDataRels0.jpeg" );
+    uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName( sImageFile ), uno::UNO_QUERY);
+    CPPUNIT_ASSERT( xInputStream.is() );
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index d8480db..d07e477 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -25,6 +25,7 @@
 #include <oox/drawingml/drawingmltypes.hxx>
 #include <oox/export/utils.hxx>
 #include <oox/export/vmlexport.hxx>
+#include <oox/token/properties.hxx>
 
 #include <frmatr.hxx>
 #include <frmfmt.hxx>
@@ -41,6 +42,7 @@
 #include <docxexport.hxx>
 #include <docxexportfilter.hxx>
 #include <writerhelper.hxx>
+#include <comphelper/seqstream.hxx>
 
 using namespace com::sun::star;
 using namespace oox;
@@ -683,6 +685,78 @@ void DocxSdrExport::writeDMLEffectLst(const SwFrmFmt& rFrmFmt)
 
 }
 
+void DocxSdrExport::writeDiagramRels(uno::Reference<xml::dom::XDocument> xDom,
+                                     uno::Sequence< uno::Sequence< uno::Any > > xRelSeq,
+                                     uno::Reference< io::XOutputStream > xOutStream, OUString sGrabBagProperyName)
+{
+    // add image relationships of OOXData, OOXDiagram
+    OUString sType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
+    uno::Reference< xml::sax::XSAXSerializable > xSerializer(xDom, uno::UNO_QUERY);
+    uno::Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(comphelper::getProcessComponentContext());
+    xWriter->setOutputStream(xOutStream);
+
+    // retrieve the relationships from Sequence
+    for (sal_Int32 j = 0; j < xRelSeq.getLength(); j++)
+    {
+        // diagramDataRelTuple[0] => RID,
+        // diagramDataRelTuple[1] => xInputStream
+        // diagramDataRelTuple[2] => extension
+        uno::Sequence< uno::Any > diagramDataRelTuple = xRelSeq[j];
+
+        OUString sRelId, sExtension;
+        diagramDataRelTuple[0] >>= sRelId;
+        diagramDataRelTuple[2] >>= sExtension;
+        OUString sContentType;
+        if (sExtension == ".jpeg")
+            sContentType = "image/jpeg";
+        else if (sExtension == ".WMF")
+            sContentType = "image/x-wmf";
+        sRelId = sRelId.copy(3);
+
+        StreamDataSequence dataSeq;
+        diagramDataRelTuple[1] >>= dataSeq;
+        uno::Reference<io::XInputStream> dataImagebin(new ::comphelper::SequenceInputStream(dataSeq));
+
+        OUString sFragment("../media/");
+        sFragment += sGrabBagProperyName + OUString::number(j) + sExtension;
+
+        PropertySet aProps(xOutStream);
+        aProps.setAnyProperty(PROP_RelId, uno::makeAny(sal_Int32(sRelId.toInt32())));
+
+        m_pImpl->m_rExport.GetFilter().addRelation(xOutStream, sType, sFragment);
+
+        sFragment = sFragment.replaceFirst("..","word");
+        uno::Reference< io::XOutputStream > xBinOutStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(sFragment, sContentType);
+
+        try
+        {
+            sal_Int32 nBufferSize = 512;
+            uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
+            sal_Int32 nRead;
+            do
+            {
+                nRead = dataImagebin->readBytes(aDataBuffer, nBufferSize);
+                if (nRead)
+                {
+                    if (nRead < nBufferSize)
+                    {
+                        nBufferSize = nRead;
+                        aDataBuffer.realloc(nRead);
+                    }
+                    xBinOutStream->writeBytes(aDataBuffer);
+                }
+            }
+            while (nRead);
+            xBinOutStream->flush();
+        }
+        catch (const uno::Exception& rException)
+        {
+            SAL_WARN("sw.ww8", "DocxSdrExport::writeDiagramRels Failed to copy grabbaged Image: " << rException.Message);
+        }
+        dataImagebin->closeInput();
+    }
+}
+
 void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFrmFmt,  int nAnchorId)
 {
     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
@@ -694,6 +768,8 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFr
     uno::Reference<xml::dom::XDocument> styleDom;
     uno::Reference<xml::dom::XDocument> colorDom;
     uno::Reference<xml::dom::XDocument> drawingDom;
+    uno::Sequence< uno::Sequence< uno::Any > > xDataRelSeq;
+    uno::Sequence< uno::Any > diagramDrawing;
 
     // retrieve the doms from the GrabBag
     OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
@@ -711,9 +787,12 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFr
         else if (propName == "OOXColor")
             propList[nProp].Value >>= colorDom;
         else if (propName == "OOXDrawing")
-            propList[nProp].Value >>= drawingDom;
+            propList[nProp].Value >>= diagramDrawing;
+        else if (propName == "OOXDiagramDataRels")
+            propList[nProp].Value >>= xDataRelSeq;
     }
 
+    diagramDrawing[0] >>= drawingDom;
     // check that we have the 4 mandatory XDocuments
     // if not, there was an error importing and we won't output anything
     if (!dataDom.is() || !layoutDom.is() || !styleDom.is() || !colorDom.is())
@@ -751,6 +830,7 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFr
                                           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData",
                                           dataFileName, false), RTL_TEXTENCODING_UTF8);
 
+
     // add layout relation
     OUString layoutFileName = "diagrams/layout" + OUString::number(diagramCount) + ".xml";
     OString layoutRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
@@ -814,11 +894,15 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFr
 
     // write data file
     serializer.set(dataDom, uno::UNO_QUERY);
-    writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + dataFileName,
-                            "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml"));
+    uno::Reference< io::XOutputStream > xDataOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(
+                "word/" + dataFileName, "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml");
+    writer->setOutputStream(xDataOutputStream);
     serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
                           uno::Sequence< beans::StringPair >());
 
+    // write the associated Images and rels for data file
+    writeDiagramRels(dataDom, xDataRelSeq, xDataOutputStream, OUString("OOXDiagramDataRels"));
+
     // write layout file
     serializer.set(layoutDom, uno::UNO_QUERY);
     writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + layoutFileName,
@@ -841,13 +925,20 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFr
                           uno::Sequence< beans::StringPair >());
 
     // write drawing file
+
     if (drawingDom.is())
     {
         serializer.set(drawingDom, uno::UNO_QUERY);
-        writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + drawingFileName,
-                                "application/vnd.openxmlformats-officedocument.drawingml.diagramDrawing+xml"));
+        uno::Reference< io::XOutputStream > xDrawingOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + drawingFileName,
+                "application/vnd.openxmlformats-officedocument.drawingml.diagramDrawing+xml");
+        writer->setOutputStream(xDrawingOutputStream);
         serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
                               uno::Sequence< beans::StringPair >());
+
+        // write the associated Images and rels for drawing file
+        uno::Sequence< uno::Sequence< uno::Any > > xDrawingRelSeq;
+        diagramDrawing[1] >>= xDrawingRelSeq;
+        writeDiagramRels(drawingDom, xDrawingRelSeq, xDrawingOutputStream, OUString("OOXDiagramDrawingRels"));
     }
 }
 
diff --git a/sw/source/filter/ww8/docxsdrexport.hxx b/sw/source/filter/ww8/docxsdrexport.hxx
index 25c0ea1..675d756 100644
--- a/sw/source/filter/ww8/docxsdrexport.hxx
+++ b/sw/source/filter/ww8/docxsdrexport.hxx
@@ -11,7 +11,7 @@
 #define INCLUDED_SW_SOURCE_FILTER_WW8_DOCXSDREXPORT_HXX
 
 #include <boost/shared_ptr.hpp>
-
+#include <com/sun/star/xml/dom/XDocument.hpp>
 namespace oox
 {
 namespace drawingml
@@ -83,6 +83,9 @@ public:
     void writeDMLEffectLst(const SwFrmFmt& rFrmFmt);
     /// Writes a diagram (smartart).
     void writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFrmFmt, int nAnchorId);
+    void writeDiagramRels( com::sun::star::uno::Reference< com::sun::star::xml::dom::XDocument> xDom,
+            com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< com::sun::star::uno::Any > > xRelSeq,
+            com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > xOutStream, OUString sGrabBagProperyName);
     /// Writes text frame in DML format.
     void writeDMLTextFrame(sw::Frame* pParentFrame, int nAnchorId);
     /// Writes text frame in VML format.


More information about the Libreoffice-commits mailing list