diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-07-01 12:34:52 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-07-01 17:15:30 +0200 |
commit | 1e3263a677b61c718d0fd1be15c066b933f7de18 (patch) | |
tree | 621a09584a2f57f1060c23baf66faca2d50589b6 | |
parent | e190196f255b7d0147d61fd967a2b2a61a932185 (diff) |
XLSX export: handle button form controls
This builds on top of commit 94678a7b9c6b7e577c15adacc885e03551bcf17b
(XLSX export: improve handling of checkbox (form controls), 2021-06-30),
so now both checkboxes and buttons are handled during export.
Change-Id: I278b4925414d29399401cc15ab3d944db88ee0c5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118219
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | oox/source/token/tokens.txt | 5 | ||||
-rw-r--r-- | sc/qa/unit/data/xlsx/button-form-control.xlsx | bin | 0 -> 11190 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_export-test2.cxx | 25 | ||||
-rw-r--r-- | sc/source/filter/excel/xeescher.cxx | 63 | ||||
-rw-r--r-- | sc/source/filter/xcl97/xcl97rec.cxx | 1 |
5 files changed, 93 insertions, 1 deletions
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 4d2fb881f0bc..997b3e8b3b25 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -713,6 +713,7 @@ autoLoad autoNoTable autoPage autoPageBreaks +autoPict autoRecover autoRedefine autoRepublish @@ -1403,6 +1404,7 @@ contributors control control1 control2 +controlPr controls convMailMergeEsc convex @@ -2372,6 +2374,7 @@ forcedash foredepth forestGreen forgetLastTabAlignment +formControlPr formFld formLetters formProt @@ -3179,6 +3182,7 @@ location lock lockRevision lockStructure +lockText lockWindows locked lockedCanvas @@ -3661,6 +3665,7 @@ objOverTx objTx object objectDefaults +objectType objects obliqueBottom obliqueBottomLeft diff --git a/sc/qa/unit/data/xlsx/button-form-control.xlsx b/sc/qa/unit/data/xlsx/button-form-control.xlsx Binary files differnew file mode 100644 index 000000000000..c5e9fe65a245 --- /dev/null +++ b/sc/qa/unit/data/xlsx/button-form-control.xlsx diff --git a/sc/qa/unit/subsequent_export-test2.cxx b/sc/qa/unit/subsequent_export-test2.cxx index 6036bddd8369..d23145c67cf2 100644 --- a/sc/qa/unit/subsequent_export-test2.cxx +++ b/sc/qa/unit/subsequent_export-test2.cxx @@ -188,6 +188,7 @@ public: void testTdf126541_SheetVisibilityImportXlsx(); void testTdf140431(); void testCheckboxFormControlXlsxExport(); + void testButtonFormControlXlsxExport(); CPPUNIT_TEST_SUITE(ScExportTest2); @@ -284,6 +285,7 @@ public: CPPUNIT_TEST(testTdf126541_SheetVisibilityImportXlsx); CPPUNIT_TEST(testTdf140431); CPPUNIT_TEST(testCheckboxFormControlXlsxExport); + CPPUNIT_TEST(testButtonFormControlXlsxExport); CPPUNIT_TEST_SUITE_END(); @@ -2323,6 +2325,29 @@ void ScExportTest2::testCheckboxFormControlXlsxExport() assertXPathContent(pDoc, "/xml/v:shape/xx:ClientData/xx:Anchor", "1, 22, 3, 3, 3, 30, 6, 1"); } +void ScExportTest2::testButtonFormControlXlsxExport() +{ + // Given a document that has a checkbox form control: + ScDocShellRef xShell = loadDoc(u"button-form-control.", FORMAT_XLSX); + CPPUNIT_ASSERT(xShell.is()); + + // When exporting to XLSX: + std::shared_ptr<utl::TempFile> pXPathFile + = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX); + + // Then make sure its control markup is written and it has a correct position + size: + xmlDocUniquePtr pDoc + = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml"); + CPPUNIT_ASSERT(pDoc); + // Without the fix in place, this test would have failed with: + // - XPath '//x:anchor/x:from/xdr:col' not found + // i.e. the control markup was missing, the button was lost on export. + assertXPathContent(pDoc, "//x:anchor/x:from/xdr:col", "1"); + assertXPathContent(pDoc, "//x:anchor/x:from/xdr:row", "3"); + assertXPathContent(pDoc, "//x:anchor/x:to/xdr:col", "3"); + assertXPathContent(pDoc, "//x:anchor/x:to/xdr:row", "7"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 2f1253c0a16e..fcffbd7534b2 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -1144,6 +1144,9 @@ void VmlFormControlExporter::EndShape(sal_Int32 nShapeElement) case EXC_OBJTYPE_CHECKBOX: aObjectType = "Checkbox"; break; + case EXC_OBJTYPE_BUTTON: + aObjectType = "Button"; + break; } pVmlDrawing->startElement(FSNS(XML_x, XML_ClientData), XML_ObjectType, aObjectType); OString aAnchor = OString::number(m_aAreaFrom.Left()); @@ -1156,7 +1159,11 @@ void VmlFormControlExporter::EndShape(sal_Int32 nShapeElement) aAnchor += ", " + OString::number(m_aAreaTo.Bottom()); XclXmlUtils::WriteElement(pVmlDrawing, FSNS(XML_x, XML_Anchor), aAnchor); - // XclExpOcxControlObj::WriteSubRecs() has the same fixed value. + // XclExpOcxControlObj::WriteSubRecs() has the same fixed values. + if (m_nObjType == EXC_OBJTYPE_BUTTON) + { + XclXmlUtils::WriteElement(pVmlDrawing, FSNS(XML_x, XML_TextHAlign), "Center"); + } XclXmlUtils::WriteElement(pVmlDrawing, FSNS(XML_x, XML_TextVAlign), "Center"); pVmlDrawing->endElement(FSNS(XML_x, XML_ClientData)); @@ -1384,6 +1391,21 @@ OUString XclExpTbxControlObj::SaveControlPropertiesXml(XclExpXmlStream& rStrm) c break; } + case EXC_OBJTYPE_BUTTON: + { + sal_Int32 nDrawing = DrawingML::getNewDrawingUniqueId(); + sax_fastparser::FSHelperPtr pFormControl = rStrm.CreateOutputStream( + XclXmlUtils::GetStreamName("xl/", "ctrlProps/ctrlProps", nDrawing), + XclXmlUtils::GetStreamName("../", "ctrlProps/ctrlProps", nDrawing), + rStrm.GetCurrentStream()->getOutputStream(), + "application/vnd.ms-excel.controlproperties+xml", + oox::getRelationship(Relationship::CTRLPROP), &sIdFormControlPr); + + pFormControl->singleElement(XML_formControlPr, XML_xmlns, + rStrm.getNamespaceURL(OOX_NS(xls14Lst)), XML_objectType, + "Button", XML_lockText, "1"); + break; + } } return sIdFormControlPr; @@ -1441,6 +1463,45 @@ void XclExpTbxControlObj::SaveSheetXml(XclExpXmlStream& rStrm, const OUString& a break; } + case EXC_OBJTYPE_BUTTON: + { + sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); + + rWorksheet->startElement(FSNS(XML_mc, XML_AlternateContent), FSNS(XML_xmlns, XML_mc), + rStrm.getNamespaceURL(OOX_NS(mce))); + rWorksheet->startElement(FSNS(XML_mc, XML_Choice), XML_Requires, "x14"); + + rWorksheet->startElement(XML_control, XML_shapeId, OString::number(mnShapeId).getStr(), + FSNS(XML_r, XML_id), aIdFormControlPr, XML_name, msLabel); + + rWorksheet->startElement(XML_controlPr, XML_defaultSize, "0", XML_print, + mbPrint ? "true" : "false", XML_autoFill, "0", XML_autoPict, + "0"); + + rWorksheet->startElement(XML_anchor, XML_moveWithCells, "true", XML_sizeWithCells, + "false"); + + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); + tools::Rectangle aAreaFrom; + tools::Rectangle aAreaTo; + lcl_GetFromTo(mrRoot, pObj->GetLogicRect(), GetTab(), aAreaFrom, aAreaTo, + /*bInEMU=*/true); + + rWorksheet->startElement(XML_from); + lcl_WriteAnchorVertex(rWorksheet, aAreaFrom); + rWorksheet->endElement(XML_from); + rWorksheet->startElement(XML_to); + lcl_WriteAnchorVertex(rWorksheet, aAreaTo); + rWorksheet->endElement(XML_to); + rWorksheet->endElement(XML_anchor); + + rWorksheet->endElement(XML_controlPr); + + rWorksheet->endElement(XML_control); + rWorksheet->endElement(FSNS(XML_mc, XML_Choice)); + rWorksheet->endElement(FSNS(XML_mc, XML_AlternateContent)); + break; + } } } diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 56a4dd956f0e..163a7886cdc4 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -158,6 +158,7 @@ bool IsFormControlObject( const XclObj *rObj ) switch( rObj->GetObjType() ) { case EXC_OBJTYPE_CHECKBOX: + case EXC_OBJTYPE_BUTTON: return true; default: return false; |