chart2/qa/extras/chart2export.cxx                           |   53 ++++++++++++
 chart2/qa/extras/data/ods/tdf50934_barOfPie.ods             |binary
 chart2/qa/extras/data/ods/tdf50934_pieOfPie.ods             |binary
 chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx |    9 ++
 chart2/source/inc/ChartType.hxx                             |    6 -
 include/xmloff/xmltoken.hxx                                 |    3 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |   14 +++
 xmloff/source/chart/PropertyMap.hxx                         |    1 
 xmloff/source/chart/SchXMLChartContext.cxx                  |   23 ++++-
 xmloff/source/chart/SchXMLChartContext.hxx                  |    3 
 xmloff/source/chart/SchXMLExport.cxx                        |    7 +
 xmloff/source/chart/SchXMLTools.cxx                         |    7 +
 xmloff/source/core/xmltoken.cxx                             |    3 
 xmloff/source/token/tokens.txt                              |    3 
 14 files changed, 124 insertions(+), 8 deletions(-)

New commits:
commit 9ae8e74fb32254c81d36b1c95411605459e06372
Author:     Kurt Nordback <kurt.nordb...@protonmail.com>
AuthorDate: Tue Mar 5 11:01:42 2024 -0700
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Mar 18 07:07:24 2024 +0100

    tdf#50934: Add a pie-with-remainder-as-another-pie chart type
    
    Implement ODF import/export for bar-of-pie and pie-of-pie types,
    and add simple tests for this capability. The associated ODF tags
    are implemented in the loext namespace. This also required changing
    the schema.
    
    Change-Id: Ib55ae1c5818ad810f7b962d807a9163a3d02ba17
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164436
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/chart2/qa/extras/chart2export.cxx 
b/chart2/qa/extras/chart2export.cxx
index b46bc776d587..86f2dee778e6 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -18,6 +18,7 @@
 #include <com/sun/star/drawing/FillStyle.hpp>
 #include <com/sun/star/chart2/DataPointLabel.hpp>
 #include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart2/PieChartSubType.hpp>
 
 using uno::Reference;
 using beans::XPropertySet;
@@ -1132,6 +1133,58 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest, 
testErrorBarDataRangeODS)
     CPPUNIT_ASSERT_EQUAL(OUString("$Sheet1.$C$1:$C$3"), aNegRange);
 }
 
