From b10d331c1c9801adbf6d014d9348bb0a4dad3d2c Mon Sep 17 00:00:00 2001 From: Kurt Nordback Date: Wed, 17 Jul 2024 17:07:05 -0600 Subject: [PATCH] tdf#161800 - I/O of '# of values in second plot' parameter not supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for input and output of 'split position' parameter (number of entries in second plot) for of-pie charts. In OOXML this uses the supported split-pos tag. For ODF I added an extension in loext namespace for this parameter. This commit also includes simple tests for the I/O functionality in OOXML and ODF. Change-Id: I00ff59db721867fa836eb99b6677350040d005dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170666 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- chart2/qa/extras/chart2export.cxx | 65 ++++++++++++++++++ .../data/ods/tdf161800_barOfPie_split_pos.ods | Bin 0 -> 15011 bytes .../data/ods/tdf161800_pieOfPie_split_pos.ods | Bin 0 -> 15964 bytes .../qa/extras/data/xlsx/barOfPieChart2.xlsx | Bin 0 -> 8130 bytes .../qa/extras/data/xlsx/pieOfPieChart2.xlsx | Bin 0 -> 8036 bytes .../chartapiwrapper/DiagramWrapper.cxx | 6 +- .../dialogs/ChartTypeDialogController.cxx | 21 +++++- .../controller/dialogs/tp_ChartType.cxx | 3 +- .../controller/sidebar/ChartTypePanel.cxx | 4 +- chart2/source/inc/ChartType.hxx | 2 +- .../source/inc/ChartTypeDialogController.hxx | 6 +- chart2/source/model/main/Diagram.cxx | 6 ++ .../model/template/ChartTypeManager.cxx | 20 +++--- chart2/source/model/template/PieChartType.cxx | 6 +- .../model/template/PieChartTypeTemplate.cxx | 15 ++-- .../model/template/PieChartTypeTemplate.hxx | 1 + chart2/source/view/charttypes/PieChart.cxx | 21 +++--- chart2/source/view/charttypes/PieChart.hxx | 8 +-- .../view/main/SeriesPlotterContainer.cxx | 6 ++ include/oox/export/chartexport.hxx | 2 +- .../drawingml/chart/typegroupcontext.cxx | 2 +- .../drawingml/chart/typegroupconverter.cxx | 4 ++ oox/source/drawingml/chart/typegroupmodel.cxx | 2 +- oox/source/export/chartexport.cxx | 13 +++- oox/source/token/properties.txt | 1 + .../OpenDocument-v1.4+libreoffice-schema.rng | 9 +++ xmloff/inc/xmlprop.hxx | 1 + xmloff/source/chart/SchXMLChartContext.cxx | 9 ++- xmloff/source/chart/SchXMLChartContext.hxx | 1 + xmloff/source/chart/SchXMLExport.cxx | 37 +++++++++- 30 files changed, 218 insertions(+), 53 deletions(-) create mode 100644 chart2/qa/extras/data/ods/tdf161800_barOfPie_split_pos.ods create mode 100644 chart2/qa/extras/data/ods/tdf161800_pieOfPie_split_pos.ods create mode 100644 chart2/qa/extras/data/xlsx/barOfPieChart2.xlsx create mode 100644 chart2/qa/extras/data/xlsx/pieOfPieChart2.xlsx diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx index c57c238ef3b0..3f37794e1d10 100644 --- a/chart2/qa/extras/chart2export.cxx +++ b/chart2/qa/extras/chart2export.cxx @@ -546,6 +546,28 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testBarOfPieChart) assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:ofPieChart/c:ofPieType[1]", "val", u"bar"); } +CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testPieOfPieSplitPos) +{ + loadFromFile(u"xlsx/pieOfPieChart2.xlsx"); + save(u"Calc Office Open XML"_ustr); + xmlDocUniquePtr pXmlDoc = parseExport(u"xl/charts/chart1.xml"_ustr); + CPPUNIT_ASSERT(pXmlDoc); + + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:ofPieChart"); + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:ofPieChart/c:splitPos[1]", "val", u"4"); +} + +CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testBarOfPieSplitPos) +{ + loadFromFile(u"xlsx/barOfPieChart2.xlsx"); + save(u"Calc Office Open XML"_ustr); + xmlDocUniquePtr pXmlDoc = parseExport(u"xl/charts/chart1.xml"_ustr); + CPPUNIT_ASSERT(pXmlDoc); + + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:ofPieChart"); + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:ofPieChart/c:splitPos[1]", "val", u"5"); +} + CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testDisplayUnits) { loadFromFile(u"docx/DisplayUnits.docx"); @@ -1133,6 +1155,49 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest, tdf50934_pieOfPie) CPPUNIT_ASSERT_EQUAL(chart2::PieChartSubType_PIE, subPieType); } +CPPUNIT_TEST_FIXTURE(Chart2ExportTest, tdf161800_barOfPie_split_pos) +{ + loadFromFile(u"ods/tdf161800_barOfPie_split_pos.ods"); + saveAndReload(u"calc8"_ustr); + + uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0 ); + CPPUNIT_ASSERT(xChartDoc.is()); + + Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, 0 ); + CPPUNIT_ASSERT(xChartType.is()); + + // Verify that it saves and loads with the correct split position + Reference< beans::XPropertySet > xPropSet( xChartType, uno::UNO_QUERY_THROW ); + uno::Any aAny = xPropSet->getPropertyValue(u"SplitPos"_ustr); + CPPUNIT_ASSERT(aAny.hasValue()); + double nSplitPos; + aAny >>= nSplitPos; + CPPUNIT_ASSERT_EQUAL(4.0, nSplitPos); +} + +CPPUNIT_TEST_FIXTURE(Chart2ExportTest, tdf161800_pieOfPie_split_pos) +{ + loadFromFile(u"ods/tdf161800_pieOfPie_split_pos.ods"); + saveAndReload(u"calc8"_ustr); + + uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0 ); + CPPUNIT_ASSERT(xChartDoc.is()); + + Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, 0 ); + CPPUNIT_ASSERT(xChartType.is()); + + CPPUNIT_ASSERT_EQUAL(u"com.sun.star.chart2.PieChartType"_ustr, + xChartType->getChartType()); + + // Verify that it saves and loads with the correct split position + Reference< beans::XPropertySet > xPropSet( xChartType, uno::UNO_QUERY_THROW ); + uno::Any aAny = xPropSet->getPropertyValue(u"SplitPos"_ustr); + CPPUNIT_ASSERT(aAny.hasValue()); + double nSplitPos; + aAny >>= nSplitPos; + CPPUNIT_ASSERT_EQUAL(3.0, nSplitPos); +} + CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testChartCrash) { loadFromFile(u"docx/FDO75975.docx"); diff --git a/chart2/qa/extras/data/ods/tdf161800_barOfPie_split_pos.ods b/chart2/qa/extras/data/ods/tdf161800_barOfPie_split_pos.ods new file mode 100644 index 0000000000000000000000000000000000000000..a87941bfa22d073600d8676a71330661124ddef9 GIT binary patch literal 15011 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 literal 0 HcmV?d00001 diff --git a/chart2/qa/extras/data/xlsx/barOfPieChart2.xlsx b/chart2/qa/extras/data/xlsx/barOfPieChart2.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..be24cd293915a8f77ad31c0db7df5f1c6b0ebeab GIT binary patch literal 8130 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 literal 0 HcmV?d00001 diff --git a/chart2/qa/extras/data/xlsx/pieOfPieChart2.xlsx b/chart2/qa/extras/data/xlsx/pieOfPieChart2.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..c80f0169cc89baab5387aebfeaf9cae6f9fc0b4c GIT binary patch literal 8036 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::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); - rOutProperties.emplace_back( "CompositeSize", - PROP_DIAGRAM_COMPOSITE_SIZE, + rOutProperties.emplace_back( "SplitPos", + PROP_DIAGRAM_SPLIT_POS, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); diff --git a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx index 308ff1930457..365df1c328f9 100644 --- a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx +++ b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx @@ -305,7 +305,8 @@ rtl::Reference< ChartTypeTemplate > ChartTypeDialogController::getCurrentTemplat } void ChartTypeDialogController::commitToModel( const ChartTypeParameter& rParameter - , const rtl::Reference<::chart::ChartModel>& xChartModel ) + , const rtl::Reference<::chart::ChartModel>& xChartModel + , const uno::Reference& xTemplateProps) { rtl::Reference< ::chart::ChartTypeManager > xTemplateManager = xChartModel->getTypeManager(); rtl::Reference< ::chart::ChartTypeTemplate > xTemplate( getCurrentTemplate( rParameter, xTemplateManager ) ); @@ -329,6 +330,20 @@ void ChartTypeDialogController::commitToModel( const ChartTypeParameter& rParame if (xDiagram.is()) { xDiagram->setPropertyValue(CHART_UNONAME_SORT_BY_XVALUES, uno::Any(rParameter.bSortByXValues)); + + sal_Int32 nSplitPos; + try { + if (xTemplateProps.is()) { + xTemplateProps->getPropertyValue(u"SplitPos"_ustr) >>= nSplitPos; + xDiagram->setPropertyValue(u"SplitPos"_ustr, uno::Any(nSplitPos)); + } + } + catch( uno::Exception & ex ) + { + //not all templates need to support SplitPos + ex.Context.is();//to have debug information without compilation warnings + } + } } void ChartTypeDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& /*rParameter*/ ) @@ -763,7 +778,7 @@ void OfPieChartDialogController::fillExtraControls( { try { - xTemplateProps->getPropertyValue( u"CompositeSize"_ustr ) >>= nCompositeSize; + xTemplateProps->getPropertyValue( u"SplitPos"_ustr ) >>= nCompositeSize; } catch( const uno::Exception & ) { @@ -801,7 +816,7 @@ void OfPieChartDialogController::setTemplateProperties( const uno::Reference< be if( xTemplateProps.is()) { sal_Int32 nCompositeSize = m_xMF_CompositeSize->get_value(); - xTemplateProps->setPropertyValue( u"CompositeSize"_ustr , uno::Any(nCompositeSize) ); + xTemplateProps->setPropertyValue( u"SplitPos"_ustr , uno::Any(nCompositeSize) ); } } diff --git a/chart2/source/controller/dialogs/tp_ChartType.cxx b/chart2/source/controller/dialogs/tp_ChartType.cxx index 811c4df19017..12fa0325cef4 100644 --- a/chart2/source/controller/dialogs/tp_ChartType.cxx +++ b/chart2/source/controller/dialogs/tp_ChartType.cxx @@ -166,7 +166,8 @@ void ChartTypeTabPage::commitToModel( const ChartTypeParameter& rParameter ) return; m_aTimerTriggeredControllerLock.startTimer(); - m_pCurrentMainType->commitToModel( rParameter, m_xChartModel ); + uno::Reference< beans::XPropertySet > xTemplateProps( static_cast(getCurrentTemplate().get()), uno::UNO_QUERY ); + m_pCurrentMainType->commitToModel( rParameter, m_xChartModel, xTemplateProps ); } void ChartTypeTabPage::stateChanged() diff --git a/chart2/source/controller/sidebar/ChartTypePanel.cxx b/chart2/source/controller/sidebar/ChartTypePanel.cxx index 38ea92912a19..fa85ded6d4a6 100644 --- a/chart2/source/controller/sidebar/ChartTypePanel.cxx +++ b/chart2/source/controller/sidebar/ChartTypePanel.cxx @@ -391,7 +391,9 @@ void ChartTypePanel::commitToModel(const ChartTypeParameter& rParameter) return; m_aTimerTriggeredControllerLock.startTimer(); - m_pCurrentMainType->commitToModel(rParameter, m_xChartModel); + uno::Reference xTemplateProps( + static_cast(getCurrentTemplate().get()), uno::UNO_QUERY); + m_pCurrentMainType->commitToModel(rParameter, m_xChartModel, xTemplateProps); } void ChartTypePanel::selectMainType() diff --git a/chart2/source/inc/ChartType.hxx b/chart2/source/inc/ChartType.hxx index 7b1fccfb159e..697b0d7ffc91 100644 --- a/chart2/source/inc/ChartType.hxx +++ b/chart2/source/inc/ChartType.hxx @@ -43,7 +43,7 @@ enum PROP_PIECHARTTYPE_USE_RINGS, PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, PROP_PIECHARTTYPE_SUBTYPE, // none, of-bar, of-pie - PROP_PIECHARTTYPE_COMPOSITESIZE + PROP_PIECHARTTYPE_SPLIT_POS }; diff --git a/chart2/source/inc/ChartTypeDialogController.hxx b/chart2/source/inc/ChartTypeDialogController.hxx index cbeeb8b59406..1d36a433d96a 100644 --- a/chart2/source/inc/ChartTypeDialogController.hxx +++ b/chart2/source/inc/ChartTypeDialogController.hxx @@ -130,8 +130,10 @@ public: virtual void adjustParameterToSubType(ChartTypeParameter& rParameter); virtual void adjustParameterToMainType(ChartTypeParameter& rParameter); OUString getServiceNameForParameter(const ChartTypeParameter& rParameter) const; - void commitToModel(const ChartTypeParameter& rParameter, - const rtl::Reference<::chart::ChartModel>& xChartModel); + void + commitToModel(const ChartTypeParameter& rParameter, + const rtl::Reference<::chart::ChartModel>& xChartModel, + const css::uno::Reference& xTemplateProps); rtl::Reference<::chart::ChartTypeTemplate> getCurrentTemplate(const ChartTypeParameter& rParameter, const rtl::Reference<::chart::ChartTypeManager>& xTemplateManager) const; diff --git a/chart2/source/model/main/Diagram.cxx b/chart2/source/model/main/Diagram.cxx index bbd5dd61fab2..c3c4e0be9cc6 100644 --- a/chart2/source/model/main/Diagram.cxx +++ b/chart2/source/model/main/Diagram.cxx @@ -98,6 +98,7 @@ enum PROP_DIAGRAM_3DRELATIVEHEIGHT, PROP_DIAGRAM_DATATABLEHBORDER, PROP_DIAGRAM_OF_PIE_TYPE, + PROP_DIAGRAM_SPLIT_POS, PROP_DIAGRAM_DATATABLEVBORDER, PROP_DIAGRAM_DATATABLEOUTLINE, PROP_DIAGRAM_EXTERNALDATA @@ -188,6 +189,10 @@ void lcl_AddPropertiesToVector( PROP_DIAGRAM_OF_PIE_TYPE, cppu::UnoType::get(), beans::PropertyAttribute::MAYBEVOID ); + rOutProperties.emplace_back( "SplitPos", + PROP_DIAGRAM_SPLIT_POS, + cppu::UnoType::get(), + beans::PropertyAttribute::MAYBEVOID ); rOutProperties.emplace_back( "ExternalData", PROP_DIAGRAM_EXTERNALDATA, cppu::UnoType::get(), @@ -209,6 +214,7 @@ const ::chart::tPropertyValueMap& StaticDiagramDefaults() ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aMap, PROP_DIAGRAM_3DRELATIVEHEIGHT, 100 ); ::chart::PropertyHelper::setPropertyValueDefault< chart2::PieChartSubType >( aMap, PROP_DIAGRAM_OF_PIE_TYPE, chart2::PieChartSubType_NONE); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aMap, PROP_DIAGRAM_SPLIT_POS, 2 ); ::chart::SceneProperties::AddDefaultsToMap( aMap ); return aMap; }(); diff --git a/chart2/source/model/template/ChartTypeManager.cxx b/chart2/source/model/template/ChartTypeManager.cxx index b81e47ee3884..deb70d9aa03c 100644 --- a/chart2/source/model/template/ChartTypeManager.cxx +++ b/chart2/source/model/template/ChartTypeManager.cxx @@ -396,52 +396,52 @@ rtl::Reference< ::chart::ChartTypeTemplate > ChartTypeManager::createTemplate( case TEMPLATE_PIE: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, false, - chart2::PieChartSubType_NONE, 2 )); + chart2::PieChartSubType_NONE, 3, 2)); break; case TEMPLATE_PIEALLEXPLODED: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_ALL_EXPLODED, false, - chart2::PieChartSubType_NONE, 2 )); + chart2::PieChartSubType_NONE, 3, 2 )); break; case TEMPLATE_DONUT: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, true, - chart2::PieChartSubType_NONE, 2 )); + chart2::PieChartSubType_NONE, 3, 2 )); break; case TEMPLATE_DONUTALLEXPLODED: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_ALL_EXPLODED, true, - chart2::PieChartSubType_NONE, 2 )); + chart2::PieChartSubType_NONE, 3, 2 )); break; case TEMPLATE_BAROFPIE: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, false, - chart2::PieChartSubType_BAR, 2 )); + chart2::PieChartSubType_BAR, 3, 2 )); break; case TEMPLATE_PIEOFPIE: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, false, - chart2::PieChartSubType_PIE, 2 )); + chart2::PieChartSubType_PIE, 3, 2 )); break; case TEMPLATE_THREEDPIE: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, false, - chart2::PieChartSubType_NONE, 3 )); + chart2::PieChartSubType_NONE, 3, 3 )); break; case TEMPLATE_THREEDPIEALLEXPLODED: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_ALL_EXPLODED, false, - chart2::PieChartSubType_NONE, 3 )); + chart2::PieChartSubType_NONE, 3, 3 )); break; case TEMPLATE_THREEDDONUT: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_NONE, true, - chart2::PieChartSubType_NONE, 3 )); + chart2::PieChartSubType_NONE, 3, 3 )); break; case TEMPLATE_THREEDDONUTALLEXPLODED: xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, chart2::PieChartOffsetMode_ALL_EXPLODED, true, - chart2::PieChartSubType_NONE, 3 )); + chart2::PieChartSubType_NONE, 3, 3 )); break; case TEMPLATE_SCATTERLINESYMBOL: diff --git a/chart2/source/model/template/PieChartType.cxx b/chart2/source/model/template/PieChartType.cxx index 224b37a88865..36f9a59d0862 100644 --- a/chart2/source/model/template/PieChartType.cxx +++ b/chart2/source/model/template/PieChartType.cxx @@ -47,7 +47,7 @@ namespace ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, ::chart::PROP_PIECHARTTYPE_USE_RINGS, false ); ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, ::chart::PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, 100 ); ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, ::chart::PROP_PIECHARTTYPE_SUBTYPE, chart2::PieChartSubType_NONE ); - ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, ::chart::PROP_PIECHARTTYPE_COMPOSITESIZE, 2 ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, ::chart::PROP_PIECHARTTYPE_SPLIT_POS, 2 ); return aOutMap; }(); return aStaticDefaults; @@ -72,8 +72,8 @@ namespace ::chart::PROP_PIECHARTTYPE_SUBTYPE, cppu::UnoType::get(), beans::PropertyAttribute::MAYBEDEFAULT }, - { u"CompositeSize"_ustr, - ::chart::PROP_PIECHARTTYPE_COMPOSITESIZE, + { u"SplitPos"_ustr, + ::chart::PROP_PIECHARTTYPE_SPLIT_POS, cppu::UnoType::get(), beans::PropertyAttribute::MAYBEVOID } }; diff --git a/chart2/source/model/template/PieChartTypeTemplate.cxx b/chart2/source/model/template/PieChartTypeTemplate.cxx index cc5c0c0ed09f..0cdeb48ecfce 100644 --- a/chart2/source/model/template/PieChartTypeTemplate.cxx +++ b/chart2/source/model/template/PieChartTypeTemplate.cxx @@ -56,7 +56,7 @@ enum PROP_PIE_TEMPLATE_DIMENSION, PROP_PIE_TEMPLATE_USE_RINGS, PROP_PIE_TEMPLATE_SUB_PIE_TYPE, - PROP_PIE_TEMPLATE_COMPOSITE_SIZE + PROP_PIE_TEMPLATE_SPLIT_POS }; ::chart::tPropertyValueMap& StaticPieChartTypeTemplateDefaults() @@ -69,7 +69,8 @@ enum ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIE_TEMPLATE_DIMENSION, 2 ); ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_USE_RINGS, false ); ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_SUB_PIE_TYPE, chart2::PieChartSubType_NONE ); - ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIE_TEMPLATE_COMPOSITE_SIZE, 2 ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( + aOutMap, PROP_PIE_TEMPLATE_SPLIT_POS, 2 ); return aOutMap; }(); return aStaticDefaults; @@ -106,8 +107,8 @@ enum cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT }, - { u"CompositeSize"_ustr, - PROP_PIE_TEMPLATE_COMPOSITE_SIZE, + { u"SplitPos"_ustr, + PROP_PIE_TEMPLATE_SPLIT_POS, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT } @@ -140,6 +141,7 @@ PieChartTypeTemplate::PieChartTypeTemplate( chart2::PieChartOffsetMode eMode, bool bRings, chart2::PieChartSubType eSubType, + sal_Int32 nCompositeSize, sal_Int32 nDim /* = 2 */ ) : ChartTypeTemplate( xContext, rServiceName ) { @@ -147,7 +149,7 @@ PieChartTypeTemplate::PieChartTypeTemplate( setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DIMENSION, uno::Any( nDim )); setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_USE_RINGS, uno::Any( bRings )); setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_SUB_PIE_TYPE, uno::Any( eSubType )); - setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_COMPOSITE_SIZE, uno::Any( sal_Int32(2) )); + setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_SPLIT_POS, uno::Any( nCompositeSize )); } PieChartTypeTemplate::~PieChartTypeTemplate() @@ -274,7 +276,8 @@ void PieChartTypeTemplate::createChartTypes( xCT->setFastPropertyValue( PROP_PIECHARTTYPE_SUBTYPE, getFastPropertyValue( PROP_PIE_TEMPLATE_SUB_PIE_TYPE )); // "SubType" xCT->setFastPropertyValue( - PROP_PIECHARTTYPE_COMPOSITESIZE, getFastPropertyValue( PROP_PIE_TEMPLATE_COMPOSITE_SIZE )); // "CompositeSize" + PROP_PIECHARTTYPE_SPLIT_POS, getFastPropertyValue( + PROP_PIE_TEMPLATE_SPLIT_POS )); // "CompositeSize" rCoordSys[0]->setChartTypes( std::vector{xCT} ); if( !aSeriesSeq.empty() ) diff --git a/chart2/source/model/template/PieChartTypeTemplate.hxx b/chart2/source/model/template/PieChartTypeTemplate.hxx index c7b3b9b6951c..d95b8c49d900 100644 --- a/chart2/source/model/template/PieChartTypeTemplate.hxx +++ b/chart2/source/model/template/PieChartTypeTemplate.hxx @@ -39,6 +39,7 @@ public: css::chart2::PieChartOffsetMode eMode, bool bRings, css::chart2::PieChartSubType eSubType, + sal_Int32 nCompositeSize, sal_Int32 nDim ); virtual ~PieChartTypeTemplate() override; diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx index 4bda2129817d..82ed7f32f6d4 100644 --- a/chart2/source/view/charttypes/PieChart.cxx +++ b/chart2/source/view/charttypes/PieChart.cxx @@ -195,7 +195,7 @@ PieChart::PieChart( const rtl::Reference& xChartTypeModel , m_bUseRings(false) , m_bSizeExcludesLabelsAndExplodedSegments(bExcludingPositioning) , m_eSubType(PieChartSubType_NONE) - , m_nCompositeSize(2) + , m_nSplitPos(2) , m_fMaxOffset(std::numeric_limits::quiet_NaN()) { PlotterBase::m_pPosHelper = &m_aPosHelper; @@ -230,7 +230,7 @@ PieChart::PieChart( const rtl::Reference& xChartTypeModel } try { - xChartTypeModel->getFastPropertyValue(PROP_PIECHARTTYPE_COMPOSITESIZE) >>= m_nCompositeSize; // "CompositeSize" + xChartTypeModel->getFastPropertyValue(PROP_PIECHARTTYPE_SPLIT_POS) >>= m_nSplitPos; // "CompositeSize" } catch( const uno::Exception& ) { @@ -1050,7 +1050,7 @@ void PieChart::createShapes() PieDataSrcBase *pDataSrc = nullptr; PieDataSrc normalPieSrc; - OfPieDataSrc ofPieSrc(m_nCompositeSize); + OfPieDataSrc ofPieSrc(m_nSplitPos); // Default to regular pie if too few points for of-pie ::css::chart2::PieChartSubType eSubType = @@ -2303,26 +2303,25 @@ uno::Reference< beans::XPropertySet > PieDataSrc::getProps( // class OfPieDataSrc //======================= -// For now, just implement the default Excel behavior, which is that the -// right pie consists of the last three entries in the series. Other -// behaviors should be supported later. +// Support data splits only of the type "last n entries go in right subchart", +// for now. // TODO sal_Int32 OfPieDataSrc::getNPoints(const VDataSeries* pSeries, enum SubPieType eType) const { if (eType == SubPieType::LEFT) { - return pSeries->getTotalPointCount() - m_nCompositeSize + 1; + return pSeries->getTotalPointCount() - m_nSplitPos + 1; } else { assert(eType == SubPieType::RIGHT); - return m_nCompositeSize; + return m_nSplitPos; } } double OfPieDataSrc::getData(const VDataSeries* pSeries, sal_Int32 nPtIdx, enum SubPieType eType) const { - const sal_Int32 n = pSeries->getTotalPointCount() - m_nCompositeSize; + const sal_Int32 n = pSeries->getTotalPointCount() - m_nSplitPos; if (eType == SubPieType::LEFT) { // nPtIdx should be in [0, n] if (nPtIdx < n) { @@ -2331,7 +2330,7 @@ double OfPieDataSrc::getData(const VDataSeries* pSeries, sal_Int32 nPtIdx, // composite wedge assert(nPtIdx == n); double total = 0; - for (sal_Int32 i = n; i < n + m_nCompositeSize; ++i) { + for (sal_Int32 i = n; i < n + m_nSplitPos; ++i) { total += pSeries->getYValue(i); } return total; @@ -2347,7 +2346,7 @@ uno::Reference< beans::XPropertySet > OfPieDataSrc::getProps( enum SubPieType eType) const { const sal_Int32 nPts = pSeries->getTotalPointCount(); - const sal_Int32 n = nPts - m_nCompositeSize; + const sal_Int32 n = nPts - m_nSplitPos; if (eType == SubPieType::LEFT) { // nPtIdx should be in [0, n] if (nPtIdx < n) { diff --git a/chart2/source/view/charttypes/PieChart.hxx b/chart2/source/view/charttypes/PieChart.hxx index c5cb1e535cc8..b2fa3b8982ec 100644 --- a/chart2/source/view/charttypes/PieChart.hxx +++ b/chart2/source/view/charttypes/PieChart.hxx @@ -101,8 +101,8 @@ public: class OfPieDataSrc : public PieDataSrcBase { public: - OfPieDataSrc(sal_Int32 nCompositeSize): - m_nCompositeSize(nCompositeSize) + OfPieDataSrc(sal_Int32 nSplitPos): + m_nSplitPos(nSplitPos) {} // Minimum sensible number of data points @@ -118,7 +118,7 @@ public: const VDataSeries* pSeries, sal_Int32 nPtIdx, enum SubPieType eType) const; private: - sal_Int32 m_nCompositeSize; + double m_nSplitPos; }; //======================= @@ -276,7 +276,7 @@ private: //member bool m_bSizeExcludesLabelsAndExplodedSegments; ::css::chart2::PieChartSubType m_eSubType; // Number of entries in an of-pie composite wedge - sal_Int32 m_nCompositeSize; + double m_nSplitPos; struct PieLabelInfo { diff --git a/chart2/source/view/main/SeriesPlotterContainer.cxx b/chart2/source/view/main/SeriesPlotterContainer.cxx index 43b62ae747ad..8ad97c3d1717 100644 --- a/chart2/source/view/main/SeriesPlotterContainer.cxx +++ b/chart2/source/view/main/SeriesPlotterContainer.cxx @@ -154,6 +154,7 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(ChartModel& rChart sal_Int32 nStartingAngle = 90; sal_Int32 n3DRelativeHeight = 100; PieChartSubType ePieChartSubType = PieChartSubType_NONE; + double nSplitPos = 2; try { xDiagram->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= bSortByXValues; @@ -167,6 +168,8 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(ChartModel& rChart xDiagram->getPropertyValue(u"3DRelativeHeight"_ustr) >>= n3DRelativeHeight; } xDiagram->getPropertyValue(u"SubPieType"_ustr) >>= ePieChartSubType; + + xDiagram->getPropertyValue(u"SplitPos"_ustr) >>= nSplitPos; } catch (const uno::Exception&) { @@ -234,6 +237,9 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(ChartModel& rChart uno::Any(ePieChartSubType)); // Reset the diagram-level property so it's not persistent. xDiagram->setPropertyValue(u"SubPieType"_ustr, uno::Any(PieChartSubType_NONE)); + + xChartType->setFastPropertyValue(PROP_PIECHARTTYPE_SPLIT_POS, uno::Any(nSplitPos)); + //xDiagram->setPropertyValue(u"SplitPos"_ustr, uno::Any(nSplitPos)); } if (nT == 0) diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 1b708b83d479..e88bb05dc5d0 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -195,7 +195,7 @@ private: void exportDoughnutChart( const css::uno::Reference< css::chart2::XChartType >& xChartType ); void exportLineChart( const css::uno::Reference< css::chart2::XChartType >& xChartType ); void exportOfPieChart( const css::uno::Reference< css::chart2::XChartType >& - xChartType, const char* s_subtype ); + xChartType, const char* s_subtype, double nSplitPos ); void exportPieChart( const css::uno::Reference< css::chart2::XChartType >& xChartType ); void exportRadarChart( const css::uno::Reference< css::chart2::XChartType >& xChartType ); void exportScatterChart( const css::uno::Reference< css::chart2::XChartType >& xChartType ); diff --git a/oox/source/drawingml/chart/typegroupcontext.cxx b/oox/source/drawingml/chart/typegroupcontext.cxx index 9604e58a2507..393073261533 100644 --- a/oox/source/drawingml/chart/typegroupcontext.cxx +++ b/oox/source/drawingml/chart/typegroupcontext.cxx @@ -296,7 +296,7 @@ ContextHandlerRef OfPieTypeGroupContext::onCreateContext( sal_Int32 nElement, co case C_TOKEN( serLines ): return new ShapePrWrapperContext( *this, mrModel.mxSerLines.create() ); case C_TOKEN( splitPos ): - mrModel.mfSplitPos = rAttribs.getDouble( XML_val, 0.0 ); + mrModel.mfSplitPos = rAttribs.getDouble( XML_val, 2.0 ); return nullptr; case C_TOKEN( splitType ): mrModel.mnSplitType = rAttribs.getToken( XML_val, XML_auto ); diff --git a/oox/source/drawingml/chart/typegroupconverter.cxx b/oox/source/drawingml/chart/typegroupconverter.cxx index 9127e7d47006..71be134a9f03 100644 --- a/oox/source/drawingml/chart/typegroupconverter.cxx +++ b/oox/source/drawingml/chart/typegroupconverter.cxx @@ -358,6 +358,10 @@ void TypeGroupConverter::convertFromModel( const Reference< XDiagram >& rxDiagra if (maTypeInfo.meTypeId == TYPEID_OFPIE) { aDiaProp.setProperty(PROP_SubPieType, convertOfPieType(mrModel.mnOfPieType)); + if (mrModel.mnSplitType == XML_auto || + mrModel.mnSplitType == XML_pos) { + aDiaProp.setProperty(PROP_SplitPos, mrModel.mfSplitPos); + } } else { aDiaProp.setProperty(PROP_SubPieType, PieChartSubType_NONE); } diff --git a/oox/source/drawingml/chart/typegroupmodel.cxx b/oox/source/drawingml/chart/typegroupmodel.cxx index 9479f93c4939..257237a8a57c 100644 --- a/oox/source/drawingml/chart/typegroupmodel.cxx +++ b/oox/source/drawingml/chart/typegroupmodel.cxx @@ -32,7 +32,7 @@ UpDownBarsModel::~UpDownBarsModel() } TypeGroupModel::TypeGroupModel( sal_Int32 nTypeId, bool bMSO2007Doc ) : - mfSplitPos( 0.0 ), + mfSplitPos( 2.0 ), mnBarDir( XML_col ), mnBubbleScale( 100 ), mnFirstAngle( 0 ), diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index 78d3d4cbcebf..261b6c2a96e1 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -1764,8 +1764,13 @@ void ChartExport::exportPlotArea(const Reference< css::chart::XChartDocument >& default: assert(false); } + double fSplitPos; + if (!xChartTypeProp.getProperty(fSplitPos, + PROP_SplitPos)) { + fSplitPos = 2; + } - exportOfPieChart(xChartType, sSubType); + exportOfPieChart(xChartType, sSubType, fSplitPos); } else { exportPieChart( xChartType ); } @@ -2323,7 +2328,8 @@ void ChartExport::exportDoughnutChart( const Reference< chart2::XChartType >& xC void ChartExport::exportOfPieChart( const Reference< chart2::XChartType >& xChartType, - const char* sSubType ) + const char* sSubType, + double fSplitPos) { FSHelperPtr pFS = GetFS(); pFS->startElement(FSNS(XML_c, XML_ofPieChart)); @@ -2335,6 +2341,9 @@ void ChartExport::exportOfPieChart( bool bPrimaryAxes = true; exportAllSeries(xChartType, bPrimaryAxes); + pFS->singleElement(FSNS(XML_c, XML_splitType), XML_val, "pos"); + pFS->singleElement(FSNS(XML_c, XML_splitPos), XML_val, OString::number(fSplitPos)); + pFS->endElement( FSNS( XML_c, XML_ofPieChart ) ); } diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 0cb978129ccc..d73008a80539 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -555,6 +555,7 @@ SpinIncrement SpinValue SpinValueMax SpinValueMin +SplitPos StackCharacters StackingDirection StartPosition diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng index 7ae65dc531ee..e874f15852fc 100644 --- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng @@ -2762,6 +2762,15 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. + + + + + + + + + diff --git a/xmloff/inc/xmlprop.hxx b/xmloff/inc/xmlprop.hxx index 8f47e328ff44..dd48cb11ff63 100644 --- a/xmloff/inc/xmlprop.hxx +++ b/xmloff/inc/xmlprop.hxx @@ -595,6 +595,7 @@ inline constexpr OUString PROP_Speed = u"Speed"_ustr; inline constexpr OUString PROP_SplineOrder = u"SplineOrder"_ustr; inline constexpr OUString PROP_SplineResolution = u"SplineResolution"_ustr; inline constexpr OUString PROP_SplineType = u"SplineType"_ustr; +inline constexpr OUString PROP_SplitPos = u"SplitPos"_ustr; inline constexpr OUString PROP_Stacked = u"Stacked"_ustr; inline constexpr OUString PROP_StackedBarsConnected = u"StackedBarsConnected"_ustr; inline constexpr OUString PROP_StackedText = u"StackedText"_ustr; diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx index c79071dac166..a6cd20a3d54f 100644 --- a/xmloff/source/chart/SchXMLChartContext.cxx +++ b/xmloff/source/chart/SchXMLChartContext.cxx @@ -232,7 +232,8 @@ SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper, mbRowHasLabels( false ), meDataRowSource( chart::ChartDataRowSource_COLUMNS ), mbIsStockChart( false ), - mPieSubType(css::chart2::PieChartSubType_NONE) + mPieSubType(css::chart2::PieChartSubType_NONE), + mfPieSplitPos(2.0) { } @@ -400,6 +401,9 @@ void SchXMLChartContext::startFastElement( sal_Int32 /*nElement*/, mPieSubType = css::chart2::PieChartSubType_PIE; } break; + case XML_ELEMENT(LO_EXT, XML_SPLIT_POSITION): + mfPieSplitPos = aIter.toDouble(); + break; default: XMLOFF_WARN_UNKNOWN("xmloff", aIter); } @@ -748,12 +752,13 @@ void SchXMLChartContext::endFastElement(sal_Int32 ) // cleanup: remove empty chart type groups lcl_removeEmptyChartTypeGroups( xNewDoc ); - // Handle sub-pie type. Is this the right place to do this? + // Handle of-pie paramters. Is this the right place to do this? if (maChartTypeServiceName == "com.sun.star.chart2.PieChartType") { Reference< chart2::XDiagram> xDia(xNewDoc->getFirstDiagram()); uno::Reference< beans::XPropertySet > xDiaProp( xDia, uno::UNO_QUERY ); if( xDiaProp.is()) { xDiaProp->setPropertyValue(u"SubPieType"_ustr, uno::Any(mPieSubType)); + xDiaProp->setPropertyValue(u"SplitPos"_ustr, uno::Any(mfPieSplitPos)); } } diff --git a/xmloff/source/chart/SchXMLChartContext.hxx b/xmloff/source/chart/SchXMLChartContext.hxx index b7f94fa6c986..563ae2ebe8e1 100644 --- a/xmloff/source/chart/SchXMLChartContext.hxx +++ b/xmloff/source/chart/SchXMLChartContext.hxx @@ -101,6 +101,7 @@ private: css::chart::ChartDataRowSource meDataRowSource; bool mbIsStockChart; css::chart2::PieChartSubType mPieSubType; + double mfPieSplitPos; OUString msCategoriesAddress; OUString msChartAddress; diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx index 4e3fa02b7651..f58904997ce6 100644 --- a/xmloff/source/chart/SchXMLExport.cxx +++ b/xmloff/source/chart/SchXMLExport.cxx @@ -114,7 +114,6 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Any; using ::std::vector; - namespace { /** @@ -1287,11 +1286,47 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > XML_NAMESPACE_CHART, GetXMLToken(eXMLChartType )) ); } + bool bIsOfPie = false; // Handle subtype for of-pie charts if (sChartType == u"com.sun.star.chart.BarOfPieDiagram") { mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUB_BAR, OUString::boolean(true)); + bIsOfPie = true; } else if (sChartType == u"com.sun.star.chart.PieOfPieDiagram") { mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUB_PIE, OUString::boolean(true)); + bIsOfPie = true; + } + + if (bIsOfPie) { + + // Find the split position. We have to dig deep into the + // structure tree to get it, which is awkward. Part of the + // problem is that the split position is sort of a series-level + // parameter, but is generally handled at the chart level since + // of-pie charts have only a single series. + double fSplitPos = 2.0; + + Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xNewDiagram, uno::UNO_QUERY ); + if (xBCooSysCnt.is()) { + const Sequence< Reference< chart2::XCoordinateSystem > > + aCooSysSeq( xBCooSysCnt->getCoordinateSystems()); + for (const auto& rCooSys : aCooSysSeq ) { + Reference< chart2::XChartTypeContainer > xCTCnt( rCooSys, uno::UNO_QUERY ); + if( ! xCTCnt.is()) + continue; + const Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes()); + for (const auto& rChartType : aCTSeq ) { + Reference< beans::XPropertySet > xCTProp( rChartType, uno::UNO_QUERY ); + + if (xCTProp.is()) { + xCTProp->getPropertyValue(u"SplitPos"_ustr) >>= fSplitPos; + } + } + } + } + + // Insert split position for of-pie chart + mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SPLIT_POSITION, + OUString::number(fSplitPos)); } //column-mapping or row-mapping