chart2/source/chart2.component | 5 + chart2/source/tools/ChartTypeHelper.cxx | 2 oox/inc/drawingml/chart/seriescontext.hxx | 14 +++++ oox/inc/drawingml/chart/seriesmodel.hxx | 1 oox/inc/drawingml/chart/typegroupcontext.hxx | 12 ++++ oox/source/drawingml/chart/chartspacefragment.cxx | 47 +++++++++++++++++ oox/source/drawingml/chart/plotareacontext.cxx | 59 +++++++++++++++++++--- oox/source/drawingml/chart/seriescontext.cxx | 48 +++++++++++++++++ oox/source/drawingml/chart/typegroupcontext.cxx | 15 +++++ oox/source/token/tokens.txt | 19 +++++++ 10 files changed, 215 insertions(+), 7 deletions(-)
New commits: commit 84d4a5dc218bf2cef908c614efb7f09c821ae00c Author: knordback <kurt.nordb...@collabora.com> AuthorDate: Thu Mar 13 11:23:31 2025 -0600 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Tue Apr 22 14:39:00 2025 +0200 tdf#165742 Step 3: Establish a narrow input path for chartex This is a subtask of tdf#165742: Chartex charts are lost on input from OOXML and re-export. Build out the narrowest parsing path down to ChartType for funnel charts. No other data or parameters are supported at this point other than the chart type. This is a step towards more extensive support for I/O of chartex charts to/from OOXML. Change-Id: If33f4320c373262de19a7b0b31d28ce8f1de29e8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183463 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/chart2/source/chart2.component b/chart2/source/chart2.component index 9ec6602562cd..e548e68d94f3 100644 --- a/chart2/source/chart2.component +++ b/chart2/source/chart2.component @@ -160,6 +160,11 @@ <service name="com.sun.star.chart2.FormattedString"/> <service name="com.sun.star.chart2.DataPointCustomLabelField"/> </implementation> + <implementation name="com.sun.star.comp.chart.FunnelChartType" + constructor="com_sun_star_comp_chart_FunnelChartType_get_implementation"> + <service name="com.sun.star.chart2.ChartType"/> + <service name="com.sun.star.chart2.FunnelChartType"/> + </implementation> <implementation name="com.sun.star.comp.chart.LineChartType" constructor="com_sun_star_comp_chart_LineChartType_get_implementation"> <service name="com.sun.star.beans.PropertySet"/> diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx index 03539c1883e8..8582611360f9 100644 --- a/chart2/source/tools/ChartTypeHelper.cxx +++ b/chart2/source/tools/ChartTypeHelper.cxx @@ -71,6 +71,7 @@ uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedLabelPlacements( const else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) + || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FUNNEL) // TODO: check this ) { aRet.realloc(5); @@ -310,6 +311,7 @@ uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedMissingValueTreatments( OUString aChartTypeName = xChartType->getChartType(); if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) || + aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FUNNEL) || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) ) { aRet.realloc( 2 ); diff --git a/oox/inc/drawingml/chart/seriescontext.hxx b/oox/inc/drawingml/chart/seriescontext.hxx index d3fe3bb05128..05b3ebe84c66 100644 --- a/oox/inc/drawingml/chart/seriescontext.hxx +++ b/oox/inc/drawingml/chart/seriescontext.hxx @@ -237,6 +237,20 @@ public: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; }; +/** Handler for a data series context for chartex chart types (cx:series element + * for boxWhisker, clusteredColumn/histogram, funnel, paretoLine, waterfall, + * sunburst, treemap, and regionMap). + */ +class ChartexSeriesContext final : public SeriesContextBase +{ +public: + explicit ChartexSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel ); + virtual ~ChartexSeriesContext() override; + + virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; +}; + + } // namespace oox::drawingml::chart diff --git a/oox/inc/drawingml/chart/seriesmodel.hxx b/oox/inc/drawingml/chart/seriesmodel.hxx index 4f48115676f0..81c6e770ee1c 100644 --- a/oox/inc/drawingml/chart/seriesmodel.hxx +++ b/oox/inc/drawingml/chart/seriesmodel.hxx @@ -211,6 +211,7 @@ struct SeriesModel bool mbBubble3d; /// True = show bubbles with 3D shade. bool mbInvertNeg; /// True = invert negative data points. bool mbSmooth; /// True = smooth series line. + sal_Int32 mnCxChartType; /// Enumerated chartex type explicit SeriesModel(bool bMSO2007Doc); ~SeriesModel(); diff --git a/oox/inc/drawingml/chart/typegroupcontext.hxx b/oox/inc/drawingml/chart/typegroupcontext.hxx index d3af8436d7ac..07b45d5c50bd 100644 --- a/oox/inc/drawingml/chart/typegroupcontext.hxx +++ b/oox/inc/drawingml/chart/typegroupcontext.hxx @@ -154,6 +154,18 @@ public: }; +/** Handler for chartex type group contexts + */ +class ChartexTypeGroupContext final : public TypeGroupContextBase +{ +public: + explicit ChartexTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel ); + virtual ~ChartexTypeGroupContext() override; + + virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; +}; + + } // namespace oox::drawingml::chart #endif diff --git a/oox/source/drawingml/chart/chartspacefragment.cxx b/oox/source/drawingml/chart/chartspacefragment.cxx index 538631ee63ca..1361ddf31d7a 100644 --- a/oox/source/drawingml/chart/chartspacefragment.cxx +++ b/oox/source/drawingml/chart/chartspacefragment.cxx @@ -52,7 +52,7 @@ ContextHandlerRef ChartSpaceFragment::onCreateContext( sal_Int32 nElement, const case C_TOKEN( chartSpace ): return this; case CX_TOKEN(chartSpace) : - break; + return this; } break; @@ -136,7 +136,52 @@ ContextHandlerRef ChartSpaceFragment::onCreateContext( sal_Int32 nElement, const return new View3DContext( *this, mrModel.mxView3D.create(bMSO2007Document) ); } break; + + // chartex handling case CX_TOKEN(chartSpace) : + switch (nElement) { + case CX_TOKEN(chartData): + // TODO + return nullptr; + case CX_TOKEN(chart): + return this; + case CX_TOKEN(spPr): + return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); + case CX_TOKEN(txPr): + return new TextBodyContext( *this, mrModel.mxTextProp.create() ); + case CX_TOKEN(clrMapOvr): + // TODO + return nullptr; + case CX_TOKEN(fmtOvrs): + // TODO + return nullptr; + case CX_TOKEN(printSettings): + // TODO + return nullptr; + case CX_TOKEN(extLst): + // TODO + return nullptr; + default: + // shouldn't happen + assert(false); + + } + break; + case CX_TOKEN(chart) : + switch (nElement) { + case CX_TOKEN(title): + return new TitleContext( *this, mrModel.mxTitle.create() ); + case CX_TOKEN(plotArea): + return new PlotAreaContext( *this, mrModel.mxPlotArea.create() ); + case CX_TOKEN(legend): + return new LegendContext( *this, mrModel.mxLegend.create() ); + case CX_TOKEN(extLst): + // TODO + return nullptr; + default: + // shouldn't happen + assert(false); + } break; } return nullptr; diff --git a/oox/source/drawingml/chart/plotareacontext.cxx b/oox/source/drawingml/chart/plotareacontext.cxx index 7ffa7c81eed0..5ab97cb70497 100644 --- a/oox/source/drawingml/chart/plotareacontext.cxx +++ b/oox/source/drawingml/chart/plotareacontext.cxx @@ -116,7 +116,7 @@ PlotAreaContext::~PlotAreaContext() { } -ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs) { bool bMSO2007Doc = getFilter().isMSO2007Document(); switch( getCurrentElement() ) @@ -165,12 +165,59 @@ ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const At return new ShapePropertiesContext( *this, mrModel.mxShapeProp.getOrCreate() ); case C_TOKEN(dTable): return new DataTableContext( *this, mrModel.mxDataTable.create() ); -#if 0 - case CHARTEX_TOKEN( funnel ): - return new FunnelTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement, false ) ); -#endif } - break; + break; + case CX_TOKEN(plotArea) : + switch (nElement) { + case CX_TOKEN(plotAreaRegion) : + return this; + case CX_TOKEN(axis) : + // TODO + return nullptr; + case CX_TOKEN(spPr) : + return new ShapePropertiesContext( *this, mrModel.mxShapeProp.getOrCreate() ); + case CX_TOKEN(extLst) : + // TODO + return nullptr; + } + break; + case CX_TOKEN(plotAreaRegion) : + switch (nElement) { + case CX_TOKEN(plotSurface) : + // TODO + return nullptr; + case CX_TOKEN(series) : + if (rAttribs.hasAttribute(XML_layoutId)) { + sal_Int32 nChartType = 0; + OUString sChartId = rAttribs.getStringDefaulted(XML_layoutId); + assert(!sChartId.isEmpty()); + + if (sChartId == "boxWhisker") { + nChartType = CX_TOKEN(boxWhisker); + } else if (sChartId == "clusteredColumn") { + nChartType = CX_TOKEN(clusteredColumn); + } else if (sChartId == "funnel") { + nChartType = CX_TOKEN(funnel); + } else if (sChartId == "paretoLine") { + nChartType = CX_TOKEN(paretoLine); + } else if (sChartId == "regionMap") { + nChartType = CX_TOKEN(regionMap); + } else if (sChartId == "sunburst") { + nChartType = CX_TOKEN(sunburst); + } else if (sChartId == "treemap") { + nChartType = CX_TOKEN(treemap); + } else if (sChartId == "waterfall") { + nChartType = CX_TOKEN(waterfall); + } + assert(nChartType != 0); + + return new ChartexTypeGroupContext( *this, + mrModel.maTypeGroups.create( nChartType, false ) ); + } + break; + + } + break; } return nullptr; } diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx index bfbc28304ab3..867ba684fd2d 100644 --- a/oox/source/drawingml/chart/seriescontext.cxx +++ b/oox/source/drawingml/chart/seriescontext.cxx @@ -445,6 +445,7 @@ ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const mrModel.mxLabels->mpLabelsSource = &rLabelsSource; return new DataSourceContext( *this, rLabelsSource ); } + break; } return nullptr; } @@ -746,6 +747,53 @@ ContextHandlerRef SurfaceSeriesContext::onCreateContext( sal_Int32 nElement, con return SeriesContextBase::onCreateContext( nElement, rAttribs ); } +ChartexSeriesContext::ChartexSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) : + SeriesContextBase( rParent, rModel ) +{ +} + +ChartexSeriesContext::~ChartexSeriesContext() +{ +} + +ContextHandlerRef ChartexSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( getCurrentElement() ) + { + case CX_TOKEN( tx ): + // TODO + return nullptr; + case CX_TOKEN( spPr ): + // TODO + return nullptr; + case CX_TOKEN( valueColors ): + // TODO + return nullptr; + case CX_TOKEN( valueColorPositions ): + // TODO + return nullptr; + case CX_TOKEN( dataPt ): + // TODO + return nullptr; + case CX_TOKEN( dataLabels ): + // TODO + return nullptr; + case CX_TOKEN( dataId ): + // TODO + return nullptr; + case CX_TOKEN( layoutPr ): + // TODO + return nullptr; + case CX_TOKEN( axisId ): + // TODO + return nullptr; + case CX_TOKEN( extLst ): + // TODO + return nullptr; + } + return SeriesContextBase::onCreateContext( nElement, rAttribs ); +} + } // namespace oox /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/chart/typegroupcontext.cxx b/oox/source/drawingml/chart/typegroupcontext.cxx index 393073261533..d5f97c25cdac 100644 --- a/oox/source/drawingml/chart/typegroupcontext.cxx +++ b/oox/source/drawingml/chart/typegroupcontext.cxx @@ -396,6 +396,21 @@ ContextHandlerRef SurfaceTypeGroupContext::onCreateContext( sal_Int32 nElement, return nullptr; } +ChartexTypeGroupContext::ChartexTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) : + TypeGroupContextBase( rParent, rModel ) +{ +} + +ChartexTypeGroupContext::~ChartexTypeGroupContext() +{ +} + +ContextHandlerRef ChartexTypeGroupContext::onCreateContext( [[maybe_unused]] sal_Int32 nElement, + [[maybe_unused]] const AttributeList& rAttribs ) +{ + return new ChartexSeriesContext( *this, mrModel.maSeries.create(false) ); +} + } // namespace oox::drawingml::chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 333dc269dfd8..a51a44c77bdf 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -750,6 +750,7 @@ axPos axis axisCol axisColor +axisId axisPage axisPosition axisRow @@ -967,6 +968,7 @@ bottomRight boundingCube box boxPr +boxWhisker br bracePair bracketPair @@ -1172,6 +1174,7 @@ characteristic charset chart chartAndTx +chartData chartFormat chartFormats chartObject @@ -1260,6 +1263,7 @@ clrTo clrVal clsid clustered +clusteredColumn cm cmAuthor cmAuthorLst @@ -1654,11 +1658,14 @@ dataDxfId dataExtractLoad dataField dataFields +dataId +dataLabels dataModel dataModelExt dataOnRows dataOnly dataPosition +dataPt dataRef dataRefs dataSource @@ -2353,6 +2360,7 @@ flythrough fmla fmt fmtId +fmtOvrs fmtScheme fmtid focus @@ -3019,8 +3027,10 @@ layout layoutDef layoutDefHdr layoutDefHdrLst +layoutId layoutInCell layoutNode +layoutPr layoutRawTableWidth layoutTableRowsApart layoutTarget @@ -3897,6 +3907,7 @@ parameterType parameters parent parentSet +paretoLine parsePre partyFavor partyGlass @@ -4056,6 +4067,8 @@ plaqueTabs plastic plcHide plotArea +plotAreaRegion +plotSurface plotVisOnly plum plus @@ -4299,6 +4312,7 @@ refreshOnLoad refreshedBy refreshedDate refreshedVersion +regionMap regroupid regrouptable regular @@ -5076,6 +5090,7 @@ summaryBelow summaryLength summaryRight sun +sunburst sunrise sunset sup @@ -5435,6 +5450,7 @@ translucentPowder transp trapezoid tree +treemap trees trellis trend @@ -5646,6 +5662,8 @@ val valAx value valueBetween +valueColors +valueColorPositions valueEqual valueGreaterThan valueGreaterThanOrEqual @@ -5728,6 +5746,7 @@ wR warmMatte warning warp +waterfall watermarks wavAudioFile wave