+CPPUNIT_TEST_FIXTURE(Chart2ExportTest, tdf50934_barOfPie)
+{
+    loadFromFile(u"ods/tdf50934_barOfPie.ods");
+    saveAndReload("calc8");
+
+    uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 
0, mxComponent );
+    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 as bar-of-pie
+    Reference< chart2::XDiagram> xDia(xChartDoc->getFirstDiagram());
+    CPPUNIT_ASSERT(xDia.is());
+    uno::Reference< beans::XPropertySet > xDiaProp( xDia, uno::UNO_QUERY );
+    CPPUNIT_ASSERT(xDiaProp.is());
+    uno::Any aAny = xDiaProp->getPropertyValue("SubPieType");
+    CPPUNIT_ASSERT(aAny.hasValue());
+    chart2::PieChartSubType subPieType;
+    aAny >>= subPieType;
+    CPPUNIT_ASSERT_EQUAL(chart2::PieChartSubType_BAR, subPieType);
+}
+
+CPPUNIT_TEST_FIXTURE(Chart2ExportTest, tdf50934_pieOfPie)
+{
+    loadFromFile(u"ods/tdf50934_pieOfPie.ods");
+    saveAndReload("calc8");
+
+    uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 
0, mxComponent );
+    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 as pie-of-pie
+    Reference< chart2::XDiagram> xDia(xChartDoc->getFirstDiagram());
+    CPPUNIT_ASSERT(xDia.is());
+    uno::Reference< beans::XPropertySet > xDiaProp( xDia, uno::UNO_QUERY );
+    CPPUNIT_ASSERT(xDiaProp.is());
+    uno::Any aAny = xDiaProp->getPropertyValue("SubPieType");
+    CPPUNIT_ASSERT(aAny.hasValue());
+    chart2::PieChartSubType subPieType;
+    aAny >>= subPieType;
+    CPPUNIT_ASSERT_EQUAL(chart2::PieChartSubType_PIE, subPieType);
+}
+
 CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testChartCrash)
 {
     loadFromFile(u"docx/FDO75975.docx");
diff --git a/chart2/qa/extras/data/ods/tdf50934_barOfPie.ods 
b/chart2/qa/extras/data/ods/tdf50934_barOfPie.ods
new file mode 100644
index 000000000000..d9b577a38a36
Binary files /dev/null and b/chart2/qa/extras/data/ods/tdf50934_barOfPie.ods 
differ
diff --git a/chart2/qa/extras/data/ods/tdf50934_pieOfPie.ods 
b/chart2/qa/extras/data/ods/tdf50934_pieOfPie.ods
new file mode 100644
index 000000000000..74a9f85f6981
Binary files /dev/null and b/chart2/qa/extras/data/ods/tdf50934_pieOfPie.ods 
differ
diff --git a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx 
b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
index 949aaa9a6dae..2917b989f040 100644
--- a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
@@ -465,6 +465,15 @@ OUString lcl_getDiagramType( std::u16string_view 
rTemplateServiceName )
         if( aName.find( u"Area" ) != std::u16string_view::npos )
             return "com.sun.star.chart.AreaDiagram";
 
+        // Handle bar-of-pie and pie-of-pie before simple pie
+        // "BarOfPie"
+        if( aName.find( u"BarOfPie" ) != std::u16string_view::npos )
+            return "com.sun.star.chart.BarOfPieDiagram";
+
+        // "PieOfPie"
+        if( aName.find( u"PieOfPie" ) != std::u16string_view::npos )
+            return "com.sun.star.chart.PieOfPieDiagram";
+
         // "Pie" "PieAllExploded" "ThreeDPie" "ThreeDPieAllExploded"
         if( aName.find( u"Pie" ) != std::u16string_view::npos )
             return "com.sun.star.chart.PieDiagram";
diff --git a/chart2/source/inc/ChartType.hxx b/chart2/source/inc/ChartType.hxx
index fccafdb323b6..fa55cf05694f 100644
--- a/chart2/source/inc/ChartType.hxx
+++ b/chart2/source/inc/ChartType.hxx
@@ -75,12 +75,6 @@ public:
     // ____ XChartType ____
     // still abstract ! implement !
     virtual OUString SAL_CALL getChartType() override = 0;
-#if 0
-    virtual ::com::sun::star::chart2::PieChartSubType SAL_CALL 
getPieChartSubType() override
-    {
-        return ::com::sun::star::chart2::PieChartSubType_NONE;
-    }
-#endif
     virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL
         createCoordinateSystem( ::sal_Int32 DimensionCount ) final override;
     virtual css::uno::Sequence< OUString > SAL_CALL
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index b6fa0dc2acba..ce732e3911a6 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1909,7 +1909,10 @@ namespace xmloff::token {
         XML_STYLES,
         XML_STYLESHEET,
         XML_SUB_TABLE,
+        XML_SUB_BAR,
+        XML_SUB_NONE,
         XML_SUBJECT,
+        XML_SUB_PIE,
         XML_SUBSET,
         XML_SUBTITLE,
         XML_SUBTOTAL_FIELD,
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index a68033d1954e..b14c02bfbbe1 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2717,6 +2717,20 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+    <!-- TODO no proposal -->
+  <rng:define name="chart-chart-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:sub-bar">
+        <rng:ref name="boolean"/>
+      </rng:attribute>
+    </rng:optional>
+    <rng:optional>
+      <rng:attribute name="loext:sub-pie">
+        <rng:ref name="boolean"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
   <!-- OFFICE-2112, TODO half of this missing in proposal -->
   <rng:define name="table-table-protection">
     <rng:element name="loext:table-protection">
diff --git a/xmloff/source/chart/PropertyMap.hxx 
b/xmloff/source/chart/PropertyMap.hxx
index cd6370e78bc9..ec5987559e06 100644
--- a/xmloff/source/chart/PropertyMap.hxx
+++ b/xmloff/source/chart/PropertyMap.hxx
@@ -42,6 +42,7 @@
 #define XML_SCH_TYPE_LABEL_BORDER_STYLE     ( XML_SCH_TYPES_START + 17 )
 #define XML_SCH_TYPE_LABEL_BORDER_OPACITY   ( XML_SCH_TYPES_START + 18 )
 #define XML_SCH_TYPE_LABEL_FILL_STYLE       ( XML_SCH_TYPES_START + 19 )
+#define XML_SCH_TYPE_OF_PIE_TYPE            ( XML_SCH_TYPES_START + 20 )
 
 // context ids
 #define XML_SCH_CONTEXT_USER_SYMBOL                 ( XML_SCH_CTF_START + 0 )
diff --git a/xmloff/source/chart/SchXMLChartContext.cxx 
b/xmloff/source/chart/SchXMLChartContext.cxx
index b2def8e37fd1..9d5522feaceb 100644
--- a/xmloff/source/chart/SchXMLChartContext.cxx
+++ b/xmloff/source/chart/SchXMLChartContext.cxx
@@ -231,7 +231,8 @@ SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& 
rImpHelper,
         mbColHasLabels( false ),
         mbRowHasLabels( false ),
         meDataRowSource( chart::ChartDataRowSource_COLUMNS ),
-        mbIsStockChart( false )
+        mbIsStockChart( false ),
+        mPieSubType(com::sun::star::chart2::PieChartSubType_NONE)
 {
 }
 
@@ -317,6 +318,7 @@ void SchXMLChartContext::startFastElement( sal_Int32 
/*nElement*/,
     OUString sAutoStyleName;
     OUString aOldChartTypeName;
     bool bHasAddin = false;
+    mPieSubType = com::sun::star::chart2::PieChartSubType_NONE;
 
     for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
     {
@@ -385,6 +387,16 @@ void SchXMLChartContext::startFastElement( sal_Int32 
/*nElement*/,
             case XML_ELEMENT(CHART,  XML_ROW_MAPPING):
                 msRowTrans = aIter.toString();
                 break;
+            case XML_ELEMENT(LO_EXT, XML_SUB_BAR):
+                if (aIter.toString().toBoolean()) {
+                    mPieSubType = com::sun::star::chart2::PieChartSubType_BAR;
+                }
+                break;
+            case XML_ELEMENT(LO_EXT, XML_SUB_PIE):
+                if (aIter.toString().toBoolean()) {
+                    mPieSubType = com::sun::star::chart2::PieChartSubType_PIE;
+                }
+                break;
             default:
                 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
         }
@@ -752,6 +764,15 @@ 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?
+    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("SubPieType", uno::Any(mPieSubType));
+        }
+    }
+
     // set stack mode before a potential chart type detection (in case we have 
a rectangular range)
     uno::Reference< chart::XDiagram > xDiagram( xDoc->getDiagram() );
     uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
diff --git a/xmloff/source/chart/SchXMLChartContext.hxx 
b/xmloff/source/chart/SchXMLChartContext.hxx
index 40ba13e0177c..f79be55b88d9 100644
--- a/xmloff/source/chart/SchXMLChartContext.hxx
+++ b/xmloff/source/chart/SchXMLChartContext.hxx
@@ -23,6 +23,8 @@
 #include <com/sun/star/chart/ChartDataRowSource.hpp>
 #include <com/sun/star/awt/Size.hpp>
 
+#include <com/sun/star/chart2/PieChartSubType.hpp>
+
 #include "transporttypes.hxx"
 
 #include <vector>
@@ -98,6 +100,7 @@ private:
     bool mbRowHasLabels;
     css::chart::ChartDataRowSource meDataRowSource;
     bool mbIsStockChart;
+    com::sun::star::chart2::PieChartSubType mPieSubType;
 
     OUString msCategoriesAddress;
     OUString msChartAddress;
diff --git a/xmloff/source/chart/SchXMLExport.cxx 
b/xmloff/source/chart/SchXMLExport.cxx
index 4fb0227a162a..79238a5b34be 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -1284,6 +1284,13 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< 
chart::XChartDocument >
                             XML_NAMESPACE_CHART, GetXMLToken(eXMLChartType )) 
);
             }
 
