summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-03-13 10:49:30 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-04-08 10:07:35 +0200
commitaafaf1f55fa413ad49d4556cf7c0a713dd206ae4 (patch)
tree1cfe3368ee1aeec9fb45e081c89c7d59ecc1432f /sw/source
parent31ac398cfa30694b18240d31df17a58d699b5bf6 (diff)
PPTX export: save SmartArt as diagram instead of group of shapes
preserving SmartArt allows editing it in PowerPoint after saving as pptx file * moved common parts for docx and pptx export to oox/drawingml * fixed export tests that expected shapes on output Change-Id: I3e70a9f4177bebf5e1671232f4cd0ef0e7212626 Reviewed-on: https://gerrit.libreoffice.org/69598 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx34
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx3
-rw-r--r--sw/source/filter/ww8/docxsdrexport.cxx275
-rw-r--r--sw/source/filter/ww8/docxsdrexport.hxx5
4 files changed, 7 insertions, 310 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index f1c56fa5b686..7e621fa52948 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -5677,7 +5677,10 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const ww8::Frame &rFrame, const P
const SdrObject* pSdrObj = rFrame.GetFrameFormat().FindRealSdrObject();
if ( pSdrObj )
{
- if ( IsDiagram( pSdrObj ) )
+ uno::Reference<drawing::XShape> xShape(
+ const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
+
+ if (xShape.is() && oox::drawingml::DrawingML::IsDiagram(xShape))
{
if ( !m_pPostponedDiagrams )
{
@@ -5786,35 +5789,6 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const ww8::Frame &rFrame, const P
m_pSerializer->mergeTopMarks(Tag_OutputFlyFrame, sax_fastparser::MergeMarks::POSTPONE);
}
-bool DocxAttributeOutput::IsDiagram( const SdrObject* sdrObject )
-{
- uno::Reference< drawing::XShape > xShape( const_cast<SdrObject*>(sdrObject)->getUnoShape(), uno::UNO_QUERY );
- if ( !xShape.is() )
- return false;
-
- uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
- if ( !xPropSet.is() )
- return false;
-
- // if the shape doesn't have the InteropGrabBag property, it's not a diagram
- uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
- OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
- if ( !xPropSetInfo->hasPropertyByName( aName ) )
- return false;
-
- uno::Sequence< beans::PropertyValue > propList;
- xPropSet->getPropertyValue( aName ) >>= propList;
- for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
- {
- // if we find any of the diagram components, it's a diagram
- OUString propName = propList[nProp].Name;
- if ( propName == "OOXData" || propName == "OOXLayout" || propName == "OOXStyle" ||
- propName == "OOXColor" || propName == "OOXDrawing")
- return true;
- }
- return false;
-}
-
void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj)
{
const EditTextObject& rEditObj = rParaObj.GetTextObject();
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 4ed30cccf7cf..2ea64b8f207b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -400,9 +400,6 @@ private:
void WriteActiveXControl(const SdrObject* pObject, const SwFrameFormat& rFrameFormat, bool bInsideRun);
bool ExportAsActiveXControl(const SdrObject* pObject) const;
- /// checks whether the current component is a diagram
- static bool IsDiagram (const SdrObject* sdrObject);
-
void InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t const & pTableTextNodeInfoInner );
void StartTable( ww8::WW8TableNodeInfoInner::Pointer_t const & pTableTextNodeInfoInner );
void StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t const & pTableTextNodeInfoInner );
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 5f5cfe9ceb39..d28c3c9b21a6 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -1125,290 +1125,19 @@ void DocxSdrExport::writeDMLEffectLst(const SwFrameFormat& rFrameFormat)
m_pImpl->getSerializer()->endElementNS(XML_a, XML_effectLst);
}
-void DocxSdrExport::writeDiagramRels(const uno::Sequence<uno::Sequence<uno::Any>>& xRelSeq,
- const uno::Reference<io::XOutputStream>& xOutStream,
- const OUString& sGrabBagProperyName, int nAnchorId)
-{
- // add image relationships of OOXData, OOXDiagram
- OUString sType(oox::getRelationship(Relationship::IMAGE));
- 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;
- OUString sExtension;
- diagramDataRelTuple[0] >>= sRelId;
- diagramDataRelTuple[2] >>= sExtension;
- OUString sContentType;
- if (sExtension.equalsIgnoreAsciiCase(".WMF"))
- sContentType = "image/x-wmf";
- else
- sContentType = "image/" + sExtension.copy(1);
- sRelId = sRelId.copy(3);
-
- StreamDataSequence dataSeq;
- diagramDataRelTuple[1] >>= dataSeq;
- uno::Reference<io::XInputStream> dataImagebin(
- new ::comphelper::SequenceInputStream(dataSeq));
-
- OUString sFragment("../media/");
- //nAnchorId is used to make the name unique irrespective of the number of smart arts.
- sFragment += sGrabBagProperyName + OUString::number(nAnchorId) + "_" + OUString::number(j)
- + sExtension;
-
- PropertySet aProps(xOutStream);
- aProps.setAnyProperty(PROP_RelId, uno::makeAny(sRelId.toInt32()));
-
- m_pImpl->getExport().GetFilter().addRelation(xOutStream, sType, sFragment);
-
- sFragment = sFragment.replaceFirst("..", "word");
- uno::Reference<io::XOutputStream> xBinOutStream
- = m_pImpl->getExport().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);
- }
- dataImagebin->closeInput();
- }
-}
-
void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrameFormat& rFrameFormat,
- int nAnchorId)
+ int nDiagramId)
{
- sax_fastparser::FSHelperPtr pFS = m_pImpl->getSerializer();
uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(sdrObject)->getUnoShape(),
uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
-
- uno::Reference<xml::dom::XDocument> dataDom;
- uno::Reference<xml::dom::XDocument> layoutDom;
- 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
- uno::Sequence<beans::PropertyValue> propList;
- xPropSet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= propList;
- for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp)
- {
- OUString propName = propList[nProp].Name;
- if (propName == "OOXData")
- propList[nProp].Value >>= dataDom;
- else if (propName == "OOXLayout")
- propList[nProp].Value >>= layoutDom;
- else if (propName == "OOXStyle")
- propList[nProp].Value >>= styleDom;
- else if (propName == "OOXColor")
- propList[nProp].Value >>= colorDom;
- else if (propName == "OOXDrawing")
- {
- propList[nProp].Value >>= diagramDrawing;
- diagramDrawing[0]
- >>= drawingDom; // if there is OOXDrawing property then set drawingDom here only.
- }
- else if (propName == "OOXDiagramDataRels")
- propList[nProp].Value >>= xDataRelSeq;
- }
-
- // 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())
- return;
// write necessary tags to document.xml
Size aSize(sdrObject->GetSnapRect().GetWidth(), sdrObject->GetSnapRect().GetHeight());
startDMLAnchorInline(&rFrameFormat, aSize);
- // generate a unique id
- sax_fastparser::FastAttributeList* pDocPrAttrList
- = sax_fastparser::FastSerializerHelper::createAttrList();
- pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
- OUString sName = "Diagram" + OUString::number(nAnchorId);
- pDocPrAttrList->add(XML_name, OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
- sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
- pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
-
- sal_Int32 diagramCount;
- diagramCount = nAnchorId;
-
- pFS->singleElementNS(XML_wp, XML_cNvGraphicFramePr, FSEND);
-
- pFS->startElementNS(
- XML_a, XML_graphic, FSNS(XML_xmlns, XML_a),
- OUStringToOString(m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dml)),
- RTL_TEXTENCODING_UTF8)
- .getStr(),
- FSEND);
-
- pFS->startElementNS(XML_a, XML_graphicData, XML_uri,
- "http://schemas.openxmlformats.org/drawingml/2006/diagram", FSEND);
-
- // add data relation
- OUString dataFileName = "diagrams/data" + OUString::number(diagramCount) + ".xml";
- OString dataRelId = OUStringToOString(
- m_pImpl->getExport().GetFilter().addRelation(
- pFS->getOutputStream(), oox::getRelationship(Relationship::DIAGRAMDATA), dataFileName),
- RTL_TEXTENCODING_UTF8);
-
- // add layout relation
- OUString layoutFileName = "diagrams/layout" + OUString::number(diagramCount) + ".xml";
- OString layoutRelId
- = OUStringToOString(m_pImpl->getExport().GetFilter().addRelation(
- pFS->getOutputStream(),
- oox::getRelationship(Relationship::DIAGRAMLAYOUT), layoutFileName),
- RTL_TEXTENCODING_UTF8);
-
- // add style relation
- OUString styleFileName = "diagrams/quickStyle" + OUString::number(diagramCount) + ".xml";
- OString styleRelId = OUStringToOString(
- m_pImpl->getExport().GetFilter().addRelation(
- pFS->getOutputStream(), oox::getRelationship(Relationship::DIAGRAMQUICKSTYLE),
- styleFileName),
- RTL_TEXTENCODING_UTF8);
-
- // add color relation
- OUString colorFileName = "diagrams/colors" + OUString::number(diagramCount) + ".xml";
- OString colorRelId
- = OUStringToOString(m_pImpl->getExport().GetFilter().addRelation(
- pFS->getOutputStream(),
- oox::getRelationship(Relationship::DIAGRAMCOLORS), colorFileName),
- RTL_TEXTENCODING_UTF8);
-
- OUString drawingFileName;
- if (drawingDom.is())
- {
- // add drawing relation
- drawingFileName = "diagrams/drawing" + OUString::number(diagramCount) + ".xml";
- OUString drawingRelId = m_pImpl->getExport().GetFilter().addRelation(
- pFS->getOutputStream(), oox::getRelationship(Relationship::DIAGRAMDRAWING),
- drawingFileName);
-
- // the data dom contains a reference to the drawing relation. We need to update it with the new generated
- // relation value before writing the dom to a file
+ m_pImpl->getDrawingML()->WriteDiagram(xShape, nDiagramId);
- // Get the dsp:damaModelExt node from the dom
- uno::Reference<xml::dom::XNodeList> nodeList = dataDom->getElementsByTagNameNS(
- "http://schemas.microsoft.com/office/drawing/2008/diagram", "dataModelExt");
-
- // There must be one element only so get it
- uno::Reference<xml::dom::XNode> node = nodeList->item(0);
-
- // Get the list of attributes of the node
- uno::Reference<xml::dom::XNamedNodeMap> nodeMap = node->getAttributes();
-
- // Get the node with the relId attribute and set its new value
- uno::Reference<xml::dom::XNode> relIdNode = nodeMap->getNamedItem("relId");
- relIdNode->setNodeValue(drawingRelId);
- }
-
- pFS->singleElementNS(
- XML_dgm, XML_relIds, FSNS(XML_xmlns, XML_dgm),
- OUStringToOString(m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dmlDiagram)),
- RTL_TEXTENCODING_UTF8)
- .getStr(),
- FSNS(XML_xmlns, XML_r),
- OUStringToOString(m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(officeRel)),
- RTL_TEXTENCODING_UTF8)
- .getStr(),
- FSNS(XML_r, XML_dm), dataRelId.getStr(), FSNS(XML_r, XML_lo), layoutRelId.getStr(),
- FSNS(XML_r, XML_qs), styleRelId.getStr(), FSNS(XML_r, XML_cs), colorRelId.getStr(), FSEND);
-
- pFS->endElementNS(XML_a, XML_graphicData);
- pFS->endElementNS(XML_a, XML_graphic);
endDMLAnchorInline(&rFrameFormat);
-
- uno::Reference<xml::sax::XSAXSerializable> serializer;
- uno::Reference<xml::sax::XWriter> writer
- = xml::sax::Writer::create(comphelper::getProcessComponentContext());
-
- // write data file
- serializer.set(dataDom, uno::UNO_QUERY);
- uno::Reference<io::XOutputStream> xDataOutputStream
- = m_pImpl->getExport().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(xDataRelSeq, xDataOutputStream, "OOXDiagramDataRels", nAnchorId);
-
- // write layout file
- serializer.set(layoutDom, uno::UNO_QUERY);
- writer->setOutputStream(m_pImpl->getExport().GetFilter().openFragmentStream(
- "word/" + layoutFileName,
- "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"));
- serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW),
- uno::Sequence<beans::StringPair>());
-
- // write style file
- serializer.set(styleDom, uno::UNO_QUERY);
- writer->setOutputStream(m_pImpl->getExport().GetFilter().openFragmentStream(
- "word/" + styleFileName,
- "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"));
- serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW),
- uno::Sequence<beans::StringPair>());
-
- // write color file
- serializer.set(colorDom, uno::UNO_QUERY);
- writer->setOutputStream(m_pImpl->getExport().GetFilter().openFragmentStream(
- "word/" + colorFileName,
- "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"));
- serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW),
- uno::Sequence<beans::StringPair>());
-
- // write drawing file
-
- if (drawingDom.is())
- {
- serializer.set(drawingDom, uno::UNO_QUERY);
- uno::Reference<io::XOutputStream> xDrawingOutputStream
- = m_pImpl->getExport().GetFilter().openFragmentStream(
- "word/" + drawingFileName,
- "application/vnd.ms-office.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(xDrawingRelSeq, xDrawingOutputStream, "OOXDiagramDrawingRels", nAnchorId);
- }
}
void DocxSdrExport::writeOnlyTextOfFrame(ww8::Frame const* pParentFrame)
diff --git a/sw/source/filter/ww8/docxsdrexport.hxx b/sw/source/filter/ww8/docxsdrexport.hxx
index 81a8da881381..613978761706 100644
--- a/sw/source/filter/ww8/docxsdrexport.hxx
+++ b/sw/source/filter/ww8/docxsdrexport.hxx
@@ -95,10 +95,7 @@ public:
/// Write <a:effectLst>, the effect list.
void writeDMLEffectLst(const SwFrameFormat& rFrameFormat);
/// Writes a diagram (smartart).
- void writeDiagram(const SdrObject* sdrObject, const SwFrameFormat& rFrameFormat, int nAnchorId);
- void writeDiagramRels(const css::uno::Sequence< css::uno::Sequence<css::uno::Any> >& xRelSeq,
- const css::uno::Reference<css::io::XOutputStream>& xOutStream, const OUString& sGrabBagProperyName,
- int nAnchorId);
+ void writeDiagram(const SdrObject* sdrObject, const SwFrameFormat& rFrameFormat, int nDiagramId);
/// Writes text frame in DML format.
void writeDMLTextFrame(ww8::Frame const* pParentFrame, int nAnchorId, bool bTextBoxOnly = false);
/// Writes text frame in VML format.