sc/qa/unit/data/xls/tdf170285_controlsInGroupShape.xls |binary
 sc/qa/unit/subsequent_export_test2.cxx                 |   12 ++++++++++++
 sc/source/filter/xcl97/xcl97rec.cxx                    |   11 +++++++----
 3 files changed, 19 insertions(+), 4 deletions(-)

New commits:
commit 84877dab3a77ac683495a7c8a4359ed2cb69dce7
Author:     Justin Luth <[email protected]>
AuthorDate: Fri Jan 9 20:49:19 2026 -0500
Commit:     Miklos Vajna <[email protected]>
CommitDate: Mon Jan 12 13:16:38 2026 +0100

    tdf#170285 xlsx export: don't skip groupshapes of unknown shape type
    
    The problem was that Microsoft Excel was unable
    to cleanly open some round-tripped XLS -> XLSX files.
    
    7.4.4 commit c4d7b9c3ec6e44b96134fdfb036be7f9fcf39f9
    skipped grouped shapes because ShapeExport::WriteGroupShape
    has a loop for all contained shapes [xGroupShape->getCount()]
    that calls WriteShape(xChild);
    However, it can only write ShapeExport::IsShapeTypeKnown
    and com.sun.star.drawing.ControlShape is not known.
    
    make CppunitTest_sc_subsequent_export_test2 \
        CPPUNIT_TEST_NAME=testTdf170285_controlsInGroupShape
    
    Change-Id: I1c281f85a986836389ce5b1d13a84fcbe8640995
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196948
    Reviewed-by: Justin Luth <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 1efe51bb6d335064b0bdf2c55eb37b417d5af134)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196978
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sc/qa/unit/data/xls/tdf170285_controlsInGroupShape.xls 
b/sc/qa/unit/data/xls/tdf170285_controlsInGroupShape.xls
new file mode 100644
index 000000000000..f1e186dee53c
Binary files /dev/null and 
b/sc/qa/unit/data/xls/tdf170285_controlsInGroupShape.xls differ
diff --git a/sc/qa/unit/subsequent_export_test2.cxx 
b/sc/qa/unit/subsequent_export_test2.cxx
index 5f4cb0dac9ce..9c64fc917fbf 100644
--- a/sc/qa/unit/subsequent_export_test2.cxx
+++ b/sc/qa/unit/subsequent_export_test2.cxx
@@ -52,6 +52,18 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testGroupShape)
     assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:grpSp/xdr:grpSpPr");
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf170285_controlsInGroupShape)
+{
+    createScDoc("xls/tdf170285_controlsInGroupShape.xls");
+
+    save(TestFilter::XLSM);
+    xmlDocUniquePtr pDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
+    // without the fix, this was 0
+    assertXPath(pDoc, "//mc:AlternateContent[1]/mc:Choice/x:control", 
"shapeId", u"1001");
+    // without the fix, this was also 0
+    assertXPath(pDoc, "//mc:AlternateContent[2]/mc:Choice/x:control", 
"shapeId", u"1002");
+}
+
 CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf166724_cellAnchor)
 {
     // given a hand-modified document where the checkbox position was changed 
to not match anchor
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx 
b/sc/source/filter/xcl97/xcl97rec.cxx
index e07e84c5e39d..24f1de018026 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -236,15 +236,18 @@ void SaveDrawingMLObjects( XclExpObjList& rList, 
XclExpXmlStream& rStrm )
         if (IsVmlObject(rxObj.get()) || !IsValidObject(*rxObj))
             continue;
 
+        const auto pObj = dynamic_cast<XclObjAny*>(rxObj.get());
         if (nSkipObj == 0)
             aList.push_back(rxObj.get());
         else
+        {
             --nSkipObj;
+            // Don't skip objects that GroupShape doesn't know how to export
+            if (!pObj || !ShapeExport::IsShapeTypeKnown(pObj->GetShape()))
+                aList.push_back(rxObj.get());
+        }
 
-        XclObjAny* pObj = nullptr;
-        if (rxObj->GetObjType() == 0) // group (it can be a subgroup)
-            pObj = dynamic_cast<XclObjAny*>(rxObj.get());
-        if (pObj)
+        if (pObj && rxObj->GetObjType() == EXC_OBJTYPE_GROUP) // (it can be a 
subgroup)
         {
             css::uno::Reference<css::drawing::XShapes> 
xShapes(pObj->GetShape(), UNO_QUERY);
             if (xShapes)

Reply via email to