From ece4a0f78bb60ef079722e8fa029f0ec253d0452 Mon Sep 17 00:00:00 2001 From: Vasily Melenchuk Date: Tue, 14 May 2019 17:00:59 +0300 Subject: tdf#125518: docx export: save anchors for diagrams Previously all diagrams were saved as inline objects ignoring possible wrapping options and anchors. Change-Id: I0952fb33d4be4c288c919156af9549f8195b7ead Reviewed-on: https://gerrit.libreoffice.org/72291 Reviewed-by: Thorsten Behrens Tested-by: Thorsten Behrens --- sw/qa/extras/ooxmlexport/data/tdf125518.odt | Bin 0 -> 34438 bytes sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 23 +++++++++++++++++++++++ sw/source/filter/ww8/docxattributeoutput.cxx | 23 +++++++---------------- sw/source/filter/ww8/docxattributeoutput.hxx | 11 +++++++++-- 4 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/tdf125518.odt diff --git a/sw/qa/extras/ooxmlexport/data/tdf125518.odt b/sw/qa/extras/ooxmlexport/data/tdf125518.odt new file mode 100644 index 000000000000..92df094a8962 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf125518.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index 4da5d109324a..d377f9b14449 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -409,6 +409,29 @@ DECLARE_OOXMLEXPORT_TEST(testTdf78657, "tdf78657_picture_hyperlink.docx") assertXPath(pXmlRels, "/rels:Relationships/rels:Relationship[@Target='http://www.google.com']", "TargetMode", "External"); } +DECLARE_OOXMLEXPORT_TEST(testTdf125518, "tdf125518.odt") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + return; + + // First diagram is anchored + OUString anchorName = getXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[2]/w:drawing/wp:anchor/wp:docPr", "name"); + CPPUNIT_ASSERT_EQUAL(OUString("Object1"), anchorName); + + // Second diagram has anchor + anchorName = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[1]/w:drawing/wp:anchor/wp:docPr", "name"); + CPPUNIT_ASSERT_EQUAL(OUString("Objekt1"), anchorName); + + // Third diagram has no anchor + anchorName = getXPath(pXmlDoc, "/w:document/w:body/w:p[12]/w:r[2]/w:drawing/wp:inline/wp:docPr", "name"); + CPPUNIT_ASSERT_EQUAL(OUString("Object2"), anchorName); + + // 4th diagram has anchor too + anchorName = getXPath(pXmlDoc, "/w:document/w:body/w:p[14]/w:r[3]/w:drawing/wp:anchor/wp:docPr", "name"); + CPPUNIT_ASSERT_EQUAL(OUString("Object3"), anchorName); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 5733823ed24a..2414c7efcb75 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -4948,14 +4948,14 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat ) { - if( WriteOLEChart( pSdrObj, rSize )) + if( WriteOLEChart( pSdrObj, rSize, pFlyFrameFormat )) return; if( WriteOLEMath( rOLENode )) return; PostponeOLE( rOLENode, rSize, pFlyFrameFormat ); } -bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize ) +bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat ) { uno::Reference< drawing::XShape > xShape( const_cast(pSdrObj)->getUnoShape(), uno::UNO_QUERY ); if (!xShape.is()) @@ -4975,7 +4975,7 @@ bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& r if (!SotExchange::IsChart(aClassID)) return false; - m_aPostponedCharts.push_back(std::pair(pSdrObj, rSize)); + m_aPostponedCharts.push_back(PostponedChart(pSdrObj, rSize, pFlyFrameFormat)); return true; } @@ -4987,10 +4987,10 @@ void DocxAttributeOutput::WritePostponedChart() if (m_aPostponedCharts.empty()) return; - for (const auto& itr : m_aPostponedCharts) + for (const PostponedChart& rChart : m_aPostponedCharts) { uno::Reference< chart2::XChartDocument > xChartDoc; - uno::Reference< drawing::XShape > xShape( const_cast(itr.first)->getUnoShape(), uno::UNO_QUERY ); + uno::Reference< drawing::XShape > xShape(const_cast(rChart.object)->getUnoShape(), uno::UNO_QUERY ); if( xShape.is() ) { uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY ); @@ -5001,16 +5001,8 @@ void DocxAttributeOutput::WritePostponedChart() if( xChartDoc.is() ) { SAL_INFO("sw.ww8", "DocxAttributeOutput::WriteOLE2Obj: export chart "); - m_pSerializer->startElementNS(XML_w, XML_drawing); - m_pSerializer->startElementNS( XML_wp, XML_inline, - XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0" ); - OString aWidth( OString::number( TwipsToEMU( itr.second.Width() ) ) ); - OString aHeight( OString::number( TwipsToEMU( itr.second.Height() ) ) ); - m_pSerializer->singleElementNS(XML_wp, XML_extent, XML_cx, aWidth, XML_cy, aHeight); - // TODO - the right effectExtent, extent including the effect - m_pSerializer->singleElementNS( XML_wp, XML_effectExtent, - XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0" ); + m_rExport.SdrExporter().startDMLAnchorInline(rChart.frame, rChart.size); OUString sName("Object 1"); uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY ); @@ -5046,9 +5038,8 @@ void DocxAttributeOutput::WritePostponedChart() m_pSerializer->endElementNS( XML_a, XML_graphicData ); m_pSerializer->endElementNS( XML_a, XML_graphic ); - m_pSerializer->endElementNS( XML_wp, XML_inline ); - m_pSerializer->endElementNS( XML_w, XML_drawing ); + m_rExport.SdrExporter().endDMLAnchorInline(rChart.frame); } } diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 8c858f5a107a..2d4726bbebdb 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -393,7 +393,7 @@ private: void FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrameFormat* pOLEFrameFormat, SwOLENode* pOLENode, const SdrObject* pSdrObj = nullptr); void WriteSrcRect( const SdrObject* pSdrObj, const SwFrameFormat* pFrameFormat ); void WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat); - bool WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize ); + bool WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat); bool WriteOLEMath( const SwOLENode& rNode ); void PostponeOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat ); void WriteOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* rFlyFrameFormat ); @@ -882,7 +882,14 @@ private: std::vector m_aPostponedMaths; /// count charts consistently for unit tests unsigned int m_nChartCount; - std::vector> m_aPostponedCharts; + struct PostponedChart + { + PostponedChart( const SdrObject* sdrObject, const Size& rSize, const SwFlyFrameFormat* rFrame ) : object(sdrObject), size(rSize), frame(rFrame) {}; + const SdrObject* object; + const Size size; + const SwFlyFrameFormat* frame; + }; + std::vector m_aPostponedCharts; std::vector m_aPostponedFormControls; std::vector m_aPostponedActiveXControls; const SwField* pendingPlaceholder; -- cgit v1.2.3