summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/qa/unit/data/xlsx/groupShape.xlsxbin0 -> 9499 bytes
-rw-r--r--sc/qa/unit/subsequent_export_test2.cxx12
-rw-r--r--sc/source/filter/xcl97/xcl97rec.cxx25
3 files changed, 30 insertions, 7 deletions
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
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/groupShape.xlsx
Binary files 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)