summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2017-02-26 22:48:06 +0100
committerTomaž Vajngerl <quikee@gmail.com>2017-04-04 13:39:29 +0000
commit9009663deb8f0862f419fd99bf0b761c7f923eff (patch)
treeea25976de0919f9d2161037d83be0eace4c1070b
parent1931b5b01c6fdaa204d26ec4b9675dad16373cf2 (diff)
tdf#83257 [API-CHANGE] Pivot chart implementation
This is a squashed commit of the pivot chart implementation. Some of the changes: - Add pivot chart specific (pivot table) data provider which provides the data from a pivot table to the associated chart. - When inserting a chart and the cursor is in a pivot table, in that case insert a pivot chart - Modify the pivot chart when the pivot table changes - Collect and set the number format for the values - isDataFromSpreadsheet check for the creation wizard - In ChartView (and VLegend) check if the data provider is a pivot chart data provider and get the pivot table field names to create the buttons on the UI. - Adds the functionallity to show a filter pop-up (from calc) when clicking on row / column / page field buttons. - Remove (X)PopupRequest as we won't need it. - Add ODF import/export for pivot charts: + Added loext:data-pilot-source attribute on chart:chart which is the internal name of the pivot table with which the pivot chart is associated with. If the element is present, then the it means the chart is a pivot chart, else it is a normal chart + Added service to create pivot chart data provider through UNO + Add new methods to XPivotChartDataProvider to create value and label data sequences separately from the data source, which is needed for pivot chart import + When importing defer setting the data provider until a later time when we know if we are creating a chart od a pivot chart - Pivot chart ODF round-trip test - Add table pivot chart supplier API: This adds the XTablePivotChartSupplier and related interfaces so we can access, create, delete pivot charts from UNO in a sheet document. With this we now distinguish between normal charts and pivot charts. This was mainly needed because we can't extend the "published" interfaces of TableChartSupplier. - Added an extensive test, which uses the API to create a new pivot chart when there was none, and checks that the pivot chart updates when the pivot table updates. Change-Id: Ia9ed96fd6b1d342e61c2f7f9fa33a5e03dda21af Reviewed-on: https://gerrit.libreoffice.org/36023 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--chart2/CppunitTest_chart2_pivot_chart_test.mk131
-rw-r--r--chart2/Module_chart2.mk1
-rw-r--r--chart2/inc/ChartModel.hxx9
-rw-r--r--chart2/qa/extras/PivotChartTest.cxx298
-rw-r--r--chart2/qa/extras/charttest.hxx77
-rw-r--r--chart2/qa/extras/data/ods/PivotChartRoundTrip.odsbin0 -> 21988 bytes
-rw-r--r--chart2/qa/extras/data/ods/PivotTableExample.odsbin0 -> 17183 bytes
-rw-r--r--chart2/source/controller/dialogs/DialogModel.hxx3
-rw-r--r--chart2/source/controller/dialogs/dlg_CreationWizard.cxx61
-rw-r--r--chart2/source/controller/drawinglayer/DrawViewWrapper.cxx7
-rw-r--r--chart2/source/controller/inc/ChartController.hxx2
-rw-r--r--chart2/source/controller/inc/dlg_CreationWizard.hxx37
-rw-r--r--chart2/source/controller/main/ChartController_Window.cxx71
-rw-r--r--chart2/source/inc/PopupRequest.hxx11
-rw-r--r--chart2/source/model/main/ChartModel.cxx23
-rw-r--r--chart2/source/model/main/ChartModel_Persistence.cxx36
-rw-r--r--chart2/source/view/main/ChartView.cxx50
-rw-r--r--chart2/source/view/main/VLegend.cxx29
-rw-r--r--include/xmloff/xmlnmspe.hxx1
-rw-r--r--include/xmloff/xmltoken.hxx1
-rw-r--r--offapi/UnoApi_offapi.mk7
-rw-r--r--offapi/com/sun/star/chart2/data/PivotTableFieldEntry.idl (renamed from offapi/com/sun/star/chart2/data/XPopupRequest.idl)25
-rw-r--r--offapi/com/sun/star/chart2/data/PopupRequest.idl44
-rw-r--r--offapi/com/sun/star/chart2/data/XDataReceiver.idl2
-rw-r--r--offapi/com/sun/star/chart2/data/XPivotTableDataProvider.idl90
-rw-r--r--offapi/com/sun/star/table/XTablePivotChart.idl36
-rw-r--r--offapi/com/sun/star/table/XTablePivotCharts.idl63
-rw-r--r--offapi/com/sun/star/table/XTablePivotChartsSupplier.idl41
-rw-r--r--sc/Library_sc.mk6
-rw-r--r--sc/inc/ChartTools.hxx50
-rw-r--r--sc/inc/PivotTableDataProvider.hxx190
-rw-r--r--sc/inc/PivotTableDataSequence.hxx170
-rw-r--r--sc/inc/PivotTableDataSource.hxx59
-rw-r--r--sc/inc/TablePivotChart.hxx74
-rw-r--r--sc/inc/TablePivotCharts.hxx76
-rw-r--r--sc/inc/cellsuno.hxx6
-rw-r--r--sc/inc/servuno.hxx2
-rw-r--r--sc/inc/unonames.hxx1
-rw-r--r--sc/source/ui/drawfunc/fuins2.cxx95
-rw-r--r--sc/source/ui/inc/tabview.hxx2
-rw-r--r--sc/source/ui/unoobj/ChartTools.cxx127
-rw-r--r--sc/source/ui/unoobj/PivotTableDataProvider.cxx843
-rw-r--r--sc/source/ui/unoobj/PivotTableDataSequence.cxx278
-rw-r--r--sc/source/ui/unoobj/PivotTableDataSource.cxx51
-rw-r--r--sc/source/ui/unoobj/TablePivotChart.cxx104
-rw-r--r--sc/source/ui/unoobj/TablePivotCharts.cxx279
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx17
-rw-r--r--sc/source/ui/unoobj/chartuno.cxx48
-rw-r--r--sc/source/ui/unoobj/servuno.cxx7
-rw-r--r--sc/source/ui/view/tabview3.cxx18
-rw-r--r--sc/source/ui/view/tabvwshb.cxx32
-rw-r--r--xmloff/inc/SchXMLImport.hxx3
-rw-r--r--xmloff/source/chart/SchXMLChartContext.cxx72
-rw-r--r--xmloff/source/chart/SchXMLChartContext.hxx2
-rw-r--r--xmloff/source/chart/SchXMLExport.cxx8
-rw-r--r--xmloff/source/chart/SchXMLImport.cxx61
-rw-r--r--xmloff/source/chart/SchXMLSeries2Context.cxx50
-rw-r--r--xmloff/source/chart/SchXMLTools.cxx21
-rw-r--r--xmloff/source/core/xmltoken.cxx1
-rw-r--r--xmloff/source/token/tokens.txt3
60 files changed, 3583 insertions, 329 deletions
diff --git a/chart2/CppunitTest_chart2_pivot_chart_test.mk b/chart2/CppunitTest_chart2_pivot_chart_test.mk
new file mode 100644
index 000000000000..418db1af9cc9
--- /dev/null
+++ b/chart2/CppunitTest_chart2_pivot_chart_test.mk
@@ -0,0 +1,131 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,chart2_pivot_chart_test))
+
+$(eval $(call gb_CppunitTest_use_externals,chart2_pivot_chart_test, \
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,chart2_pivot_chart_test, \
+ chart2/qa/extras/PivotChartTest \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,chart2_pivot_chart_test, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ for \
+ forui \
+ i18nlangtag \
+ msfilter \
+ vcl \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sb \
+ sc \
+ sw \
+ sd \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vbahelper \
+ xo \
+ sw \
+ $(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,chart2_pivot_chart_test,\
+ -I$(SRCDIR)/chart2/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,chart2_pivot_chart_test))
+$(eval $(call gb_CppunitTest_use_ure,chart2_pivot_chart_test))
+$(eval $(call gb_CppunitTest_use_vcl,chart2_pivot_chart_test))
+
+$(eval $(call gb_CppunitTest_use_components,chart2_pivot_chart_test,\
+ basic/util/sb \
+ animations/source/animcore/animcore \
+ chart2/source/controller/chartcontroller \
+ chart2/source/chartcore \
+ comphelper/util/comphelp \
+ configmgr/source/configmgr \
+ dtrans/util/mcnttype \
+ dbaccess/util/dba \
+ embeddedobj/util/embobj \
+ eventattacher/source/evtatt \
+ filter/source/config/cache/filterconfig1 \
+ filter/source/odfflatxml/odfflatxml \
+ filter/source/storagefilterdetect/storagefd \
+ filter/source/xmlfilteradaptor/xmlfa \
+ filter/source/xmlfilterdetect/xmlfd \
+ forms/util/frm \
+ framework/util/fwk \
+ i18npool/util/i18npool \
+ linguistic/source/lng \
+ oox/util/oox \
+ package/source/xstor/xstor \
+ package/util/package2 \
+ sax/source/expatwrap/expwrap \
+ sc/util/sc \
+ sc/util/scd \
+ sc/util/scfilt \
+ sw/util/sw \
+ sw/util/swd \
+ sw/util/msword \
+ sd/util/sd \
+ sd/util/sdfilt \
+ sd/util/sdd \
+ $(call gb_Helper_optional,SCRIPTING, \
+ sc/util/vbaobj) \
+ scaddins/source/analysis/analysis \
+ scaddins/source/datefunc/date \
+ scripting/source/basprov/basprov \
+ scripting/util/scriptframe \
+ sfx2/util/sfx \
+ sot/util/sot \
+ svl/source/fsstor/fsstorage \
+ svl/util/svl \
+ svtools/util/svt \
+ svx/util/svx \
+ svx/util/svxcore \
+ toolkit/util/tk \
+ ucb/source/core/ucb1 \
+ ucb/source/ucp/file/ucpfile1 \
+ ucb/source/ucp/tdoc/ucptdoc1 \
+ unotools/util/utl \
+ unoxml/source/rdf/unordf \
+ unoxml/source/service/unoxml \
+ uui/util/uui \
+ writerfilter/util/writerfilter \
+ xmloff/util/xo \
+ xmlscript/util/xmlscript \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,chart2_pivot_chart_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/chart2/Module_chart2.mk b/chart2/Module_chart2.mk
index f39140d61002..3273055d5373 100644
--- a/chart2/Module_chart2.mk
+++ b/chart2/Module_chart2.mk
@@ -34,6 +34,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,chart2,\
CppunitTest_chart2_import \
CppunitTest_chart2_trendcalculators \
CppunitTest_chart2_dump \
+ CppunitTest_chart2_pivot_chart_test \
))
ifeq ($(ENABLE_CHART_TESTS),TRUE)
diff --git a/chart2/inc/ChartModel.hxx b/chart2/inc/ChartModel.hxx
index 29b764b6c546..63bd12667612 100644
--- a/chart2/inc/ChartModel.hxx
+++ b/chart2/inc/ChartModel.hxx
@@ -45,6 +45,7 @@
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/qa/XDumper.hpp>
+#include <com/sun/star/awt/XRequestCallback.hpp>
// public API
#include <com/sun/star/chart2/data/XDataProvider.hpp>
@@ -143,7 +144,7 @@ private:
css::awt::Size m_aVisualAreaSize;
css::uno::Reference< css::frame::XModel > m_xParent;
css::uno::Reference< css::chart2::data::XRangeHighlighter > m_xRangeHighlighter;
- css::uno::Reference<css::chart2::data::XPopupRequest> m_xPopupRequest;
+ css::uno::Reference<css::awt::XRequestCallback> m_xPopupRequest;
std::vector< GraphicObject > m_aGraphicObjectVector;
css::uno::Reference< css::chart2::data::XDataProvider > m_xDataProvider;
@@ -383,7 +384,7 @@ public:
virtual void SAL_CALL attachNumberFormatsSupplier( const css::uno::Reference<
css::util::XNumberFormatsSupplier >& xSupplier ) override;
virtual css::uno::Reference< css::chart2::data::XRangeHighlighter > SAL_CALL getRangeHighlighter() override;
- virtual css::uno::Reference< css::chart2::data::XPopupRequest > SAL_CALL getPopupRequest() override;
+ virtual css::uno::Reference<css::awt::XRequestCallback> SAL_CALL getPopupRequest() override;
// ____ XTitled ____
virtual css::uno::Reference< css::chart2::XTitle > SAL_CALL getTitleObject() override;
@@ -469,6 +470,10 @@ public:
void setTimeBasedRange(sal_Int32 nStart, sal_Int32 nEnd);
+ bool isDataFromSpreadsheet();
+
+ bool isDataFromPivotTable();
+
#if HAVE_FEATURE_OPENGL
OpenGLWindow* getOpenGLWindow() { return mpOpenGLWindow;}
#endif
diff --git a/chart2/qa/extras/PivotChartTest.cxx b/chart2/qa/extras/PivotChartTest.cxx
new file mode 100644
index 000000000000..8d1c11d0ce5d
--- /dev/null
+++ b/chart2/qa/extras/PivotChartTest.cxx
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "charttest.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
+#include <com/sun/star/sheet/XDataPilotTables.hpp>
+#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/table/XTablePivotChart.hpp>
+#include <com/sun/star/table/XTablePivotCharts.hpp>
+#include <com/sun/star/table/XTablePivotChartsSupplier.hpp>
+
+#include <rtl/strbuf.hxx>
+
+#include <algorithm>
+
+class PivotChartTest : public ChartTest
+{
+public:
+ PivotChartTest() : ChartTest()
+ {}
+
+ void testRoundtrip();
+ void testChangePivotTable();
+
+ CPPUNIT_TEST_SUITE(PivotChartTest);
+ CPPUNIT_TEST(testRoundtrip);
+ CPPUNIT_TEST(testChangePivotTable);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+namespace
+{
+
+void lclModifyOrientation(uno::Reference<sheet::XDataPilotDescriptor> const & xDescriptor,
+ OUString const & sFieldName,
+ sheet::DataPilotFieldOrientation eOrientation)
+{
+ uno::Reference<container::XIndexAccess> xPilotIndexAccess(xDescriptor->getDataPilotFields(), UNO_QUERY_THROW);
+ sal_Int32 nCount = xPilotIndexAccess->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<container::XNamed> xNamed(xPilotIndexAccess->getByIndex(i), UNO_QUERY_THROW);
+ OUString aName = xNamed->getName();
+ uno::Reference<beans::XPropertySet> xPropSet(xNamed, UNO_QUERY_THROW);
+ if (aName == sFieldName)
+ xPropSet->setPropertyValue("Orientation", uno::makeAny(eOrientation));
+ }
+}
+
+bool lclCheckSequence(std::vector<double> const & reference,
+ uno::Sequence<uno::Any> const & values,
+ double delta)
+{
+ if (reference.size() != size_t(values.getLength()))
+ {
+ printf ("Sequence size differs - reference is %ld but actual is %ld\n",
+ reference.size(), size_t(values.getLength()));
+ return false;
+ }
+
+ for (size_t i = 0; i < reference.size(); ++i)
+ {
+ double value = values[i].get<double>();
+
+ if (std::fabs(reference[i] - value) > delta)
+ {
+ printf ("Value %f is not the same as reference %f (delta %f)\n", value, reference[i], delta);
+ return false;
+ }
+ }
+ return true;
+}
+
+OUString lclGetLabel(Reference<chart2::XChartDocument> const & xChartDoc, sal_Int32 nSeriesIndex)
+{
+ Reference<chart2::data::XDataSequence> xLabelDataSequence = getLabelDataSequenceFromDoc(xChartDoc, nSeriesIndex);
+ return xLabelDataSequence->getData()[0].get<OUString>();
+}
+
+uno::Reference<sheet::XDataPilotTable> lclGetPivotTableByName(sal_Int32 nIndex, OUString const & sPivotTableName,
+ uno::Reference<lang::XComponent> const & xComponent)
+{
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(xComponent, UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xSheetIndexAccess(xDoc->getSheets(), UNO_QUERY_THROW);
+ uno::Any aAny = xSheetIndexAccess->getByIndex(nIndex);
+ uno::Reference<sheet::XSpreadsheet> xSheet;
+ CPPUNIT_ASSERT(aAny >>= xSheet);
+ uno::Reference<sheet::XDataPilotTablesSupplier> xDataPilotTablesSupplier(xSheet, uno::UNO_QUERY_THROW);
+ uno::Reference<sheet::XDataPilotTables> xDataPilotTables = xDataPilotTablesSupplier->getDataPilotTables();
+ return uno::Reference<sheet::XDataPilotTable>(xDataPilotTables->getByName(sPivotTableName), UNO_QUERY_THROW);
+}
+
+} // end anonymous namespace
+
+void PivotChartTest::testRoundtrip()
+{
+ uno::Sequence<uno::Any> xSequence;
+ Reference<chart2::XChartDocument> xChartDoc;
+
+ std::vector<double> aReference1 { 10162.033139, 16614.523063, 27944.146101 };
+ OUString aExpectedLabel1("Exp.");
+
+ std::vector<double> aReference2 { 101879.458079, 178636.929704, 314626.484864 };
+ OUString aExpectedLabel2("Rev.");
+
+ load("/chart2/qa/extras/data/ods/", "PivotChartRoundTrip.ods");
+
+ xChartDoc = getPivotChartDocFromSheet(1, mxComponent);
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getNumberOfDataSeries(xChartDoc));
+
+ // Check the data series
+ {
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference1, xSequence, 1E-4));
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel1, lclGetLabel(xChartDoc, 0));
+ }
+ {
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 1)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference2, xSequence, 1E-4));
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel2, lclGetLabel(xChartDoc, 1));
+ }
+
+ // Modify the pivot table
+ {
+ uno::Reference<sheet::XDataPilotTable> xDataPilotTable = lclGetPivotTableByName(1, "DataPilot1", mxComponent);
+ uno::Reference<sheet::XDataPilotDescriptor> xDataPilotDescriptor(xDataPilotTable, UNO_QUERY_THROW);
+
+ lclModifyOrientation(xDataPilotDescriptor, "Exp.", sheet::DataPilotFieldOrientation_HIDDEN);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getNumberOfDataSeries(xChartDoc));
+
+ // Check again the data series
+ {
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference2, xSequence, 1E-4));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), lclGetLabel(xChartDoc, 0));
+ }
+
+ reload("calc8");
+
+ xChartDoc = getPivotChartDocFromSheet(1, mxComponent);
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getNumberOfDataSeries(xChartDoc));
+
+ // Check again the data series
+ {
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference2, xSequence, 1E-4));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), lclGetLabel(xChartDoc, 0));
+ }
+}
+
+void PivotChartTest::testChangePivotTable()
+{
+ uno::Sequence<uno::Any> xSequence;
+ Reference<chart2::XChartDocument> xChartDoc;
+
+ load("/chart2/qa/extras/data/ods/", "PivotTableExample.ods");
+
+ // Check that we don't have any pivot chart in the document
+ uno::Reference<table::XTablePivotCharts> xTablePivotCharts = getTablePivotChartsFromSheet(1, mxComponent);
+ uno::Reference<container::XIndexAccess> xIndexAccess(xTablePivotCharts, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
+
+ // Create a new pivot chart
+ xTablePivotCharts->addNewByName("Chart", awt::Rectangle{0, 0, 9000, 9000}, "DataPilot1");
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+ // Get the pivot chart document so we ca access its data
+ xChartDoc.set(getPivotChartDocFromSheet(xTablePivotCharts, 0));
+
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ // Check first data series
+ {
+ std::vector<double> aReference { 10162.033139, 16614.523063, 27944.146101 };
+ OUString aExpectedLabel("Exp.");
+
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-4));
+
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel, lclGetLabel(xChartDoc, 0));
+ }
+
+ // Check second data series
+ {
+ std::vector<double> aReference { 101879.458079, 178636.929704, 314626.484864 };
+ OUString aExpectedLabel("Rev.");
+
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 1)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-4));
+
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel, lclGetLabel(xChartDoc, 1));
+ }
+
+ // Modify the pivot table
+ {
+ uno::Reference<sheet::XDataPilotTable> xDataPilotTable = lclGetPivotTableByName(1, "DataPilot1", mxComponent);
+ uno::Reference<sheet::XDataPilotDescriptor> xDataPilotDescriptor(xDataPilotTable, UNO_QUERY_THROW);
+
+ lclModifyOrientation(xDataPilotDescriptor, "Service Month", sheet::DataPilotFieldOrientation_ROW);
+ lclModifyOrientation(xDataPilotDescriptor, "Group Segment", sheet::DataPilotFieldOrientation_COLUMN);
+ lclModifyOrientation(xDataPilotDescriptor, "Rev.", sheet::DataPilotFieldOrientation_HIDDEN);
+ }
+
+ // Check the pivot chart again as we expect it has been updated when we updated the pivot table
+
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ // Check the first data series
+ {
+ std::vector<double> aReference { 2855.559, 1780.326, 2208.713, 2130.064, 1187.371 };
+ OUString aExpectedLabel("Big");
+
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel, lclGetLabel(xChartDoc, 0));
+ }
+
+ // Check the second data series
+ {
+ std::vector<double> aReference { 4098.908, 2527.286, 4299.716, 2362.225, 3326.389 };
+ OUString aExpectedLabel("Medium");
+
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 1)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel, lclGetLabel(xChartDoc, 1));
+ }
+
+ // Check the third data series
+ {
+ std::vector<double> aReference { 4926.303, 5684.060, 4201.398, 7290.795, 5841.591 };
+ OUString aExpectedLabel("Small");
+
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 2)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+
+ CPPUNIT_ASSERT_EQUAL(aExpectedLabel, lclGetLabel(xChartDoc, 2));
+ }
+
+ // Modify the pivot table
+ {
+ uno::Reference<sheet::XDataPilotTable> xDataPilotTable = lclGetPivotTableByName(1, "DataPilot1", mxComponent);
+ uno::Reference<sheet::XDataPilotDescriptor> xDataPilotDescriptor(xDataPilotTable, UNO_QUERY_THROW);
+
+ lclModifyOrientation(xDataPilotDescriptor, "Service Month", sheet::DataPilotFieldOrientation_HIDDEN);
+ }
+
+ // Check the pivot chart again as we expect it has been updated when we updated the pivot table
+
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ // Check the first data series
+ {
+ std::vector<double> aReference { 10162.033139 };
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 0)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+ CPPUNIT_ASSERT_EQUAL(OUString("Big"), lclGetLabel(xChartDoc, 0));
+ }
+ // Check the second data series
+ {
+ std::vector<double> aReference { 16614.523063 };
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 1)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+ CPPUNIT_ASSERT_EQUAL(OUString("Medium"), lclGetLabel(xChartDoc, 1));
+ }
+ // Check the third data series
+ {
+ std::vector<double> aReference { 27944.146101 };
+ xSequence = getDataSequenceFromDocByRole(xChartDoc, "values-y", 2)->getData();
+ CPPUNIT_ASSERT(lclCheckSequence(aReference, xSequence, 1E-3));
+ CPPUNIT_ASSERT_EQUAL(OUString("Small"), lclGetLabel(xChartDoc, 2));
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PivotChartTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/charttest.hxx b/chart2/qa/extras/charttest.hxx
index 1d2f4afe9150..b75dac6d25b5 100644
--- a/chart2/qa/extras/charttest.hxx
+++ b/chart2/qa/extras/charttest.hxx
@@ -24,6 +24,9 @@
#include <com/sun/star/table/XTableChartsSupplier.hpp>
#include <com/sun/star/table/XTableCharts.hpp>
#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/table/XTablePivotChartsSupplier.hpp>
+#include <com/sun/star/table/XTablePivotCharts.hpp>
+#include <com/sun/star/table/XTablePivotChart.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XStorable.hpp>
@@ -213,6 +216,64 @@ Reference< chart2::XChartDocument > getChartDocFromSheet( sal_Int32 nSheet, uno:
return xChartDoc;
}
+uno::Reference<table::XTablePivotCharts> getTablePivotChartsFromSheet(sal_Int32 nSheet, uno::Reference<lang::XComponent> const & xComponent)
+{
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(xComponent, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xDoc.is());
+
+ uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xIA.is());
+
+ uno::Reference<table::XTablePivotChartsSupplier> xChartSupplier(xIA->getByIndex(nSheet), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xChartSupplier.is());
+
+ uno::Reference<table::XTablePivotCharts> xTablePivotCharts = xChartSupplier->getPivotCharts();
+ CPPUNIT_ASSERT(xTablePivotCharts.is());
+
+ return xTablePivotCharts;
+}
+
+Reference<lang::XComponent> getPivotChartCompFromSheet(sal_Int32 nSheet, uno::Reference<lang::XComponent> const & xComponent)
+{
+ uno::Reference<table::XTablePivotCharts> xTablePivotCharts = getTablePivotChartsFromSheet(nSheet, xComponent);
+
+ uno::Reference<container::XIndexAccess> xIACharts(xTablePivotCharts, UNO_QUERY_THROW);
+ uno::Reference<table::XTablePivotChart> xTablePivotChart(xIACharts->getByIndex(0), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xTablePivotChart.is());
+
+ uno::Reference<document::XEmbeddedObjectSupplier> xEmbObjectSupplier(xTablePivotChart, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xEmbObjectSupplier.is());
+
+ uno::Reference<lang::XComponent> xChartComp(xEmbObjectSupplier->getEmbeddedObject(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xChartComp.is());
+
+ return xChartComp;
+}
+
+Reference<chart2::XChartDocument> getPivotChartDocFromSheet(sal_Int32 nSheet, uno::Reference<lang::XComponent> const & xComponent)
+{
+ uno::Reference<chart2::XChartDocument> xChartDoc(getPivotChartCompFromSheet(nSheet, xComponent), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xChartDoc.is());
+ return xChartDoc;
+}
+
+Reference<chart2::XChartDocument> getPivotChartDocFromSheet(uno::Reference<table::XTablePivotCharts> const & xTablePivotCharts, sal_Int32 nIndex)
+{
+ uno::Reference<container::XIndexAccess> xIACharts(xTablePivotCharts, UNO_QUERY_THROW);
+ uno::Reference<table::XTablePivotChart> xTablePivotChart(xIACharts->getByIndex(nIndex), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xTablePivotChart.is());
+
+ uno::Reference<document::XEmbeddedObjectSupplier> xEmbObjectSupplier(xTablePivotChart, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xEmbObjectSupplier.is());
+
+ uno::Reference<lang::XComponent> xChartComp(xEmbObjectSupplier->getEmbeddedObject(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xChartComp.is());
+
+ uno::Reference<chart2::XChartDocument> xChartDoc(xChartComp, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xChartDoc.is());
+ return xChartDoc;
+}
+
Reference< chart2::XChartType > getChartTypeFromDoc( Reference< chart2::XChartDocument > const & xChartDoc,
sal_Int32 nChartType, sal_Int32 nCooSys = 0 )
{
@@ -257,8 +318,20 @@ Reference<chart2::XAxis> getAxisFromDoc(
return xAxis;
}
-Reference< chart2::XDataSeries > getDataSeriesFromDoc( uno::Reference< chart2::XChartDocument > const & xChartDoc,
- sal_Int32 nDataSeries, sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0 )
+sal_Int32 getNumberOfDataSeries(uno::Reference<chart2::XChartDocument> const & xChartDoc,
+ sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0)
+{
+ Reference<chart2::XChartType> xChartType = getChartTypeFromDoc(xChartDoc, nChartType, nCooSys);
+ Reference<chart2::XDataSeriesContainer> xDataSeriesContainer(xChartType, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xDataSeriesContainer.is());
+
+ uno::Sequence<uno::Reference<chart2::XDataSeries>> xSeriesSequence(xDataSeriesContainer->getDataSeries());
+ return xSeriesSequence.getLength();
+}
+
+Reference< chart2::XDataSeries > getDataSeriesFromDoc(uno::Reference<chart2::XChartDocument> const & xChartDoc,
+ sal_Int32 nDataSeries, sal_Int32 nChartType = 0,
+ sal_Int32 nCooSys = 0)
{
Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, nChartType, nCooSys );
Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, UNO_QUERY_THROW );
diff --git a/chart2/qa/extras/data/ods/PivotChartRoundTrip.ods b/chart2/qa/extras/data/ods/PivotChartRoundTrip.ods
new file mode 100644
index 000000000000..c34521e0bc52
--- /dev/null
+++ b/chart2/qa/extras/data/ods/PivotChartRoundTrip.ods
Binary files differ
diff --git a/chart2/qa/extras/data/ods/PivotTableExample.ods b/chart2/qa/extras/data/ods/PivotTableExample.ods
new file mode 100644
index 000000000000..bc8df8170208
--- /dev/null
+++ b/chart2/qa/extras/data/ods/PivotTableExample.ods
Binary files differ
diff --git a/chart2/source/controller/dialogs/DialogModel.hxx b/chart2/source/controller/dialogs/DialogModel.hxx
index 55251b1ad775..722ce266bc98 100644
--- a/chart2/source/controller/dialogs/DialogModel.hxx
+++ b/chart2/source/controller/dialogs/DialogModel.hxx
@@ -146,6 +146,8 @@ public:
// relative ordering, to get e.g. x-values and y-values in the right order
static sal_Int32 GetRoleIndexForSorting( const OUString & rInternalRoleString );
+ ChartModel& getModel() const;
+
private:
css::uno::Reference< css::chart2::XChartDocument >
m_xChartDocument;
@@ -168,7 +170,6 @@ private:
sal_Int32 countSeries() const;
- ChartModel& getModel() const;
mutable DialogModelTimeBasedInfo maTimeBasedInfo;
};
diff --git a/chart2/source/controller/dialogs/dlg_CreationWizard.cxx b/chart2/source/controller/dialogs/dlg_CreationWizard.cxx
index 501272f5c486..b4beb73575a4 100644
--- a/chart2/source/controller/dialogs/dlg_CreationWizard.cxx
+++ b/chart2/source/controller/dialogs/dlg_CreationWizard.cxx
@@ -33,10 +33,10 @@
#define CHART_WIZARD_PAGEWIDTH 250
#define CHART_WIZARD_PAGEHEIGHT 170
+using namespace css;
+
namespace chart
{
-using namespace ::com::sun::star;
-
#define PATH_FULL 1
#define STATE_FIRST 0
#define STATE_CHARTTYPE STATE_FIRST
@@ -45,41 +45,42 @@ using namespace ::com::sun::star;
#define STATE_OBJECTS 3
#define STATE_LAST STATE_OBJECTS
-CreationWizard::CreationWizard( vcl::Window* pParent, const uno::Reference< frame::XModel >& xChartModel
- , const uno::Reference< uno::XComponentContext >& xContext )
- : svt::RoadmapWizard( pParent )
+CreationWizard::CreationWizard(vcl::Window* pParent, const uno::Reference<frame::XModel>& xChartModel,
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : svt::RoadmapWizard(pParent)
, m_xChartModel(xChartModel,uno::UNO_QUERY)
- , m_xCC( xContext )
+ , m_xComponentContext(xContext)
, m_pTemplateProvider(nullptr)
, m_nLastState(STATE_LAST)
- , m_aTimerTriggeredControllerLock( xChartModel )
- , m_bCanTravel( true )
+ , m_aTimerTriggeredControllerLock(xChartModel)
+ , m_bCanTravel(true)
{
- m_pDialogModel.reset( new DialogModel( m_xChartModel, m_xCC ));
- defaultButton( WizardButtonFlags::FINISH );
+ m_pDialogModel.reset(new DialogModel(m_xChartModel, m_xComponentContext));
+ defaultButton(WizardButtonFlags::FINISH);
this->setTitleBase(SCH_RESSTR(STR_DLG_CHART_WIZARD));
- declarePath( PATH_FULL
- , {STATE_CHARTTYPE
- , STATE_SIMPLE_RANGE
- , STATE_DATA_SERIES
- , STATE_OBJECTS}
- );
- this->SetRoadmapHelpId( HID_SCH_WIZARD_ROADMAP );
- this->SetRoadmapInteractive( true );
- Size aAdditionalRoadmapSize( LogicToPixel( Size( 85, 0 ), MapUnit::MapAppFont ) );
+ WizardPath aPath = {
+ STATE_CHARTTYPE,
+ STATE_SIMPLE_RANGE,
+ STATE_DATA_SERIES,
+ STATE_OBJECTS
+ };
+
+ declarePath(PATH_FULL, aPath);
+
+ this->SetRoadmapHelpId(HID_SCH_WIZARD_ROADMAP);
+ this->SetRoadmapInteractive(true);
+
+ Size aAdditionalRoadmapSize(LogicToPixel(Size(85, 0), MapUnit::MapAppFont));
Size aSize(LogicToPixel(Size(CHART_WIZARD_PAGEWIDTH, CHART_WIZARD_PAGEHEIGHT), MapUnit::MapAppFont));
aSize.Width() += aAdditionalRoadmapSize.Width();
- this->SetSizePixel( aSize );
-
- uno::Reference< chart2::XChartDocument > xChartDoc( m_xChartModel, uno::UNO_QUERY );
- bool bHasOwnData = (xChartDoc.is() && xChartDoc->hasInternalDataProvider());
+ this->SetSizePixel(aSize);
- if( bHasOwnData )
+ if (!m_pDialogModel->getModel().isDataFromSpreadsheet())
{
- this->enableState( STATE_SIMPLE_RANGE, false );
- this->enableState( STATE_DATA_SERIES, false );
+ enableState(STATE_SIMPLE_RANGE, false);
+ enableState(STATE_DATA_SERIES, false);
}
// Call ActivatePage, to create and activate the first page
@@ -117,15 +118,17 @@ VclPtr<TabPage> CreationWizard::createPage(WizardState nState)
break;
case STATE_OBJECTS:
{
- pRet = VclPtr<TitlesAndObjectsTabPage>::Create(this,m_xChartModel,m_xCC);
+ pRet = VclPtr<TitlesAndObjectsTabPage>::Create(this,m_xChartModel, m_xComponentContext);
m_aTimerTriggeredControllerLock.startTimer();
}
break;
default:
break;
}
- if(pRet)
- pRet->SetText(OUString());//remove title of pages to not get them in the wizard title
+
+ if (pRet)
+ pRet->SetText(OUString()); //remove title of pages to not get them in the wizard title
+
return pRet;
}
diff --git a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx
index 47932bb49d82..c1005f5e0ef3 100644
--- a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx
+++ b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx
@@ -182,8 +182,13 @@ SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
if( pRet )
{
- //ignore some special shapes
+ // ignore some special shapes
OUString aShapeName = pRet->GetName();
+
+ // return right away if it is a field button
+ if (aShapeName.startsWith("FieldButton"))
+ return pRet;
+
if( aShapeName.match("PlotAreaIncludingAxes") || aShapeName.match("PlotAreaExcludingAxes") )
{
pRet->SetMarkProtect( true );
diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx
index ae579cf14b3d..d69a7a268fd2 100644
--- a/chart2/source/controller/inc/ChartController.hxx
+++ b/chart2/source/controller/inc/ChartController.hxx
@@ -487,6 +487,8 @@ private:
void executeDispatch_ToggleGridHorizontal();
void executeDispatch_ToggleGridVertical();
+ void sendPopupRequest(OUString const & rCID, tools::Rectangle aRectangle);
+
void impl_ShapeControllerDispatch( const css::util::URL& rURL,
const css::uno::Sequence< css::beans::PropertyValue >& rArgs );
diff --git a/chart2/source/controller/inc/dlg_CreationWizard.hxx b/chart2/source/controller/inc/dlg_CreationWizard.hxx
index fed019004716..a1fed3c8ae55 100644
--- a/chart2/source/controller/inc/dlg_CreationWizard.hxx
+++ b/chart2/source/controller/inc/dlg_CreationWizard.hxx
@@ -24,57 +24,56 @@
#include "TabPageNotifiable.hxx"
#include <com/sun/star/chart2/XChartDocument.hpp>
-#include <svtools/roadmapwizard.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
+#include <svtools/roadmapwizard.hxx>
+
#include <memory>
namespace chart
{
-class RangeChooserTabPage;
-class DataSourceTabPage;
class DialogModel;
class ChartTypeTemplateProvider;
class CreationWizard : public svt::RoadmapWizard, public TabPageNotifiable
{
public:
- CreationWizard( vcl::Window* pParent,
- const css::uno::Reference< css::frame::XModel >& xChartModel
- , const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ CreationWizard(vcl::Window* pParent,
+ const css::uno::Reference<css::frame::XModel>& xChartModel,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext);
CreationWizard() = delete;
virtual ~CreationWizard() override;
// TabPageNotifiable
- virtual void setInvalidPage( TabPage * pTabPage ) override;
- virtual void setValidPage( TabPage * pTabPage ) override;
+ virtual void setInvalidPage(TabPage * pTabPage) override;
+ virtual void setValidPage(TabPage * pTabPage) override;
protected:
- virtual bool leaveState( WizardState _nState ) override;
- virtual WizardState determineNextState(WizardState nCurrentState) const override;
- virtual void enterState(WizardState nState) override;
+ virtual bool leaveState( WizardState _nState ) override;
+ virtual WizardState determineNextState(WizardState nCurrentState) const override;
+ virtual void enterState(WizardState nState) override;
- virtual OUString getStateDisplayName( WizardState nState ) const override;
+ virtual OUString getStateDisplayName(WizardState nState) const override;
private:
virtual VclPtr<TabPage> createPage(WizardState nState) override;
- css::uno::Reference< css::chart2::XChartDocument > m_xChartModel;
- css::uno::Reference< css::uno::XComponentContext> m_xCC;
- ChartTypeTemplateProvider* m_pTemplateProvider;
+ css::uno::Reference<css::chart2::XChartDocument> m_xChartModel;
+ css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+ ChartTypeTemplateProvider* m_pTemplateProvider;
std::unique_ptr<DialogModel> m_pDialogModel;
WizardState m_nLastState;
- TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
+ TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
-// RangeChooserTabPage * m_pRangeChooserTabPage;
-// DataSourceTabPage * m_pDataSourceTabPage;
- bool m_bCanTravel;
+ bool m_bCanTravel;
};
+
} //namespace chart
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx
index 11dd2d832ab4..441e8da6e682 100644
--- a/chart2/source/controller/main/ChartController_Window.cxx
+++ b/chart2/source/controller/main/ChartController_Window.cxx
@@ -45,18 +45,23 @@
#include "LegendHelper.hxx"
#include "servicenames_charttypes.hxx"
#include "DrawCommandDispatch.hxx"
+#include "PopupRequest.hxx"
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/awt/PopupMenuDirection.hpp>
#include <com/sun/star/frame/DispatchHelper.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XPopupMenuController.hpp>
#include <com/sun/star/util/XUpdatable.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+
#include <comphelper/propertysequence.hxx>
#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
#include <toolkit/awt/vclxmenu.hxx>
@@ -556,7 +561,16 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
if(!pChartWindow || !pDrawViewWrapper )
return;
- Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
+ Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
+
+ // Check if button was clicked
+ SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos);
+ if (pObject)
+ {
+ OUString aCID = pObject->GetName();
+ if (aCID.startsWith("FieldButton"))
+ return; // Don't take any action if button was clicked
+ }
if ( MOUSE_LEFT == rMEvt.GetButtons() )
{
@@ -722,7 +736,19 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
if(!pChartWindow || !pDrawViewWrapper)
return;
- Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
+ Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel());
+
+ // Check if button was clicked
+ SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos);
+ if (pObject)
+ {
+ OUString aCID = pObject->GetName();
+ if (aCID.startsWith("FieldButton"))
+ {
+ sendPopupRequest(aCID, pObject->GetCurrentBoundRect());
+ return;
+ }
+ }
if(pDrawViewWrapper->IsTextEdit())
{
@@ -1958,6 +1984,47 @@ css::uno::Reference<css::uno::XInterface> const & ChartController::getChartView(
return m_xChartView;
}
+void ChartController::sendPopupRequest(OUString const & rCID, tools::Rectangle aRectangle)
+{
+ ChartModel* pChartModel = dynamic_cast<ChartModel*>(m_aModel->getModel().get());
+ if (!pChartModel)
+ return;
+
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider;
+ xPivotTableDataProvider.set(pChartModel->getDataProvider(), uno::UNO_QUERY);
+ if (!xPivotTableDataProvider.is())
+ return;
+
+ OUString sPivotTableName = xPivotTableDataProvider->getPivotTableName();
+
+ PopupRequest* pPopupRequest = dynamic_cast<PopupRequest*>(pChartModel->getPopupRequest().get());
+ if (!pPopupRequest)
+ return;
+
+ // Get dimension index from CID
+ sal_Int32 nStartPos = rCID.lastIndexOf('.');
+ nStartPos++;
+ sal_Int32 nEndPos = rCID.getLength();
+ OUString sDimensionIndex = rCID.copy(nStartPos, nEndPos - nStartPos);
+ sal_Int32 nDimensionIndex = sDimensionIndex.toInt32();
+
+ awt::Rectangle xRectangle {
+ sal_Int32(aRectangle.Left()),
+ sal_Int32(aRectangle.Top()),
+ sal_Int32(aRectangle.GetWidth()),
+ sal_Int32(aRectangle.GetHeight())
+ };
+
+ uno::Sequence<beans::PropertyValue> aCallbackData = comphelper::InitPropertySequence(
+ {
+ {"Rectangle", uno::makeAny<awt::Rectangle>(xRectangle)},
+ {"DimensionIndex", uno::makeAny<sal_Int32>(nDimensionIndex)},
+ {"PivotTableName", uno::makeAny<OUString>(sPivotTableName)},
+ });
+
+ pPopupRequest->getCallback()->notify(uno::makeAny(aCallbackData));
+}
+
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/inc/PopupRequest.hxx b/chart2/source/inc/PopupRequest.hxx
index e564003c9e44..fb98d3d9b19d 100644
--- a/chart2/source/inc/PopupRequest.hxx
+++ b/chart2/source/inc/PopupRequest.hxx
@@ -12,8 +12,8 @@
#include "MutexContainer.hxx"
#include <cppuhelper/compbase.hxx>
-#include <com/sun/star/chart2/data/XPopupRequest.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XRequestCallback.hpp>
namespace chart
{
@@ -21,16 +21,21 @@ namespace chart
namespace impl
{
-typedef cppu::WeakComponentImplHelper<css::chart2::data::XPopupRequest> PopupRequest_Base;
+typedef cppu::WeakComponentImplHelper<css::awt::XRequestCallback> PopupRequest_Base;
}
-class PopupRequest : public MutexContainer, public impl::PopupRequest_Base
+class OOO_DLLPUBLIC_CHARTTOOLS PopupRequest : public MutexContainer, public impl::PopupRequest_Base
{
public:
explicit PopupRequest();
virtual ~PopupRequest() override;
+ css::uno::Reference<css::awt::XCallback> getCallback()
+ {
+ return m_xCallback;
+ }
+
protected:
// ____ XRequestCallback ____
virtual void SAL_CALL addCallback(const css::uno::Reference< ::css::awt::XCallback >& xCallback,
diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx
index 814bd315928b..579a9c341eb8 100644
--- a/chart2/source/model/main/ChartModel.cxx
+++ b/chart2/source/model/main/ChartModel.cxx
@@ -38,6 +38,7 @@
#include <vcl/openglwin.hxx>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/supportsservice.hxx>
@@ -63,6 +64,7 @@
#include <com/sun/star/drawing/XShapes.hpp>
#include <com/sun/star/document/DocumentProperties.hpp>
#include <com/sun/star/chart2/XTimeBased.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <svl/zforlist.hxx>
@@ -744,7 +746,7 @@ Reference< chart2::data::XDataSource > ChartModel::impl_createDefaultData()
xIni->initialize(aArgs);
}
//create data
- uno::Sequence< beans::PropertyValue > aArgs( 4 );
+ uno::Sequence<beans::PropertyValue> aArgs(4);
aArgs[0] = beans::PropertyValue(
"CellRangeRepresentation", -1,
uno::Any( OUString("all") ), beans::PropertyState_DIRECT_VALUE );
@@ -816,6 +818,12 @@ void SAL_CALL ChartModel::attachDataProvider( const uno::Reference< chart2::data
}
}
+ uno::Reference<util::XModifyBroadcaster> xModifyBroadcaster(xDataProvider, uno::UNO_QUERY);
+ if (xModifyBroadcaster.is())
+ {
+ xModifyBroadcaster->addModifyListener(this);
+ }
+
m_xDataProvider.set( xDataProvider );
m_xInternalDataProvider.clear();
@@ -911,7 +919,7 @@ Reference< chart2::data::XRangeHighlighter > SAL_CALL ChartModel::getRangeHighli
return m_xRangeHighlighter;
}
-Reference<chart2::data::XPopupRequest> SAL_CALL ChartModel::getPopupRequest()
+Reference<awt::XRequestCallback> SAL_CALL ChartModel::getPopupRequest()
{
if (!m_xPopupRequest.is())
m_xPopupRequest.set(new PopupRequest);
@@ -1348,6 +1356,17 @@ void ChartModel::update()
#endif
}
+bool ChartModel::isDataFromSpreadsheet()
+{
+ return !isDataFromPivotTable() && !hasInternalDataProvider();
+}
+
+bool ChartModel::isDataFromPivotTable()
+{
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(m_xDataProvider, uno::UNO_QUERY);
+ return xPivotTableDataProvider.is();
+}
+
} // namespace chart
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
diff --git a/chart2/source/model/main/ChartModel_Persistence.cxx b/chart2/source/model/main/ChartModel_Persistence.cxx
index c19aeaf7c4d6..58585018b2f0 100644
--- a/chart2/source/model/main/ChartModel_Persistence.cxx
+++ b/chart2/source/model/main/ChartModel_Persistence.cxx
@@ -22,8 +22,10 @@
#include "macros.hxx"
#include "ChartViewHelper.hxx"
#include "ChartModelHelper.hxx"
+#include "DataSourceHelper.hxx"
#include "AxisHelper.hxx"
#include "ThreeDHelper.hxx"
+#include "DiagramHelper.hxx"
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
@@ -44,11 +46,14 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+
#include <ucbhelper/content.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/cvtgrf.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
+#include <comphelper/sequence.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
@@ -704,10 +709,35 @@ void SAL_CALL ChartModel::removeModifyListener(
}
// util::XModifyListener
-void SAL_CALL ChartModel::modified( const lang::EventObject& )
+void SAL_CALL ChartModel::modified( const lang::EventObject& rEvenObject)
{
- if( m_nInLoad == 0 )
- setModified( true );
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rEvenObject.Source, uno::UNO_QUERY);
+ if (xPivotTableDataProvider.is())
+ {
+ lockControllers();
+ uno::Reference<chart2::data::XDataProvider> xDataProvider(xPivotTableDataProvider, uno::UNO_QUERY);
+ try
+ {
+ uno::Sequence<beans::PropertyValue> aArguments =
+ DataSourceHelper::createArguments("PivotChart", uno::Sequence<sal_Int32>(), true, true, true);
+
+ Reference<chart2::data::XDataSource> xDataSource(xDataProvider->createDataSource(aArguments));
+ Reference<lang::XMultiServiceFactory> xFactory(getChartTypeManager(), uno::UNO_QUERY);
+ Reference<chart2::XDiagram> xDiagram(getFirstDiagram());
+
+ DiagramHelper::tTemplateWithServiceName aTemplateAndService = DiagramHelper::getTemplateForDiagram(xDiagram, xFactory);
+ css::uno::Reference<css::chart2::XChartTypeTemplate> xChartTypeTemplate(aTemplateAndService.first);
+ xChartTypeTemplate->changeDiagramData(xDiagram, xDataSource, aArguments);
+ }
+ catch (const uno::Exception & ex)
+ {
+ ASSERT_EXCEPTION(ex);
+ }
+ unlockControllers();
+ }
+
+ if (m_nInLoad == 0)
+ setModified(true);
}
// lang::XEventListener (base of util::XModifyListener)
diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx
index 2053ab09eaea..6dccabf2d74f 100644
--- a/chart2/source/view/main/ChartView.cxx
+++ b/chart2/source/view/main/ChartView.cxx
@@ -90,6 +90,8 @@
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+#include <com/sun/star/chart2/data/PivotTableFieldEntry.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/GraphicExportFilter.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
@@ -114,6 +116,7 @@
#include <comphelper/classids.hxx>
#include "servicenames_charttypes.hxx"
+
#include <rtl/strbuf.hxx>
#include <rtl/ustring.hxx>
@@ -2490,78 +2493,63 @@ void lcl_createButtons(const uno::Reference< drawing::XShapes>& xPageShapes,
ChartModel& rModel,
awt::Rectangle& rRemainingSpace)
{
- uno::Reference<beans::XPropertySet> xModelPage(rModel.getPageBackground());
-
-// TODO: Get this from the PivotTable
- std::vector<OUString> aPageFields {
-// "Subdivision", "Subdivision2"
- };
- std::vector<OUString> aDataFields {
-// "Sum - Revenue", "Sum - Expenses"
- };
- std::vector<OUString> aColumnFields {
-// "Group Segment", "Group Segment 2"
- };
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rModel.getDataProvider(), uno::UNO_QUERY);
+ if (!xPivotTableDataProvider.is())
+ return;
+ uno::Reference<beans::XPropertySet> xModelPage(rModel.getPageBackground());
awt::Size aSize(3000, 700); // size of the button
long x = 0;
- int nCIDIndex = 0;
- if (!aPageFields.empty())
+ if (xPivotTableDataProvider->getPageFields().hasElements())
{
x = 0;
- nCIDIndex = 0;
- for (OUString const & aPageField : aPageFields)
+ for (css::chart2::data::PivotTableFieldEntry const & rPageFieldEntry : xPivotTableDataProvider->getPageFields())
{
std::unique_ptr<VButton> pButton(new VButton);
pButton->init(xPageShapes, xShapeFactory);
awt::Point aNewPosition = awt::Point(rRemainingSpace.X + x + 100, rRemainingSpace.Y + 100);
- pButton->setLabel(aPageField);
- pButton->setCID("PageFieldButton." + OUString::number(nCIDIndex));
+ pButton->setLabel(rPageFieldEntry.Name);
+ pButton->setCID("FieldButton.Page." + OUString::number(rPageFieldEntry.DimensionIndex));
pButton->createShapes(aNewPosition, aSize, xModelPage);
x += aSize.Width + 100;
- nCIDIndex += 1;
}
rRemainingSpace.Y += (aSize.Height + 100 + 100);
rRemainingSpace.Height -= (aSize.Height + 100 + 100);
}
- if (!aDataFields.empty())
+ if (xPivotTableDataProvider->getDataFields().hasElements())
{
x = 200;
- nCIDIndex = 0;
- for (OUString const & aDataField : aDataFields)
+ for (css::chart2::data::PivotTableFieldEntry const & rDataFieldEntry : xPivotTableDataProvider->getDataFields())
{
std::unique_ptr<VButton> pButton(new VButton);
pButton->init(xPageShapes, xShapeFactory);
awt::Point aNewPosition = awt::Point(rRemainingSpace.X + x + 100, rRemainingSpace.Y + 100);
- pButton->setLabel(aDataField);
- pButton->setCID("DataFieldButton." + OUString::number(nCIDIndex));
+ pButton->setLabel(rDataFieldEntry.Name);
+ pButton->setCID("FieldButton.Data." + OUString::number(rDataFieldEntry.DimensionIndex));
pButton->createShapes(aNewPosition, aSize, xModelPage);
x += aSize.Width + 100;
- nCIDIndex += 1;
}
rRemainingSpace.Y += (aSize.Height + 100 + 100);
rRemainingSpace.Height -= (aSize.Height + 100 + 100);
}
- if (!aColumnFields.empty())
+ if (xPivotTableDataProvider->getRowFields().hasElements())
{
x = 200;
- nCIDIndex = 0;
- for (OUString const & aColumnField : aColumnFields)
+ for (css::chart2::data::PivotTableFieldEntry const & rRowFieldEntry : xPivotTableDataProvider->getRowFields())
{
std::unique_ptr<VButton> pButton(new VButton);
pButton->init(xPageShapes, xShapeFactory);
awt::Point aNewPosition = awt::Point(rRemainingSpace.X + x + 100,
rRemainingSpace.Y + rRemainingSpace.Height - aSize.Height - 100);
- pButton->setLabel(aColumnField);
- pButton->setCID("ColumnFieldButton." + OUString::number(nCIDIndex));
+ pButton->setLabel(rRowFieldEntry.Name);
+ pButton->setCID("FieldButton.Row." + OUString::number(rRowFieldEntry.DimensionIndex));
pButton->createShapes(aNewPosition, aSize, xModelPage);
x += aSize.Width + 100;
- nCIDIndex += 1;
}
rRemainingSpace.Height -= (aSize.Height + 100 + 100);
}
diff --git a/chart2/source/view/main/VLegend.cxx b/chart2/source/view/main/VLegend.cxx
index 698f7fcc9400..e2d9b735cefd 100644
--- a/chart2/source/view/main/VLegend.cxx
+++ b/chart2/source/view/main/VLegend.cxx
@@ -37,9 +37,12 @@
#include <com/sun/star/chart/ChartLegendExpansion.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+#include <com/sun/star/chart2/data/PivotTableFieldEntry.hpp>
#include <rtl/ustrbuf.hxx>
#include <svl/languageoptions.hxx>
+
#include <vector>
#include <algorithm>
@@ -766,33 +769,31 @@ std::vector<std::shared_ptr<VButton>> lcl_createButtons(
const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory,
ChartModel& rModel, long& nUsedHeight)
{
-// TODO: get this info from the Pivot Table
- std::vector<OUString> aRowFields {
-// "Service Months"
- };
-
std::vector<std::shared_ptr<VButton>> aButtons;
- if (aRowFields.empty())
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rModel.getDataProvider(), uno::UNO_QUERY);
+ if (!xPivotTableDataProvider.is())
+ return aButtons;
+
+ if (!xPivotTableDataProvider->getColumnFields().hasElements())
return aButtons;
uno::Reference<beans::XPropertySet> xModelPage(rModel.getPageBackground());
- int nCIDIndex = 0;
awt::Size aSize(2000, 700);
-
- for (OUString const & sRowField : aRowFields)
+ int y = 100;
+ for (chart2::data::PivotTableFieldEntry const & sColumnFieldEntry : xPivotTableDataProvider->getColumnFields())
{
std::shared_ptr<VButton> pButton(new VButton);
aButtons.push_back(pButton);
pButton->init(xLegendContainer, xShapeFactory);
- awt::Point aNewPosition = awt::Point(100, 100);
- pButton->setLabel(sRowField);
- pButton->setCID("RowFieldButton." + OUString::number(nCIDIndex));
+ awt::Point aNewPosition = awt::Point(100, y);
+ pButton->setLabel(sColumnFieldEntry.Name);
+ pButton->setCID("FieldButton.Column." + OUString::number(sColumnFieldEntry.DimensionIndex));
pButton->createShapes(aNewPosition, aSize, xModelPage);
- nCIDIndex += 1;
+ y += aSize.Height + 100;;
}
- nUsedHeight += aSize.Height + 100;
+ nUsedHeight += y + 100;
return aButtons;
}
diff --git a/include/xmloff/xmlnmspe.hxx b/include/xmloff/xmlnmspe.hxx
index ae588d28eeac..7675b556ed5c 100644
--- a/include/xmloff/xmlnmspe.hxx
+++ b/include/xmloff/xmlnmspe.hxx
@@ -89,7 +89,6 @@ XML_NAMESPACE_EXT( LO, 42U )
// namespaces used in the technical preview (SO 5.2)
XML_OLD_NAMESPACE( FO, 0U )
XML_OLD_NAMESPACE( XLINK, 1U )
-
XML_OLD_NAMESPACE( OFFICE, 2U )
XML_OLD_NAMESPACE( STYLE, 3U )
XML_OLD_NAMESPACE( TEXT, 4U )
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 4430d298d63b..9ab65abfd195 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -547,6 +547,7 @@ namespace xmloff { namespace token {
XML_DATA_LABEL_NUMBER,
XML_DATA_LABEL_SYMBOL,
XML_DATA_LABEL_TEXT,
+ XML_DATA_PILOT_SOURCE,
XML_DATA_PILOT_FIELD,
XML_DATA_PILOT_GRAND_TOTAL,
XML_DATA_PILOT_LEVEL,
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 49602b9555e7..ded4b7039c12 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -88,6 +88,7 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/chart2,\
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/chart2/data,\
DatabaseDataProvider \
LabeledDataSequence \
+ PivotTableFieldEntry \
))
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/configuration,\
ReadOnlyAccess \
@@ -658,7 +659,6 @@ $(eval $(call gb_UnoApi_add_idlfiles_noheader,offapi,com/sun/star/chart2/data,\
DataSequence \
DataSink \
DataSource \
- PopupRequest \
RangeHighlighter \
RangeHighlightListener \
TabularDataProviderArguments \
@@ -2058,7 +2058,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/chart2/data,\
XLabeledDataSequence \
XLabeledDataSequence2 \
XNumericalDataSequence \
- XPopupRequest \
+ XPivotTableDataProvider \
XRangeHighlighter \
XRangeXMLConversion \
XSheetDataProvider \
@@ -3639,6 +3639,9 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/table,\
XTableChart \
XTableCharts \
XTableChartsSupplier \
+ XTablePivotChart \
+ XTablePivotCharts \
+ XTablePivotChartsSupplier \
XTableColumns \
XTableRows \
))
diff --git a/offapi/com/sun/star/chart2/data/XPopupRequest.idl b/offapi/com/sun/star/chart2/data/PivotTableFieldEntry.idl
index 07116789b311..4d8973ff355b 100644
--- a/offapi/com/sun/star/chart2/data/XPopupRequest.idl
+++ b/offapi/com/sun/star/chart2/data/PivotTableFieldEntry.idl
@@ -7,11 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
-
-#ifndef com_sun_star_chart2_data_XPopupRequest_idl
-#define com_sun_star_chart2_data_XPopupRequest_idl
-
-#include <com/sun/star/uno/XInterface.idl>
+#ifndef com_sun_star_chart2_data_PivotTableFieldEntry_idl
+#define com_sun_star_chart2_data_PivotTableFieldEntry_idl
module com
{
@@ -25,17 +22,21 @@ module data
{
/**
- @since LibreOffice 5.4
+ *
+ * @since LibreOffice 5.4
*/
-interface XPopupRequest : com::sun::star::awt::XRequestCallback
+struct PivotTableFieldEntry
{
+ string Name;
+
+ long DimensionIndex;
};
-} ; // data
-} ; // chart2
-} ; // com
-} ; // sun
-} ; // star
+}; // data
+}; // chart2
+}; // com
+}; // sun
+}; // star
#endif
diff --git a/offapi/com/sun/star/chart2/data/PopupRequest.idl b/offapi/com/sun/star/chart2/data/PopupRequest.idl
deleted file mode 100644
index f83ccc09a56b..000000000000
--- a/offapi/com/sun/star/chart2/data/PopupRequest.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- */
-
-#ifndef com_sun_star_chart2_data_PopupRequest_idl
-#define com_sun_star_chart2_data_PopupRequest_idl
-
-#include <com/sun/star/chart2/data/XPopupRequest.idl>
-
-module com
-{
-module sun
-{
-module star
-{
-module chart2
-{
-module data
-{
-
-/** @since LibreOffice 5.4
- */
-service PopupRequest
-{
- /**
- */
- interface XPopupRequest;
-};
-
-} ; // data
-} ; // chart2
-} ; // com
-} ; // sun
-} ; // star
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/chart2/data/XDataReceiver.idl b/offapi/com/sun/star/chart2/data/XDataReceiver.idl
index abfbc830dd51..a7c853b1f9e6 100644
--- a/offapi/com/sun/star/chart2/data/XDataReceiver.idl
+++ b/offapi/com/sun/star/chart2/data/XDataReceiver.idl
@@ -92,7 +92,7 @@ interface XDataReceiver : ::com::sun::star::uno::XInterface
@since LibreOffice 5.4
*/
- XPopupRequest getPopupRequest();
+ com::sun::star::awt::XRequestCallback getPopupRequest();
};
} ; // data
diff --git a/offapi/com/sun/star/chart2/data/XPivotTableDataProvider.idl b/offapi/com/sun/star/chart2/data/XPivotTableDataProvider.idl
new file mode 100644
index 000000000000..731988bc2167
--- /dev/null
+++ b/offapi/com/sun/star/chart2/data/XPivotTableDataProvider.idl
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef com_sun_star_chart2_data_XPivotTableDataProvider_idl
+#define com_sun_star_chart2_data_XPivotTableDataProvider_idl
+
+#include <com/sun/star/uno/XInterface.idl>
+#include <com/sun/star/chart2/data/PivotTableFieldEntry.idl>
+
+module com { module sun { module star { module chart2 { module data {
+
+/**
+ * Data provider specific for pivot chart data.
+ *
+ * @since LibreOffice 5.4
+ */
+interface XPivotTableDataProvider : com::sun::star::uno::XInterface
+{
+ /** names of column fields from the associated pivot table
+ *
+ * @since LibreOffice 5.4
+ */
+ sequence<com::sun::star::chart2::data::PivotTableFieldEntry> getColumnFields();
+
+ /** names of row fields from the associated pivot table
+ *
+ * @since LibreOffice 5.4
+ */
+ sequence<com::sun::star::chart2::data::PivotTableFieldEntry> getRowFields();
+
+ /** names of page fields from the associated pivot table
+ *
+ * @since LibreOffice 5.4
+ */
+ sequence<com::sun::star::chart2::data::PivotTableFieldEntry> getPageFields();
+
+ /** names of data fields from the associated pivot table
+ *
+ * @since LibreOffice 5.4
+ */
+ sequence<com::sun::star::chart2::data::PivotTableFieldEntry> getDataFields();
+
+ /** get the associated pivot table name
+ *
+ * @since LibreOffice 5.4
+ */
+ string getPivotTableName();
+
+ /** set the associated pivot table name
+ *
+ * @since LibreOffice 5.4
+ */
+ void setPivotTableName([in] string sPivotTableName);
+
+ /** creates a single data sequence of values for the given data series index.
+ *
+ * @param nIndex
+ * index of the data series
+ *
+ * @since LibreOffice 5.4
+ */
+ XDataSequence createDataSequenceOfValuesByIndex([in] long nIndex);
+
+ /** creates a single data sequence of label(s) for the given data series index.
+ *
+ * @param nIndex
+ * index of the data series
+ *
+ * @since LibreOffice 5.4
+ */
+ XDataSequence createDataSequenceOfLabelsByIndex([in] long nIndex);
+
+ /** creates a single data sequence of categories.
+ *
+ * @since LibreOffice 5.4
+ */
+ XDataSequence createDataSequenceOfCategories();
+};
+
+};};};};};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/table/XTablePivotChart.idl b/offapi/com/sun/star/table/XTablePivotChart.idl
new file mode 100644
index 000000000000..b6c53d6fe97d
--- /dev/null
+++ b/offapi/com/sun/star/table/XTablePivotChart.idl
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __com_sun_star_table_XTablePivotChart_idl__
+#define __com_sun_star_table_XTablePivotChart_idl__
+
+#include <com/sun/star/uno/XInterface.idl>
+
+module com { module sun { module star { module table {
+
+
+/** provides access to the settings of a pivot chart object in a
+ table or spreadsheet.
+
+ @since LibreOffice 5.4
+ */
+interface XTablePivotChart: com::sun::star::uno::XInterface
+{
+ /** returns the pivot table name of the associated pivot table
+
+ @since LibreOffice 5.4
+ */
+ string getPivotTableName();
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/table/XTablePivotCharts.idl b/offapi/com/sun/star/table/XTablePivotCharts.idl
new file mode 100644
index 000000000000..e16b74b0ceac
--- /dev/null
+++ b/offapi/com/sun/star/table/XTablePivotCharts.idl
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __com_sun_star_table_XTablePivotCharts_idl__
+#define __com_sun_star_table_XTablePivotCharts_idl__
+
+#include <com/sun/star/container/XNameAccess.idl>
+#include <com/sun/star/awt/Rectangle.idl>
+
+
+module com { module sun { module star { module table {
+
+
+/** provides methods to access pivot charts via name and to insert
+ and remove pivot charts.
+
+ @since LibreOffice 5.4
+ */
+interface XTablePivotCharts: com::sun::star::container::XNameAccess
+{
+
+ /** creates a pivot chart and adds it to the collection.
+
+ @param aName
+ is the name of the chart. This name is used to reference the
+ chart in the collection.
+
+ @param aRect
+ contains the rectangular location of the chart within the table
+ (in 1/100th mm).
+
+ @param aPivotTableName
+ the name of the pivot table (data pilot) to associate the pivot chart with
+
+ @since LibreOffice 5.4
+ */
+ void addNewByName(
+ [in] string aName,
+ [in] com::sun::star::awt::Rectangle aRect,
+ [in] string aPivotTableName);
+
+
+ /** removes a pivot chart from the collection.
+
+ @param aName
+ is the name of the chart to remove.
+
+ @since LibreOffice 5.4
+ */
+ void removeByName([in] string aName);
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/table/XTablePivotChartsSupplier.idl b/offapi/com/sun/star/table/XTablePivotChartsSupplier.idl
new file mode 100644
index 000000000000..44017411c7b7
--- /dev/null
+++ b/offapi/com/sun/star/table/XTablePivotChartsSupplier.idl
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __com_sun_star_table_XTablePivotChartsSupplier_idl__
+#define __com_sun_star_table_XTablePivotChartsSupplier_idl__
+
+#include <com/sun/star/uno/XInterface.idl>
+#include <com/sun/star/table/XTablePivotCharts.idl>
+
+
+module com { module sun { module star { module table {
+
+
+/** provides a method to access a collection of pivot charts in a table
+ or spreadsheet.
+
+ @since LibreOffice 5.4
+ */
+interface XTablePivotChartsSupplier: com::sun::star::uno::XInterface
+{
+
+ /** returns the collection of pivot charts.
+
+ @since LibreOffice 5.4
+ */
+ com::sun::star::table::XTablePivotCharts getPivotCharts();
+
+};
+
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 9068e5098cc4..0a888ee0e403 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -573,6 +573,12 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/unoobj/notesuno \
sc/source/ui/unoobj/optuno \
sc/source/ui/unoobj/pageuno \
+ sc/source/ui/unoobj/PivotTableDataProvider \
+ sc/source/ui/unoobj/PivotTableDataSource \
+ sc/source/ui/unoobj/PivotTableDataSequence \
+ sc/source/ui/unoobj/TablePivotCharts \
+ sc/source/ui/unoobj/TablePivotChart \
+ sc/source/ui/unoobj/ChartTools \
sc/source/ui/unoobj/servuno \
sc/source/ui/unoobj/shapeuno \
sc/source/ui/unoobj/srchuno \
diff --git a/sc/inc/ChartTools.hxx b/sc/inc/ChartTools.hxx
new file mode 100644
index 000000000000..dc9a5c52fb5b
--- /dev/null
+++ b/sc/inc/ChartTools.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_SC_INC_CHARTTOOLS_HXX
+#define INCLUDED_SC_INC_CHARTTOOLS_HXX
+
+#include <svx/svdoole2.hxx>
+#include <svx/svditer.hxx>
+
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+
+namespace sc {
+namespace tools {
+
+enum class ChartSourceType
+{
+ CELL_RANGE,
+ PIVOT_TABLE
+};
+
+class ChartIterator
+{
+private:
+ std::unique_ptr<SdrObjListIter> m_pIterator;
+ ChartSourceType m_eChartSourceType;
+public:
+ ChartIterator(ScDocShell* pDocShell, SCTAB nTab, ChartSourceType eChartSourceType);
+ SdrOle2Obj* next();
+};
+
+SdrOle2Obj* findChartsByName(ScDocShell* pDocShell, SCTAB nTab,
+ OUString const & rName,
+ ChartSourceType eChartSourceType);
+
+SdrOle2Obj* getChartByIndex(ScDocShell* pDocShell, SCTAB nTab,
+ long nIndex, ChartSourceType eChartSourceType);
+
+}} // end sc::tools
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/PivotTableDataProvider.hxx b/sc/inc/PivotTableDataProvider.hxx
new file mode 100644
index 000000000000..8135cba9d58d
--- /dev/null
+++ b/sc/inc/PivotTableDataProvider.hxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_PIVOTTABLEDATAPROVIDER_HXX
+#define INCLUDED_SC_INC_PIVOTTABLEDATAPROVIDER_HXX
+
+#include "cellsuno.hxx"
+#include "externalrefmgr.hxx"
+#include "types.hxx"
+
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/chart2/data/XDataSequence.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+#include <com/sun/star/chart2/data/PivotTableFieldEntry.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ustring.hxx>
+#include <svl/itemprop.hxx>
+
+#include <memory>
+#include <vector>
+
+namespace sc
+{
+
+struct ValueAndFormat;
+
+typedef cppu::WeakImplHelper<css::chart2::data::XDataProvider,
+ css::chart2::data::XPivotTableDataProvider,
+ css::beans::XPropertySet,
+ css::lang::XServiceInfo,
+ css::util::XModifyBroadcaster>
+ PivotTableDataProvider_Base;
+
+class PivotTableDataProvider : public PivotTableDataProvider_Base, public SfxListener
+{
+public:
+
+ explicit PivotTableDataProvider(ScDocument* pDoc);
+ virtual ~PivotTableDataProvider() override;
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
+ // XDataProvider
+ virtual sal_Bool SAL_CALL
+ createDataSourcePossible(const css::uno::Sequence<css::beans::PropertyValue>& aArguments) override;
+
+ virtual css::uno::Reference<css::chart2::data::XDataSource> SAL_CALL
+ createDataSource(const css::uno::Sequence<css::beans::PropertyValue>& aArguments) override;
+
+ virtual css::uno::Sequence<css::beans::PropertyValue> SAL_CALL
+ detectArguments(const css::uno::Reference<css::chart2::data::XDataSource>& xDataSource) override;
+
+ virtual sal_Bool SAL_CALL
+ createDataSequenceByRangeRepresentationPossible(const OUString& aRangeRepresentation) override;
+
+ virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ createDataSequenceByRangeRepresentation(const OUString& aRangeRepresentation) override;
+
+ virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ createDataSequenceByValueArray(const OUString& aRole, const OUString& aRangeRepresentation) override;
+
+ virtual css::uno::Reference<css::sheet::XRangeSelection> SAL_CALL getRangeSelection() override;
+
+ // XPivotTableDataProvider
+ virtual css::uno::Sequence<css::chart2::data::PivotTableFieldEntry> SAL_CALL
+ getColumnFields() override;
+ virtual css::uno::Sequence<css::chart2::data::PivotTableFieldEntry> SAL_CALL
+ getRowFields() override;
+ virtual css::uno::Sequence<css::chart2::data::PivotTableFieldEntry> SAL_CALL
+ getPageFields() override;
+ virtual css::uno::Sequence<css::chart2::data::PivotTableFieldEntry> SAL_CALL
+ getDataFields() override;
+
+ virtual OUString SAL_CALL getPivotTableName() override;
+
+ virtual void SAL_CALL setPivotTableName(const OUString& sPivotTableName) override;
+
+ virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ createDataSequenceOfValuesByIndex(sal_Int32 nIndex) override;
+ virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ createDataSequenceOfLabelsByIndex(sal_Int32 nIndex) override;
+ virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ createDataSequenceOfCategories() override;
+
+ // XPropertySet
+ virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
+
+ virtual void SAL_CALL
+ setPropertyValue(const OUString& rPropertyName, const css::uno::Any& rValue) override;
+
+ virtual css::uno::Any SAL_CALL
+ getPropertyValue(const OUString& rPropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override;
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& rListener) override;
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& rListener) override;
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& rListener) override;
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL
+ addModifyListener(const css::uno::Reference<css::util::XModifyListener>& aListener) override;
+
+ virtual void SAL_CALL
+ removeModifyListener(const css::uno::Reference<css::util::XModifyListener>& aListener) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+private:
+
+ css::uno::Reference<css::chart2::data::XDataSource>
+ createValuesDataSource(OUString const & aRangeRepresentation);
+ css::uno::Reference<css::chart2::data::XDataSource>
+ createCategoriesDataSource(OUString const & aRangeRepresentation, bool bOrientationIsColumn);
+
+ css::uno::Reference<css::chart2::data::XLabeledDataSequence> newLabeledDataSequence();
+
+ void setLabeledDataSequenceValues(css::uno::Reference<css::chart2::data::XLabeledDataSequence> & xResult,
+ OUString const & sRoleValues, OUString const & sIdValues,
+ std::vector<ValueAndFormat> const & rValues);
+
+ void setLabeledDataSequence(css::uno::Reference<css::chart2::data::XLabeledDataSequence> & xResult,
+ OUString const & sRoleValues, OUString const & sIdValues,
+ std::vector<ValueAndFormat> const & rValues,
+ OUString const & sRoleLabel, OUString const & sIdLabel,
+ std::vector<ValueAndFormat> const & rLabel);
+
+ void assignLabelsToDataSequence(css::uno::Reference<css::chart2::data::XDataSequence> & rDataSequence,
+ size_t nIndex);
+
+ void assignValuesToDataSequence(css::uno::Reference<css::chart2::data::XDataSequence> & rDataSequence,
+ size_t nIndex);
+
+ void collectPivotTableData();
+
+ ScDocument* m_pDocument;
+ OUString m_sPivotTableName;
+ SfxItemPropertySet m_aPropSet;
+ bool m_bIncludeHiddenCells;
+
+ std::vector<std::vector<ValueAndFormat>> m_aCategoriesColumnOrientation;
+ std::vector<std::vector<ValueAndFormat>> m_aCategoriesRowOrientation;
+ std::vector<std::vector<ValueAndFormat>> m_aLabels;
+ std::vector<std::vector<ValueAndFormat>> m_aDataRowVector;
+
+ std::vector<css::chart2::data::PivotTableFieldEntry> m_aColumnFields;
+ std::vector<css::chart2::data::PivotTableFieldEntry> m_aRowFields;
+ std::vector<css::chart2::data::PivotTableFieldEntry> m_aPageFields;
+ std::vector<css::chart2::data::PivotTableFieldEntry> m_aDataFields;
+
+ bool m_bNeedsUpdate;
+
+ css::uno::Reference<css::uno::XComponentContext> m_xContext;
+
+ std::vector<css::uno::Reference<css::util::XModifyListener>> m_aValueListeners;
+};
+
+}
+
+#endif // INCLUDED_SC_INC_PIVOTTABLEDATAPROVIDER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/PivotTableDataSequence.hxx b/sc/inc/PivotTableDataSequence.hxx
new file mode 100644
index 000000000000..f5e508e6dbab
--- /dev/null
+++ b/sc/inc/PivotTableDataSequence.hxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_PIVOTTABLEDATASEQUENCE_HXX
+#define INCLUDED_SC_INC_PIVOTTABLEDATASEQUENCE_HXX
+
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataSequence.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/data/DataSequenceRole.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+
+#include <com/sun/star/sheet/XDataPilotResults.hpp>
+
+#include <svl/lstner.hxx>
+#include <svl/itemprop.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/math.hxx>
+
+#include "unonames.hxx"
+#include "document.hxx"
+
+#include "dpsave.hxx"
+
+namespace sc
+{
+
+typedef cppu::WeakImplHelper<css::chart2::data::XDataSequence,
+ css::chart2::data::XTextualDataSequence,
+ css::chart2::data::XNumericalDataSequence,
+ css::util::XCloneable,
+ css::util::XModifyBroadcaster,
+ css::beans::XPropertySet,
+ css::lang::XServiceInfo>
+ PivotTableDataSequence_Base;
+
+struct ValueAndFormat
+{
+ double m_fValue;
+ OUString m_aString;
+ bool m_bIsValue;
+ sal_uInt32 m_nNumberFormat;
+
+ explicit ValueAndFormat()
+ : m_fValue(0.0)
+ , m_aString()
+ , m_bIsValue(true)
+ , m_nNumberFormat(0)
+ {
+ rtl::math::setNan(&m_fValue);
+ }
+
+ explicit ValueAndFormat(double fValue, sal_uInt32 nNumberFormat)
+ : m_fValue(fValue)
+ , m_aString()
+ , m_bIsValue(true)
+ , m_nNumberFormat(nNumberFormat)
+ {}
+
+ explicit ValueAndFormat(OUString const & rString)
+ : m_fValue(0.0)
+ , m_aString(rString)
+ , m_bIsValue(false)
+ , m_nNumberFormat(0)
+ {
+ rtl::math::setNan(&m_fValue);
+ }
+};
+
+class PivotTableDataSequence : public PivotTableDataSequence_Base, public SfxListener
+{
+public:
+ explicit PivotTableDataSequence(ScDocument* pDocument, OUString const & sPivotTableName,
+ OUString const & sID, std::vector<ValueAndFormat> const & rData);
+
+ virtual ~PivotTableDataSequence() override;
+ PivotTableDataSequence(const PivotTableDataSequence&) = delete;
+ PivotTableDataSequence& operator=(const PivotTableDataSequence&) = delete;
+
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
+ // XDataSequence
+ virtual css::uno::Sequence<css::uno::Any> SAL_CALL getData() override;
+ virtual OUString SAL_CALL getSourceRangeRepresentation() override;
+ virtual css::uno::Sequence<OUString> SAL_CALL
+ generateLabel(css::chart2::data::LabelOrigin nOrigin) override;
+
+ virtual sal_Int32 SAL_CALL getNumberFormatKeyByIndex(sal_Int32 nIndex) override;
+
+ // XNumericalDataSequence
+ virtual css::uno::Sequence<double> SAL_CALL getNumericalData() override;
+
+ // XTextualDataSequence
+ virtual css::uno::Sequence<OUString> SAL_CALL getTextualData() override;
+
+ // XPropertySet
+ virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL
+ getPropertySetInfo() override;
+
+ virtual void SAL_CALL setPropertyValue(const OUString& rPropertyName,
+ const css::uno::Any& rValue) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& rPropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference< css::beans::XPropertyChangeListener>& xListener) override;
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference< css::beans::XPropertyChangeListener>& rListener) override;
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference< css::beans::XVetoableChangeListener>& rListener) override;
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const OUString& rPropertyName,
+ const css::uno::Reference< css::beans::XVetoableChangeListener>& rListener) override;
+
+ // XCloneable
+ virtual css::uno::Reference<css::util::XCloneable> SAL_CALL createClone() override;
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ const css::uno::Reference<css::util::XModifyListener>& aListener) override;
+
+ virtual void SAL_CALL removeModifyListener(
+ const css::uno::Reference<css::util::XModifyListener>& aListener) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+ // Other
+
+ void setRole(css::chart2::data::DataSequenceRole const & aRole)
+ {
+ m_aRole = aRole;
+ }
+
+private:
+ ScDocument* m_pDocument;
+ OUString m_sPivotTableName;
+ OUString m_aID;
+ std::vector<ValueAndFormat> m_aData;
+ SfxItemPropertySet m_aPropSet;
+ css::chart2::data::DataSequenceRole m_aRole;
+ std::vector<css::uno::Reference<css::util::XModifyListener>> m_aValueListeners;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/PivotTableDataSource.hxx b/sc/inc/PivotTableDataSource.hxx
new file mode 100644
index 000000000000..326f7c31b8a7
--- /dev/null
+++ b/sc/inc/PivotTableDataSource.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_PIVOTTABLEDATASOURCE_HXX
+#define INCLUDED_SC_INC_PIVOTTABLEDATASOURCE_HXX
+
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include "document.hxx"
+
+#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
+
+namespace sc
+{
+
+typedef cppu::WeakImplHelper<css::chart2::data::XDataSource,
+ css::lang::XServiceInfo>
+ PivotTableDataSource_Base;
+
+class PivotTableDataSource : public PivotTableDataSource_Base, public SfxListener
+{
+public:
+ explicit PivotTableDataSource(OUString const & aRangeRepresentation,
+ std::vector<css::uno::Reference<css::chart2::data::XLabeledDataSequence>>& xLabeledSequence);
+ virtual ~PivotTableDataSource() override;
+ virtual void Notify(SfxBroadcaster& rBroadcaster, const SfxHint& rHint) override;
+
+ // XDataSource
+ virtual css::uno::Sequence<css::uno::Reference<css::chart2::data::XLabeledDataSequence>> SAL_CALL
+ getDataSequences() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+
+ virtual css::uno::Sequence<OUString> SAL_CALL
+ getSupportedServiceNames() override;
+
+private:
+ std::vector<css::uno::Reference<css::chart2::data::XLabeledDataSequence>> m_xLabeledSequence;
+ OUString m_aRangeRepresentation;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/TablePivotChart.hxx b/sc/inc/TablePivotChart.hxx
new file mode 100644
index 000000000000..dce05e711f86
--- /dev/null
+++ b/sc/inc/TablePivotChart.hxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_TABLEPIVOTCHART_HXX
+#define INCLUDED_SC_INC_TABLEPIVOTCHART_HXX
+
+#include <com/sun/star/table/XTablePivotChart.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include "types.hxx"
+
+class ScDocShell;
+
+namespace sc
+{
+
+typedef cppu::WeakComponentImplHelper<css::table::XTablePivotChart,
+ css::document::XEmbeddedObjectSupplier,
+ css::container::XNamed,
+ css::lang::XServiceInfo>
+ TablePivotChart_Base;
+
+class TablePivotChart : public cppu::BaseMutex,
+ public TablePivotChart_Base,
+ public SfxListener
+{
+private:
+ ScDocShell* m_pDocShell;
+ SCTAB m_nTab; // Charts are per sheet
+ OUString m_aChartName;
+
+public:
+ TablePivotChart(ScDocShell* pDocShell, SCTAB nTab, OUString const & rName);
+ virtual ~TablePivotChart() override;
+
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
+ // XComponent
+ using TablePivotChart_Base::disposing;
+
+ // XEmbeddedObjectSupplier
+ virtual css::uno::Reference<css::lang::XComponent> SAL_CALL
+ getEmbeddedObject() override;
+
+ // XNamed
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName(OUString const & aName) override;
+
+ // XTablePivotChart
+ virtual OUString SAL_CALL getPivotTableName() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/TablePivotCharts.hxx b/sc/inc/TablePivotCharts.hxx
new file mode 100644
index 000000000000..f60726ee2650
--- /dev/null
+++ b/sc/inc/TablePivotCharts.hxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_TABLEPIVOTCHARTS_HXX
+#define INCLUDED_SC_INC_TABLEPIVOTCHARTS_HXX
+
+#include <com/sun/star/table/XTablePivotCharts.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+#include <svl/lstner.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include "types.hxx"
+
+class ScDocShell;
+
+namespace sc
+{
+typedef cppu::WeakImplHelper<css::table::XTablePivotCharts,
+ css::container::XIndexAccess,
+ css::lang::XServiceInfo>
+ TablePivotCharts_Base;
+
+class TablePivotCharts : public TablePivotCharts_Base, public SfxListener
+{
+private:
+ ScDocShell* m_pDocShell;
+ SCTAB m_nTab;
+
+public:
+ TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab);
+
+ virtual ~TablePivotCharts() override;
+
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
+ // XTablePivotCharts
+ virtual void SAL_CALL addNewByName(OUString const & aName,
+ const css::awt::Rectangle& aRect,
+ OUString const & aDataPilotName) override;
+ virtual void SAL_CALL removeByName(OUString const & aName) override;
+
+ // XNameAccess
+ virtual css::uno::Any SAL_CALL getByName(OUString const & aName) override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getElementNames() override;
+ virtual sal_Bool SAL_CALL hasByName(OUString const & aName) override;
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx
index aded180f3f69..95cef41b70f2 100644
--- a/sc/inc/cellsuno.hxx
+++ b/sc/inc/cellsuno.hxx
@@ -31,6 +31,7 @@
#include <svl/listener.hxx>
#include <svl/itemprop.hxx>
#include <com/sun/star/table/XTableChartsSupplier.hpp>
+#include <com/sun/star/table/XTablePivotChartsSupplier.hpp>
#include <com/sun/star/chart/XChartDataArray.hpp>
#include <com/sun/star/text/XTextFieldsSupplier.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
@@ -771,6 +772,7 @@ class ScTableSheetObj : public ScCellRangeObj,
public css::sheet::XSheetPageBreak,
public css::sheet::XCellRangeMovement,
public css::table::XTableChartsSupplier,
+ public css::table::XTablePivotChartsSupplier,
public css::sheet::XDataPilotTablesSupplier,
public css::sheet::XScenariosSupplier,
public css::sheet::XSheetAnnotationsSupplier,
@@ -856,6 +858,10 @@ public:
virtual css::uno::Reference< css::table::XTableCharts > SAL_CALL
getCharts() override;
+ // XTablePivotChartsSupplier
+ virtual css::uno::Reference<css::table::XTablePivotCharts> SAL_CALL
+ getPivotCharts() override;
+
// XDataPilotTablesSupplier
virtual css::uno::Reference< css::sheet::XDataPilotTables > SAL_CALL
getDataPilotTables() override;
diff --git a/sc/inc/servuno.hxx b/sc/inc/servuno.hxx
index 44049dd0f98e..e81463273c49 100644
--- a/sc/inc/servuno.hxx
+++ b/sc/inc/servuno.hxx
@@ -50,7 +50,7 @@ public:
SHEETDOCSET ,
// BM
- CHDATAPROV ,
+ CHDATAPROV , CHART_PIVOTTABLE_DATAPROVIDER,
// formula parser
FORMULAPARS , OPCODEMAPPER ,
// VBA specific
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 469183d18b78..6e104542f7dc 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -32,6 +32,7 @@
#define SC_SERVICENAME_CHDATAPROV "com.sun.star.chart2.data.DataProvider"
#define SC_SERVICENAME_CHRANGEHILIGHT "com.sun.star.chart2.data.RangeHighlightListener"
+#define SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER "com.sun.star.chart2.data.PivotTableDataProvider"
// document
#define SC_UNO_AREALINKS "AreaLinks"
diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx
index 7f351853e575..f6cf018b0d75 100644
--- a/sc/source/ui/drawfunc/fuins2.cxx
+++ b/sc/source/ui/drawfunc/fuins2.cxx
@@ -63,8 +63,7 @@
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <cppuhelper/bootstrap.hxx>
-using namespace ::com::sun::star;
-
+#include "PivotTableDataProvider.hxx"
#include "chart2uno.hxx"
#include "fuinsert.hxx"
#include "tabvwsh.hxx"
@@ -79,18 +78,23 @@ using namespace ::com::sun::star;
#include "drawview.hxx"
#include "markdata.hxx"
#include "gridwin.hxx"
+#include "dpobject.hxx"
#include <memory>
-namespace {
+using namespace css;
+
+namespace
+{
-void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData,
- const OUString& rRangeParam )
+void lcl_ChartInit(const uno::Reference <embed::XEmbeddedObject>& xObj, ScViewData* pViewData,
+ const OUString& rRangeParam, bool bRangeIsPivotTable)
{
ScDocShell* pDocShell = pViewData->GetDocShell();
ScDocument& rScDoc = pDocShell->GetDocument();
- OUString aRangeString( rRangeParam );
- if ( aRangeString.isEmpty() )
+ OUString aRangeString(rRangeParam);
+
+ if (aRangeString.isEmpty() && !bRangeIsPivotTable)
{
SCCOL nCol1 = 0;
SCROW nRow1 = 0;
@@ -118,7 +122,7 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie
}
}
- if ( !aRangeString.isEmpty() )
+ if (!aRangeString.isEmpty())
{
// connect to Calc data (if no range string, leave chart alone, with its own data)
@@ -129,8 +133,19 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie
OSL_ASSERT( xReceiver.is());
if( xReceiver.is() )
{
- uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( &rScDoc );
- xReceiver->attachDataProvider( xDataProvider );
+ uno::Reference<chart2::data::XDataProvider> xDataProvider;
+ if (bRangeIsPivotTable)
+ {
+ std::unique_ptr<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(&rScDoc));
+ pPivotTableDataProvider->setPivotTableName(aRangeString);
+ xDataProvider.set(pPivotTableDataProvider.release());
+ }
+ else
+ {
+ xDataProvider.set(new ScChart2DataProvider(&rScDoc));
+ }
+
+ xReceiver->attachDataProvider(xDataProvider);
uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
@@ -329,7 +344,7 @@ FuInsertOLE::FuInsertOLE(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawView*
// Chart initialisieren ?
if ( SvtModuleOptions().IsChart() && SotExchange::IsChart( SvGlobalName( xObj->getClassID() ) ) )
- lcl_ChartInit( xObj, &pViewSh->GetViewData(), OUString() );
+ lcl_ChartInit(xObj, &pViewSh->GetViewData(), OUString(), false);
ScViewData& rData = pViewSh->GetViewData();
@@ -393,7 +408,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV
SdrModel* pDoc, SfxRequest& rReq)
: FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
{
- const SfxItemSet* pReqArgs = rReq.GetArgs();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
if( ! rReq.IsAPI() )
rReq.Done();
@@ -405,6 +420,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV
// get range
OUString aRangeString;
+ bool bRangeIsPivotTable = false;
ScRange aPositionRange; // cell range for chart positioning
ScMarkData aMark = pViewSh->GetViewData().GetMarkData();
if( pReqArgs )
@@ -417,35 +433,46 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV
}
else
{
- bool bAutomaticMark = false;
- if ( !aMark.IsMarked() && !aMark.IsMultiMarked() )
+ ScDocument* pDocument = pViewSh->GetViewData().GetDocument();
+ ScDPObject* pObject = pDocument->GetDPAtCursor(pViewSh->GetViewData().GetCurX(),
+ pViewSh->GetViewData().GetCurY(),
+ pViewSh->GetViewData().GetTabNo());
+ if (pObject)
{
- pViewSh->GetViewData().GetView()->MarkDataArea();
- bAutomaticMark = true;
+ aRangeString = pObject->GetName();
+ bRangeIsPivotTable = true;
}
+ else
+ {
+ bool bAutomaticMark = false;
+ if ( !aMark.IsMarked() && !aMark.IsMultiMarked() )
+ {
+ pViewSh->GetViewData().GetView()->MarkDataArea();
+ bAutomaticMark = true;
+ }
- ScMarkData aMultiMark( aMark );
- aMultiMark.MarkToMulti();
+ ScMarkData aMultiMark( aMark );
+ aMultiMark.MarkToMulti();
- ScRangeList aRanges;
- aMultiMark.FillRangeListWithMarks( &aRanges, false );
- OUString aStr;
- ScDocument* pDocument = pViewSh->GetViewData().GetDocument();
- aRanges.Format( aStr, ScRefFlags::RANGE_ABS_3D, pDocument, pDocument->GetAddressConvention() );
- aRangeString = aStr;
+ ScRangeList aRanges;
+ aMultiMark.FillRangeListWithMarks( &aRanges, false );
+ OUString aStr;
+ aRanges.Format( aStr, ScRefFlags::RANGE_ABS_3D, pDocument, pDocument->GetAddressConvention() );
+ aRangeString = aStr;
- // get "total" range for positioning
- if ( !aRanges.empty() )
- {
- aPositionRange = *aRanges[ 0 ];
- for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i )
+ // get "total" range for positioning
+ if ( !aRanges.empty() )
{
- aPositionRange.ExtendTo( *aRanges[ i ] );
+ aPositionRange = *aRanges[ 0 ];
+ for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i )
+ {
+ aPositionRange.ExtendTo( *aRanges[ i ] );
+ }
}
- }
- if(bAutomaticMark)
- pViewSh->GetViewData().GetView()->Unmark();
+ if(bAutomaticMark)
+ pViewSh->GetViewData().GetView()->Unmark();
+ }
}
// adapted old code
@@ -568,7 +595,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV
}
}
- lcl_ChartInit( xObj, &rData, aRangeString ); // set source range, auto-detect column/row headers
+ lcl_ChartInit(xObj, &rData, aRangeString, bRangeIsPivotTable); // set source range, auto-detect column/row headers
// Objekt-Position
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index b217c5ba0b2a..a9cccb10bbbd 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -487,7 +487,7 @@ public:
void ClearHighlightRanges();
void DoChartSelection( const css::uno::Sequence< css::chart2::data::HighlightedRange > & rHilightRanges );
- void DoDPFieldPopup(Point aPoint, Size aSize);
+ void DoDPFieldPopup(OUString const & rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize);
long GetGridWidth( ScHSplitPos eWhich );
long GetGridHeight( ScVSplitPos eWhich );
diff --git a/sc/source/ui/unoobj/ChartTools.cxx b/sc/source/ui/unoobj/ChartTools.cxx
new file mode 100644
index 000000000000..77818723c7aa
--- /dev/null
+++ b/sc/source/ui/unoobj/ChartTools.cxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "ChartTools.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <comphelper/classids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/globname.hxx>
+#include <svx/charthelper.hxx>
+#include <svtools/embedhlp.hxx>
+
+using namespace css;
+
+namespace sc {
+namespace tools {
+
+ChartIterator::ChartIterator(ScDocShell* pDocShell, SCTAB nTab, ChartSourceType eChartSourceType)
+ : m_eChartSourceType(eChartSourceType)
+{
+ if (!pDocShell)
+ return;
+ ScDocument& rDoc = pDocShell->GetDocument();
+ ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+ if (!pDrawLayer)
+ return;
+ SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(nTab));
+ if (!pPage)
+ return;
+ m_pIterator.reset(new SdrObjListIter(*pPage, SdrIterMode::DeepNoGroups));
+}
+
+SdrOle2Obj* ChartIterator::next()
+{
+ if (!m_pIterator)
+ return nullptr;
+
+ SdrObject* pObject = m_pIterator->Next();
+ while (pObject)
+ {
+ if (pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject))
+ {
+ SdrOle2Obj* pOleObject = static_cast<SdrOle2Obj*>(pObject);
+ uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
+ if (xObject.is())
+ {
+ uno::Reference<chart2::XChartDocument> xChartDoc(xObject->getComponent(), uno::UNO_QUERY);
+ if (xChartDoc.is())
+ {
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xChartDoc->getDataProvider(), uno::UNO_QUERY);
+ if (xPivotTableDataProvider.is() && m_eChartSourceType == ChartSourceType::PIVOT_TABLE)
+ {
+ return pOleObject;
+ }
+ else if (!xPivotTableDataProvider.is() && m_eChartSourceType == ChartSourceType::CELL_RANGE)
+ {
+ return pOleObject;
+ }
+ }
+ }
+ }
+ pObject = m_pIterator->Next();
+ }
+ return nullptr;
+}
+
+SdrOle2Obj* findChartsByName(ScDocShell* pDocShell, SCTAB nTab, OUString const & rName, ChartSourceType eChartSourceType)
+{
+ if (!pDocShell)
+ return nullptr;
+
+ ChartIterator aIterator(pDocShell, nTab, eChartSourceType);
+
+ SdrOle2Obj* pObject = aIterator.next();
+ while (pObject)
+ {
+ uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
+ if (xObject.is())
+ {
+ OUString aObjectName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
+ if (aObjectName == rName)
+ return pObject;
+ }
+ pObject = aIterator.next();
+ }
+ return nullptr;
+}
+
+SdrOle2Obj* getChartByIndex(ScDocShell* pDocShell, SCTAB nTab, long nIndex, ChartSourceType eChartSourceType)
+{
+ if (!pDocShell)
+ return nullptr;
+
+ ChartIterator aIterator(pDocShell, nTab, eChartSourceType);
+
+ SdrOle2Obj* pObject = aIterator.next();
+ long i = 0;
+ while (pObject)
+ {
+ if (i == nIndex)
+ {
+ return pObject;
+ }
+
+ i++;
+ pObject = aIterator.next();
+ }
+ return nullptr;
+}
+
+}} // end sc::tools
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataProvider.cxx b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
new file mode 100644
index 000000000000..84eb756c3bf3
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
@@ -0,0 +1,843 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include "PivotTableDataProvider.hxx"
+#include "PivotTableDataSource.hxx"
+#include "PivotTableDataSequence.hxx"
+
+#include <vcl/svapp.hxx>
+
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "unonames.hxx"
+#include "docsh.hxx"
+
+#include <sfx2/objsh.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+
+#include <com/sun/star/sheet/XDataPilotResults.hpp>
+#include <com/sun/star/sheet/DataResultFlags.hpp>
+
+#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
+#include <com/sun/star/sheet/XLevelsSupplier.hpp>
+#include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+
+#include "dpobject.hxx"
+
+#include "hints.hxx"
+
+#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
+
+#include <unordered_map>
+
+using namespace css;
+
+namespace sc
+{
+namespace
+{
+
+const SfxItemPropertyMapEntry* lcl_GetDataProviderPropertyMap()
+{
+ static const SfxItemPropertyMapEntry aDataProviderPropertyMap_Impl[] =
+ {
+ { OUString(SC_UNONAME_INCLUDEHIDDENCELLS), 0, cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(SC_UNONAME_USE_INTERNAL_DATA_PROVIDER), 0, cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ return aDataProviderPropertyMap_Impl;
+}
+
+uno::Reference<frame::XModel> lcl_GetXModel(ScDocument * pDoc)
+{
+ uno::Reference<frame::XModel> xModel;
+ SfxObjectShell* pObjSh(pDoc ? pDoc->GetDocumentShell() : nullptr);
+ if (pObjSh)
+ xModel.set(pObjSh->GetModel());
+ return xModel;
+}
+
+OUString lcl_identifierForData(sal_Int32 index)
+{
+ return "Data " + OUString::number(index + 1);
+}
+
+OUString lcl_identifierForLabel(sal_Int32 index)
+{
+ return "Label " + OUString::number(index + 1);
+}
+
+} // end anonymous namespace
+
+SC_SIMPLE_SERVICE_INFO(PivotTableDataProvider, "PivotTableDataProvider", SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER)
+
+// DataProvider ==============================================================
+
+PivotTableDataProvider::PivotTableDataProvider(ScDocument* pDoc)
+ : m_pDocument(pDoc)
+ , m_aPropSet(lcl_GetDataProviderPropertyMap())
+ , m_bIncludeHiddenCells(true)
+ , m_bNeedsUpdate(true)
+ , m_xContext(comphelper::getProcessComponentContext())
+{
+ if (m_pDocument)
+ m_pDocument->AddUnoObject(*this);
+}
+
+PivotTableDataProvider::~PivotTableDataProvider()
+{
+ SolarMutexGuard g;
+
+ if (m_pDocument)
+ m_pDocument->RemoveUnoObject( *this);
+}
+
+void PivotTableDataProvider::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pDocument = nullptr;
+ }
+ else if (dynamic_cast<const ScDataPilotModifiedHint*>(&rHint))
+ {
+ if (m_pDocument)
+ {
+ OUString sPivotTableName = static_cast<const ScDataPilotModifiedHint&>(rHint).GetName();
+ if (sPivotTableName == m_sPivotTableName)
+ {
+ m_bNeedsUpdate = true;
+ for (uno::Reference<util::XModifyListener> const & xListener : m_aValueListeners)
+ {
+ css::chart::ChartDataChangeEvent aEvent(static_cast<cppu::OWeakObject*>(this),
+ css::chart::ChartDataChangeType_ALL,
+ 0, 0, 0, 0);
+ xListener->modified(aEvent);
+ }
+ }
+ }
+ }
+}
+
+sal_Bool SAL_CALL PivotTableDataProvider::createDataSourcePossible(const uno::Sequence<beans::PropertyValue>& /*aArguments*/)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDocument)
+ return false;
+
+ if (m_sPivotTableName.isEmpty())
+ return false;
+
+ ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
+ return bool(pDPCollection->GetByName(m_sPivotTableName));
+}
+
+uno::Reference<chart2::data::XDataSource> SAL_CALL
+ PivotTableDataProvider::createDataSource(const uno::Sequence<beans::PropertyValue>& aArguments)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDocument)
+ throw uno::RuntimeException();
+
+ bool bLabel = true;
+ bool bCategories = false;
+ bool bOrientCol = true;
+ OUString aRangeRepresentation;
+ OUString sPivotTable;
+ uno::Sequence<sal_Int32> aSequenceMapping;
+ bool bTimeBased = false;
+
+ for (beans::PropertyValue const & rProperty : aArguments)
+ {
+ if (rProperty.Name == "DataRowSource")
+ {
+ chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
+ if (!(rProperty.Value >>= eSource))
+ {
+ sal_Int32 nSource(0);
+ if (rProperty.Value >>= nSource)
+ eSource = chart::ChartDataRowSource(nSource);
+ }
+ bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
+ }
+ else if (rProperty.Name == "FirstCellAsLabel")
+ rProperty.Value >>= bLabel;
+ else if (rProperty.Name == "HasCategories")
+ rProperty.Value >>= bCategories;
+ else if (rProperty.Name == "CellRangeRepresentation")
+ rProperty.Value >>= aRangeRepresentation;
+ else if (rProperty.Name == "SequenceMapping")
+ rProperty.Value >>= aSequenceMapping;
+ else if (rProperty.Name == "TimeBased")
+ rProperty.Value >>= bTimeBased;
+ else if (rProperty.Name == "ConnectedPivotTable")
+ rProperty.Value >>= sPivotTable;
+ }
+
+ uno::Reference<chart2::data::XDataSource> xResult;
+
+ if (aRangeRepresentation == "Categories")
+ xResult = createCategoriesDataSource(aRangeRepresentation, bOrientCol);
+ else
+ xResult = createValuesDataSource(aRangeRepresentation);
+
+ return xResult;
+}
+
+uno::Reference<chart2::data::XLabeledDataSequence>
+ PivotTableDataProvider::newLabeledDataSequence()
+{
+ uno::Reference<chart2::data::XLabeledDataSequence> xResult;
+ if (!m_xContext.is())
+ return xResult;
+ xResult.set(chart2::data::LabeledDataSequence::create(m_xContext), uno::UNO_QUERY_THROW);
+ return xResult;
+}
+
+void PivotTableDataProvider::setLabeledDataSequenceValues(uno::Reference<chart2::data::XLabeledDataSequence> & xResult,
+ OUString const & sRoleValues, OUString const & sIdValues,
+ std::vector<ValueAndFormat> const & rValues)
+{
+ std::unique_ptr<PivotTableDataSequence> pSequence(
+ new PivotTableDataSequence(m_pDocument, m_sPivotTableName, sIdValues, rValues));
+ pSequence->setRole(sRoleValues);
+ xResult->setValues(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
+}
+
+void PivotTableDataProvider::setLabeledDataSequence(uno::Reference<chart2::data::XLabeledDataSequence> & xResult,
+ OUString const & sRoleValues, OUString const & sIdValues,
+ std::vector<ValueAndFormat> const & rValues,
+ OUString const & sRoleLabel, OUString const & sIdLabel,
+ std::vector<ValueAndFormat> const & rLabel)
+{
+ setLabeledDataSequenceValues(xResult, sRoleValues, sIdValues, rValues);
+
+ std::unique_ptr<PivotTableDataSequence> pLabelSequence(
+ new PivotTableDataSequence(m_pDocument, m_sPivotTableName, sIdLabel, rLabel));
+ pLabelSequence->setRole(sRoleLabel);
+ xResult->setLabel(uno::Reference<chart2::data::XDataSequence>(pLabelSequence.release()));
+}
+
+uno::Reference<chart2::data::XDataSource>
+PivotTableDataProvider::createCategoriesDataSource(OUString const & rRangeRepresentation,
+ bool bOrientationIsColumn)
+{
+ if (m_bNeedsUpdate)
+ collectPivotTableData();
+
+ uno::Reference<chart2::data::XDataSource> xDataSource;
+ std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
+
+ if (bOrientationIsColumn)
+ {
+ for (std::vector<ValueAndFormat> const & rCategories : m_aCategoriesColumnOrientation)
+ {
+ uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
+ setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories);
+ aLabeledSequences.push_back(xResult);
+ }
+ }
+ else
+ {
+ for (std::vector<ValueAndFormat> const & rCategories : m_aCategoriesRowOrientation)
+ {
+ uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
+ setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories);
+ aLabeledSequences.push_back(xResult);
+ }
+ }
+
+ xDataSource.set(new PivotTableDataSource(rRangeRepresentation, aLabeledSequences));
+ return xDataSource;
+}
+
+void PivotTableDataProvider::collectPivotTableData()
+{
+ ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
+ ScDPObject* pDPObject = pDPCollection->GetByName(m_sPivotTableName);
+
+ uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->GetSource(), uno::UNO_QUERY);
+ uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults();
+
+ m_aCategoriesColumnOrientation.clear();
+ m_aCategoriesRowOrientation.clear();
+ m_aLabels.clear();
+ m_aDataRowVector.clear();
+ m_aColumnFields.clear();
+ m_aRowFields.clear();
+ m_aPageFields.clear();
+ m_aDataFields.clear();
+
+ double fNan;
+ rtl::math::setNan(&fNan);
+
+ for (uno::Sequence<sheet::DataResult> const & xDataResults : xDataResultsSequence)
+ {
+ size_t nIndex = 0;
+ for (sheet::DataResult const & rDataResult : xDataResults)
+ {
+ if (rDataResult.Flags == 0 || rDataResult.Flags & css::sheet::DataResultFlags::HASDATA)
+ {
+ if (nIndex >= m_aDataRowVector.size())
+ m_aDataRowVector.resize(nIndex + 1);
+ m_aDataRowVector[nIndex].push_back(ValueAndFormat(rDataResult.Flags ? rDataResult.Value : fNan, 0));
+ }
+ nIndex++;
+ }
+ }
+
+ uno::Reference<sheet::XDimensionsSupplier> xDimensionsSupplier(pDPObject->GetSource());
+ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess(xDimensionsSupplier->getDimensions());
+
+ std::unordered_map<OUString, sal_Int32, OUStringHash> aDataFieldNumberFormatMap;
+ std::vector<OUString> aDataFieldNamesVectors;
+
+ std::unordered_map<OUString, OUString, OUStringHash> aDataFieldCaptionNames;
+ std::vector<std::pair<OUString, sal_Int32>> aDataFieldPairs;
+
+ sheet::DataPilotFieldOrientation eDataFieldOrientation = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ for (sal_Int32 nDim = 0; nDim < xDims->getCount(); nDim++)
+ {
+ uno::Reference<uno::XInterface> xDim = ScUnoHelpFunctions::AnyToInterface(xDims->getByIndex(nDim));
+ uno::Reference<beans::XPropertySet> xDimProp(xDim, uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xDimName(xDim, uno::UNO_QUERY);
+ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp(xDim, uno::UNO_QUERY);
+
+ if (!xDimProp.is() || !xDimSupp.is())
+ continue;
+
+ sheet::DataPilotFieldOrientation eDimOrient = sheet::DataPilotFieldOrientation(
+ ScUnoHelpFunctions::GetEnumProperty(xDimProp, SC_UNO_DP_ORIENTATION,
+ sheet::DataPilotFieldOrientation_HIDDEN));
+
+ if (eDimOrient == sheet::DataPilotFieldOrientation_HIDDEN)
+ continue;
+
+ uno::Reference<container::XIndexAccess> xHierarchies = new ScNameToIndexAccess(xDimSupp->getHierarchies());
+ sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_USEDHIERARCHY);
+ if (nHierarchy >= xHierarchies->getCount())
+ nHierarchy = 0;
+
+ uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface(xHierarchies->getByIndex(nHierarchy));
+
+ uno::Reference<sheet::XLevelsSupplier> xLevelsSupplier(xHierarchy, uno::UNO_QUERY);
+
+ if (!xLevelsSupplier.is())
+ continue;
+
+ uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess(xLevelsSupplier->getLevels());
+
+ for (long nLevel = 0; nLevel < xLevels->getCount(); nLevel++)
+ {
+ uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(xLevels->getByIndex(nLevel));
+ uno::Reference<container::XNamed> xLevelName(xLevel, uno::UNO_QUERY);
+ uno::Reference<sheet::XDataPilotMemberResults> xLevelResult(xLevel, uno::UNO_QUERY );
+
+ bool bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(xDimProp, SC_UNO_DP_ISDATALAYOUT);
+ long nDimPos = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_POSITION);
+ sal_Int32 nNumberFormat = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_NUMBERFO);
+
+ if (xLevelName.is() && xLevelResult.is())
+ {
+ switch (eDimOrient)
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ {
+ m_aColumnFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
+
+ uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
+ size_t i = 0;
+ OUString sCaption;
+ OUString sName;
+ m_aLabels.resize(aSequence.getLength());
+ for (sheet::MemberResult & rMember : aSequence)
+ {
+ if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER ||
+ rMember.Flags & sheet::MemberResultFlags::CONTINUE)
+ {
+ if (!(rMember.Flags & sheet::MemberResultFlags::CONTINUE))
+ {
+ sCaption = rMember.Caption;
+ sName = rMember.Name;
+ }
+
+ if (size_t(nDimPos) >= m_aLabels[i].size())
+ m_aLabels[i].resize(nDimPos + 1);
+ m_aLabels[i][nDimPos] = ValueAndFormat(sCaption);
+
+ if (bIsDataLayout)
+ {
+ // Remember data fields to determine the number format of data
+ aDataFieldNamesVectors.push_back(sName);
+ eDataFieldOrientation = sheet::DataPilotFieldOrientation_COLUMN;
+ // Remember the caption name
+ aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
+ }
+ i++;
+ }
+ }
+ }
+ break;
+
+ case sheet::DataPilotFieldOrientation_ROW:
+ {
+ m_aRowFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
+
+ uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
+ m_aCategoriesRowOrientation.resize(aSequence.getLength());
+ size_t i = 0;
+ for (sheet::MemberResult & rMember : aSequence)
+ {
+ bool bHasContinueFlag = rMember.Flags & sheet::MemberResultFlags::CONTINUE;
+
+ if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER || bHasContinueFlag)
+ {
+ std::unique_ptr<ValueAndFormat> pItem;
+
+ double fValue = rMember.Value;
+
+ if (rtl::math::isNan(fValue))
+ {
+ OUString sStringValue = bHasContinueFlag ? "" : rMember.Caption;
+ pItem.reset(new ValueAndFormat(sStringValue));
+ }
+ else
+ {
+ if (bHasContinueFlag)
+ pItem.reset(new ValueAndFormat());
+ else
+ pItem.reset(new ValueAndFormat(fValue, nNumberFormat));
+ }
+
+ if (size_t(nDimPos) >= m_aCategoriesColumnOrientation.size())
+ m_aCategoriesColumnOrientation.resize(nDimPos + 1);
+ m_aCategoriesColumnOrientation[nDimPos].push_back(*pItem);
+
+ if (size_t(nDimPos) >= m_aCategoriesRowOrientation[i].size())
+ m_aCategoriesRowOrientation[i].resize(nDimPos + 1);
+ m_aCategoriesRowOrientation[i][nDimPos] = *pItem;
+
+ if (bIsDataLayout)
+ {
+ // Remember data fields to determine the number format of data
+ aDataFieldNamesVectors.push_back(rMember.Name);
+ eDataFieldOrientation = sheet::DataPilotFieldOrientation_ROW;
+
+ // Remember the caption name
+ aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
+ }
+ i++;
+ }
+ }
+ }
+ break;
+
+ case sheet::DataPilotFieldOrientation_PAGE:
+ {
+ m_aPageFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
+ }
+ break;
+
+ case sheet::DataPilotFieldOrientation_DATA:
+ {
+ aDataFieldNumberFormatMap[xLevelName->getName()] = nNumberFormat;
+ aDataFieldPairs.push_back(std::pair<OUString, sal_Int32>(xLevelName->getName(), nDim));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ // Fill data field entry info
+ for (std::pair<OUString, sal_Int32> & rPair : aDataFieldPairs)
+ {
+ m_aDataFields.push_back(chart2::data::PivotTableFieldEntry{
+ aDataFieldCaptionNames[rPair.first],
+ rPair.second});
+ }
+
+ // Apply number format to the data
+ if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_ROW)
+ {
+ for (std::vector<ValueAndFormat> & rDataRow : m_aDataRowVector)
+ {
+ size_t i = 0;
+ for (ValueAndFormat & rItem : rDataRow)
+ {
+ OUString sName = aDataFieldNamesVectors[i];
+ sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName];
+ rItem.m_nNumberFormat = nNumberFormat;
+ i++;
+ }
+ }
+ }
+ else if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_COLUMN)
+ {
+ size_t i = 0;
+ for (std::vector<ValueAndFormat> & rDataRow : m_aDataRowVector)
+ {
+ OUString sName = aDataFieldNamesVectors[i];
+ sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName];
+ for (ValueAndFormat & rItem : rDataRow)
+ {
+ rItem.m_nNumberFormat = nNumberFormat;
+ }
+ i++;
+ }
+ }
+
+ m_bNeedsUpdate = false;
+}
+
+void PivotTableDataProvider::assignValuesToDataSequence(uno::Reference<chart2::data::XDataSequence> & rDataSequence,
+ size_t nIndex)
+{
+ if (nIndex >= m_aDataRowVector.size())
+ return;
+
+ OUString sDataID = lcl_identifierForData(nIndex);
+
+ std::vector<ValueAndFormat> const & rRowOfData = m_aDataRowVector[size_t(nIndex)];
+ std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
+ sDataID, rRowOfData));
+ pSequence->setRole("values-y");
+ rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
+}
+
+void PivotTableDataProvider::assignLabelsToDataSequence(uno::Reference<chart2::data::XDataSequence> & rDataSequence,
+ size_t nIndex)
+{
+ if (nIndex >= m_aLabels.size())
+ return;
+
+ OUString sLabelID = lcl_identifierForLabel(nIndex);
+
+ OUString aLabel;
+ bool bFirst = true;
+ for (ValueAndFormat const & rItem : m_aLabels[size_t(nIndex)])
+ {
+ if (bFirst)
+ {
+ aLabel += rItem.m_aString;
+ bFirst = false;
+ }
+ else
+ {
+ aLabel += " - " + rItem.m_aString;
+ }
+ }
+
+ std::vector<ValueAndFormat> aLabelVector { ValueAndFormat(aLabel) };
+
+ std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
+ sLabelID, aLabelVector));
+ pSequence->setRole("values-y");
+ rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
+}
+
+uno::Reference<chart2::data::XDataSource>
+ PivotTableDataProvider::createValuesDataSource(OUString const & rRangeRepresentation)
+{
+ if (m_bNeedsUpdate)
+ collectPivotTableData();
+
+ uno::Reference<chart2::data::XDataSource> xDataSource;
+ std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
+
+ {
+ std::vector<ValueAndFormat> aFirstCategories;
+ if (!m_aCategoriesColumnOrientation.empty())
+ {
+ std::copy(m_aCategoriesColumnOrientation[0].begin(),
+ m_aCategoriesColumnOrientation[0].end(),
+ std::back_inserter(aFirstCategories));
+ }
+ uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
+ setLabeledDataSequenceValues(xResult, "categories", "Categories", aFirstCategories);
+ aLabeledSequences.push_back(xResult);
+ }
+
+ {
+ int i = 0;
+ for (std::vector<ValueAndFormat> const & rRowOfData : m_aDataRowVector)
+ {
+ OUString aValuesId = lcl_identifierForData(i);
+ OUString aLabelsId = lcl_identifierForLabel(i);
+
+ OUString aLabel;
+ bool bFirst = true;
+ for (ValueAndFormat const & rItem : m_aLabels[i])
+ {
+ if (bFirst)
+ {
+ aLabel += rItem.m_aString;
+ bFirst = false;
+ }
+ else
+ {
+ aLabel += " - " + rItem.m_aString;
+ }
+ }
+
+ std::vector<ValueAndFormat> aLabelVector { ValueAndFormat(aLabel) };
+
+ uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
+ setLabeledDataSequence(xResult, "values-y", aValuesId, rRowOfData,
+ "values-y", aLabelsId, aLabelVector);
+ aLabeledSequences.push_back(xResult);
+ i++;
+ }
+ }
+
+ xDataSource.set(new PivotTableDataSource(rRangeRepresentation, aLabeledSequences));
+ return xDataSource;
+}
+
+
+uno::Sequence<beans::PropertyValue> SAL_CALL PivotTableDataProvider::detectArguments(
+ const uno::Reference<chart2::data::XDataSource> & xDataSource)
+{
+ uno::Sequence<beans::PropertyValue> aArguments;
+
+ if (!m_pDocument ||!xDataSource.is())
+ return aArguments;
+
+ aArguments.realloc(4);
+
+ aArguments[0] = beans::PropertyValue("CellRangeRepresentation", -1, uno::Any(OUString("PivotChart")),
+ beans::PropertyState_DIRECT_VALUE);
+
+ aArguments[1] = beans::PropertyValue("DataRowSource", -1, uno::Any(chart::ChartDataRowSource_COLUMNS),
+ beans::PropertyState_DIRECT_VALUE);
+
+ aArguments[2] = beans::PropertyValue("FirstCellAsLabel", -1, uno::Any(false),
+ beans::PropertyState_DIRECT_VALUE);
+
+ aArguments[3] = beans::PropertyValue("HasCategories", -1, uno::Any(true),
+ beans::PropertyState_DIRECT_VALUE);
+
+ return aArguments;
+}
+
+sal_Bool SAL_CALL PivotTableDataProvider::createDataSequenceByRangeRepresentationPossible(const OUString& /*aRangeRepresentation*/)
+{
+ SolarMutexGuard aGuard;
+ return false;
+}
+
+uno::Reference<chart2::data::XDataSequence> SAL_CALL
+ PivotTableDataProvider::createDataSequenceByRangeRepresentation(const OUString& /*rRangeRepresentation*/)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<chart2::data::XDataSequence> xDataSequence;
+ return xDataSequence;
+}
+
+uno::Reference<chart2::data::XDataSequence> SAL_CALL
+ PivotTableDataProvider::createDataSequenceByValueArray(const OUString& /*aRole*/,
+ const OUString& /*aRangeRepresentation*/)
+{
+ return uno::Reference<chart2::data::XDataSequence>();
+}
+
+uno::Reference<sheet::XRangeSelection> SAL_CALL PivotTableDataProvider::getRangeSelection()
+{
+ uno::Reference<sheet::XRangeSelection> xResult;
+
+ uno::Reference<frame::XModel> xModel(lcl_GetXModel(m_pDocument));
+ if (xModel.is())
+ xResult.set(xModel->getCurrentController(), uno::UNO_QUERY);
+
+ return xResult;
+}
+
+uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getColumnFields()
+{
+ return comphelper::containerToSequence(m_aColumnFields);
+}
+
+uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getRowFields()
+{
+ return comphelper::containerToSequence(m_aRowFields);
+}
+
+uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getPageFields()
+{
+ return comphelper::containerToSequence(m_aPageFields);
+}
+
+uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getDataFields()
+{
+ return comphelper::containerToSequence(m_aDataFields);
+}
+
+OUString PivotTableDataProvider::getPivotTableName()
+{
+ return m_sPivotTableName;
+}
+
+void PivotTableDataProvider::setPivotTableName(const OUString& sPivotTableName)
+{
+ ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
+ ScDPObject* pDPObject = pDPCollection->GetByName(sPivotTableName);
+ if (pDPObject)
+ m_sPivotTableName = sPivotTableName;
+}
+
+uno::Reference<chart2::data::XDataSequence>
+ PivotTableDataProvider::createDataSequenceOfValuesByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ if (m_bNeedsUpdate)
+ collectPivotTableData();
+
+ uno::Reference<chart2::data::XDataSequence> xDataSequence;
+ assignValuesToDataSequence(xDataSequence, size_t(nIndex));
+ return xDataSequence;
+}
+
+uno::Reference<css::chart2::data::XDataSequence>
+ PivotTableDataProvider::createDataSequenceOfLabelsByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ if (m_bNeedsUpdate)
+ collectPivotTableData();
+
+ uno::Reference<chart2::data::XDataSequence> xDataSequence;
+ assignLabelsToDataSequence(xDataSequence, size_t(nIndex));
+ return xDataSequence;
+}
+
+uno::Reference<css::chart2::data::XDataSequence>
+ PivotTableDataProvider::createDataSequenceOfCategories()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_bNeedsUpdate)
+ collectPivotTableData();
+
+ uno::Reference<chart2::data::XDataSequence> xDataSequence;
+
+ if (m_aCategoriesColumnOrientation.empty())
+ return xDataSequence;
+
+ std::vector<ValueAndFormat> const & rCategories = m_aCategoriesColumnOrientation[0];
+
+ std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
+ "Categories", rCategories));
+ pSequence->setRole("categories");
+ xDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
+
+ return xDataSequence;
+}
+
+// XModifyBroadcaster ========================================================
+
+void SAL_CALL PivotTableDataProvider::addModifyListener(const uno::Reference< util::XModifyListener>& aListener)
+{
+ SolarMutexGuard aGuard;
+
+ m_aValueListeners.push_back(uno::Reference<util::XModifyListener>(aListener));
+}
+
+void SAL_CALL PivotTableDataProvider::removeModifyListener(const uno::Reference<util::XModifyListener>& aListener )
+{
+ SolarMutexGuard aGuard;
+
+ sal_uInt16 nCount = m_aValueListeners.size();
+ for (sal_uInt16 n = nCount; n--;)
+ {
+ uno::Reference<util::XModifyListener>& rObject = m_aValueListeners[n];
+ if (rObject == aListener)
+ {
+ m_aValueListeners.erase(m_aValueListeners.begin() + n);
+ }
+ }
+}
+
+// DataProvider XPropertySet -------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo> SAL_CALL
+ PivotTableDataProvider::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef =
+ new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
+ return aRef;
+}
+
+void SAL_CALL PivotTableDataProvider::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
+{
+ if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
+ {
+ if (!(rValue >>= m_bIncludeHiddenCells))
+ throw lang::IllegalArgumentException();
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL PivotTableDataProvider::getPropertyValue(const OUString& rPropertyName)
+{
+ uno::Any aRet;
+ if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
+ aRet <<= m_bIncludeHiddenCells;
+ else if (rPropertyName == SC_UNONAME_USE_INTERNAL_DATA_PROVIDER)
+ {
+ // This is a read-only property.
+ aRet <<= m_pDocument->PastingDrawFromOtherDoc();
+ }
+ else
+ throw beans::UnknownPropertyException();
+ return aRet;
+}
+
+void SAL_CALL PivotTableDataProvider::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataProvider::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*rListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataProvider::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*rListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataProvider::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*rListener*/ )
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataSequence.cxx b/sc/source/ui/unoobj/PivotTableDataSequence.cxx
new file mode 100644
index 000000000000..da8bb26c3dc3
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataSequence.cxx
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "PivotTableDataSequence.hxx"
+
+#include <sal/config.h>
+
+#include "miscuno.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "hints.hxx"
+
+#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
+
+using namespace css;
+
+namespace sc
+{
+
+SC_SIMPLE_SERVICE_INFO( PivotTableDataSequence, "PivotTableDataSequence", "com.sun.star.chart2.data.DataSequence")
+
+const SfxItemPropertyMapEntry* lcl_GetDataSequencePropertyMap()
+{
+ static const SfxItemPropertyMapEntry aDataSequencePropertyMap_Impl[] =
+ {
+ { OUString(SC_UNONAME_HIDDENVALUES), 0, cppu::UnoType<uno::Sequence<sal_Int32>>::get(), 0, 0 },
+ { OUString(SC_UNONAME_ROLE), 0, cppu::UnoType<css::chart2::data::DataSequenceRole>::get(), 0, 0 },
+ { OUString(SC_UNONAME_INCLUDEHIDDENCELLS), 0, cppu::UnoType<bool>::get(), 0, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ return aDataSequencePropertyMap_Impl;
+}
+
+PivotTableDataSequence::PivotTableDataSequence(ScDocument* pDocument, OUString const & sPivotTableName, OUString const & sID,
+ std::vector<ValueAndFormat> const & rData)
+ : m_pDocument(pDocument)
+ , m_sPivotTableName(sPivotTableName)
+ , m_aID(sID)
+ , m_aData(rData)
+ , m_aPropSet(lcl_GetDataSequencePropertyMap())
+{
+ if (m_pDocument)
+ m_pDocument->AddUnoObject(*this);
+}
+
+PivotTableDataSequence::~PivotTableDataSequence()
+{
+ SolarMutexGuard g;
+
+ if (m_pDocument)
+ m_pDocument->RemoveUnoObject(*this);
+}
+
+void PivotTableDataSequence::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pDocument = nullptr;
+ }
+}
+
+uno::Sequence<uno::Any> SAL_CALL PivotTableDataSequence::getData()
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pDocument)
+ throw uno::RuntimeException();
+
+ uno::Sequence<uno::Any> aSeq(m_aData.size());
+
+ size_t i = 0;
+ for (ValueAndFormat const & rItem : m_aData)
+ {
+ if (rItem.m_bIsValue)
+ aSeq[i] <<= double(rItem.m_fValue);
+ else
+ aSeq[i] <<= OUString(rItem.m_aString);
+ i++;
+ }
+ return aSeq;
+}
+
+// XNumericalDataSequence --------------------------------------------------
+
+uno::Sequence<double> SAL_CALL PivotTableDataSequence::getNumericalData()
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDocument)
+ throw uno::RuntimeException();
+
+ uno::Sequence<double> aSeq(m_aData.size());
+
+ size_t i = 0;
+ for (ValueAndFormat const & rItem : m_aData)
+ {
+ aSeq[i] = rItem.m_fValue;
+ i++;
+ }
+ return aSeq;
+}
+
+// XTextualDataSequence --------------------------------------------------
+
+uno::Sequence<OUString> SAL_CALL PivotTableDataSequence::getTextualData()
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDocument)
+ throw uno::RuntimeException();
+
+ uno::Sequence<OUString> aSeq(m_aData.size());
+
+ size_t i = 0;
+ for (ValueAndFormat const & rItem : m_aData)
+ {
+ if (!rItem.m_bIsValue)
+ aSeq[i] = rItem.m_aString;
+ i++;
+ }
+ return aSeq;
+}
+
+OUString SAL_CALL PivotTableDataSequence::getSourceRangeRepresentation()
+{
+ SolarMutexGuard aGuard;
+
+ return m_aID;
+}
+
+uno::Sequence<OUString> SAL_CALL PivotTableDataSequence::generateLabel(chart2::data::LabelOrigin /*eOrigin*/)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDocument)
+ throw uno::RuntimeException();
+
+ uno::Sequence<OUString> aSeq;
+ return aSeq;
+}
+
+sal_Int32 SAL_CALL PivotTableDataSequence::getNumberFormatKeyByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if (nIndex == -1 && !m_aData.empty())
+ {
+ return m_aData[0].m_nNumberFormat;
+ }
+ else if (nIndex < 0 && size_t(nIndex) >= m_aData.size())
+ {
+ SAL_WARN("sc.ui", "Passed invalid index to getNumberFormatKeyByIndex(). Will return default value '0'.");
+ return 0;
+ }
+ return m_aData[size_t(nIndex)].m_nNumberFormat;
+}
+
+// XCloneable ================================================================
+
+uno::Reference<util::XCloneable> SAL_CALL PivotTableDataSequence::createClone()
+{
+ SolarMutexGuard aGuard;
+
+ std::unique_ptr<PivotTableDataSequence> pClone;
+ pClone.reset(new PivotTableDataSequence(m_pDocument, m_sPivotTableName, m_aID, m_aData));
+ pClone->setRole(m_aRole);
+
+ uno::Reference<util::XCloneable> xClone(pClone.release());
+
+ return xClone;
+}
+
+// XModifyBroadcaster ========================================================
+
+void SAL_CALL PivotTableDataSequence::addModifyListener(const uno::Reference<util::XModifyListener>& aListener)
+{
+ SolarMutexGuard aGuard;
+ m_aValueListeners.push_back(uno::Reference<util::XModifyListener>(aListener));
+}
+
+void SAL_CALL PivotTableDataSequence::removeModifyListener(const uno::Reference<util::XModifyListener>& aListener)
+{
+ SolarMutexGuard aGuard;
+
+ sal_uInt16 nCount = m_aValueListeners.size();
+ for (sal_uInt16 n = nCount; n--; )
+ {
+ uno::Reference<util::XModifyListener>& rObj = m_aValueListeners[n];
+ if (rObj == aListener)
+ {
+ m_aValueListeners.erase(m_aValueListeners.begin() + n);
+ }
+ }
+}
+
+// DataSequence XPropertySet -------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo> SAL_CALL PivotTableDataSequence::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo(m_aPropSet.getPropertyMap());
+ return aRef;
+}
+
+void SAL_CALL PivotTableDataSequence::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
+{
+ if (rPropertyName == SC_UNONAME_ROLE)
+ {
+ if (!(rValue >>= m_aRole))
+ throw lang::IllegalArgumentException();
+ }
+ else if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS
+ || rPropertyName == SC_UNONAME_HIDDENVALUES
+ || rPropertyName == SC_UNONAME_TIME_BASED
+ || rPropertyName == SC_UNONAME_HAS_STRING_LABEL)
+ {}
+ else
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL PivotTableDataSequence::getPropertyValue(const OUString& rPropertyName)
+{
+ uno::Any aReturn;
+ if (rPropertyName == SC_UNONAME_ROLE)
+ aReturn <<= m_aRole;
+ else if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
+ aReturn <<= false;
+ else if (rPropertyName == SC_UNONAME_HIDDENVALUES)
+ {
+ css::uno::Sequence<sal_Int32> aHiddenValues;
+ aReturn <<= aHiddenValues;
+ }
+ else if (rPropertyName == SC_UNONAME_TIME_BASED)
+ {
+ aReturn <<= false;
+ }
+ else if (rPropertyName == SC_UNONAME_HAS_STRING_LABEL)
+ {
+ aReturn <<= false;
+ }
+ else
+ throw beans::UnknownPropertyException();
+ return aReturn;
+}
+
+void SAL_CALL PivotTableDataSequence::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataSequence::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataSequence::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+void SAL_CALL PivotTableDataSequence::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
+{
+ OSL_FAIL("Not yet implemented");
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataSource.cxx b/sc/source/ui/unoobj/PivotTableDataSource.cxx
new file mode 100644
index 000000000000..752f8a4b4efe
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataSource.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "PivotTableDataSource.hxx"
+
+#include <sal/config.h>
+
+#include "miscuno.hxx"
+#include "docsh.hxx"
+
+#include <comphelper/sequence.hxx>
+
+using namespace css;
+
+namespace sc
+{
+
+SC_SIMPLE_SERVICE_INFO(PivotTableDataSource, "PivotTableDataSource", "com.sun.star.chart2.data.DataSource")
+
+PivotTableDataSource::PivotTableDataSource(OUString const & aRangeRepresentation,
+ std::vector<css::uno::Reference<css::chart2::data::XLabeledDataSequence>>& xLabeledSequence)
+ : m_xLabeledSequence(xLabeledSequence)
+ , m_aRangeRepresentation(aRangeRepresentation)
+{
+}
+
+PivotTableDataSource::~PivotTableDataSource()
+{
+}
+
+void PivotTableDataSource::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& /*rHint*/)
+{
+}
+
+uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence>> SAL_CALL
+ PivotTableDataSource::getDataSequences()
+{
+ SolarMutexGuard aGuard;
+
+ return comphelper::containerToSequence(m_xLabeledSequence);
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/TablePivotChart.cxx b/sc/source/ui/unoobj/TablePivotChart.cxx
new file mode 100644
index 000000000000..64d2d87890b1
--- /dev/null
+++ b/sc/source/ui/unoobj/TablePivotChart.cxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
+#include <svx/charthelper.hxx>
+#include <svtools/embedhlp.hxx>
+
+#include "miscuno.hxx"
+#include "docsh.hxx"
+
+#include "TablePivotChart.hxx"
+#include "ChartTools.hxx"
+
+using namespace css;
+
+namespace sc
+{
+
+SC_SIMPLE_SERVICE_INFO(TablePivotChart, "TablePivotChart", "com.sun.star.table.TablePivotChart")
+
+TablePivotChart::TablePivotChart(ScDocShell* pDocShell, SCTAB nTab, const OUString& rName)
+ : TablePivotChart_Base(m_aMutex)
+ , m_pDocShell(pDocShell)
+ , m_nTab(nTab)
+ , m_aChartName(rName)
+{
+ if (m_pDocShell)
+ m_pDocShell->GetDocument().AddUnoObject(*this);
+}
+
+TablePivotChart::~TablePivotChart()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pDocShell)
+ m_pDocShell->GetDocument().RemoveUnoObject(*this);
+}
+
+void TablePivotChart::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ m_pDocShell = nullptr;
+}
+
+// XEmbeddedObjectSupplier
+
+uno::Reference<lang::XComponent> SAL_CALL TablePivotChart::getEmbeddedObject()
+{
+ SolarMutexGuard aGuard;
+ SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, m_aChartName, sc::tools::ChartSourceType::PIVOT_TABLE);
+ if (pObject && svt::EmbeddedObjectRef::TryRunningState(pObject->GetObjRef()))
+ return uno::Reference<lang::XComponent>(pObject->GetObjRef()->getComponent(), uno::UNO_QUERY);
+ return nullptr;
+}
+
+// XNamed
+
+OUString SAL_CALL TablePivotChart::getName()
+{
+ SolarMutexGuard aGuard;
+ return m_aChartName;
+}
+
+void SAL_CALL TablePivotChart::setName(OUString const & /* aName */)
+{
+ SolarMutexGuard aGuard;
+ throw uno::RuntimeException(); // name cannot be changed
+}
+
+// XTablePivotChart
+
+OUString SAL_CALL TablePivotChart::getPivotTableName()
+{
+ SolarMutexGuard aGuard;
+ OUString aPivotTableName;
+
+ SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, m_aChartName, sc::tools::ChartSourceType::PIVOT_TABLE);
+
+ uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
+ if (xObject.is())
+ {
+ uno::Reference<chart2::XChartDocument> xChartDoc(xObject->getComponent(), uno::UNO_QUERY);
+ if (xChartDoc.is())
+ {
+ uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xChartDoc->getDataProvider(), uno::UNO_QUERY);
+ if (xPivotTableDataProvider.is())
+ {
+ aPivotTableName = xPivotTableDataProvider->getPivotTableName();
+ }
+ }
+ }
+
+ return aPivotTableName;
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/TablePivotCharts.cxx b/sc/source/ui/unoobj/TablePivotCharts.cxx
new file mode 100644
index 000000000000..e76a88b05f25
--- /dev/null
+++ b/sc/source/ui/unoobj/TablePivotCharts.cxx
@@ -0,0 +1,279 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+
+#include <tools/gen.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/charthelper.hxx>
+#include <sfx2/app.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <comphelper/classids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/globname.hxx>
+#include <svtools/embedhlp.hxx>
+#include <comphelper/sequence.hxx>
+
+#include "TablePivotChart.hxx"
+#include "TablePivotCharts.hxx"
+#include "PivotTableDataProvider.hxx"
+#include "ChartTools.hxx"
+
+#include "miscuno.hxx"
+#include "docsh.hxx"
+#include "drwlayer.hxx"
+#include "undodat.hxx"
+#include "convuno.hxx"
+
+using namespace css;
+
+namespace sc
+{
+
+SC_SIMPLE_SERVICE_INFO(TablePivotCharts, "TablePivotCharts", "com.sun.star.table.TablePivotCharts")
+
+TablePivotCharts::TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab)
+ : m_pDocShell(pDocShell)
+ , m_nTab(nTab)
+{
+ m_pDocShell->GetDocument().AddUnoObject(*this);
+}
+
+TablePivotCharts::~TablePivotCharts()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pDocShell)
+ m_pDocShell->GetDocument().RemoveUnoObject(*this);
+}
+
+void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ m_pDocShell = nullptr;
+}
+
+// XTablePivotCharts
+void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName,
+ const awt::Rectangle& aRect,
+ OUString const & rDataPilotName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pDocShell)
+ return;
+
+ ScDocument& rDoc = m_pDocShell->GetDocument();
+ ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer();
+ SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
+ if (!pPage)
+ return;
+
+ // chart can't be inserted if any ole object with that name exists on any table
+ // (empty string: generate valid name)
+
+ OUString aName = rName;
+ SCTAB nDummy;
+ if (!aName.isEmpty() && pModel->GetNamedObject(aName, OBJ_OLE2, nDummy))
+ {
+ // object exists - only RuntimeException is specified
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference<embed::XEmbeddedObject> xObject;
+
+ if (SvtModuleOptions().IsChart())
+ xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName);
+
+ if (xObject.is())
+ {
+ Point aRectPos(aRect.X, aRect.Y);
+ bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab);
+ if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL))
+ aRectPos.X() = 0;
+
+ if (aRectPos.Y() < 0)
+ aRectPos.Y() = 0;
+
+ Size aRectSize(aRect.Width, aRect.Height);
+ if (aRectSize.Width() <= 0)
+ aRectSize.Width() = 5000; // default size
+
+ if (aRectSize.Height() <= 0)
+ aRectSize.Height() = 5000;
+
+ ::tools::Rectangle aInsRect(aRectPos, aRectSize);
+
+ sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
+ MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject->getMapUnit(nAspect)));
+ Size aSize(aInsRect.GetSize());
+ aSize = vcl::Window::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit));
+ awt::Size aAwtSize;
+ aAwtSize.Width = aSize.Width();
+ aAwtSize.Height = aSize.Height();
+
+ std::unique_ptr<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(&rDoc));
+ pPivotTableDataProvider->setPivotTableName(rDataPilotName);
+
+ uno::Reference<chart2::data::XDataProvider> xDataProvider(pPivotTableDataProvider.release());
+
+ uno::Reference<chart2::data::XDataReceiver> xReceiver;
+ uno::Reference<embed::XComponentSupplier> xCompSupp(xObject, uno::UNO_QUERY);
+
+ if (xCompSupp.is())
+ xReceiver.set(xCompSupp->getComponent(), uno::UNO_QUERY);
+
+ if (xReceiver.is())
+ {
+ xReceiver->attachDataProvider(xDataProvider);
+
+ uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
+ xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
+
+ uno::Sequence<beans::PropertyValue> aArgs(3);
+ aArgs[0] = beans::PropertyValue("CellRangeRepresentation", -1, uno::makeAny(OUString(rDataPilotName)), beans::PropertyState_DIRECT_VALUE);
+ aArgs[1] = beans::PropertyValue("HasCategories", -1, uno::makeAny(true), beans::PropertyState_DIRECT_VALUE);
+ aArgs[2] = beans::PropertyValue("DataRowSource", -1, uno::makeAny(chart::ChartDataRowSource_COLUMNS), beans::PropertyState_DIRECT_VALUE);
+ xReceiver->setArguments(aArgs);
+ }
+
+ SdrOle2Obj* pObject = new SdrOle2Obj(svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT),
+ aName, aInsRect);
+
+ if (xObject.is())
+ xObject->setVisualAreaSize(nAspect, aAwtSize);
+
+ pPage->InsertObject(pObject);
+ pModel->AddUndo(new SdrUndoInsertObj(*pObject));
+ }
+}
+
+void SAL_CALL TablePivotCharts::removeByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE);
+ if (pObject)
+ {
+ ScDocument& rDoc = m_pDocShell->GetDocument();
+ ScDrawLayer* pModel = rDoc.GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
+ pModel->AddUndo(new SdrUndoDelObj(*pObject));
+ pPage->RemoveObject(pObject->GetOrdNum());
+ }
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL TablePivotCharts::getCount()
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nCount = 0;
+
+ if (!m_pDocShell)
+ return nCount;
+
+ sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
+
+ SdrOle2Obj* pOleObject = aIterator.next();
+ while (pOleObject)
+ {
+ if (pOleObject->GetObjRef().is())
+ nCount++;
+ pOleObject = aIterator.next();
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ SdrOle2Obj* pObject = sc::tools::getChartByIndex(m_pDocShell, m_nTab, nIndex,
+ sc::tools::ChartSourceType::PIVOT_TABLE);
+ if (!pObject)
+ throw lang::IndexOutOfBoundsException();
+
+ OUString aName;
+ uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
+ if (xObject.is())
+ aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
+
+ if (aName.isEmpty())
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName));
+ if (xChart.is())
+ return uno::makeAny(xChart);
+ else
+ throw lang::IndexOutOfBoundsException();
+}
+
+uno::Type SAL_CALL TablePivotCharts::getElementType()
+{
+ SolarMutexGuard aGuard;
+ return cppu::UnoType<table::XTablePivotChart>::get();
+}
+
+sal_Bool SAL_CALL TablePivotCharts::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return getCount() != 0;
+}
+
+uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE))
+ throw container::NoSuchElementException();
+
+ uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName));
+ if (xChart.is())
+ return uno::makeAny(xChart);
+ else
+ throw container::NoSuchElementException();
+}
+
+uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ std::vector<OUString> aElements;
+ sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
+
+ SdrOle2Obj* pOleObject = aIterator.next();
+ while (pOleObject)
+ {
+ uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
+ if (xObject.is())
+ {
+ OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
+ aElements.push_back(aName);
+ }
+ pOleObject = aIterator.next();
+ }
+ return comphelper::containerToSequence(aElements);
+}
+
+sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName)
+{
+ SolarMutexGuard aGuard;
+
+ return sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE) != nullptr;
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 0c597a82934e..6a4f61012ba9 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -130,6 +130,7 @@
#include "dputil.hxx"
#include <sortparam.hxx>
#include "condformatuno.hxx"
+#include "TablePivotCharts.hxx"
#include <list>
#include <memory>
@@ -6726,6 +6727,7 @@ uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType )
SC_QUERYINTERFACE( sheet::XSheetLinkable )
SC_QUERYINTERFACE( sheet::XExternalSheetName )
SC_QUERYINTERFACE( document::XEventsSupplier )
+ SC_QUERYINTERFACE( table::XTablePivotChartsSupplier )
return ScCellRangeObj::queryInterface( rType );
}
@@ -6749,7 +6751,8 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes()
long nParentLen = aParentTypes.getLength();
const uno::Type* pParentPtr = aParentTypes.getConstArray();
- aTypes.realloc( nParentLen + 18 );
+ aTypes.realloc(nParentLen + 19);
+
uno::Type* pPtr = aTypes.getArray();
pPtr[nParentLen + 0] = cppu::UnoType<sheet::XSpreadsheet>::get();
pPtr[nParentLen + 1] = cppu::UnoType<container::XNamed>::get();
@@ -6769,6 +6772,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes()
pPtr[nParentLen +15] = cppu::UnoType<sheet::XSheetLinkable>::get();
pPtr[nParentLen +16] = cppu::UnoType<sheet::XExternalSheetName>::get();
pPtr[nParentLen +17] = cppu::UnoType<document::XEventsSupplier>::get();
+ pPtr[nParentLen +18] = cppu::UnoType<table::XTablePivotChartsSupplier>::get();
for (long i=0; i<nParentLen; i++)
pPtr[i] = pParentPtr[i]; // parent types first
@@ -6808,6 +6812,17 @@ uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts()
return nullptr;
}
+uno::Reference<table::XTablePivotCharts> SAL_CALL ScTableSheetObj::getPivotCharts()
+{
+ SolarMutexGuard aGuard;
+ ScDocShell* pDocSh = GetDocShell();
+ if (pDocSh)
+ return new sc::TablePivotCharts(pDocSh, GetTab_Impl());
+
+ OSL_FAIL("no Document");
+ return nullptr;
+}
+
uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables()
{
SolarMutexGuard aGuard;
diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx
index 78152703066f..20c3f9e1f989 100644
--- a/sc/source/ui/unoobj/chartuno.cxx
+++ b/sc/source/ui/unoobj/chartuno.cxx
@@ -38,6 +38,7 @@
#include <svx/charthelper.hxx>
#include <svtools/embedhlp.hxx>
+#include "ChartTools.hxx"
#include "chartuno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
@@ -48,47 +49,13 @@
#include "chart2uno.hxx"
#include "convuno.hxx"
-using namespace com::sun::star;
+using namespace css;
#define PROP_HANDLE_RELATED_CELLRANGES 1
SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" )
SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" )
-static SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
-{
- if (pDocShell)
- {
- ScDocument& rDoc = pDocShell->GetDocument();
- ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
- if (pDrawLayer)
- {
- SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
- OSL_ENSURE(pPage, "Page nicht gefunden");
- if (pPage)
- {
- SdrObjListIter aIter( *pPage, SdrIterMode::DeepNoGroups );
- SdrObject* pObject = aIter.Next();
- while (pObject)
- {
- if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
- {
- uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
- if ( xObj.is() )
- {
- OUString aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
- if ( aObjName == rName )
- return static_cast<SdrOle2Obj*>(pObject);
- }
- }
- pObject = aIter.Next();
- }
- }
- }
- }
- return nullptr;
-}
-
ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
pDocShell( pDocSh ),
nTab( nT )
@@ -156,7 +123,7 @@ ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const
ScChartObj* ScChartsObj::GetObjectByName_Impl(const OUString& aName) const
{
- if ( lcl_FindChartObj( pDocShell, nTab, aName ) )
+ if (sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE))
return new ScChartObj( pDocShell, nTab, aName );
return nullptr;
}
@@ -297,7 +264,7 @@ void SAL_CALL ScChartsObj::addNewByName( const OUString& rName,
void SAL_CALL ScChartsObj::removeByName( const OUString& aName )
{
SolarMutexGuard aGuard;
- SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aName );
+ SdrOle2Obj* pObj = sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE);
if (pObj)
{
ScDocument& rDoc = pDocShell->GetDocument();
@@ -429,7 +396,9 @@ uno::Sequence<OUString> SAL_CALL ScChartsObj::getElementNames()
sal_Bool SAL_CALL ScChartsObj::hasByName( const OUString& aName )
{
SolarMutexGuard aGuard;
- return ( lcl_FindChartObj( pDocShell, nTab, aName ) != nullptr );
+ SdrOle2Obj* aOle2Obj = sc::tools::findChartsByName(pDocShell, nTab, aName,
+ sc::tools::ChartSourceType::CELL_RANGE);
+ return aOle2Obj != nullptr;
}
ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN)
@@ -742,7 +711,8 @@ void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress
uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject()
{
SolarMutexGuard aGuard;
- SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName );
+ SdrOle2Obj* pObject = sc::tools::findChartsByName(pDocShell, nTab, aChartName,
+ sc::tools::ChartSourceType::CELL_RANGE);
if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) )
{
//TODO/LATER: is it OK that something is returned for *all* objects, not only own objects?
diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx
index 6b2fac6b79e8..04fb81f7776f 100644
--- a/sc/source/ui/unoobj/servuno.cxx
+++ b/sc/source/ui/unoobj/servuno.cxx
@@ -44,6 +44,7 @@
#include "addruno.hxx"
#include "chart2uno.hxx"
#include "tokenuno.hxx"
+#include "PivotTableDataProvider.hxx"
// Support creation of GraphicObjectResolver and EmbeddedObjectResolver
#include <svx/xmleohlp.hxx>
@@ -292,6 +293,7 @@ const ProvNamesId_Type aProvNamesId[] =
{ "com.sun.star.sheet.DocumentSettings",Type::SHEETDOCSET },
{ SC_SERVICENAME_CHDATAPROV, Type::CHDATAPROV },
+ { SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER, Type::CHART_PIVOTTABLE_DATAPROVIDER },
{ SC_SERVICENAME_FORMULAPARS, Type::FORMULAPARS },
{ SC_SERVICENAME_OPCODEMAPPER, Type::OPCODEMAPPER },
{ "ooo.vba.VBAObjectModuleObjectProvider", Type::VBAOBJECTPROVIDER },
@@ -388,6 +390,7 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
Type nType, ScDocShell* pDocShell )
{
uno::Reference<uno::XInterface> xRet;
+
switch (nType)
{
case Type::SHEET:
@@ -523,6 +526,10 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
if (pDocShell)
xRet = *new ScChart2DataProvider( &pDocShell->GetDocument() );
break;
+ case Type::CHART_PIVOTTABLE_DATAPROVIDER:
+ if (pDocShell)
+ xRet = *new sc::PivotTableDataProvider(&pDocShell->GetDocument());
+ break;
case Type::FORMULAPARS:
if (pDocShell)
xRet.set(static_cast<sheet::XFormulaParser*>(new ScFormulaParserObj( pDocShell )));
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 84c56659065e..71204128ce60 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -2469,27 +2469,23 @@ void ScTabView::DoChartSelection(
}
}
-void ScTabView::DoDPFieldPopup(Point aPoint, Size /*aSize*/)
+void ScTabView::DoDPFieldPopup(OUString const & rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize)
{
ScDocument& rDocument = aViewData.GetDocShell()->GetDocument();
ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
+
if (!pWin)
return;
- ScDPCollection* pDPs = rDocument.GetDPCollection();
- // TODO - DP name should be a parameter
- ScDPObject* pDPObj = pDPs->GetByName("DataPilot1");
-
- pDPObj->BuildAllDimensionMembers();
+ ScDPCollection* pDPCollection = rDocument.GetDPCollection();
+ ScDPObject* pDPObject = pDPCollection->GetByName(rPivotTableName);
- //const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
- //bool bIsDataLayout;
- //OUString aDimName = pDPObj->GetDimName(0, bIsDataLayout);
+ pDPObject->BuildAllDimensionMembers();
Point aScreenPoint = pWin->OutputToScreenPixel(pWin->LogicToPixel(aPoint));
- //Size aScreenSize = pWin->LogicToPixel(aSize);
+ Size aScreenSize = pWin->LogicToPixel(aSize);
- pWin->DPLaunchFieldPopupMenu(aScreenPoint, Size(1, 1), 1, pDPObj);
+ pWin->DPLaunchFieldPopupMenu(aScreenPoint, aScreenSize, nDimensionIndex, pDPObject);
}
// PaintGrid - repaint data range
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
index 3dced2749fd7..52990c0f9428 100644
--- a/sc/source/ui/view/tabvwshb.cxx
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -19,6 +19,8 @@
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/awt/XRequestCallback.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
@@ -111,10 +113,32 @@ public:
{}
// XCallback
- virtual void SAL_CALL notify(const css::uno::Any& /*aData*/) override
+ virtual void SAL_CALL notify(const css::uno::Any& aData) override
{
- tools::Rectangle aRect = m_pObject->GetLogicRect();
- m_pViewShell->DoDPFieldPopup(aRect.TopLeft(), aRect.GetSize());
+ uno::Sequence<beans::PropertyValue> aProperties;
+ if (aData >>= aProperties)
+ {
+ awt::Rectangle xRectangle;
+ sal_Int32 dimensionIndex = 0;
+ OUString sPivotTableName("DataPilot1");
+
+ for (beans::PropertyValue const & rProperty : aProperties)
+ {
+ if (rProperty.Name == "Rectangle")
+ rProperty.Value >>= xRectangle;
+ if (rProperty.Name == "DimensionIndex")
+ rProperty.Value >>= dimensionIndex;
+ if (rProperty.Name == "PivotTableName")
+ rProperty.Value >>= sPivotTableName;
+ }
+
+ tools::Rectangle aChartRect = m_pObject->GetLogicRect();
+
+ Point aPoint(xRectangle.X + aChartRect.Left(), xRectangle.Y + aChartRect.Top());
+ Size aSize(xRectangle.Width, xRectangle.Height);
+
+ m_pViewShell->DoDPFieldPopup(sPivotTableName, dimensionIndex, aPoint, aSize);
+ }
}
};
@@ -209,7 +233,7 @@ void ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
new ScChartRangeSelectionListener( this ));
xRangeHightlighter->addSelectionChangeListener( xListener );
}
- uno::Reference<chart2::data::XPopupRequest> xPopupRequest(xDataReceiver->getPopupRequest());
+ uno::Reference<awt::XRequestCallback> xPopupRequest(xDataReceiver->getPopupRequest());
if (xPopupRequest.is())
{
uno::Reference<awt::XCallback> xCallback(new PopupCallback(this, pObj));
diff --git a/xmloff/inc/SchXMLImport.hxx b/xmloff/inc/SchXMLImport.hxx
index 233ecde5b6c9..a1c3f698dca3 100644
--- a/xmloff/inc/SchXMLImport.hxx
+++ b/xmloff/inc/SchXMLImport.hxx
@@ -97,7 +97,8 @@ enum SchXMLChartAttrMap
XML_TOK_CHART_HEIGHT,
XML_TOK_CHART_STYLE_NAME,
XML_TOK_CHART_COL_MAPPING,
- XML_TOK_CHART_ROW_MAPPING
+ XML_TOK_CHART_ROW_MAPPING,
+ XML_TOK_CHART_DATA_PILOT_SOURCE,
};
enum SchXMLPlotAreaAttrTokenMap
diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx
index 4ce36805398c..1dc1c145e16e 100644
--- a/xmloff/source/chart/SchXMLChartContext.cxx
+++ b/xmloff/source/chart/SchXMLChartContext.cxx
@@ -52,11 +52,15 @@
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
using namespace com::sun::star;
using namespace ::xmloff::token;
using com::sun::star::uno::Reference;
@@ -237,10 +241,67 @@ SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper,
SchXMLChartContext::~SchXMLChartContext()
{}
+void lcl_setDataProvider(uno::Reference<chart2::XChartDocument> const & xChartDoc, OUString const & sDataPilotSource)
+{
+ if (!xChartDoc.is())
+ return;
+
+ try
+ {
+ uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY);
+ uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY);
+ if (xChild.is() && xDataReceiver.is())
+ {
+ bool bHasOwnData = true;
+
+ Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY);
+ if (xFact.is())
+ {
+ if (!xChartDoc->getDataProvider().is())
+ {
+ bool bHasDataPilotSource = !sDataPilotSource.isEmpty();
+ OUString aDataProviderServiceName("com.sun.star.chart2.data.DataProvider");
+ if (bHasDataPilotSource)
+ aDataProviderServiceName = "com.sun.star.chart2.data.PivotTableDataProvider";
+
+ const uno::Sequence<OUString> aServiceNames(xFact->getAvailableServiceNames());
+
+ if (std::find(aServiceNames.begin(), aServiceNames.end(), aDataProviderServiceName) != aServiceNames.end())
+ {
+ Reference<chart2::data::XDataProvider> xProvider(xFact->createInstance(aDataProviderServiceName), uno::UNO_QUERY);
+
+ if (xProvider.is())
+ {
+ xDataReceiver->attachDataProvider(xProvider);
+ if (bHasDataPilotSource)
+ {
+ Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xProvider, uno::UNO_QUERY);
+ xPivotTableDataProvider->setPivotTableName(sDataPilotSource);
+ }
+ bHasOwnData = false;
+ }
+ }
+ }
+ else
+ bHasOwnData = false;
+ }
+ // else we have no parent => we have our own data
+
+ if (bHasOwnData && ! xChartDoc->hasInternalDataProvider())
+ xChartDoc->createInternalDataProvider(false);
+ }
+ }
+ catch (const uno::Exception & rEx)
+ {
+ OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
+ SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr);
+ }
+}
+
void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
// parse attributes
- sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetChartAttrTokenMap();
uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY);
@@ -264,10 +325,12 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut
switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
{
+ case XML_TOK_CHART_DATA_PILOT_SOURCE:
+ msDataPilotSource = aValue;
+ break;
case XML_TOK_CHART_HREF:
m_aXLinkHRefAttributeToIndicateDataProvider = aValue;
break;
-
case XML_TOK_CHART_CLASS:
{
OUString sClassName;
@@ -328,6 +391,11 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut
}
}
+ uno::Reference<chart::XChartDocument> xDoc = mrImportHelper.GetChartDocument();
+ uno::Reference<chart2::XChartDocument> xNewDoc(xDoc, uno::UNO_QUERY);
+
+ lcl_setDataProvider(xNewDoc, msDataPilotSource);
+
if( aOldChartTypeName.isEmpty() )
{
SAL_WARN("xmloff.chart", "need a charttype to create a diagram" );
diff --git a/xmloff/source/chart/SchXMLChartContext.hxx b/xmloff/source/chart/SchXMLChartContext.hxx
index 649c9b6cc387..11b69987ac93 100644
--- a/xmloff/source/chart/SchXMLChartContext.hxx
+++ b/xmloff/source/chart/SchXMLChartContext.hxx
@@ -104,6 +104,8 @@ private:
OUString msCategoriesAddress;
OUString msChartAddress;
+ OUString msDataPilotSource;
+
SeriesDefaultsAndStyles maSeriesDefaultsAndStyles;
tSchXMLLSequencesPerIndex maLSequencesPerIndex;
diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx
index 9b8c205fa038..de3e32c7cd58 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -90,6 +90,7 @@
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.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>
@@ -1213,6 +1214,13 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >
mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
}
+ Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xNewDoc->getDataProvider(), uno::UNO_QUERY);
+ if (xPivotTableDataProvider.is())
+ {
+ OUString sPivotTableName = xPivotTableDataProvider->getPivotTableName();
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, sPivotTableName);
+ }
+
OUString sChartType( xDiagram->getDiagramType() );
// attributes
diff --git a/xmloff/source/chart/SchXMLImport.cxx b/xmloff/source/chart/SchXMLImport.cxx
index 5d33fc69301b..10d8fc105b39 100644
--- a/xmloff/source/chart/SchXMLImport.cxx
+++ b/xmloff/source/chart/SchXMLImport.cxx
@@ -249,6 +249,7 @@ const SvXMLTokenMap& SchXMLImportHelper::GetChartAttrTokenMap()
{ XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_CHART_STYLE_NAME },
{ XML_NAMESPACE_CHART, XML_COLUMN_MAPPING, XML_TOK_CHART_COL_MAPPING },
{ XML_NAMESPACE_CHART, XML_ROW_MAPPING, XML_TOK_CHART_ROW_MAPPING },
+ { XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, XML_TOK_CHART_DATA_PILOT_SOURCE },
XML_TOKEN_MAP_END
};
@@ -574,65 +575,37 @@ SvXMLImportContext* SchXMLImport::CreateStylesContext(
return pStylesCtxt;
}
-void SAL_CALL SchXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
+void SAL_CALL SchXMLImport::setTargetDocument(const uno::Reference<lang::XComponent>& xDoc)
{
- uno::Reference< chart2::XChartDocument > xOldDoc( GetModel(), uno::UNO_QUERY );
- if( xOldDoc.is() && xOldDoc->hasControllersLocked() )
+ uno::Reference<chart2::XChartDocument> xOldDoc(GetModel(), uno::UNO_QUERY);
+ if (xOldDoc.is() && xOldDoc->hasControllersLocked())
xOldDoc->unlockControllers();
- SvXMLImport::setTargetDocument( xDoc );
+ SvXMLImport::setTargetDocument(xDoc);
- //set data provider and number formatter
- // try to get an XDataProvider and set it
- // @todo: if we have our own data, we must not use the parent as data provider
- uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
+ uno::Reference<chart2::XChartDocument> xChartDoc(GetModel(), uno::UNO_QUERY);
- if( xChartDoc.is() )
+ if (xChartDoc.is())
try
{
- //prevent rebuild of view during load ( necesarry especially if loaded not via load api, which is the case for example if binary files are loaded )
+ // prevent rebuild of view during load (necesarry especially if loaded not
+ // via load api, which is the case for example if binary files are loaded)
xChartDoc->lockControllers();
- uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
- uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
- if( xChild.is() && xDataReceiver.is())
+ uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY);
+ uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY);
+ if (xChild.is() && xDataReceiver.is())
{
- bool bHasOwnData = true;
-
- Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
- if( xFact.is() )
+ Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY);
+ if (xFact.is())
{
//if the parent has a number formatter we will use the numberformatter of the parent
- Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xFact, uno::UNO_QUERY );
- xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
-
- if ( !xChartDoc->getDataProvider().is() )
- {
- const OUString aDataProviderServiceName( "com.sun.star.chart2.data.DataProvider");
- const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames());
- const OUString * pBegin = aServiceNames.getConstArray();
- const OUString * pEnd = pBegin + aServiceNames.getLength();
- if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
- {
- Reference< chart2::data::XDataProvider > xProvider(
- xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
- if( xProvider.is())
- {
- xDataReceiver->attachDataProvider( xProvider );
- bHasOwnData = false;
- }
- }
- }
- else
- bHasOwnData = false;
+ Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(xFact, uno::UNO_QUERY);
+ xDataReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
}
-// else we have no parent => we have our own data
-
- if( bHasOwnData && ! xChartDoc->hasInternalDataProvider() )
- xChartDoc->createInternalDataProvider( false );
}
}
- catch( const uno::Exception & rEx )
+ catch (const uno::Exception & rEx)
{
OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr);
diff --git a/xmloff/source/chart/SchXMLSeries2Context.cxx b/xmloff/source/chart/SchXMLSeries2Context.cxx
index 70eda5253150..82e3a7c67da7 100644
--- a/xmloff/source/chart/SchXMLSeries2Context.cxx
+++ b/xmloff/source/chart/SchXMLSeries2Context.cxx
@@ -30,6 +30,7 @@
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart/ChartAxisAssign.hpp>
#include <com/sun/star/chart/ChartSymbolType.hpp>
@@ -407,20 +408,31 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib
uno::makeAny( true ));
}
+ Reference<chart2::data::XDataProvider> xDataProvider(mxNewDoc->getDataProvider());
+ Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
+
+ Reference<chart2::data::XDataSequence> xSequenceValues;
+
// values
- Reference< chart2::data::XDataSequence > xSeq;
- if( bHasRange && !m_aSeriesRange.isEmpty() )
- xSeq = SchXMLTools::CreateDataSequence( m_aSeriesRange, mxNewDoc );
+ if (xPivotTableDataProvider.is()) // is pivot chart
+ {
+ xSequenceValues.set(xPivotTableDataProvider->createDataSequenceOfValuesByIndex(mnSeriesIndex));
+ }
+ else
+ {
+ if (bHasRange && !m_aSeriesRange.isEmpty())
+ xSequenceValues = SchXMLTools::CreateDataSequence(m_aSeriesRange, mxNewDoc);
+ }
- Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
- if( xSeqProp.is())
+ Reference<beans::XPropertySet> xSeqProp(xSequenceValues, uno::UNO_QUERY);
+ if (xSeqProp.is())
{
OUString aMainRole("values-y");
- if ( maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType" )
+ if (maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType")
aMainRole = "values-size";
- xSeqProp->setPropertyValue("Role", uno::makeAny( aMainRole ));
+ xSeqProp->setPropertyValue("Role", uno::makeAny(aMainRole));
}
- xLabeledSeq->setValues( xSeq );
+ xLabeledSeq->setValues(xSequenceValues);
// register for setting local data if external data provider is not present
maPostponedSequences.insert(
@@ -428,18 +440,24 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib
tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_VALUES ), xLabeledSeq ));
// label
- if( !aSeriesLabelRange.isEmpty() )
+ Reference<chart2::data::XDataSequence> xSequenceLabel;
+
+ if (xPivotTableDataProvider.is())
{
- Reference< chart2::data::XDataSequence > xLabelSequence =
- SchXMLTools::CreateDataSequence( aSeriesLabelRange, mxNewDoc );
- xLabeledSeq->setLabel( xLabelSequence );
+ xSequenceLabel.set(xPivotTableDataProvider->createDataSequenceOfLabelsByIndex(mnSeriesIndex));
}
- else if( !aSeriesLabelString.isEmpty() )
+ else
{
- Reference< chart2::data::XDataSequence > xLabelSequence =
- SchXMLTools::CreateDataSequenceWithoutConvert( aSeriesLabelString, mxNewDoc );
- xLabeledSeq->setLabel( xLabelSequence );
+ if (!aSeriesLabelRange.isEmpty())
+ {
+ xSequenceLabel.set(SchXMLTools::CreateDataSequence(aSeriesLabelRange, mxNewDoc));
+ }
+ else if (!aSeriesLabelString.isEmpty())
+ {
+ xSequenceLabel.set(SchXMLTools::CreateDataSequenceWithoutConvert(aSeriesLabelString, mxNewDoc));
+ }
}
+ xLabeledSeq->setLabel(xSequenceLabel);
// Note: Even if we have no label, we have to register the label
// for creation, because internal data always has labels. If
diff --git a/xmloff/source/chart/SchXMLTools.cxx b/xmloff/source/chart/SchXMLTools.cxx
index 31c1ac161b1a..f00ce12d94f3 100644
--- a/xmloff/source/chart/SchXMLTools.cxx
+++ b/xmloff/source/chart/SchXMLTools.cxx
@@ -36,6 +36,7 @@
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
+#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
@@ -488,11 +489,21 @@ void CreateCategories(
bRangeConverted = true;
}
}
- Reference< chart2::data::XDataSequence > xSeq(
- xDataProvider->createDataSequenceByRangeRepresentation( aConvertedRange ));
- xLabeledSeq->setValues( xSeq );
- if( bRangeConverted )
- setXMLRangePropertyAtDataSequence( xSeq, rRangeAddress );
+
+ Reference<chart2::data::XDataSequence> xSequence;
+ Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
+ if (xPivotTableDataProvider.is())
+ {
+ xSequence.set(xPivotTableDataProvider->createDataSequenceOfCategories());
+ }
+ else
+ {
+ xSequence.set(xDataProvider->createDataSequenceByRangeRepresentation(aConvertedRange));
+ if (bRangeConverted)
+ setXMLRangePropertyAtDataSequence(xSequence, rRangeAddress);
+ }
+ xLabeledSeq->setValues(xSequence);
+
}
catch( const lang::IllegalArgumentException & ex )
{
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 5ee0ce8dfa84..166aa91b0a42 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -549,6 +549,7 @@ namespace xmloff { namespace token {
TOKEN( "data-label-number", XML_DATA_LABEL_NUMBER ),
TOKEN( "data-label-symbol", XML_DATA_LABEL_SYMBOL ),
TOKEN( "data-label-text", XML_DATA_LABEL_TEXT ),
+ TOKEN( "data-pilot-source", XML_DATA_PILOT_SOURCE ),
TOKEN( "data-pilot-field", XML_DATA_PILOT_FIELD ),
TOKEN( "data-pilot-grand-total", XML_DATA_PILOT_GRAND_TOTAL ),
TOKEN( "data-pilot-level", XML_DATA_PILOT_LEVEL ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index e8878d8ec6c1..70386737e4ed 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -471,6 +471,7 @@ data-cell-range-address
data-label-number
data-label-symbol
data-label-text
+data-pilot-source
data-pilot-field
data-pilot-grand-total
data-pilot-level
@@ -3050,4 +3051,4 @@ max-numerator-digits
zeros-numerator-digits
zeros-denominator-digits
integer-fraction-delimiter
-TOKEN_END_DUMMY \ No newline at end of file
+TOKEN_END_DUMMY