From 7460e4f4a7b15cc7984adf65bc17e3d580413224 Mon Sep 17 00:00:00 2001 From: Tünde Tóth Date: Wed, 29 Mar 2023 15:09:11 +0200 Subject: tdf#154469 DOCX export: fix hyperlink in group shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hyperlink inserted to shape lost after export, if the shape was inside a group shape. Follow-up to commit 7f4f88b883f81fbce975f72aea0f66a54e269ead "tdf#145147 DOCX import: fix hyperlink in group shape". Change-Id: I48b582c04b6f779cb5393179f65a32d7a7eca5ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149716 Tested-by: László Németh Reviewed-by: László Németh --- include/oox/core/xmlfilterbase.hxx | 4 ++++ oox/source/export/shapes.cxx | 23 +++++++++++++++++++++++ sw/qa/extras/ooxmlexport/data/grouped_link.docx | Bin 0 -> 21001 bytes sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 11 +++++++++++ sw/qa/extras/ooxmlimport/data/grouped_link.docx | Bin 21001 -> 0 bytes sw/qa/extras/ooxmlimport/ooxmlimport2.cxx | 10 ---------- sw/source/filter/ww8/docxattributeoutput.cxx | 6 ++++++ 7 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/grouped_link.docx delete mode 100644 sw/qa/extras/ooxmlimport/data/grouped_link.docx diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx index 89a7994a904b..317c2a2cb789 100644 --- a/include/oox/core/xmlfilterbase.hxx +++ b/include/oox/core/xmlfilterbase.hxx @@ -221,6 +221,10 @@ public: */ sal_Int32 GetUniqueId() { return mnMaxDocId++; } + sal_Int32 GetMaxDocId() { return mnMaxDocId; } + + void SetMaxDocId(sal_Int32 maxDocId) { mnMaxDocId = maxDocId; } + /** Write the document properties into into the current OPC package. @param xProperties The document properties to export. diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index eab82a86336d..83d308ca793f 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -902,6 +902,29 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) else { pFS->startElementNS(mnXmlNamespace, XML_wsp); + if (m_xParent.is()) + { + pFS->startElementNS(mnXmlNamespace, XML_cNvPr, XML_id, + OString::number(GetShapeID(xShape) == -1 ? GetNewShapeID(xShape) + : GetShapeID(xShape)), + XML_name, GetShapeName(xShape)); + + if (GetProperty(rXPropSet, "Hyperlink")) + { + OUString sURL; + mAny >>= sURL; + if (!sURL.isEmpty()) + { + OUString sRelId = mpFB->addRelation( + mpFS->getOutputStream(), oox::getRelationship(Relationship::HYPERLINK), + mpURLTransformer->getTransformedString(sURL), + mpURLTransformer->isExternalURL(sURL)); + + mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId); + } + } + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); + } pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr); } diff --git a/sw/qa/extras/ooxmlexport/data/grouped_link.docx b/sw/qa/extras/ooxmlexport/data/grouped_link.docx new file mode 100644 index 000000000000..8c5657b708b4 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/grouped_link.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 04ce5b8d452c..908d8db90e3e 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -878,6 +878,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf149996, "lorem_hyperlink.fodt") // because the exported file was corrupted. } +DECLARE_OOXMLEXPORT_TEST(testGroupedShapeLink, "grouped_link.docx") +{ + // tdf#145147 Hyperlink in grouped shape not imported + // tdf#154469 Hyperlink in grouped shape not exported + uno::Reference xGroupShape(getShape(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("https://www.libreoffice.org"), + getProperty(xGroupShape->getByIndex(0), "Hyperlink")); + CPPUNIT_ASSERT_EQUAL(OUString("https://www.documentfoundation.org"), + getProperty(xGroupShape->getByIndex(1), "Hyperlink")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlimport/data/grouped_link.docx b/sw/qa/extras/ooxmlimport/data/grouped_link.docx deleted file mode 100644 index 8c5657b708b4..000000000000 Binary files a/sw/qa/extras/ooxmlimport/data/grouped_link.docx and /dev/null differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index bcd75b78ecf5..caaa4b6842de 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -1144,16 +1144,6 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf154695) } } -CPPUNIT_TEST_FIXTURE(Test, testTdf145147) -{ - createSwDoc("grouped_link.docx"); - uno::Reference xGroupShape(getShape(1), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(OUString("https://www.libreoffice.org"), - getProperty(xGroupShape->getByIndex(0), "Hyperlink")); - CPPUNIT_ASSERT_EQUAL(OUString("https://www.documentfoundation.org"), - getProperty(xGroupShape->getByIndex(1), "Hyperlink")); -} - // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 70e5156644e3..8f7a5b9d7bf1 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5872,10 +5872,12 @@ void DocxAttributeOutput::WritePostponedCustomShape() for( const auto & rPostponedDrawing : *m_oPostponedCustomShape) { + m_rExport.GetFilter().SetMaxDocId(m_anchorId + 1); if ( IsAlternateContentChoiceOpen() ) m_rExport.SdrExporter().writeDMLDrawing(rPostponedDrawing.object, rPostponedDrawing.frame, m_anchorId++); else m_rExport.SdrExporter().writeDMLAndVMLDrawing(rPostponedDrawing.object, *rPostponedDrawing.frame, m_anchorId++); + m_anchorId = m_rExport.GetFilter().GetMaxDocId(); } m_oPostponedCustomShape.reset(); } @@ -5894,10 +5896,12 @@ void DocxAttributeOutput::WritePostponedDMLDrawing() for( const auto & rPostponedDrawing : *pPostponedDMLDrawings ) { // Avoid w:drawing within another w:drawing. + m_rExport.GetFilter().SetMaxDocId(m_anchorId + 1); if ( IsAlternateContentChoiceOpen() && !( m_rExport.SdrExporter().IsDrawingOpen()) ) m_rExport.SdrExporter().writeDMLDrawing(rPostponedDrawing.object, rPostponedDrawing.frame, m_anchorId++); else m_rExport.SdrExporter().writeDMLAndVMLDrawing(rPostponedDrawing.object, *rPostponedDrawing.frame, m_anchorId++); + m_anchorId = m_rExport.GetFilter().GetMaxDocId(); } m_oPostponedOLEs = std::move(pPostponedOLEs); @@ -5953,6 +5957,7 @@ void DocxAttributeOutput::WriteFlyFrame(const ww8::Frame& rFrame) { if (!m_oPostponedDMLDrawings) { + m_rExport.GetFilter().SetMaxDocId(m_anchorId + 1); if ( IsAlternateContentChoiceOpen() ) { // Do not write w:drawing inside w:drawing. Instead Postpone the Inner Drawing. @@ -5963,6 +5968,7 @@ void DocxAttributeOutput::WriteFlyFrame(const ww8::Frame& rFrame) } else m_rExport.SdrExporter().writeDMLAndVMLDrawing( pSdrObj, rFrame.GetFrameFormat(), m_anchorId++); + m_anchorId = m_rExport.GetFilter().GetMaxDocId(); m_bPostponedProcessingFly = false ; } -- cgit