summaryrefslogtreecommitdiff
path: root/sw
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 /sw
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
Diffstat (limited to 'sw')
-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
4 files changed, 123 insertions, 7 deletions
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.