summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinaya Mandke <vinaya.mandke@synerzip.com>2014-02-25 13:13:11 +0530
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-03-05 10:13:40 +0100
commit6536826f2f4c747582d60ed40b0418c6a67a9829 (patch)
tree24cd3f23906b7c86dea42f62cf44bbea65113d60
parentd043c9e3be791993348afaba6effdc3731f7c33d (diff)
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
-rw-r--r--include/oox/drawingml/shape.hxx3
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx15
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx4
-rw-r--r--oox/source/drawingml/shape.cxx40
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx11
-rw-r--r--sw/qa/extras/ooxmlexport/data/fdo74792.docxbin0 -> 127945 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx24
-rw-r--r--sw/source/filter/ww8/docxsdrexport.cxx101
-rw-r--r--sw/source/filter/ww8/docxsdrexport.hxx5
9 files changed, 193 insertions, 10 deletions
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index fa3f58c83d9c..7f3ba65c716d 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 da439ea4f6f5..4672a2818cc3 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 031c66b1cbf6..ae611c9d81f9 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 ce1d3b6596fd..3a2ebae8ddb1 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 d97069b839ad..dc20747b0fd6 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 000000000000..3d00009a03f3
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/fdo74792.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index f88543882ebf..094519cf6c12 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 d8480db3c9e4..d07e477b06e8 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 25c0ea126cbc..675d756a8a6e 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.