+            // 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));
+            } else if (sChartType == u"com.sun.star.chart.PieOfPieDiagram") {
+                mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUB_PIE, 
OUString::boolean(true));
+            }
+
             //column-mapping or row-mapping
             if( maSequenceMapping.hasElements() )
             {
diff --git a/xmloff/source/chart/SchXMLTools.cxx 
b/xmloff/source/chart/SchXMLTools.cxx
index 120e361f84f0..4287b731a7fb 100644
--- a/xmloff/source/chart/SchXMLTools.cxx
+++ b/xmloff/source/chart/SchXMLTools.cxx
@@ -167,6 +167,10 @@ static const tMakeStringStringMap& 
lcl_getChartTypeNameMap()
          "com.sun.star.chart2.ColumnChartType"},
         {"com.sun.star.chart.PieDiagram",
          "com.sun.star.chart2.PieChartType"},
+        {"com.sun.star.chart.BarOfPieDiagram",
+         "com.sun.star.chart2.BarOfPieChartType"},
+        {"com.sun.star.chart.PieOfPieDiagram",
+         "com.sun.star.chart2.PieOfPieChartType"},
         {"com.sun.star.chart.DonutDiagram",
          "com.sun.star.chart2.DonutChartType"},
         {"com.sun.star.chart.XYDiagram",
@@ -304,7 +308,8 @@ XMLTokenEnum getTokenByChartType(
             else if( aServiceName == u"Bar" ||
                      (!bUseOldNames && aServiceName == u"Column"))
                 eResult = XML_BAR;
-            else if ( aServiceName == u"Pie" )
+            else if ( aServiceName == u"Pie" || aServiceName == u"BarOfPie" ||
+                    aServiceName == u"PieOfPie" )
                 eResult = XML_CIRCLE;
             else if ( aServiceName == u"Donut" )
                 eResult = XML_RING;
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 78ac1500e07a..3fb58743418b 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1922,7 +1922,10 @@ namespace xmloff::token {
         TOKEN( "styles",                          XML_STYLES ),
         TOKEN( "stylesheet",                      XML_STYLESHEET ),
         TOKEN( "sub-table",                       XML_SUB_TABLE ),
+        TOKEN( "sub-bar",                         XML_SUB_BAR ),
+        TOKEN( "sub-none",                        XML_SUB_NONE ),
         TOKEN( "subject",                         XML_SUBJECT ),
+        TOKEN( "sub-pie",                         XML_SUB_PIE ),
         TOKEN( "subset",                          XML_SUBSET ),
         TOKEN( "subtitle",                        XML_SUBTITLE ),
         TOKEN( "subtotal-field",                  XML_SUBTOTAL_FIELD ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 882ad0e5978d..5045d866fd0a 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -1822,7 +1822,10 @@ style-ref
 styles
 stylesheet
 sub-table
+sub-bar
+sub-none
 subject
+sub-pie
 subset
 subtitle
 subtotal-field

Reply via email to