sc/qa/unit/data/xlsx/tdf161365.xlsx    |binary
 sc/qa/unit/subsequent_export_test2.cxx |   44 +++++++++++++++++++++++++++++++++
 sc/source/filter/excel/xeescher.cxx    |   40 ++++++++++++++++++++----------
 sc/source/filter/inc/xeescher.hxx      |    2 +
 4 files changed, 73 insertions(+), 13 deletions(-)

New commits:
commit a5abe9cd407d17d0536cc16283f85f68dc36022f
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Fri May 23 08:51:08 2025 +0000
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Mon May 26 07:02:00 2025 +0200

    tdf#161365 xlsx export: checkbox requires valid anchor to be shown
    
    - checkboxes exported XLSX -> XLSX become invisible in both LO and MSO
    - the file inspection shows we used 0 as a value for all the anchor
      properties (from and to) in both sheet1.xml and drawing1.xml
    - we used maAreaFrom/To which are calculated if XBindableValue
      and SC_SERVICENAME_VALBIND are supported in the control model
      in the XclExpTbxControlObj
    - we can fetch these values directly when saving checkbox form XShape
    - it can be noticed we lack other properties too - for background color,
      to do later as this already makes it usable
    
    Change-Id: Icb833b6943df7d73aad7414f8a115351ea4c7d05
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185711
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sc/qa/unit/data/xlsx/tdf161365.xlsx 
b/sc/qa/unit/data/xlsx/tdf161365.xlsx
new file mode 100644
index 000000000000..f2ff32ba916c
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf161365.xlsx differ
diff --git a/sc/qa/unit/subsequent_export_test2.cxx 
b/sc/qa/unit/subsequent_export_test2.cxx
index 55908afd7558..3a667750f4af 100644
--- a/sc/qa/unit/subsequent_export_test2.cxx
+++ b/sc/qa/unit/subsequent_export_test2.cxx
@@ -1210,6 +1210,50 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf142881)
     assertXPathContent(pDrawing1, 
"/xdr:wsDr/xdr:twoCellAnchor[4]/xdr:to/xdr:row"_ostr, "19");
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf161365)
+{
+    createScDoc("xlsx/tdf161365.xlsx");
+
+    save("Calc Office Open XML");
+
+    xmlDocUniquePtr pSheet1 = parseExport("xl/worksheets/sheet1.xml");
+    CPPUNIT_ASSERT(pSheet1);
+
+    assertXPathContent(
+        pSheet1,
+        
"/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control/x:controlPr/x:anchor/x:from/xdr:col"_ostr,
+        "1");
+    assertXPathContent(
+        pSheet1,
+        
"/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control/x:controlPr/x:anchor/x:from/xdr:row"_ostr,
+        "2");
+
+    assertXPathContent(
+        pSheet1,
+        
"/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control/x:controlPr/x:anchor/x:to/xdr:col"_ostr,
+        "2");
+    assertXPathContent(
+        pSheet1,
+        
"/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control/x:controlPr/x:anchor/x:to/xdr:row"_ostr,
+        "3");
+
+    xmlDocUniquePtr pDrawing1 = parseExport("xl/drawings/drawing1.xml");
+    CPPUNIT_ASSERT(pDrawing1);
+
+    assertXPathContent(
+        pDrawing1,
+        
"/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:from/xdr:col"_ostr,
 "1");
+    assertXPathContent(
+        pDrawing1,
+        
"/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:from/xdr:row"_ostr,
 "2");
+    assertXPathContent(
+        pDrawing1, 
"/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:to/xdr:col"_ostr,
+        "2");
+    assertXPathContent(
+        pDrawing1, 
"/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:to/xdr:row"_ostr,
+        "3");
+}
+
 CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf112567b)
 {
     // Set the system locale to Hungarian (a language with different range 
separator)
diff --git a/sc/source/filter/excel/xeescher.cxx 
b/sc/source/filter/excel/xeescher.cxx
index 8827b78afe64..9bf0dedcdfbd 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -1213,6 +1213,30 @@ void XclExpTbxControlObj::SaveVml(XclExpXmlStream& rStrm)
                                       /*pWrapAttrList=*/nullptr, 
/*bOOxmlExport=*/true, mnShapeId);
 }
 
