From f547cf17a179ebd7de5c2b4dd2d00d0027a25429 Mon Sep 17 00:00:00 2001 From: Dennis Francis Date: Thu, 2 Sep 2021 14:33:55 +0530 Subject: [API CHANGE] oox: fix import of chart date categories Before this fix, date categories imported in oox's DataSourceContext were stored as formatted strings according to number format code in under the tree. As a result chart2 could not recognize them as dates. This causes problems like: * The axis that is linked to date categories cannot use the scaling/range-selection(min/max)/increments specs mentioned as axis properties. This results in distorted/unreadable chart renders w.r.t the date axis. * No re-formatting is attempted as per the number format provided for axis. This patch introduces a role qualifer argument to the XDataProvider interface method createDataSequenceByValueArray to support categories of date type via this method. When exporting to oox, write date categories and format code under This patch also fixes some discrepancies in date axis interval computation (auto mode) found by already existing unit tests. Change-Id: Ibc53b0a56fdddba80ba452d5567ce98d80460ea7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121525 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- chart2/qa/extras/chart2dump/chart2dump.cxx | 1 + .../qa/extras/chart2dump/data/date-categories.pptx | Bin 0 -> 41931 bytes .../reference/axislabeltest/date-categories.txt | 180 +++++++++++++++++++++ chart2/qa/extras/chart2export2.cxx | 39 +++++ chart2/qa/extras/chart2import.cxx | 46 +++--- chart2/qa/extras/charttest.hxx | 37 +++++ chart2/source/inc/InternalDataProvider.hxx | 6 +- chart2/source/tools/InternalDataProvider.cxx | 20 ++- chart2/source/view/axes/ScaleAutomatism.cxx | 4 +- chart2/source/view/axes/VCoordinateSystem.cxx | 6 +- chart2/source/view/charttypes/AreaChart.cxx | 4 +- dbaccess/source/core/inc/DatabaseDataProvider.hxx | 2 +- dbaccess/source/core/misc/DatabaseDataProvider.cxx | 2 +- include/oox/drawingml/chart/chartconverter.hxx | 3 +- include/oox/drawingml/chart/datasourcemodel.hxx | 3 + include/oox/export/chartexport.hxx | 1 + offapi/com/sun/star/chart2/data/XDataProvider.idl | 23 ++- oox/source/drawingml/chart/chartconverter.cxx | 4 +- oox/source/drawingml/chart/datasourcecontext.cxx | 23 ++- oox/source/drawingml/chart/datasourceconverter.cxx | 6 +- oox/source/drawingml/chart/datasourcemodel.cxx | 4 +- oox/source/export/chartexport.cxx | 43 ++++- sc/inc/PivotTableDataProvider.hxx | 3 +- sc/inc/chart2uno.hxx | 3 +- sc/source/filter/inc/excelchartconverter.hxx | 3 +- sc/source/filter/oox/excelchartconverter.cxx | 2 +- sc/source/ui/unoobj/PivotTableDataProvider.cxx | 3 +- sc/source/ui/unoobj/chart2uno.cxx | 3 +- sw/inc/unochart.hxx | 2 +- sw/source/core/unocore/unochart.cxx | 3 +- 30 files changed, 412 insertions(+), 67 deletions(-) create mode 100644 chart2/qa/extras/chart2dump/data/date-categories.pptx create mode 100644 chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt diff --git a/chart2/qa/extras/chart2dump/chart2dump.cxx b/chart2/qa/extras/chart2dump/chart2dump.cxx index 28768ca68957..fc3944f494e3 100644 --- a/chart2/qa/extras/chart2dump/chart2dump.cxx +++ b/chart2/qa/extras/chart2dump/chart2dump.cxx @@ -616,6 +616,7 @@ DECLARE_DUMP_TEST(AxisLabelTest, Chart2DumpTest, false) "formated_axis_labels.odp", "percent_stacked_column_chart.odp", "tdf118150.xlsx", + "date-categories.pptx", }; for (const OUString& sTestFile : aTestFiles) diff --git a/chart2/qa/extras/chart2dump/data/date-categories.pptx b/chart2/qa/extras/chart2dump/data/date-categories.pptx new file mode 100644 index 000000000000..b9e0c69f32b7 Binary files /dev/null and b/chart2/qa/extras/chart2dump/data/date-categories.pptx differ diff --git a/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt b/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt new file mode 100644 index 000000000000..a9274fd7838a --- /dev/null +++ b/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt @@ -0,0 +1,180 @@ +/// CID/D=0:CS=0:Axis=0,0 +// nAxisLabelsCount +22 +// xLabel->getString() +15/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +17/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +19/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +21/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +23/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +25/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +27/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +29/Jun/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +1/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +3/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +5/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +7/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +9/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +11/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +13/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +15/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +17/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +19/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +21/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +23/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +25/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +27/Jul/21 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +/// CID/D=0:CS=0:Axis=1,0 +// nAxisLabelsCount +7 +// xLabel->getString() +0 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +20 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +40 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +60 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +80 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +100 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 +// xLabel->getString() +120 +// static_cast(aLabelFontColor) +5855577 +// fLabelFontHeight +9 diff --git a/chart2/qa/extras/chart2export2.cxx b/chart2/qa/extras/chart2export2.cxx index d7862946fd4d..2652572f847f 100644 --- a/chart2/qa/extras/chart2export2.cxx +++ b/chart2/qa/extras/chart2export2.cxx @@ -102,6 +102,7 @@ public: void testGraphicBlipXLSX(); void testNameRangeXLSX(); void testTdf143942(); + void testDateCategoriesPPTX(); CPPUNIT_TEST_SUITE(Chart2ExportTest2); CPPUNIT_TEST(testSetSeriesToSecondaryAxisXLSX); @@ -166,6 +167,7 @@ public: CPPUNIT_TEST(testGraphicBlipXLSX); CPPUNIT_TEST(testNameRangeXLSX); CPPUNIT_TEST(testTdf143942); + CPPUNIT_TEST(testDateCategoriesPPTX); CPPUNIT_TEST_SUITE_END(); }; @@ -1601,6 +1603,43 @@ void Chart2ExportTest2::testTdf143942() } } +void Chart2ExportTest2::testDateCategoriesPPTX() +{ + load(u"/chart2/qa/extras/data/pptx/", "bnc889755.pptx"); + xmlDocUniquePtr pXmlDoc = parseExport("ppt/charts/chart", "Impress Office Open XML"); + CPPUNIT_ASSERT(pXmlDoc); + + constexpr size_t nCats = 16; + double aDates[nCats] = { + 41183, 41214, 41244, 41275, 41306, 41334, 41365, 41395, + 41426, 41456, 41487, 41518, 41548, 41579, 41609, 41640, + }; + + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat"); + assertXPathContent(pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/" + "c:numCache/c:formatCode", + "mmm\\-yy"); + assertXPath( + pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:ptCount", + "val", OUString::number(nCats)); + + for (size_t i = 0; i < nCats; ++i) + { + assertXPath( + pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:pt[" + + OString::number(i + 1) + "]", + "idx", OUString::number(i)); + assertXPathContent( + pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:pt[" + + OString::number(i + 1) + "]/c:v", + OUString::number(aDates[i])); + } +} + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx index 388e0e5f1900..0b0977a1ebd8 100644 --- a/chart2/qa/extras/chart2import.cxx +++ b/chart2/qa/extras/chart2import.cxx @@ -29,7 +29,9 @@ #include #include #include +#include #include +#include #include #include @@ -767,26 +769,20 @@ void Chart2ImportTest::testBnc889755() uno::Reference xChartDoc(getChartDocFromDrawImpress(0, 5), uno::UNO_QUERY_THROW); CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider()); - uno::Reference< chart2::XInternalDataProvider > xDataProvider( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); - uno::Reference< chart::XChartDataArray > xChartDataArray(xDataProvider, uno::UNO_QUERY_THROW); - uno::Sequence< OUString > aRowLabels = xChartDataArray->getRowDescriptions(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(16), aRowLabels.getLength()); - CPPUNIT_ASSERT_EQUAL(OUString("Oct-12"), aRowLabels[0]); - CPPUNIT_ASSERT_EQUAL(OUString("Nov-12"), aRowLabels[1]); - CPPUNIT_ASSERT_EQUAL(OUString("Dec-12"), aRowLabels[2]); - CPPUNIT_ASSERT_EQUAL(OUString("Jan-13"), aRowLabels[3]); - CPPUNIT_ASSERT_EQUAL(OUString("Feb-13"), aRowLabels[4]); - CPPUNIT_ASSERT_EQUAL(OUString("Mar-13"), aRowLabels[5]); - CPPUNIT_ASSERT_EQUAL(OUString("Apr-13"), aRowLabels[6]); - CPPUNIT_ASSERT_EQUAL(OUString("May-13"), aRowLabels[7]); - CPPUNIT_ASSERT_EQUAL(OUString("Jun-13"), aRowLabels[8]); - CPPUNIT_ASSERT_EQUAL(OUString("Jul-13"), aRowLabels[9]); - CPPUNIT_ASSERT_EQUAL(OUString("Aug-13"), aRowLabels[10]); - CPPUNIT_ASSERT_EQUAL(OUString("Sep-13"), aRowLabels[11]); - CPPUNIT_ASSERT_EQUAL(OUString("Oct-13"), aRowLabels[12]); - CPPUNIT_ASSERT_EQUAL(OUString("Nov-13"), aRowLabels[13]); - CPPUNIT_ASSERT_EQUAL(OUString("Dec-13"), aRowLabels[14]); - CPPUNIT_ASSERT_EQUAL(OUString("Jan-14"), aRowLabels[15]); + constexpr sal_Int32 nNumCategories = 16; + Sequence aDateSeq = getFormattedDateCategories(xChartDoc); + + CPPUNIT_ASSERT_EQUAL(nNumCategories, aDateSeq.getLength()); + + const OUString aExpectedDateCategories[nNumCategories] = { + "Oct-12", "Nov-12", "Dec-12", "Jan-13", + "Feb-13", "Mar-13", "Apr-13", "May-13", + "Jun-13", "Jul-13", "Aug-13", "Sep-13", + "Oct-13", "Nov-13", "Dec-13", "Jan-14", + }; + + for (size_t nIdx = 0; nIdx < nNumCategories; ++nIdx) + CPPUNIT_ASSERT_EQUAL(aExpectedDateCategories[nIdx], aDateSeq[nIdx]); //tdf#139940 - the title's gradient was lost and was filled with solid blue, instead of a "blue underline". uno::Reference xDoc(mxComponent, uno::UNO_QUERY_THROW); @@ -1724,7 +1720,7 @@ void Chart2ImportTest::testInternalDataProvider() { const uno::Reference< chart2::data::XDataProvider >& rxDataProvider = xChartDoc->getDataProvider(); // Parse 42 array - Reference xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;42;42;42}"); + Reference xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;42;42;42}", ""); Sequence xSequence = xDataSeq->getData(); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[1]); @@ -1732,7 +1728,7 @@ void Chart2ImportTest::testInternalDataProvider() { CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[3]); // Parse empty first and last - xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{\"\";42;42;\"\"}"); + xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{\"\";42;42;\"\"}", ""); xSequence = xDataSeq->getData(); CPPUNIT_ASSERT( std::isnan( *static_cast(xSequence[0].getValue()))); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[1]); @@ -1740,7 +1736,7 @@ void Chart2ImportTest::testInternalDataProvider() { CPPUNIT_ASSERT( std::isnan( *static_cast(xSequence[3].getValue()))); // Parse empty middle - xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;\"\";\"\";42}"); + xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;\"\";\"\";42}", ""); xSequence = xDataSeq->getData(); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]); CPPUNIT_ASSERT( std::isnan( *static_cast(xSequence[1].getValue())) ); @@ -1748,7 +1744,7 @@ void Chart2ImportTest::testInternalDataProvider() { CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[3]); // Parse mixed types, numeric only role - xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;\"hello\";0;\"world\"}"); + xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", "{42;\"hello\";0;\"world\"}", ""); xSequence = xDataSeq->getData(); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]); CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(0)), xSequence[1]); @@ -1756,7 +1752,7 @@ void Chart2ImportTest::testInternalDataProvider() { CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(0)), xSequence[3]); // Parse mixed types, mixed role - xDataSeq = rxDataProvider->createDataSequenceByValueArray("categories", "{42;\"hello\";0;\"world\"}"); + xDataSeq = rxDataProvider->createDataSequenceByValueArray("categories", "{42;\"hello\";0;\"world\"}", ""); xSequence = xDataSeq->getData(); CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 1 42")), xSequence[0]); CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 2 hello")), xSequence[1]); diff --git a/chart2/qa/extras/charttest.hxx b/chart2/qa/extras/charttest.hxx index 9b162acc06e8..c1772702afd0 100644 --- a/chart2/qa/extras/charttest.hxx +++ b/chart2/qa/extras/charttest.hxx @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -45,12 +46,15 @@ #include #include #include +#include +#include #include #include #include #include #include #include +#include #include @@ -121,6 +125,7 @@ public: uno::Reference getChartDocFromDrawImpress( sal_Int32 nPage, sal_Int32 nShape ); uno::Reference getChartDocFromWriter( sal_Int32 nShape ); + Sequence< OUString > getFormattedDateCategories( const Reference& xChartDoc ); awt::Size getPageSize( const Reference< chart2::XChartDocument > & xChartDoc ); awt::Size getSize(css::uno::Reference xDiagram, const awt::Size& rPageSize); @@ -635,6 +640,38 @@ sal_Int16 getNumberFormatType( const Reference& xChartDo return nType; } +Sequence< double > getDateCategories(const Reference& xChartDoc) +{ + CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider()); + uno::Reference< chart2::XInternalDataProvider > xDataProvider( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); + uno::Reference< chart::XDateCategories > xDateCategories( xDataProvider, uno::UNO_QUERY_THROW ); + CPPUNIT_ASSERT(xDateCategories.is()); + return xDateCategories->getDateCategories(); +} + +Sequence< OUString > ChartTest::getFormattedDateCategories( const Reference& xChartDoc ) +{ + Reference xNFS(xChartDoc, uno::UNO_QUERY_THROW); + Reference< util::XNumberFormatter > xNumFormatter( + util::NumberFormatter::create(comphelper::getComponentContext(m_xSFactory)), uno::UNO_QUERY_THROW ); + xNumFormatter->attachNumberFormatsSupplier(xNFS); + + Reference xAxisX = getAxisFromDoc(xChartDoc, 0, 0, 0); + chart2::ScaleData aScaleData = xAxisX->getScaleData(); + CPPUNIT_ASSERT_EQUAL(chart2::AxisType::DATE, aScaleData.AxisType); + + sal_Int32 nNumFmt = getNumberFormatFromAxis(xAxisX); + + Sequence aDateSeq = getDateCategories(xChartDoc); + const sal_Int32 nNumCategories = aDateSeq.getLength(); + Sequence aFormattedDates(nNumCategories); + + for (sal_Int32 nIdx = 0; nIdx < nNumCategories; ++nIdx) + aFormattedDates[nIdx] = xNumFormatter->convertNumberToString(nNumFmt, aDateSeq[nIdx]); + + return aFormattedDates; +} + awt::Size ChartTest::getPageSize( const Reference< chart2::XChartDocument > & xChartDoc ) { awt::Size aSize( 0, 0 ); diff --git a/chart2/source/inc/InternalDataProvider.hxx b/chart2/source/inc/InternalDataProvider.hxx index 1e5821f94e6c..34c5d4831c17 100644 --- a/chart2/source/inc/InternalDataProvider.hxx +++ b/chart2/source/inc/InternalDataProvider.hxx @@ -112,7 +112,8 @@ public: const OUString& aRangeRepresentation ) override; virtual css::uno::Reference SAL_CALL - createDataSequenceByValueArray( const OUString& aRole, const OUString& aRangeRepresentation ) override; + createDataSequenceByValueArray( const OUString& aRole, const OUString& aRangeRepresentation, + const OUString& aRoleQualifier ) override; virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override; @@ -183,7 +184,8 @@ private: createDataSequenceAndAddToMap( const OUString & rRangeRepresentation ); css::uno::Reference - createDataSequenceFromArray( const OUString& rArrayStr, std::u16string_view rRole ); + createDataSequenceFromArray( const OUString& rArrayStr, std::u16string_view rRole, + std::u16string_view rRoleQualifier); void deleteMapReferences( const OUString & rRangeRepresentation ); diff --git a/chart2/source/tools/InternalDataProvider.cxx b/chart2/source/tools/InternalDataProvider.cxx index 505159fa87b6..abbcc077e1c0 100644 --- a/chart2/source/tools/InternalDataProvider.cxx +++ b/chart2/source/tools/InternalDataProvider.cxx @@ -483,7 +483,7 @@ void InternalDataProvider::decreaseMapReferences( Reference< chart2::data::XDataSequence > InternalDataProvider::createDataSequenceAndAddToMap( const OUString & rRangeRepresentation ) { - Reference xSeq = createDataSequenceFromArray(rRangeRepresentation, u""); + Reference xSeq = createDataSequenceFromArray(rRangeRepresentation, u"", u""); if (xSeq.is()) return xSeq; @@ -493,7 +493,7 @@ Reference< chart2::data::XDataSequence > InternalDataProvider::createDataSequenc } uno::Reference -InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, std::u16string_view rRole ) +InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, std::u16string_view rRole, std::u16string_view rRoleQualifier ) { if (rArrayStr.indexOf('{') != 0 || rArrayStr[rArrayStr.getLength()-1] != '}') { @@ -620,9 +620,19 @@ InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, st { // Category labels. + // Store date categories as numbers. + bool bStoreNumeric = rRoleQualifier == u"date"; + double fValue; for (size_t i = 0; i < aRawElems.size(); ++i) { - std::vector aLabels(1, uno::Any(aRawElems[i])); + if (bStoreNumeric) + { + bool bGetDouble = bAllNumeric && !aRawElems[i].isEmpty(); + fValue = bGetDouble ? aRawElems[i].toDouble() : + std::numeric_limits::quiet_NaN(); + } + std::vector aLabels(1, + bStoreNumeric ? uno::Any(fValue) : uno::Any(aRawElems[i])); m_aInternalData.setComplexRowLabel(i, aLabels); } @@ -831,9 +841,9 @@ Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDa Reference SAL_CALL InternalDataProvider::createDataSequenceByValueArray( - const OUString& aRole, const OUString& aRangeRepresentation ) + const OUString& aRole, const OUString& aRangeRepresentation, const OUString& aRoleQualifier ) { - return createDataSequenceFromArray(aRangeRepresentation, aRole); + return createDataSequenceFromArray(aRangeRepresentation, aRole, aRoleQualifier); } Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection() diff --git a/chart2/source/view/axes/ScaleAutomatism.cxx b/chart2/source/view/axes/ScaleAutomatism.cxx index 09da37aba034..7748df078ec6 100644 --- a/chart2/source/view/axes/ScaleAutomatism.cxx +++ b/chart2/source/view/axes/ScaleAutomatism.cxx @@ -654,7 +654,7 @@ void ScaleAutomatism::calculateExplicitIncrementAndScaleForDateTimeAxis( nDaysPerInterval = 1.0; } - nNumer = static_cast( rtl::math::approxCeil( nIntervalDays/nDaysPerInterval ) ); + nNumer = static_cast( rtl::math::approxFloor( nIntervalDays/nDaysPerInterval ) ); if(nNumer<=0) nNumer=1; if( rExplicitIncrement.MajorTimeInterval.TimeUnit == DAY ) @@ -665,7 +665,7 @@ void ScaleAutomatism::calculateExplicitIncrementAndScaleForDateTimeAxis( { rExplicitIncrement.MajorTimeInterval.TimeUnit = MONTH; nDaysPerInterval = 31.0; - nNumer = static_cast( rtl::math::approxCeil( nIntervalDays/nDaysPerInterval ) ); + nNumer = static_cast( rtl::math::approxFloor( nIntervalDays/nDaysPerInterval ) ); if(nNumer<=0) nNumer=1; } diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx b/chart2/source/view/axes/VCoordinateSystem.cxx index ded24e5b1353..7259f3e92043 100644 --- a/chart2/source/view/axes/VCoordinateSystem.cxx +++ b/chart2/source/view/axes/VCoordinateSystem.cxx @@ -341,7 +341,8 @@ void VCoordinateSystem::updateScalesAndIncrementsOnAxes() void VCoordinateSystem::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) { - if( rScaleAutomatism.getScale().AxisType==AxisType::DATE && nDimIndex==0 ) + bool bDateAxisX = (rScaleAutomatism.getScale().AxisType == AxisType::DATE) && (nDimIndex == 0); + if( bDateAxisX ) { // This is a date X dimension. Determine proper time resolution. sal_Int32 nTimeResolution = css::chart::TimeUnit::MONTH; @@ -384,6 +385,9 @@ void VCoordinateSystem::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAuto m_aMergedMinMaxSupplier.isExpandWideValuesToZero( nDimIndex ), m_aMergedMinMaxSupplier.isExpandNarrowValuesTowardZero( nDimIndex ) ); + if (bDateAxisX) + return; + VAxisBase* pVAxis = getVAxis(nDimIndex, nAxisIndex); if( pVAxis ) rScaleAutomatism.setMaximumAutoMainIncrementCount( pVAxis->estimateMaximumAutoMainIncrementCount() ); diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx index 37b90cdfdbc0..e0a70af5339f 100644 --- a/chart2/source/view/charttypes/AreaChart.cxx +++ b/chart2/source/view/charttypes/AreaChart.cxx @@ -693,6 +693,8 @@ void AreaChart::createShapes() uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShapeFrontChild(pSeries.get(), m_xSeriesTarget); sal_Int32 nAttachedAxisIndex = pSeries->getAttachedAxisIndex(); + double fXMin, fXMax; + pSeries->getMinMaxXValue(fXMin, fXMax); PlottingPositionHelper& rPosHelper = getPlottingPositionHelper(nAttachedAxisIndex); m_pPosHelper = &rPosHelper; @@ -713,7 +715,7 @@ void AreaChart::createShapes() double fLogicX = pSeries->getXValue(nIndex); if (bDateCategory) { - if (std::isnan(fLogicX)) + if (std::isnan(fLogicX) || (fLogicX < fXMin || fLogicX > fXMax)) continue; fLogicX = DateHelper::RasterizeDateValue( fLogicX, m_aNullDate, m_nTimeResolution ); diff --git a/dbaccess/source/core/inc/DatabaseDataProvider.hxx b/dbaccess/source/core/inc/DatabaseDataProvider.hxx index 9131cfaf1c2b..b5b2c0ae6143 100644 --- a/dbaccess/source/core/inc/DatabaseDataProvider.hxx +++ b/dbaccess/source/core/inc/DatabaseDataProvider.hxx @@ -73,7 +73,7 @@ private: virtual css::uno::Reference SAL_CALL createDataSequenceByValueArray( - const OUString& aRole, const OUString & aRangeRepresentation) override; + const OUString& aRole, const OUString & aRangeRepresentation, const OUString& aRoleQualifier) override; virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override; diff --git a/dbaccess/source/core/misc/DatabaseDataProvider.cxx b/dbaccess/source/core/misc/DatabaseDataProvider.cxx index a7661385aea8..3517a437e10a 100644 --- a/dbaccess/source/core/misc/DatabaseDataProvider.cxx +++ b/dbaccess/source/core/misc/DatabaseDataProvider.cxx @@ -275,7 +275,7 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL DatabaseDataProvider::cre uno::Reference SAL_CALL DatabaseDataProvider::createDataSequenceByValueArray( - const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ ) + const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/, const OUString& /*aRoleQualifier*/ ) { return uno::Reference(); } diff --git a/include/oox/drawingml/chart/chartconverter.hxx b/include/oox/drawingml/chart/chartconverter.hxx index c293c48215bb..fcf3b2fee3fa 100644 --- a/include/oox/drawingml/chart/chartconverter.hxx +++ b/include/oox/drawingml/chart/chartconverter.hxx @@ -84,7 +84,8 @@ public: virtual css::uno::Reference createDataSequence( const css::uno::Reference& rxDataProvider, - const DataSequenceModel& rDataSeq, const OUString& rRole ); + const DataSequenceModel& rDataSeq, const OUString& rRole, + const OUString& aRoleQualifier ); private: ChartConverter( const ChartConverter& ) = delete; diff --git a/include/oox/drawingml/chart/datasourcemodel.hxx b/include/oox/drawingml/chart/datasourcemodel.hxx index dc8d253a7d11..49b8dcd90717 100644 --- a/include/oox/drawingml/chart/datasourcemodel.hxx +++ b/include/oox/drawingml/chart/datasourcemodel.hxx @@ -27,6 +27,8 @@ #include #include +enum class SvNumFormatType : sal_Int16; + namespace oox::drawingml::chart { @@ -39,6 +41,7 @@ struct DataSequenceModel OUString maFormatCode; /// Number format for double values. sal_Int32 mnPointCount; /// Number of points in this series source. sal_Int32 mnLevelCount; /// Number of category levels. + SvNumFormatType meFormatType; /// Type of number format in maFormatCode. explicit DataSequenceModel(); ~DataSequenceModel(); diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index c4440ae08419..3e12e5de725a 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -153,6 +153,7 @@ private: bool mbIs3DChart; bool mbStacked; bool mbPercent; + bool mbHasDateCategories; std::set maExportedAxis; diff --git a/offapi/com/sun/star/chart2/data/XDataProvider.idl b/offapi/com/sun/star/chart2/data/XDataProvider.idl index 6ab3fd4aaadd..e0f450a1a501 100644 --- a/offapi/com/sun/star/chart2/data/XDataProvider.idl +++ b/offapi/com/sun/star/chart2/data/XDataProvider.idl @@ -126,7 +126,28 @@ interface XDataProvider : ::com::sun::star::uno::XInterface [in] string aRangeRepresentation ) raises( com::sun::star::lang::IllegalArgumentException ); - XDataSequence createDataSequenceByValueArray( [in] string aRole, [in] string aValueArray ) + /** Creates a single data sequence from the string value array representation + + @param aRole + The role of the sequence inside a data series. This may be any + string. However some strings are predefined and should always + be used in the same way. + + @param aValueArray + is a string that contains the value representation of the + sequence to be created. + + @param aRoleQualifier + is a string that describes the role of the sequence. + This may be any string. However some strings are predefined + and should always be used in the same way. + + @throws com::sun::star::lang::IllegalArgumentException + if the given value array does not contain a valid value array + representation. + */ + XDataSequence createDataSequenceByValueArray( [in] string aRole, [in] string aValueArray, + [in] string aRoleQualifier ) raises( com::sun::star::lang::IllegalArgumentException ); /** Returns a component that is able to change a given range diff --git a/oox/source/drawingml/chart/chartconverter.cxx b/oox/source/drawingml/chart/chartconverter.cxx index a864aac47e47..af49c561ae51 100644 --- a/oox/source/drawingml/chart/chartconverter.cxx +++ b/oox/source/drawingml/chart/chartconverter.cxx @@ -116,7 +116,7 @@ void ChartConverter::createDataProvider( const Reference< XChartDocument >& rxCh Reference< XDataSequence > ChartConverter::createDataSequence( const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& rDataSeq, - const OUString& rRole ) + const OUString& rRole, const OUString& rRoleQualifier ) { Reference< XDataSequence > xDataSeq; if( rxDataProvider.is() ) @@ -137,7 +137,7 @@ Reference< XDataSequence > ChartConverter::createDataSequence( if (!aRangeRep.isEmpty()) { // create or add a new level to the data sequence - xDataSeq = rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep); + xDataSeq = rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep, rRoleQualifier); if (i == 0) return xDataSeq; } diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx index 1b64089d4281..f4660f5db708 100644 --- a/oox/source/drawingml/chart/datasourcecontext.cxx +++ b/oox/source/drawingml/chart/datasourcecontext.cxx @@ -99,7 +99,7 @@ void DoubleSequenceContext::onCharacters( const OUString& rChars ) if( mnPtIndex >= 0 ) { /* Import categories as String even though it could - * be values. + * be values except when the format code indicates that they are dates. * n#810508: xVal needs to be imported as double * TODO: NumberFormat conversion, remove the check then. */ @@ -118,6 +118,8 @@ void DoubleSequenceContext::onCharacters( const OUString& rChars ) SvNumFormatType nType; pNumFrmt->PutEntry( aFormatCode, nCheckPos, nType, nKey ); bNoKey = (nCheckPos != 0); + if (!bNoKey) + mrModel.meFormatType = nType; } if( bNoKey ) { @@ -126,13 +128,18 @@ void DoubleSequenceContext::onCharacters( const OUString& rChars ) else { double fValue = rChars.toDouble(); - const ::Color* pColor = nullptr; - OUString aFormattedValue; - // tdf#91250: use UNLIMITED_PRECISION in case of GENERAL Number Format of category axis labels - if( pNumFrmt->GetStandardPrec() != SvNumberFormatter::UNLIMITED_PRECISION ) - pNumFrmt->ChangeStandardPrec(SvNumberFormatter::UNLIMITED_PRECISION); - pNumFrmt->GetOutputString( fValue, nKey, aFormattedValue, &pColor ); - mrModel.maData[ mnPtIndex ] <<= aFormattedValue; + if (mrModel.meFormatType == SvNumFormatType::DATE) + mrModel.maData[ mnPtIndex ] <<= fValue; + else + { + const ::Color* pColor = nullptr; + OUString aFormattedValue; + // tdf#91250: use UNLIMITED_PRECISION in case of GENERAL Number Format of category axis labels + if( pNumFrmt->GetStandardPrec() != SvNumberFormatter::UNLIMITED_PRECISION ) + pNumFrmt->ChangeStandardPrec(SvNumberFormatter::UNLIMITED_PRECISION); + pNumFrmt->GetOutputString( fValue, nKey, aFormattedValue, &pColor ); + mrModel.maData[ mnPtIndex ] <<= aFormattedValue; + } } } else diff --git a/oox/source/drawingml/chart/datasourceconverter.cxx b/oox/source/drawingml/chart/datasourceconverter.cxx index 72399426538d..92cacb4286bf 100644 --- a/oox/source/drawingml/chart/datasourceconverter.cxx +++ b/oox/source/drawingml/chart/datasourceconverter.cxx @@ -23,6 +23,7 @@ #include #include #include +#include namespace oox::drawingml::chart { @@ -69,7 +70,10 @@ Reference< XDataSequence > DataSequenceConverter::createDataSequence( const OUSt mrModel.maData.insert(std::make_pair(0, Any(aTitle.makeStringAndClear()))); } } - xDataSeq = getChartConverter().createDataSequence(getChartDocument()->getDataProvider(), mrModel, rRole); + + bool bDateCategories = (mrModel.meFormatType == SvNumFormatType::DATE) && (rRole == "categories"); + xDataSeq = getChartConverter().createDataSequence(getChartDocument()->getDataProvider(), mrModel, + rRole, bDateCategories ? OUString("date") : OUString("")); // set sequence role PropertySet aSeqProp( xDataSeq ); diff --git a/oox/source/drawingml/chart/datasourcemodel.cxx b/oox/source/drawingml/chart/datasourcemodel.cxx index e83b6b3558a5..51514437d33d 100644 --- a/oox/source/drawingml/chart/datasourcemodel.cxx +++ b/oox/source/drawingml/chart/datasourcemodel.cxx @@ -18,12 +18,14 @@ */ #include +#include namespace oox::drawingml::chart { DataSequenceModel::DataSequenceModel() : mnPointCount( -1 ), - mnLevelCount( 1 ) + mnLevelCount( 1 ), + meFormatType( SvNumFormatType::UNDEFINED ) { } diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index c39f2f146681..8bbd4ecd1990 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -158,8 +158,9 @@ private: } -static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram ) +static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram, bool& bHasDateCategories ) { + bHasDateCategories = false; Reference< chart2::data::XLabeledDataSequence > xResult; try { @@ -182,6 +183,7 @@ static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const chart2::ScaleData aScaleData = xAxis->getScaleData(); if( aScaleData.Categories.is()) { + bHasDateCategories = aScaleData.AxisType == chart2::AxisType::DATE; xResult.set( aScaleData.Categories ); break; } @@ -220,7 +222,8 @@ static bool lcl_hasCategoryLabels( const Reference< chart2::XChartDocument >& xC { //categories are always the first sequence Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram()); - Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) ); + bool bDateCategories; + Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram, bDateCategories ) ); return xCategories.is(); } @@ -2861,7 +2864,26 @@ void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequ else { // export single category axis labels - pFS->startElement(FSNS(XML_c, XML_strRef)); + bool bWriteDateCategories = mbHasDateCategories && (nValueType == XML_cat); + OUString aNumberFormatString; + if (bWriteDateCategories) + { + Reference< css::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY ); + if( xAxisXSupp.is()) + { + Reference< XPropertySet > xAxisProp = xAxisXSupp->getXAxis(); + if (GetProperty(xAxisProp, "NumberFormat")) + { + sal_Int32 nKey = 0; + mAny >>= nKey; + aNumberFormatString = getNumberFormatCode(nKey); + } + } + if (aNumberFormatString.isEmpty()) + bWriteDateCategories = false; + } + + pFS->startElement(FSNS(XML_c, bWriteDateCategories ? XML_numRef : XML_strRef)); pFS->startElement(FSNS(XML_c, XML_f)); pFS->writeEscaped(aCellRange); @@ -2870,7 +2892,14 @@ void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequ ::std::vector< OUString > aCategories; lcl_fillCategoriesIntoStringVector(xValueSeq, aCategories); sal_Int32 ptCount = aCategories.size(); - pFS->startElement(FSNS(XML_c, XML_strCache)); + pFS->startElement(FSNS(XML_c, bWriteDateCategories ? XML_numCache : XML_strCache)); + if (bWriteDateCategories) + { + pFS->startElement(FSNS(XML_c, XML_formatCode)); + pFS->writeEscaped(aNumberFormatString); + pFS->endElement(FSNS(XML_c, XML_formatCode)); + } + pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, OString::number(ptCount)); for (sal_Int32 i = 0; i < ptCount; i++) { @@ -2881,8 +2910,8 @@ void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequ 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, bWriteDateCategories ? XML_numCache : XML_strCache)); + pFS->endElement(FSNS(XML_c, bWriteDateCategories ? XML_numRef : XML_strRef)); } pFS->endElement( FSNS( XML_c, nValueType ) ); @@ -3025,7 +3054,7 @@ void ChartExport::InitPlotArea( ) if( mbHasCategoryLabels && mxNewDiagram.is()) { - Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) ); + Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram, mbHasDateCategories ) ); if( xCategories.is() ) { mxCategoriesValues.set( xCategories->getValues() ); diff --git a/sc/inc/PivotTableDataProvider.hxx b/sc/inc/PivotTableDataProvider.hxx index d31b9adb2e02..a1df012ccad1 100644 --- a/sc/inc/PivotTableDataProvider.hxx +++ b/sc/inc/PivotTableDataProvider.hxx @@ -68,7 +68,8 @@ public: createDataSequenceByRangeRepresentation(const OUString& aRangeRepresentation) override; virtual css::uno::Reference SAL_CALL - createDataSequenceByValueArray(const OUString& aRole, const OUString& aRangeRepresentation) override; + createDataSequenceByValueArray(const OUString& aRole, const OUString& aRangeRepresentation, + const OUString& aRoleQualifier) override; virtual css::uno::Reference SAL_CALL getRangeSelection() override; diff --git a/sc/inc/chart2uno.hxx b/sc/inc/chart2uno.hxx index 79c289996cf7..b3d80a6ffe02 100644 --- a/sc/inc/chart2uno.hxx +++ b/sc/inc/chart2uno.hxx @@ -87,7 +87,8 @@ public: const OUString& aRangeRepresentation ) override; virtual css::uno::Reference SAL_CALL - createDataSequenceByValueArray( const OUString& aRole, const OUString& aRangeRepresentation ) override; + createDataSequenceByValueArray( const OUString& aRole, const OUString& aRangeRepresentation, + const OUString& aRoleQualifier ) override; virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override; diff --git a/sc/source/filter/inc/excelchartconverter.hxx b/sc/source/filter/inc/excelchartconverter.hxx index 1d3d58922929..363966a4c023 100644 --- a/sc/source/filter/inc/excelchartconverter.hxx +++ b/sc/source/filter/inc/excelchartconverter.hxx @@ -38,7 +38,8 @@ public: virtual css::uno::Reference createDataSequence( const css::uno::Reference& rxDataProvider, - const oox::drawingml::chart::DataSequenceModel& rDataSeq, const OUString& rRole ) override; + const oox::drawingml::chart::DataSequenceModel& rDataSeq, const OUString& rRole, + const OUString& aRoleQualifier ) override; }; } // namespace oox::xls diff --git a/sc/source/filter/oox/excelchartconverter.cxx b/sc/source/filter/oox/excelchartconverter.cxx index 50695b1fb8f9..bc9a0bd030bf 100644 --- a/sc/source/filter/oox/excelchartconverter.cxx +++ b/sc/source/filter/oox/excelchartconverter.cxx @@ -64,7 +64,7 @@ void ExcelChartConverter::createDataProvider( const Reference< XChartDocument >& Reference< XDataSequence > ExcelChartConverter::createDataSequence( const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& rDataSeq, - const OUString& /*rRole*/ ) + const OUString& /*rRole*/, const OUString& /*aRoleQualifier*/ ) { Reference< XDataSequence > xDataSeq; if (!rxDataProvider.is()) diff --git a/sc/source/ui/unoobj/PivotTableDataProvider.cxx b/sc/source/ui/unoobj/PivotTableDataProvider.cxx index 2971be908072..c0b96154e0a6 100644 --- a/sc/source/ui/unoobj/PivotTableDataProvider.cxx +++ b/sc/source/ui/unoobj/PivotTableDataProvider.cxx @@ -706,7 +706,8 @@ uno::Reference SAL_CALL uno::Reference SAL_CALL PivotTableDataProvider::createDataSequenceByValueArray(const OUString& /*aRole*/, - const OUString& /*aRangeRepresentation*/) + const OUString& /*aRangeRepresentation*/, + const OUString& /*aRoleQualifier*/) { return uno::Reference(); } diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index d5ed1ad3e892..5efa562cb352 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -2068,7 +2068,8 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL uno::Reference SAL_CALL ScChart2DataProvider::createDataSequenceByValueArray( - const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ ) + const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/, + const OUString& /*aRoleQualifier*/ ) { return uno::Reference(); } diff --git a/sw/inc/unochart.hxx b/sw/inc/unochart.hxx index 7147f8a036eb..f17f832600b0 100644 --- a/sw/inc/unochart.hxx +++ b/sw/inc/unochart.hxx @@ -155,7 +155,7 @@ public: virtual css::uno::Reference SAL_CALL createDataSequenceByValueArray( - const OUString& aRole, const OUString& aRangeRepresentation ) override; + const OUString& aRole, const OUString& aRangeRepresentation, const OUString& aRoleQualifier ) override; // XRangeXMLConversion virtual OUString SAL_CALL convertRangeToXML( const OUString& aRangeRepresentation ) override; diff --git a/sw/source/core/unocore/unochart.cxx b/sw/source/core/unocore/unochart.cxx index 4446c63c1080..7a78239c8ad1 100644 --- a/sw/source/core/unocore/unochart.cxx +++ b/sw/source/core/unocore/unochart.cxx @@ -1351,7 +1351,8 @@ uno::Reference< sheet::XRangeSelection > SAL_CALL SwChartDataProvider::getRangeS uno::Reference SAL_CALL SwChartDataProvider::createDataSequenceByValueArray( - const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ ) + const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/, + const OUString& /*aRoleQualifier*/ ) { return uno::Reference(); } -- cgit