[Libreoffice-commits] core.git: chart2/CppunitTest_chart2_pivot_chart_test.mk chart2/inc chart2/Module_chart2.mk chart2/qa chart2/source include/xmloff offapi/com offapi/UnoApi_offapi.mk sc/inc sc/Library_sc.mk sc/source xmloff/inc xmloff/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Tue Apr 4 13:39:55 UTC 2017


 chart2/CppunitTest_chart2_pivot_chart_test.mk               |  131 +
 chart2/Module_chart2.mk                                     |    1 
 chart2/inc/ChartModel.hxx                                   |    9 
 chart2/qa/extras/PivotChartTest.cxx                         |  298 ++++
 chart2/qa/extras/charttest.hxx                              |   77 +
 chart2/qa/extras/data/ods/PivotChartRoundTrip.ods           |binary
 chart2/qa/extras/data/ods/PivotTableExample.ods             |binary
 chart2/source/controller/dialogs/DialogModel.hxx            |    3 
 chart2/source/controller/dialogs/dlg_CreationWizard.cxx     |   61 
 chart2/source/controller/drawinglayer/DrawViewWrapper.cxx   |    7 
 chart2/source/controller/inc/ChartController.hxx            |    2 
 chart2/source/controller/inc/dlg_CreationWizard.hxx         |   37 
 chart2/source/controller/main/ChartController_Window.cxx    |   71 -
 chart2/source/inc/PopupRequest.hxx                          |   11 
 chart2/source/model/main/ChartModel.cxx                     |   23 
 chart2/source/model/main/ChartModel_Persistence.cxx         |   36 
 chart2/source/view/main/ChartView.cxx                       |   50 
 chart2/source/view/main/VLegend.cxx                         |   29 
 include/xmloff/xmlnmspe.hxx                                 |    1 
 include/xmloff/xmltoken.hxx                                 |    1 
 offapi/UnoApi_offapi.mk                                     |    7 
 offapi/com/sun/star/chart2/data/PivotTableFieldEntry.idl    |   25 
 offapi/com/sun/star/chart2/data/PopupRequest.idl            |   44 
 offapi/com/sun/star/chart2/data/XDataReceiver.idl           |    2 
 offapi/com/sun/star/chart2/data/XPivotTableDataProvider.idl |   90 +
 offapi/com/sun/star/table/XTablePivotChart.idl              |   36 
 offapi/com/sun/star/table/XTablePivotCharts.idl             |   63 
 offapi/com/sun/star/table/XTablePivotChartsSupplier.idl     |   41 
 sc/Library_sc.mk                                            |    6 
 sc/inc/ChartTools.hxx                                       |   50 
 sc/inc/PivotTableDataProvider.hxx                           |  190 ++
 sc/inc/PivotTableDataSequence.hxx                           |  170 ++
 sc/inc/PivotTableDataSource.hxx                             |   59 
 sc/inc/TablePivotChart.hxx                                  |   74 +
 sc/inc/TablePivotCharts.hxx                                 |   76 +
 sc/inc/cellsuno.hxx                                         |    6 
 sc/inc/servuno.hxx                                          |    2 
 sc/inc/unonames.hxx                                         |    1 
 sc/source/ui/drawfunc/fuins2.cxx                            |   95 -
 sc/source/ui/inc/tabview.hxx                                |    2 
 sc/source/ui/unoobj/ChartTools.cxx                          |  127 +
 sc/source/ui/unoobj/PivotTableDataProvider.cxx              |  843 ++++++++++++
 sc/source/ui/unoobj/PivotTableDataSequence.cxx              |  278 +++
 sc/source/ui/unoobj/PivotTableDataSource.cxx                |   51 
 sc/source/ui/unoobj/TablePivotChart.cxx                     |  104 +
 sc/source/ui/unoobj/TablePivotCharts.cxx                    |  279 +++
 sc/source/ui/unoobj/cellsuno.cxx                            |   17 
 sc/source/ui/unoobj/chartuno.cxx                            |   48 
 sc/source/ui/unoobj/servuno.cxx                             |    7 
 sc/source/ui/view/tabview3.cxx                              |   18 
 sc/source/ui/view/tabvwshb.cxx                              |   32 
 xmloff/inc/SchXMLImport.hxx                                 |    3 
 xmloff/source/chart/SchXMLChartContext.cxx                  |   72 -
 xmloff/source/chart/SchXMLChartContext.hxx                  |    2 
 xmloff/source/chart/SchXMLExport.cxx                        |    8 
 xmloff/source/chart/SchXMLImport.cxx                        |   61 
 xmloff/source/chart/SchXMLSeries2Context.cxx                |   50 
 xmloff/source/chart/SchXMLTools.cxx                         |   21 
 xmloff/source/core/xmltoken.cxx                             |    1 
 xmloff/source/token/tokens.txt                              |    3 
 60 files changed, 3583 insertions(+), 329 deletions(-)

New commits:
commit 9009663deb8f0862f419fd99bf0b761c7f923eff
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Sun Feb 26 22:48:06 2017 +0100

    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 at gmail.com>
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

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
Binary files /dev/null and b/chart2/qa/extras/data/ods/PivotChartRoundTrip.ods 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
Binary files /dev/null and b/chart2/qa/extras/data/ods/PivotTableExample.ods 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
similarity index 62%
rename from offapi/com/sun/star/chart2/data/XPopupRequest.idl
rename to 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 ];

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list