+void XclExpTbxControlObj::WriteAnchor(sax_fastparser::FSHelperPtr& rTarget, 
bool bIsDrawing) const
+{
+    tools::Rectangle aAreaFrom;
+    tools::Rectangle aAreaTo;
+    bool bNeedFromToCorrection = maAreaFrom.IsEmpty() || maAreaTo.IsEmpty();
+
+    if (bNeedFromToCorrection)
+    {
+        SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape);
+        lcl_GetFromTo(mrRoot, pObj->GetLogicRect(), GetTab(), aAreaFrom, 
aAreaTo, /*bInEMU=*/true);
+    }
+
+    const tools::Rectangle& rAreaFrom = bNeedFromToCorrection ? aAreaFrom : 
maAreaFrom;
+    const tools::Rectangle& rAreaTo = bNeedFromToCorrection ? aAreaTo : 
maAreaTo;
+
+    rTarget->startElement(bIsDrawing ? FSNS(XML_xdr, XML_from) : XML_from);
+    lcl_WriteAnchorVertex(rTarget, rAreaFrom);
+    rTarget->endElement(bIsDrawing ? FSNS(XML_xdr, XML_from) : XML_from);
+
+    rTarget->startElement(bIsDrawing ? FSNS(XML_xdr, XML_to) : XML_to);
+    lcl_WriteAnchorVertex(rTarget, rAreaTo);
+    rTarget->endElement(bIsDrawing ? FSNS(XML_xdr, XML_to) : XML_to);
+}
+
 // save into xl\drawings\drawing1.xml
 void XclExpTbxControlObj::SaveXml( XclExpXmlStream& rStrm )
 {
@@ -1226,12 +1250,7 @@ void XclExpTbxControlObj::SaveXml( XclExpXmlStream& 
rStrm )
 
     pDrawing->startElement(FSNS(XML_xdr, XML_twoCellAnchor), XML_editAs, 
"oneCell");
     {
-        pDrawing->startElement(FSNS(XML_xdr, XML_from));
-        lcl_WriteAnchorVertex(pDrawing, maAreaFrom);
-        pDrawing->endElement(FSNS(XML_xdr, XML_from));
-        pDrawing->startElement(FSNS(XML_xdr, XML_to));
-        lcl_WriteAnchorVertex(pDrawing, maAreaTo);
-        pDrawing->endElement(FSNS(XML_xdr, XML_to));
+        WriteAnchor(pDrawing, /* bIsDrawing */ true);
 
         pDrawing->startElement(FSNS(XML_xdr, XML_sp));
         {
@@ -1473,13 +1492,8 @@ void XclExpTbxControlObj::SaveSheetXml(XclExpXmlStream& 
rStrm, const OUString& a
             rWorksheet->write(">");
 
             rWorksheet->startElement(XML_anchor, XML_moveWithCells, "true", 
XML_sizeWithCells, "false");
-            rWorksheet->startElement(XML_from);
-            lcl_WriteAnchorVertex(rWorksheet, maAreaFrom);
-            rWorksheet->endElement(XML_from);
-            rWorksheet->startElement(XML_to);
-            lcl_WriteAnchorVertex(rWorksheet, maAreaTo);
-            rWorksheet->endElement(XML_to);
-            rWorksheet->endElement( XML_anchor );
+            WriteAnchor(rWorksheet, /* bIsDrawing */ false);
+            rWorksheet->endElement(XML_anchor);
 
             rWorksheet->write("</controlPr>");
 
diff --git a/sc/source/filter/inc/xeescher.hxx 
b/sc/source/filter/inc/xeescher.hxx
index c7adf1050b9b..82fb009979e2 100644
--- a/sc/source/filter/inc/xeescher.hxx
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -275,6 +275,8 @@ private:
     void                WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 
nSubRecId );
     /** Writes the ftSbs sub structure containing scrollbar data. */
     void                WriteSbs( XclExpStream& rStrm );
+    /** Writes an anchor, if empty calculates one form XShape */
+    void                WriteAnchor( sax_fastparser::FSHelperPtr& rTarget, 
bool bIsDrawing ) const;
 
 private:
     const css::uno::Reference< css::drawing::XShape > mxShape;

Reply via email to