chart2/qa/extras/chart2export.cxx            |   38 +++
 chart2/qa/extras/data/ods/multilevelcat.ods  |binary
 chart2/qa/extras/data/odt/multilevelcat.odt  |binary
 chart2/source/tools/InternalDataProvider.cxx |    1 
 include/oox/export/chartexport.hxx           |    3 
 oox/source/export/chartexport.cxx            |  268 ++++++++++++++++++++++-----
 6 files changed, 269 insertions(+), 41 deletions(-)

New commits:
commit 8906275d40a1828db684e7d9c9bc4934a937bc6c
Author:     Balazs Varga <balazs.varga...@gmail.com>
AuthorDate: Tue Jul 9 13:30:16 2019 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Jul 15 11:38:13 2019 +0200

    tdf#126193 Chart OOXML: Export Multi-level category labels
    
    Fix export of Multi-level category axis labels with the correct
    OOXML tags (as the OOXML Standard requested) in the correct
    order.
    
    Also fix tdf#126195: but only the export part of the whole fault,
    which combined (united) the text of the category axis labels at
    different levels.
    
    Change-Id: Iefcef00818a3bb2ee1671bf693335904be471722
    Reviewed-on: https://gerrit.libreoffice.org/75299
    Reviewed-by: László Németh <nem...@numbertext.org>
    Tested-by: László Németh <nem...@numbertext.org>

diff --git a/chart2/qa/extras/chart2export.cxx 
b/chart2/qa/extras/chart2export.cxx
index f00959bdbfeb..ab932ac2bc68 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -128,6 +128,8 @@ public:
     void testChartTitlePropertiesGradientFillPPTX();
     void testChartTitlePropertiesBitmapFillPPTX();
     void testxAxisLabelsRotation();
+    void testMultipleCategoryAxisLablesXLSX();
+    void testMultipleCategoryAxisLablesDOCX();
     void testTdf116163();
     void testTdf111824();
     void testTdf119029();
@@ -226,6 +228,8 @@ public:
     CPPUNIT_TEST(testChartTitlePropertiesGradientFillPPTX);
     CPPUNIT_TEST(testChartTitlePropertiesBitmapFillPPTX);
     CPPUNIT_TEST(testxAxisLabelsRotation);
+    CPPUNIT_TEST(testMultipleCategoryAxisLablesXLSX);
+    CPPUNIT_TEST(testMultipleCategoryAxisLablesDOCX);
     CPPUNIT_TEST(testTdf116163);
     CPPUNIT_TEST(testTdf111824);
     CPPUNIT_TEST(testTdf119029);
@@ -2092,6 +2096,40 @@ void Chart2ExportTest::testxAxisLabelsRotation()
     assertXPath(pXmlDoc1, 
"/c:chartSpace/c:chart/c:plotArea/c:catAx/c:txPr/a:bodyPr", "rot", "2700000");
 }
 
+void Chart2ExportTest::testMultipleCategoryAxisLablesXLSX()
+{
+    load("/chart2/qa/extras/data/ods/", "multilevelcat.ods");
+    xmlDocPtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
+    CPPUNIT_ASSERT(pXmlDoc);
+    // check category axis labels number of first level
+    assertXPath(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:ptCount",
 "val", "6");
+    // check category axis labels text of first level
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[1]/c:pt[1]/c:v",
 "Categoria 1");
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[1]/c:pt[6]/c:v",
 "Categoria 6");
+    // check category axis labels text of second level
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[2]/c:pt[1]/c:v",
 "2011");
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[2]/c:pt[3]/c:v",
 "2013");
+    // check the 'noMultiLvlLbl' tag - ChartExport.cxx:2950 FIXME: seems not 
support, so check the default noMultiLvlLbl value.
+    assertXPath(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:catAx/c:noMultiLvlLbl", "val", "0");
+}
+
+void Chart2ExportTest::testMultipleCategoryAxisLablesDOCX()
+{
+    load("/chart2/qa/extras/data/odt/", "multilevelcat.odt");
+    xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML 
Text");
+    CPPUNIT_ASSERT(pXmlDoc);
+    // check category axis labels number of first level
+    assertXPath(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:ptCount",
 "val", "4");
+    // check category axis labels text of first level
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[1]/c:pt[1]/c:v",
 "Categoria 1");
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[1]/c:pt[4]/c:v",
 "Categoria 4");
+    // check category axis labels text of second level
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[2]/c:pt[1]/c:v",
 "2011");
+    assertXPathContent(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:multiLvlStrRef/c:multiLvlStrCache/c:lvl[2]/c:pt[2]/c:v",
 "2012");
