sc/inc/dbdata.hxx | 22 ++++++-- sc/qa/unit/data/xlsx/tdf167689_xmlMaps_and_xmlColumnPr.xlsx |binary sc/qa/unit/subsequent_export_test4.cxx | 22 ++++++++ sc/source/core/tool/dbdata.cxx | 5 - sc/source/filter/excel/excdoc.cxx | 2 sc/source/filter/excel/xedbdata.cxx | 16 +++--- sc/source/filter/inc/tablecolumnsbuffer.hxx | 8 +-- sc/source/filter/oox/tablecolumnsbuffer.cxx | 32 ++++++++---- sc/source/filter/oox/workbookfragment.cxx | 4 - 9 files changed, 77 insertions(+), 34 deletions(-)
New commits: commit ab1dd76c8df2d936e1d5b3e761069ff10a60b307 Author: Bayram Çiçek <bayram.ci...@collabora.com> AuthorDate: Thu Aug 7 11:19:17 2025 +0300 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Wed Aug 20 13:01:54 2025 +0200 tdf#167689: Calc: add test for xmlMaps.xml follow-up for https://gerrit.libreoffice.org/c/core/+/188451 (f84f8f2ea4f7eea090075b85339599b9a3f367c4) - added a unittest for xmlMaps.xml and <xmlColumnPr> - removed unused aContent variable. - this was causing the tests to fail to load the bugdoc during createScDoc("...") - change Target="/xl/xmlMaps.xml" to Target="xmlMaps.xml" in xl/_rels/workbook.xml.rels - change xmlns attribute to xmlns:x in xl/tables/table[n].xml - add XmlColumnPrModel and TableColumnModel - these Models can be used for implementing sub-elements. Signed-off-by: Bayram Çiçek <bayram.ci...@collabora.com> Change-Id: I5e6ad575b7071f3cf4decb5d90d418b9c54ba107 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189050 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index 63141cb9ee08..5723ff4d7743 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -49,12 +49,23 @@ struct TableColumnAttributes }; // xmlColumnPr attributes -struct XmlColumnPrAttributes +struct XmlColumnPrModel { sal_uInt32 mnMapId; OUString msXpath; OUString msXmlDataType; bool mbDenormalized; + + explicit XmlColumnPrModel(); +}; + +struct TableColumnModel +{ + typedef std::unique_ptr<XmlColumnPrModel> XmlColumnPrModelPtr; + XmlColumnPrModelPtr mxXmlColumnPr; // Special settings for XML Column Properties. + XmlColumnPrModel& createXmlColumnPr(); + + explicit TableColumnModel(); }; /** Container base class to provide selected access for ScDBData. */ @@ -108,7 +119,7 @@ private: ::std::vector< OUString > maTableColumnNames; ///< names of table columns ::std::vector< TableColumnAttributes > maTableColumnAttributes; ///< attributes of table columns - ::std::vector< XmlColumnPrAttributes > maXmlColumnPrAttributes; ///< attributes of <xmlColumnPr> + ::std::vector< TableColumnModel > maTableColumnModel; bool mbTableColumnNamesDirty; SCSIZE nFilteredRowCount; @@ -165,8 +176,11 @@ public: SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; } SC_DLLPUBLIC void SetTableColumnAttributes( ::std::vector< TableColumnAttributes >&& rAttributes ); SC_DLLPUBLIC const ::std::vector< TableColumnAttributes >& GetTableColumnAttributes() const { return maTableColumnAttributes; } - SC_DLLPUBLIC void SetXmlColumnPrAttributes( const XmlColumnPrAttributes& rAttributes ); - SC_DLLPUBLIC const ::std::vector< XmlColumnPrAttributes >& GetXmlColumnPrAttributes() const { return maXmlColumnPrAttributes; } + SC_DLLPUBLIC void SetTableColumnModel( TableColumnModel& rModel ) + { + maTableColumnModel.push_back(std::move(rModel)); + } + SC_DLLPUBLIC const ::std::vector< TableColumnModel >& GetTableColumnModel() const { return maTableColumnModel; } bool AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; } /** Refresh/update the column names with the header row's cell contents. */ diff --git a/sc/qa/unit/data/xlsx/tdf167689_xmlMaps_and_xmlColumnPr.xlsx b/sc/qa/unit/data/xlsx/tdf167689_xmlMaps_and_xmlColumnPr.xlsx new file mode 100644 index 000000000000..afa63e3236e4 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf167689_xmlMaps_and_xmlColumnPr.xlsx differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index 2bd47c95359a..b039b5b5c92a 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -1731,6 +1731,28 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTotalsRowFunction) } } +CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf167689_xmlMaps_and_xmlColumnPr) +{ + createScDoc("xlsx/tdf167689_xmlMaps_and_xmlColumnPr.xlsx"); + save(u"Calc Office Open XML"_ustr); + + // xl/xmlMaps.xml + xmlDocUniquePtr pDocXml = parseExport(u"xl/xmlMaps.xml"_ustr); + CPPUNIT_ASSERT(pDocXml); + + assertXPath(pDocXml, + "/x:MapInfo/Schema/xsd:schema/xsd:element/xsd:complexType/xsd:sequence/xsd:element/" + "xsd:complexType/xsd:sequence/xsd:element[3]/xsd:complexType/xsd:sequence/" + "xsd:element[1]", + "name", u"Code"); + + // test <xmlColumnPr> of xl/tables/table1.xml + xmlDocUniquePtr pDocXmlTables = parseExport(u"xl/tables/table1.xml"_ustr); + CPPUNIT_ASSERT(pDocXmlTables); + assertXPath(pDocXmlTables, "/x:table/x:tableColumns/x:tableColumn[1]/x:xmlColumnPr", "xpath", + u"/DataList/TransactionTypeList/TransactionType/Code"); +} + CPPUNIT_TEST_FIXTURE(ScExportTest4, testAutofilterHiddenButton) { createScDoc("xlsx/hiddenButton.xlsx"); diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 74c921f5e87f..b719cb056221 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -702,11 +702,6 @@ void ScDBData::SetTableColumnAttributes( ::std::vector< TableColumnAttributes >& maTableColumnAttributes = std::move(rAttributes); } -void ScDBData::SetXmlColumnPrAttributes( const XmlColumnPrAttributes& rAttributes ) -{ - maXmlColumnPrAttributes.push_back(rAttributes); -} - void ScDBData::AdjustTableColumnAttributes( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 ) { diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 1d44f319d07a..675ec95beea3 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -1280,7 +1280,7 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) // save xl/xmlMaps.xml relationship into xl/_rels/workbook.xml.rels // save xl/xmlMaps.xml reference into [Content_Types].xml and open stream to xl/xmlMaps.xml sax_fastparser::FSHelperPtr aXmlMapsXml = rStrm.CreateOutputStream( - "xl/xmlMaps.xml", u"/xl/xmlMaps.xml", rStrm.GetCurrentStream()->getOutputStream(), + "xl/xmlMaps.xml", u"xmlMaps.xml", rStrm.GetCurrentStream()->getOutputStream(), "application/xml", oox::getRelationship(Relationship::XMLMAPS)); // start exporting xl/xmlMaps.xml diff --git a/sc/source/filter/excel/xedbdata.cxx b/sc/source/filter/excel/xedbdata.cxx index ea5123700feb..128e145ac51d 100644 --- a/sc/source/filter/excel/xedbdata.cxx +++ b/sc/source/filter/excel/xedbdata.cxx @@ -223,7 +223,7 @@ void XclExpTables::SaveTableXml( XclExpXmlStream& rStrm, const Entry& rEntry ) const std::vector< OUString >& rColNames = rData.GetTableColumnNames(); const std::vector< TableColumnAttributes >& rColAttributes = rData.GetTableColumnAttributes(); - const std::vector< XmlColumnPrAttributes >& rXmlColPrAttributes = rData.GetXmlColumnPrAttributes(); + const std::vector< TableColumnModel >& rTableColumnModel = rData.GetTableColumnModel(); if (!rColNames.empty()) { pTableStrm->startElement(XML_tableColumns, @@ -252,18 +252,18 @@ void XclExpTables::SaveTableXml( XclExpXmlStream& rStrm, const Entry& rEntry ) // OOXTODO: XML_uniqueName, ... ); - if (!rXmlColPrAttributes.empty() && (i < rXmlColPrAttributes.size())) + if (i < rTableColumnModel.size() && rTableColumnModel[i].mxXmlColumnPr) { // export <xmlColumnPr> rtl::Reference<sax_fastparser::FastAttributeList> pXmlColumnPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); - pXmlColumnPrAttrList->add(XML_mapId, - OUString::number(rXmlColPrAttributes[i].mnMapId)); - pXmlColumnPrAttrList->add(XML_xpath, rXmlColPrAttributes[i].msXpath); - pXmlColumnPrAttrList->add(XML_xmlDataType, rXmlColPrAttributes[i].msXmlDataType); - pXmlColumnPrAttrList->add(XML_denormalized, - ToPsz10(rXmlColPrAttributes[i].mbDenormalized)); + XmlColumnPrModel* rXmlColRef = rTableColumnModel[i].mxXmlColumnPr.get(); + + pXmlColumnPrAttrList->add(XML_mapId, OUString::number(rXmlColRef->mnMapId)); + pXmlColumnPrAttrList->add(XML_xpath, rXmlColRef->msXpath); + pXmlColumnPrAttrList->add(XML_xmlDataType, rXmlColRef->msXmlDataType); + pXmlColumnPrAttrList->add(XML_denormalized, ToPsz10(rXmlColRef->mbDenormalized)); pTableStrm->singleElement(XML_xmlColumnPr, pXmlColumnPrAttrList); } diff --git a/sc/source/filter/inc/tablecolumnsbuffer.hxx b/sc/source/filter/inc/tablecolumnsbuffer.hxx index c5093392b6ea..d18d9dcab957 100644 --- a/sc/source/filter/inc/tablecolumnsbuffer.hxx +++ b/sc/source/filter/inc/tablecolumnsbuffer.hxx @@ -22,6 +22,7 @@ #include <oox/helper/refvector.hxx> #include <dbdata.hxx> #include "workbookhelper.hxx" +#include <osl/diagnose.h> namespace oox { class AttributeList; } namespace oox { class SequenceInputStream; } @@ -46,15 +47,16 @@ public: const TableColumnAttributes& getColumnAttributes() const; /** Imports XML column properties for the xmlColumnPr element. */ void importXmlColumnPr(const AttributeList& rAttribs); - /** Gets the XML column properties. <xmlColumnPr> */ - const XmlColumnPrAttributes& getXmlColumnPrAttributes() const; + /** Returns access to the table column model data. */ + TableColumnModel& getModel() { return maModel; } private: OUString maName; sal_Int32 mnId; sal_Int32 mnDataDxfId; TableColumnAttributes maColumnAttributes; - XmlColumnPrAttributes maXmlColumnPrAttributes; + + TableColumnModel maModel; }; class TableColumns : public WorkbookHelper diff --git a/sc/source/filter/oox/tablecolumnsbuffer.cxx b/sc/source/filter/oox/tablecolumnsbuffer.cxx index b7a4564b1aa3..55112f7be7d2 100644 --- a/sc/source/filter/oox/tablecolumnsbuffer.cxx +++ b/sc/source/filter/oox/tablecolumnsbuffer.cxx @@ -23,6 +23,23 @@ #include <oox/helper/attributelist.hxx> #include <oox/token/tokens.hxx> +XmlColumnPrModel::XmlColumnPrModel() : + mnMapId( 1 ), + msXpath( OUString() ), + msXmlDataType( OUString() ), + mbDenormalized( false ) +{ +} + +TableColumnModel::TableColumnModel() {} + +XmlColumnPrModel& TableColumnModel::createXmlColumnPr() +{ + OSL_ENSURE( !mxXmlColumnPr, "TableColumnModel::createXmlColumnPr - multiple call" ); + mxXmlColumnPr.reset( new XmlColumnPrModel ); + return *mxXmlColumnPr; +} + namespace oox::xls { TableColumn::TableColumn( const WorkbookHelper& rHelper ) : @@ -59,15 +76,12 @@ const TableColumnAttributes& TableColumn::getColumnAttributes() const void TableColumn::importXmlColumnPr(const AttributeList& rAttribs) { - maXmlColumnPrAttributes.mnMapId = rAttribs.getInteger(XML_mapId, 0); - maXmlColumnPrAttributes.msXpath = rAttribs.getXString(XML_xpath, OUString()); - maXmlColumnPrAttributes.msXmlDataType = rAttribs.getXString(XML_xmlDataType, OUString()); - maXmlColumnPrAttributes.mbDenormalized = rAttribs.getBool(XML_denormalized, false); -} + XmlColumnPrModel& rXmlColumnPr = maModel.createXmlColumnPr(); -const XmlColumnPrAttributes& TableColumn::getXmlColumnPrAttributes() const -{ - return maXmlColumnPrAttributes; + rXmlColumnPr.mnMapId = rAttribs.getInteger(XML_mapId, 0); + rXmlColumnPr.msXpath = rAttribs.getXString(XML_xpath, OUString()); + rXmlColumnPr.msXmlDataType = rAttribs.getXString(XML_xmlDataType, OUString()); + rXmlColumnPr.mbDenormalized = rAttribs.getBool(XML_denormalized, false); } TableColumns::TableColumns( const WorkbookHelper& rHelper ) : @@ -108,7 +122,7 @@ bool TableColumns::finalizeImport( ScDBData* pDBData ) { aNames[i] = rxTableColumn->getName(); aAttributesVector[i] = rxTableColumn->getColumnAttributes(); - pDBData->SetXmlColumnPrAttributes( rxTableColumn->getXmlColumnPrAttributes() ); + pDBData->SetTableColumnModel( rxTableColumn->getModel() ); ++i; } pDBData->SetTableColumnNames( std::move(aNames) ); diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index b2649288d1e2..c55e42f34a15 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -400,10 +400,6 @@ void WorkbookFragment::finalizeImport() std::string sXmlMapsContent; size_t nBufferSize = 4096; - ucbhelper::Content aContent(aXmlMapsFragmentPath, - Reference<css::ucb::XCommandEnvironment>(), - comphelper::getProcessComponentContext()); - Reference<XInputStream> xXmlMapsInputStream( getBaseFilter().openInputStream(aXmlMapsFragmentPath), UNO_SET_THROW);