sc/qa/unit/data/xlsx/groupShape.xlsx |binary sc/qa/unit/subsequent_export_test2.cxx | 12 ++++++++++++ sc/source/filter/xcl97/xcl97rec.cxx | 25 ++++++++++++++++++------- 3 files changed, 30 insertions(+), 7 deletions(-)
New commits: commit c4d7b9c3ec6e44b96134fdfb036be7f9fcf39f9d Author: Tibor Nagy <nagy.tib...@nisz.hu> AuthorDate: Wed Nov 23 12:14:31 2022 +0100 Commit: Nagy Tibor <nagy.tib...@nisz.hu> CommitDate: Fri Nov 25 14:01:09 2022 +0100 tdf#70293 XLSX export: fix lost grouping of shapes SaveDrawingMLObjects() needs to skip all the grouped objects, including subgroups of a group to avoid of broken export. Fixing this and reverting the old workaround commit c323e60157422ae264e798b9a279a532fe9997af "ignore the (unsupported ) group customshape when exporting xlsx", Calc keeps the grouped state of the objects now. Change-Id: Ic320248a1c646d8adb9ce55bb2e5dcd880c1df6f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143142 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/sc/qa/unit/data/xlsx/groupShape.xlsx b/sc/qa/unit/data/xlsx/groupShape.xlsx new file mode 100644 index 000000000000..060b3fd2e377 Binary files /dev/null and b/sc/qa/unit/data/xlsx/groupShape.xlsx differ diff --git a/sc/qa/unit/subsequent_export_test2.cxx b/sc/qa/unit/subsequent_export_test2.cxx index 03f747e82b63..55c628f1de6b 100644 --- a/sc/qa/unit/subsequent_export_test2.cxx +++ b/sc/qa/unit/subsequent_export_test2.cxx @@ -64,6 +64,7 @@ protected: public: ScExportTest2(); + void testGroupShape(); void testMatrixMultiplicationXLSX(); void testTdf121260(); void testTextDirectionXLSX(); @@ -189,6 +190,7 @@ public: CPPUNIT_TEST_SUITE(ScExportTest2); + CPPUNIT_TEST(testGroupShape); CPPUNIT_TEST(testMatrixMultiplicationXLSX); CPPUNIT_TEST(testTdf121260); CPPUNIT_TEST(testTextDirectionXLSX); @@ -324,6 +326,16 @@ void ScExportTest2::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) XmlTestTools::registerODFNamespaces(pXmlXPathCtx); } +void ScExportTest2::testGroupShape() +{ + createScDoc("xlsx/groupShape.xlsx"); + save("Calc Office Open XML"); + + xmlDocUniquePtr pDoc = parseExport("xl/drawings/drawing1.xml"); + CPPUNIT_ASSERT(pDoc); + assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:grpSp/xdr:grpSpPr"); +} + void ScExportTest2::testMatrixMultiplicationXLSX() { createScDoc("xlsx/matrix-multiplication.xlsx"); diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 55ec685428ae..84718321b126 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -225,13 +225,29 @@ bool IsValidObject( const XclObj& rObj ) void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm ) { std::vector<XclObj*> aList; - aList.reserve(rList.size()); + // do not add objects to the list that are in the group, + // because the group already contains them. For this, count + // the next skipped objects, i.e. objects of a group, + // including objects of its subgroups + size_t nSkipObj = 0; for (const auto& rxObj : rList) { + // FIXME: Can DrawingML objects be grouped with VML or not valid objects? if (IsVmlObject(rxObj.get()) || !IsValidObject(*rxObj)) continue; - aList.push_back(rxObj.get()); + if (nSkipObj == 0) + aList.push_back(rxObj.get()); + else + --nSkipObj; + + if (rxObj->GetObjType() == 0) // group (it can be a subgroup) + { + XclObjAny* pObj = dynamic_cast<XclObjAny*>(rxObj.get()); + css::uno::Reference<css::drawing::XShapes> mXShapes(pObj->GetShape(), UNO_QUERY); + // skip (also) the objects of this group + nSkipObj += mXShapes->getCount(); + } } if (aList.empty()) @@ -1284,11 +1300,6 @@ bool ScURLTransformer::isExternalURL(const OUString& rURL) const void XclObjAny::SaveXml( XclExpXmlStream& rStrm ) { - // ignore group shapes at the moment, we don't process them correctly - // leading to ms2010 rejecting the content - if( !mxShape.is() || mxShape->getShapeType() == "com.sun.star.drawing.GroupShape" ) - return; - // Do not output any of the detective shapes and validation circles. SdrObject* pObject = SdrObject::getSdrObjectFromXShape(mxShape); if (pObject)