+    // check the 'noMultiLvlLbl' tag - ChartExport.cxx:2950 FIXME: seems not 
support, so check the default noMultiLvlLbl value.
+    assertXPath(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:catAx/c:noMultiLvlLbl", "val", "0");
+}
+
 void Chart2ExportTest::testTdf116163()
 {
     load("/chart2/qa/extras/data/pptx/", "tdf116163.pptx");
diff --git a/chart2/qa/extras/data/ods/multilevelcat.ods 
b/chart2/qa/extras/data/ods/multilevelcat.ods
new file mode 100644
index 000000000000..76b140a879af
Binary files /dev/null and b/chart2/qa/extras/data/ods/multilevelcat.ods differ
diff --git a/chart2/qa/extras/data/odt/multilevelcat.odt 
b/chart2/qa/extras/data/odt/multilevelcat.odt
new file mode 100644
index 000000000000..8148e1be1089
Binary files /dev/null and b/chart2/qa/extras/data/odt/multilevelcat.odt differ
diff --git a/chart2/source/tools/InternalDataProvider.cxx 
b/chart2/source/tools/InternalDataProvider.cxx
index 86c163e02c4e..5bea86b2d7d3 100644
--- a/chart2/source/tools/InternalDataProvider.cxx
+++ b/chart2/source/tools/InternalDataProvider.cxx
@@ -899,6 +899,7 @@ Sequence< uno::Any > SAL_CALL 
InternalDataProvider::getDataByRangeRepresentation
         }
         else
         {
+            // Maybe this 'else' part and the functions is not necessary 
anymore.
             Sequence< OUString > aLabels = m_bDataInColumns ? 
getRowDescriptions() : getColumnDescriptions();
             aResult.realloc( aLabels.getLength() );
             transform( aLabels.begin(), aLabels.end(),
diff --git a/include/oox/export/chartexport.hxx 
b/include/oox/export/chartexport.hxx
index 4716099dd8df..584b448aed2c 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -51,6 +51,7 @@ namespace com { namespace sun { namespace star {
         namespace data
         {
             class XDataSequence;
+            class XLabeledDataSequence;
         }
     }
     namespace drawing {
@@ -120,6 +121,8 @@ private:
 private:
     sal_Int32 getChartType();
 
+    css::uno::Sequence< css::uno::Sequence< rtl::OUString > > 
getSplitCategoriesList(const OUString& rRange);
+
     OUString parseFormula( const OUString& rRange );
     void InitPlotArea();
 
diff --git a/oox/source/export/chartexport.cxx 
b/oox/source/export/chartexport.cxx
index b6c764ddbd8c..5e0d67ba3d3c 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -68,10 +68,13 @@
 #include <com/sun/star/chart2/data/XDataSink.hpp>
 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
 #include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/XInternalDataProvider.hpp>
 #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+#include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
 
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/drawing/XShape.hpp>
@@ -262,7 +265,7 @@ static OUString lcl_flattenStringSequence( const Sequence< 
OUString > & rSequenc
     return aResult.makeStringAndClear();
 }
 
-static OUString lcl_getLabelString( const Reference< 
chart2::data::XDataSequence > & xLabelSeq )
+static Sequence< OUString > lcl_getLabelSequence( const Reference< 
chart2::data::XDataSequence > & xLabelSeq )
 {
     Sequence< OUString > aLabels;
 
@@ -279,7 +282,7 @@ static OUString lcl_getLabelString( const Reference< 
chart2::data::XDataSequence
             aAnies[i] >>= aLabels[i];
     }
 
-    return lcl_flattenStringSequence( aLabels );
+    return aLabels;
 }
 
 static void lcl_fillCategoriesIntoStringVector(
@@ -396,6 +399,168 @@ sal_Int32 ChartExport::getChartType( )
     return lcl_getChartType( sChartType );
 }
 
+namespace {
+
+uno::Sequence< beans::PropertyValue > createArguments(
+    const OUString & rRangeRepresentation, bool bUseColumns)
+{
+    css::chart::ChartDataRowSource eRowSource = 
css::chart::ChartDataRowSource_ROWS;
+    if (bUseColumns)
+        eRowSource = css::chart::ChartDataRowSource_COLUMNS;
+
+    uno::Sequence< beans::PropertyValue > aArguments(4);
+    aArguments[0] = beans::PropertyValue("DataRowSource"
+        , -1, uno::Any(eRowSource)
+        , beans::PropertyState_DIRECT_VALUE);
+    aArguments[1] = beans::PropertyValue("FirstCellAsLabel"
+        , -1, uno::Any(false)
+        , beans::PropertyState_DIRECT_VALUE);
+    aArguments[2] = beans::PropertyValue("HasCategories"
+        , -1, uno::Any(false)
+        , beans::PropertyState_DIRECT_VALUE);
+    aArguments[3] = beans::PropertyValue("CellRangeRepresentation"
+        , -1, uno::Any(rRangeRepresentation)
+        , beans::PropertyState_DIRECT_VALUE);
+
+    return aArguments;
+}
+
+Reference<chart2::XDataSeries> getPrimaryDataSeries(const 
Reference<chart2::XChartType>& xChartType)
+{
+    Reference< chart2::XDataSeriesContainer > xDSCnt(xChartType, 
uno::UNO_QUERY_THROW);
+
+    // export dataseries for current chart-type
+    Sequence< Reference< chart2::XDataSeries > > 
aSeriesSeq(xDSCnt->getDataSeries());
+    for (sal_Int32 nSeriesIdx = 0; nSeriesIdx < aSeriesSeq.getLength(); 
++nSeriesIdx)
+    {
+        Reference<chart2::XDataSeries> xSource(aSeriesSeq[nSeriesIdx], 
uno::UNO_QUERY);
+        if (xSource.is())
+            return xSource;
+    }
+
+    return Reference<chart2::XDataSeries>();
+}
+
+}
+
+Sequence< Sequence< OUString > > ChartExport::getSplitCategoriesList( const 
OUString& rRange )
+{
+    Reference< chart2::XChartDocument > xChartDoc(getModel(), uno::UNO_QUERY);
+    OSL_ASSERT(xChartDoc.is());
+    if (xChartDoc.is())
+    {
+        Reference< chart2::data::XDataProvider > 
xDataProvider(xChartDoc->getDataProvider());
+        OSL_ENSURE(xDataProvider.is(), "No DataProvider");
+        if (xDataProvider.is())
+        {
+            //detect whether the first series is a row or a column
+            bool bSeriesUsesColumns = true;
+            Reference< chart2::XDiagram > 
xDiagram(xChartDoc->getFirstDiagram());
+            try
+            {
+                Reference< chart2::XCoordinateSystemContainer > 
xCooSysCnt(xDiagram, uno::UNO_QUERY_THROW);
+                Sequence< Reference< chart2::XCoordinateSystem > > 
aCooSysSeq(xCooSysCnt->getCoordinateSystems());
+                for (sal_Int32 i = 0; i < aCooSysSeq.getLength(); ++i)
+                {
+                    const Reference< chart2::XChartTypeContainer > 
xCTCnt(aCooSysSeq[i], uno::UNO_QUERY_THROW);
+                    const Sequence< Reference< chart2::XChartType > > 
aChartTypeSeq(xCTCnt->getChartTypes());
+                    for (sal_Int32 j = 0; j < aChartTypeSeq.getLength(); ++j)
+                    {
+                        Reference< chart2::XDataSeries > xDataSeries = 
getPrimaryDataSeries(aChartTypeSeq[j]);
+                        if (xDataSeries.is())
+                        {
+                            uno::Reference< chart2::data::XDataSource > 
xSeriesSource(xDataSeries, uno::UNO_QUERY);
+                            const uno::Sequence< beans::PropertyValue > 
rArguments = xDataProvider->detectArguments(xSeriesSource);
+                            for (const beans::PropertyValue& rProperty : 
rArguments)
+                            {
+                                if (rProperty.Name == "DataRowSource")
+                                {
+                                    css::chart::ChartDataRowSource eRowSource;
+                                    if (rProperty.Value >>= eRowSource)
+                                    {
+                                        bSeriesUsesColumns = (eRowSource == 
css::chart::ChartDataRowSource_COLUMNS);
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (const uno::Exception &)
+            {
+                DBG_UNHANDLED_EXCEPTION("chart2");
+            }
+            // detect we have an inner data table or not
+            if (xChartDoc->hasInternalDataProvider() && rRange == "categories")
+            {
+                try
+                {
+                    css::uno::Reference< css::chart2::XAnyDescriptionAccess > 
xDataAccess(xChartDoc->getDataProvider(), uno::UNO_QUERY);
+                    const Sequence< Sequence< uno::Any > 
>aAnyCategories(bSeriesUsesColumns ? xDataAccess->getAnyRowDescriptions() : 
xDataAccess->getAnyColumnDescriptions());
+                    sal_Int32 nLevelCount = 1;//minimum is 1!
+                    for (auto const& elemLabel : aAnyCategories)
+                    {
+                        nLevelCount = 
std::max<sal_Int32>(elemLabel.getLength(), nLevelCount);
+                    }
+
+                    if (nLevelCount > 1)
+                    {
+                        //we have complex categories
+                        //sort the categories name
+                        
Sequence<Sequence<OUString>>aFinalSplitSource(nLevelCount);
+                        for (sal_Int32 i = 0; i < nLevelCount; i++)
+                        {
+                            sal_Int32 nElemLabel = 0;
+                            aFinalSplitSource[nLevelCount - i - 
1].realloc(aAnyCategories.getLength());
+                            for (auto const& elemLabel : aAnyCategories)
+                            {
+                                aFinalSplitSource[nLevelCount - i - 
1][nElemLabel] = elemLabel[i].get<OUString>();
+                                nElemLabel++;
+                            }
+                        }
+                        return aFinalSplitSource;
+                    }
+                }
+                catch (const uno::Exception &)
+                {
+                    DBG_UNHANDLED_EXCEPTION("oox");
+                }
+            }
+            else
+            {
+                try
+                {
+                    uno::Reference< chart2::data::XDataSource > 
xCategoriesSource(xDataProvider->createDataSource(
+                        createArguments(rRange, bSeriesUsesColumns)));
+
+                    if (xCategoriesSource.is())
+                    {
+                        Sequence< Reference< 
chart2::data::XLabeledDataSequence >> aCategories = 
xCategoriesSource->getDataSequences();
+                        if (aCategories.getLength() > 1)
+                        {
+                            //we have complex categories
+                            //sort the categories name
+                            
Sequence<Sequence<OUString>>aFinalSplitSource(aCategories.getLength());
+                            for (sal_Int32 i = 0; i < 
aFinalSplitSource.getLength(); i++) {
+                                const uno::Reference< 
chart2::data::XDataSequence > xCategories(aCategories[i]->getValues(), 
uno::UNO_QUERY);
+                                
aFinalSplitSource[aFinalSplitSource.getLength() - i - 1] = 
lcl_getLabelSequence(xCategories);
+                            }
+                            return aFinalSplitSource;
+                        }
+                    }
+                }
+                catch (const uno::Exception &)
+                {
+                    DBG_UNHANDLED_EXCEPTION("oox");
+                }
+            }
+        }
+    }
+
+    return Sequence< Sequence< OUString>>(0);
+}
+
 OUString ChartExport::parseFormula( const OUString& rRange )
 {
     OUString aResult;
@@ -1803,26 +1968,6 @@ void ChartExport::exportAllSeries(const 
Reference<chart2::XChartType>& xChartTyp
     exportSeries(xChartType, aSeriesSeq, rPrimaryAxes);
 }
 
-namespace {
-
-Reference<chart2::XDataSeries> getPrimaryDataSeries(const 
Reference<chart2::XChartType>& xChartType)
-{
-    Reference< chart2::XDataSeriesContainer > xDSCnt(xChartType, 
uno::UNO_QUERY_THROW);
-
-    // export dataseries for current chart-type
-    Sequence< Reference< chart2::XDataSeries > > 
aSeriesSeq(xDSCnt->getDataSeries());
-    for (sal_Int32 nSeriesIdx=0; nSeriesIdx < aSeriesSeq.getLength(); 
++nSeriesIdx)
-    {
-        Reference<chart2::XDataSeries> xSource(aSeriesSeq[nSeriesIdx], 
uno::UNO_QUERY);
-        if (xSource.is())
-            return xSource;
-    }
-
-    return Reference<chart2::XDataSeries>();
-}
-
-}
-
 void ChartExport::exportVaryColors(const Reference<chart2::XChartType>& 
xChartType)
 {
     FSHelperPtr pFS = GetFS();
@@ -2108,7 +2253,7 @@ void ChartExport::exportSeriesText( const Reference< 
chart2::data::XDataSequence
     pFS->writeEscaped( aCellRange );
     pFS->endElement( FSNS( XML_c, XML_f ) );
 
-    OUString aLabelString = lcl_getLabelString( xValueSeq );
+    OUString aLabelString = 
lcl_flattenStringSequence(lcl_getLabelSequence(xValueSeq));
     pFS->startElement(FSNS(XML_c, XML_strCache));
     pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, "1");
     pFS->startElement(FSNS(XML_c, XML_pt), XML_idx, "0");
@@ -2127,30 +2272,68 @@ void ChartExport::exportSeriesCategory( const 
Reference< chart2::data::XDataSequ
     pFS->startElement(FSNS(XML_c, XML_cat));
 
     OUString aCellRange = xValueSeq.is() ? 
xValueSeq->getSourceRangeRepresentation() : OUString();
+    Sequence< Sequence< OUString >> aFinalSplitSource = 
getSplitCategoriesList(aCellRange);
     aCellRange = parseFormula( aCellRange );
-    // TODO: need to handle XML_multiLvlStrRef according to aCellRange
-    pFS->startElement(FSNS(XML_c, XML_strRef));
 
-    pFS->startElement(FSNS(XML_c, XML_f));
-    pFS->writeEscaped( aCellRange );
-    pFS->endElement( FSNS( XML_c, XML_f ) );
+    if(aFinalSplitSource.getLength() > 1)
+    {
+        // export multi level category axis labels
+        pFS->startElement(FSNS(XML_c, XML_multiLvlStrRef));
 
-    ::std::vector< OUString > aCategories;
-    lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
-    sal_Int32 ptCount = aCategories.size();
-    pFS->startElement(FSNS(XML_c, XML_strCache));
-    pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, 
OString::number(ptCount));
-    for( sal_Int32 i = 0; i < ptCount; i++ )
+        pFS->startElement(FSNS(XML_c, XML_f));
+        pFS->writeEscaped(aCellRange);
+        pFS->endElement(FSNS(XML_c, XML_f));
+
+        sal_Int32 ptCount = aFinalSplitSource.getLength();
+        pFS->startElement(FSNS(XML_c, XML_multiLvlStrCache));
+        pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, 
OString::number(aFinalSplitSource[0].getLength()));
+        for(sal_Int32 i = 0; i < ptCount; i++)
+        {
+            pFS->startElement(FSNS(XML_c, XML_lvl));
+            for(sal_Int32 j = 0; j < aFinalSplitSource[i].getLength(); j++)
+            {
+                if(!aFinalSplitSource[i][j].isEmpty())
+                {
+                    pFS->startElement(FSNS(XML_c, XML_pt), XML_idx, 
OString::number(j));
+                    pFS->startElement(FSNS(XML_c, XML_v));
+                    pFS->writeEscaped(aFinalSplitSource[i][j]);
+                    pFS->endElement(FSNS(XML_c, XML_v));
+                    pFS->endElement(FSNS(XML_c, XML_pt));
+                }
+            }
+            pFS->endElement(FSNS(XML_c, XML_lvl));
+        }
+
+        pFS->endElement(FSNS(XML_c, XML_multiLvlStrCache));
+        pFS->endElement(FSNS(XML_c, XML_multiLvlStrRef));
+    }
+    else
     {
-        pFS->startElement(FSNS(XML_c, XML_pt), XML_idx, OString::number(i));
-        pFS->startElement(FSNS(XML_c, XML_v));
-        pFS->writeEscaped( aCategories[i] );
-        pFS->endElement( FSNS( XML_c, XML_v ) );
-        pFS->endElement( FSNS( XML_c, XML_pt ) );
+        // export single category axis labels
+        pFS->startElement(FSNS(XML_c, XML_strRef));
+
+        pFS->startElement(FSNS(XML_c, XML_f));
+        pFS->writeEscaped(aCellRange);
+        pFS->endElement(FSNS(XML_c, XML_f));
+
+        ::std::vector< OUString > aCategories;
+        lcl_fillCategoriesIntoStringVector(xValueSeq, aCategories);
+        sal_Int32 ptCount = aCategories.size();
+        pFS->startElement(FSNS(XML_c, XML_strCache));
+        pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, 
OString::number(ptCount));
+        for (sal_Int32 i = 0; i < ptCount; i++)
+        {
+            pFS->startElement(FSNS(XML_c, XML_pt), XML_idx, 
OString::number(i));
+            pFS->startElement(FSNS(XML_c, XML_v));
+            pFS->writeEscaped(aCategories[i]);
+            pFS->endElement(FSNS(XML_c, XML_v));
+            pFS->endElement(FSNS(XML_c, XML_pt));
+        }
+
+        pFS->endElement(FSNS(XML_c, XML_strCache));
+        pFS->endElement(FSNS(XML_c, XML_strRef));
     }
 
-    pFS->endElement( FSNS( XML_c, XML_strCache ) );
-    pFS->endElement( FSNS( XML_c, XML_strRef ) );
     pFS->endElement( FSNS( XML_c, XML_cat ) );
 }
 
@@ -2708,6 +2891,9 @@ void ChartExport::_exportAxis(
 
         // FIXME: seems not support? lblOffset
         pFS->singleElement(FSNS(XML_c, XML_lblOffset), XML_val, 
OString::number(100));
+
+        // FIXME: seems not support? noMultiLvlLbl
+        pFS->singleElement(FSNS(XML_c, XML_noMultiLvlLbl), XML_val, 
OString::number(0));
     }
 
     // TODO: MSO does not support random axis cross position for
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to