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.vajng...@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 <qui...@gmail.com> Tested-by: Tomaž Vajngerl <qui...@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
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits