diff options
author | Vinaya Mandke <vinaya.mandke@synerzip.com> | 2014-02-25 13:13:11 +0530 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-05 10:13:40 +0100 |
commit | 6536826f2f4c747582d60ed40b0418c6a67a9829 (patch) | |
tree | 24cd3f23906b7c86dea42f62cf44bbea65113d60 /sw | |
parent | d043c9e3be791993348afaba6effdc3731f7c33d (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.docx | bin | 0 -> 127945 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 24 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.cxx | 101 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.hxx | 5 |
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 Binary files differnew file mode 100644 index 000000000000..3d00009a03f3 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/fdo74792.docx 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. |