tdf#83257 [API-CHANGE] Pivot chart implementation
This is a squashed commit of the pivot chart implementation.
Some of the changes:
- Add pivot chart specific (pivot table) data provider which
provides the data from a pivot table to the associated chart.
- When inserting a chart and the cursor is in a pivot table,
in that case insert a pivot chart
- Modify the pivot chart when the pivot table changes
- Collect and set the number format for the values
- isDataFromSpreadsheet check for the creation wizard
- In ChartView (and VLegend) check if the data provider is a
pivot chart data provider and get the pivot table field names
to create the buttons on the UI.
- Adds the functionallity to show a filter pop-up (from calc)
when clicking on row / column / page field buttons.
- Remove (X)PopupRequest as we won't need it.
- Add ODF import/export for pivot charts:
+ Added loext:data-pilot-source attribute on chart:chart
which is the internal name of the pivot table with which the
pivot chart is associated with. If the element is present, then
the it means the chart is a pivot chart, else it is a normal
chart
+ Added service to create pivot chart data provider through UNO
+ Add new methods to XPivotChartDataProvider to create value and
label data sequences separately from the data source, which is
needed for pivot chart import
+ When importing defer setting the data provider until a later
time when we know if we are creating a chart od a pivot chart
- Pivot chart ODF round-trip test
- Add table pivot chart supplier API:
This adds the XTablePivotChartSupplier and related interfaces so
we can access, create, delete pivot charts from UNO in a sheet
document. With this we now distinguish between normal charts
and pivot charts. This was mainly needed because we can't extend
the "published" interfaces of TableChartSupplier.
- Added an extensive test, which uses the API to create a new
pivot chart when there was none, and checks that the pivot chart
updates when the pivot table updates.
Change-Id: Ia9ed96fd6b1d342e61c2f7f9fa33a5e03dda21af
Reviewed-on: https://gerrit.libreoffice.org/36023
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/chart2/CppunitTest_chart2_pivot_chart_test.mk b/chart2/CppunitTest_chart2_pivot_chart_test.mk
new file mode 100644
index 0000000..418db1a
--- /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 f39140d..3273055d 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 29b764b..63bd126 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 0000000..8d1c11d
--- /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 1d2f4af..b75dac6 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 0000000..c34521e
--- /dev/null
+++ b/chart2/qa/extras/data/ods/PivotChartRoundTrip.ods
Binary files differ
diff --git a/chart2/qa/extras/data/ods/PivotTableExample.ods b/chart2/qa/extras/data/ods/PivotTableExample.ods
new file mode 100644
index 0000000..bc8df81
--- /dev/null
+++ b/chart2/qa/extras/data/ods/PivotTableExample.ods
Binary files differ
diff --git a/chart2/source/controller/dialogs/DialogModel.hxx b/chart2/source/controller/dialogs/DialogModel.hxx
index 55251b1..722ce26 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 501272f..b4beb73 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 );
this->SetSizePixel(aSize);
uno::Reference< chart2::XChartDocument > xChartDoc( m_xChartModel, uno::UNO_QUERY );
bool bHasOwnData = (xChartDoc.is() && xChartDoc->hasInternalDataProvider());
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 47932bb..c1005f5 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 ae579cf..d69a7a2 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 fed0190..a1fed3c 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 11dd2d8..441e8da 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 e564003..fb98d3d 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 814bd31..579a9c3 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 c19aeaf..5858501 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 2053ab0..6dccabf 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<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rModel.getDataProvider(), uno::UNO_QUERY);
if (!xPivotTableDataProvider.is())
return;
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"
};
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 698f7fc..e2d9b735c 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 ae588d2..7675b55 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 4430d29..9ab65ab 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 49602b9..ded4b70 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 0711678..4d8973f 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 f83ccc0..0000000
--- 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 abfbc83..a7c853b 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 0000000..731988b
--- /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 0000000..b6c53d6
--- /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 0000000..e16b74b
--- /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 0000000..4401741
--- /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 9068e50..0a888ee 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 0000000..dc9a5c5
--- /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 0000000..8135cba
--- /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 0000000..f5e508e
--- /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 0000000..326f7c3
--- /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 0000000..dce05e7
--- /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 0000000..f60726e
--- /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 aded180f..95cef41 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 44049dd..e814632 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 469183d..6e10454 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 7f35185..f6cf018 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;
void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData,
const OUString& rRangeParam )
namespace
{
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() )
{
pViewSh->GetViewData().GetView()->MarkDataArea();
bAutomaticMark = true;
}
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;
// get "total" range for positioning
if ( !aRanges.empty() )
ScDPObject* pObject = pDocument->GetDPAtCursor(pViewSh->GetViewData().GetCurX(),
pViewSh->GetViewData().GetCurY(),
pViewSh->GetViewData().GetTabNo());
if (pObject)
{
aPositionRange = *aRanges[ 0 ];
for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i )
{
aPositionRange.ExtendTo( *aRanges[ i ] );
}
aRangeString = pObject->GetName();
bRangeIsPivotTable = true;
}
else
{
bool bAutomaticMark = false;
if ( !aMark.IsMarked() && !aMark.IsMultiMarked() )
{
pViewSh->GetViewData().GetView()->MarkDataArea();
bAutomaticMark = true;
}
if(bAutomaticMark)
pViewSh->GetViewData().GetView()->Unmark();
ScMarkData aMultiMark( aMark );
aMultiMark.MarkToMulti();
ScRangeList aRanges;
aMultiMark.FillRangeListWithMarks( &aRanges, false );
OUString aStr;
aRanges.Format( aStr, ScRefFlags::RANGE_ABS_3D, pDocument, pDocument->GetAddressConvention() );
aRangeString = aStr;
// get "total" range for positioning
if ( !aRanges.empty() )
{
aPositionRange = *aRanges[ 0 ];
for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i )
{
aPositionRange.ExtendTo( *aRanges[ i ] );
}
}
if(bAutomaticMark)
pViewSh->GetViewData().GetView()->Unmark();
}
}
// adapted old code
@@ -568,7 +595,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV
}
}
lcl_ChartInit( xObj, &rData, aRangeString ); // set source range, auto-detect column/row headers
lcl_ChartInit(xObj, &rData, aRangeString, bRangeIsPivotTable); // set source range, auto-detect column/row headers
// Objekt-Position
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index b217c5b..a9cccb1 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -487,7 +487,7 @@ public:
void ClearHighlightRanges();
void DoChartSelection( const css::uno::Sequence< css::chart2::data::HighlightedRange > & rHilightRanges );
void DoDPFieldPopup(Point aPoint, Size aSize);
void DoDPFieldPopup(OUString const & rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize);
long GetGridWidth( ScHSplitPos eWhich );
long GetGridHeight( ScVSplitPos eWhich );
diff --git a/sc/source/ui/unoobj/ChartTools.cxx b/sc/source/ui/unoobj/ChartTools.cxx
new file mode 100644
index 0000000..7781872
--- /dev/null
+++ b/sc/source/ui/unoobj/ChartTools.cxx
@@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include "ChartTools.hxx"
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <svx/svditer.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdundo.hxx>
#include <sfx2/app.hxx>
#include <unotools/moduleoptions.hxx>
#include <comphelper/classids.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/globname.hxx>
#include <svx/charthelper.hxx>
#include <svtools/embedhlp.hxx>
using namespace css;
namespace sc {
namespace tools {
ChartIterator::ChartIterator(ScDocShell* pDocShell, SCTAB nTab, ChartSourceType eChartSourceType)
: m_eChartSourceType(eChartSourceType)
{
if (!pDocShell)
return;
ScDocument& rDoc = pDocShell->GetDocument();
ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
if (!pDrawLayer)
return;
SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(nTab));
if (!pPage)
return;
m_pIterator.reset(new SdrObjListIter(*pPage, SdrIterMode::DeepNoGroups));
}
SdrOle2Obj* ChartIterator::next()
{
if (!m_pIterator)
return nullptr;
SdrObject* pObject = m_pIterator->Next();
while (pObject)
{
if (pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject))
{
SdrOle2Obj* pOleObject = static_cast<SdrOle2Obj*>(pObject);
uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
if (xObject.is())
{
uno::Reference<chart2::XChartDocument> xChartDoc(xObject->getComponent(), uno::UNO_QUERY);
if (xChartDoc.is())
{
uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xChartDoc->getDataProvider(), uno::UNO_QUERY);
if (xPivotTableDataProvider.is() && m_eChartSourceType == ChartSourceType::PIVOT_TABLE)
{
return pOleObject;
}
else if (!xPivotTableDataProvider.is() && m_eChartSourceType == ChartSourceType::CELL_RANGE)
{
return pOleObject;
}
}
}
}
pObject = m_pIterator->Next();
}
return nullptr;
}
SdrOle2Obj* findChartsByName(ScDocShell* pDocShell, SCTAB nTab, OUString const & rName, ChartSourceType eChartSourceType)
{
if (!pDocShell)
return nullptr;
ChartIterator aIterator(pDocShell, nTab, eChartSourceType);
SdrOle2Obj* pObject = aIterator.next();
while (pObject)
{
uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
if (xObject.is())
{
OUString aObjectName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
if (aObjectName == rName)
return pObject;
}
pObject = aIterator.next();
}
return nullptr;
}
SdrOle2Obj* getChartByIndex(ScDocShell* pDocShell, SCTAB nTab, long nIndex, ChartSourceType eChartSourceType)
{
if (!pDocShell)
return nullptr;
ChartIterator aIterator(pDocShell, nTab, eChartSourceType);
SdrOle2Obj* pObject = aIterator.next();
long i = 0;
while (pObject)
{
if (i == nIndex)
{
return pObject;
}
i++;
pObject = aIterator.next();
}
return nullptr;
}
}} // end sc::tools
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataProvider.cxx b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
new file mode 100644
index 0000000..84eb756
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
@@ -0,0 +1,843 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/config.h>
#include "PivotTableDataProvider.hxx"
#include "PivotTableDataSource.hxx"
#include "PivotTableDataSequence.hxx"
#include <vcl/svapp.hxx>
#include "miscuno.hxx"
#include "document.hxx"
#include "unonames.hxx"
#include "docsh.hxx"
#include <sfx2/objsh.hxx>
#include <comphelper/sequence.hxx>
#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/sheet/XDataPilotResults.hpp>
#include <com/sun/star/sheet/DataResultFlags.hpp>
#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
#include <com/sun/star/sheet/XLevelsSupplier.hpp>
#include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
#include <com/sun/star/sheet/MemberResultFlags.hpp>
#include "dpobject.hxx"
#include "hints.hxx"
#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
#include <unordered_map>
using namespace css;
namespace sc
{
namespace
{
const SfxItemPropertyMapEntry* lcl_GetDataProviderPropertyMap()
{
static const SfxItemPropertyMapEntry aDataProviderPropertyMap_Impl[] =
{
{ OUString(SC_UNONAME_INCLUDEHIDDENCELLS), 0, cppu::UnoType<bool>::get(), 0, 0 },
{ OUString(SC_UNONAME_USE_INTERNAL_DATA_PROVIDER), 0, cppu::UnoType<bool>::get(), 0, 0 },
{ OUString(), 0, css::uno::Type(), 0, 0 }
};
return aDataProviderPropertyMap_Impl;
}
uno::Reference<frame::XModel> lcl_GetXModel(ScDocument * pDoc)
{
uno::Reference<frame::XModel> xModel;
SfxObjectShell* pObjSh(pDoc ? pDoc->GetDocumentShell() : nullptr);
if (pObjSh)
xModel.set(pObjSh->GetModel());
return xModel;
}
OUString lcl_identifierForData(sal_Int32 index)
{
return "Data " + OUString::number(index + 1);
}
OUString lcl_identifierForLabel(sal_Int32 index)
{
return "Label " + OUString::number(index + 1);
}
} // end anonymous namespace
SC_SIMPLE_SERVICE_INFO(PivotTableDataProvider, "PivotTableDataProvider", SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER)
// DataProvider ==============================================================
PivotTableDataProvider::PivotTableDataProvider(ScDocument* pDoc)
: m_pDocument(pDoc)
, m_aPropSet(lcl_GetDataProviderPropertyMap())
, m_bIncludeHiddenCells(true)
, m_bNeedsUpdate(true)
, m_xContext(comphelper::getProcessComponentContext())
{
if (m_pDocument)
m_pDocument->AddUnoObject(*this);
}
PivotTableDataProvider::~PivotTableDataProvider()
{
SolarMutexGuard g;
if (m_pDocument)
m_pDocument->RemoveUnoObject( *this);
}
void PivotTableDataProvider::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::Dying)
{
m_pDocument = nullptr;
}
else if (dynamic_cast<const ScDataPilotModifiedHint*>(&rHint))
{
if (m_pDocument)
{
OUString sPivotTableName = static_cast<const ScDataPilotModifiedHint&>(rHint).GetName();
if (sPivotTableName == m_sPivotTableName)
{
m_bNeedsUpdate = true;
for (uno::Reference<util::XModifyListener> const & xListener : m_aValueListeners)
{
css::chart::ChartDataChangeEvent aEvent(static_cast<cppu::OWeakObject*>(this),
css::chart::ChartDataChangeType_ALL,
0, 0, 0, 0);
xListener->modified(aEvent);
}
}
}
}
}
sal_Bool SAL_CALL PivotTableDataProvider::createDataSourcePossible(const uno::Sequence<beans::PropertyValue>& /*aArguments*/)
{
SolarMutexGuard aGuard;
if (!m_pDocument)
return false;
if (m_sPivotTableName.isEmpty())
return false;
ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
return bool(pDPCollection->GetByName(m_sPivotTableName));
}
uno::Reference<chart2::data::XDataSource> SAL_CALL
PivotTableDataProvider::createDataSource(const uno::Sequence<beans::PropertyValue>& aArguments)
{
SolarMutexGuard aGuard;
if (!m_pDocument)
throw uno::RuntimeException();
bool bLabel = true;
bool bCategories = false;
bool bOrientCol = true;
OUString aRangeRepresentation;
OUString sPivotTable;
uno::Sequence<sal_Int32> aSequenceMapping;
bool bTimeBased = false;
for (beans::PropertyValue const & rProperty : aArguments)
{
if (rProperty.Name == "DataRowSource")
{
chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
if (!(rProperty.Value >>= eSource))
{
sal_Int32 nSource(0);
if (rProperty.Value >>= nSource)
eSource = chart::ChartDataRowSource(nSource);
}
bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
}
else if (rProperty.Name == "FirstCellAsLabel")
rProperty.Value >>= bLabel;
else if (rProperty.Name == "HasCategories")
rProperty.Value >>= bCategories;
else if (rProperty.Name == "CellRangeRepresentation")
rProperty.Value >>= aRangeRepresentation;
else if (rProperty.Name == "SequenceMapping")
rProperty.Value >>= aSequenceMapping;
else if (rProperty.Name == "TimeBased")
rProperty.Value >>= bTimeBased;
else if (rProperty.Name == "ConnectedPivotTable")
rProperty.Value >>= sPivotTable;
}
uno::Reference<chart2::data::XDataSource> xResult;
if (aRangeRepresentation == "Categories")
xResult = createCategoriesDataSource(aRangeRepresentation, bOrientCol);
else
xResult = createValuesDataSource(aRangeRepresentation);
return xResult;
}
uno::Reference<chart2::data::XLabeledDataSequence>
PivotTableDataProvider::newLabeledDataSequence()
{
uno::Reference<chart2::data::XLabeledDataSequence> xResult;
if (!m_xContext.is())
return xResult;
xResult.set(chart2::data::LabeledDataSequence::create(m_xContext), uno::UNO_QUERY_THROW);
return xResult;
}
void PivotTableDataProvider::setLabeledDataSequenceValues(uno::Reference<chart2::data::XLabeledDataSequence> & xResult,
OUString const & sRoleValues, OUString const & sIdValues,
std::vector<ValueAndFormat> const & rValues)
{
std::unique_ptr<PivotTableDataSequence> pSequence(
new PivotTableDataSequence(m_pDocument, m_sPivotTableName, sIdValues, rValues));
pSequence->setRole(sRoleValues);
xResult->setValues(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
}
void PivotTableDataProvider::setLabeledDataSequence(uno::Reference<chart2::data::XLabeledDataSequence> & xResult,
OUString const & sRoleValues, OUString const & sIdValues,
std::vector<ValueAndFormat> const & rValues,
OUString const & sRoleLabel, OUString const & sIdLabel,
std::vector<ValueAndFormat> const & rLabel)
{
setLabeledDataSequenceValues(xResult, sRoleValues, sIdValues, rValues);
std::unique_ptr<PivotTableDataSequence> pLabelSequence(
new PivotTableDataSequence(m_pDocument, m_sPivotTableName, sIdLabel, rLabel));
pLabelSequence->setRole(sRoleLabel);
xResult->setLabel(uno::Reference<chart2::data::XDataSequence>(pLabelSequence.release()));
}
uno::Reference<chart2::data::XDataSource>
PivotTableDataProvider::createCategoriesDataSource(OUString const & rRangeRepresentation,
bool bOrientationIsColumn)
{
if (m_bNeedsUpdate)
collectPivotTableData();
uno::Reference<chart2::data::XDataSource> xDataSource;
std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
if (bOrientationIsColumn)
{
for (std::vector<ValueAndFormat> const & rCategories : m_aCategoriesColumnOrientation)
{
uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories);
aLabeledSequences.push_back(xResult);
}
}
else
{
for (std::vector<ValueAndFormat> const & rCategories : m_aCategoriesRowOrientation)
{
uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories);
aLabeledSequences.push_back(xResult);
}
}
xDataSource.set(new PivotTableDataSource(rRangeRepresentation, aLabeledSequences));
return xDataSource;
}
void PivotTableDataProvider::collectPivotTableData()
{
ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
ScDPObject* pDPObject = pDPCollection->GetByName(m_sPivotTableName);
uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->GetSource(), uno::UNO_QUERY);
uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults();
m_aCategoriesColumnOrientation.clear();
m_aCategoriesRowOrientation.clear();
m_aLabels.clear();
m_aDataRowVector.clear();
m_aColumnFields.clear();
m_aRowFields.clear();
m_aPageFields.clear();
m_aDataFields.clear();
double fNan;
rtl::math::setNan(&fNan);
for (uno::Sequence<sheet::DataResult> const & xDataResults : xDataResultsSequence)
{
size_t nIndex = 0;
for (sheet::DataResult const & rDataResult : xDataResults)
{
if (rDataResult.Flags == 0 || rDataResult.Flags & css::sheet::DataResultFlags::HASDATA)
{
if (nIndex >= m_aDataRowVector.size())
m_aDataRowVector.resize(nIndex + 1);
m_aDataRowVector[nIndex].push_back(ValueAndFormat(rDataResult.Flags ? rDataResult.Value : fNan, 0));
}
nIndex++;
}
}
uno::Reference<sheet::XDimensionsSupplier> xDimensionsSupplier(pDPObject->GetSource());
uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess(xDimensionsSupplier->getDimensions());
std::unordered_map<OUString, sal_Int32, OUStringHash> aDataFieldNumberFormatMap;
std::vector<OUString> aDataFieldNamesVectors;
std::unordered_map<OUString, OUString, OUStringHash> aDataFieldCaptionNames;
std::vector<std::pair<OUString, sal_Int32>> aDataFieldPairs;
sheet::DataPilotFieldOrientation eDataFieldOrientation = sheet::DataPilotFieldOrientation_HIDDEN;
for (sal_Int32 nDim = 0; nDim < xDims->getCount(); nDim++)
{
uno::Reference<uno::XInterface> xDim = ScUnoHelpFunctions::AnyToInterface(xDims->getByIndex(nDim));
uno::Reference<beans::XPropertySet> xDimProp(xDim, uno::UNO_QUERY);
uno::Reference<container::XNamed> xDimName(xDim, uno::UNO_QUERY);
uno::Reference<sheet::XHierarchiesSupplier> xDimSupp(xDim, uno::UNO_QUERY);
if (!xDimProp.is() || !xDimSupp.is())
continue;
sheet::DataPilotFieldOrientation eDimOrient = sheet::DataPilotFieldOrientation(
ScUnoHelpFunctions::GetEnumProperty(xDimProp, SC_UNO_DP_ORIENTATION,
sheet::DataPilotFieldOrientation_HIDDEN));
if (eDimOrient == sheet::DataPilotFieldOrientation_HIDDEN)
continue;
uno::Reference<container::XIndexAccess> xHierarchies = new ScNameToIndexAccess(xDimSupp->getHierarchies());
sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_USEDHIERARCHY);
if (nHierarchy >= xHierarchies->getCount())
nHierarchy = 0;
uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface(xHierarchies->getByIndex(nHierarchy));
uno::Reference<sheet::XLevelsSupplier> xLevelsSupplier(xHierarchy, uno::UNO_QUERY);
if (!xLevelsSupplier.is())
continue;
uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess(xLevelsSupplier->getLevels());
for (long nLevel = 0; nLevel < xLevels->getCount(); nLevel++)
{
uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(xLevels->getByIndex(nLevel));
uno::Reference<container::XNamed> xLevelName(xLevel, uno::UNO_QUERY);
uno::Reference<sheet::XDataPilotMemberResults> xLevelResult(xLevel, uno::UNO_QUERY );
bool bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(xDimProp, SC_UNO_DP_ISDATALAYOUT);
long nDimPos = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_POSITION);
sal_Int32 nNumberFormat = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_NUMBERFO);
if (xLevelName.is() && xLevelResult.is())
{
switch (eDimOrient)
{
case sheet::DataPilotFieldOrientation_COLUMN:
{
m_aColumnFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
size_t i = 0;
OUString sCaption;
OUString sName;
m_aLabels.resize(aSequence.getLength());
for (sheet::MemberResult & rMember : aSequence)
{
if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER ||
rMember.Flags & sheet::MemberResultFlags::CONTINUE)
{
if (!(rMember.Flags & sheet::MemberResultFlags::CONTINUE))
{
sCaption = rMember.Caption;
sName = rMember.Name;
}
if (size_t(nDimPos) >= m_aLabels[i].size())
m_aLabels[i].resize(nDimPos + 1);
m_aLabels[i][nDimPos] = ValueAndFormat(sCaption);
if (bIsDataLayout)
{
// Remember data fields to determine the number format of data
aDataFieldNamesVectors.push_back(sName);
eDataFieldOrientation = sheet::DataPilotFieldOrientation_COLUMN;
// Remember the caption name
aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
}
i++;
}
}
}
break;
case sheet::DataPilotFieldOrientation_ROW:
{
m_aRowFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
m_aCategoriesRowOrientation.resize(aSequence.getLength());
size_t i = 0;
for (sheet::MemberResult & rMember : aSequence)
{
bool bHasContinueFlag = rMember.Flags & sheet::MemberResultFlags::CONTINUE;
if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER || bHasContinueFlag)
{
std::unique_ptr<ValueAndFormat> pItem;
double fValue = rMember.Value;
if (rtl::math::isNan(fValue))
{
OUString sStringValue = bHasContinueFlag ? "" : rMember.Caption;
pItem.reset(new ValueAndFormat(sStringValue));
}
else
{
if (bHasContinueFlag)
pItem.reset(new ValueAndFormat());
else
pItem.reset(new ValueAndFormat(fValue, nNumberFormat));
}
if (size_t(nDimPos) >= m_aCategoriesColumnOrientation.size())
m_aCategoriesColumnOrientation.resize(nDimPos + 1);
m_aCategoriesColumnOrientation[nDimPos].push_back(*pItem);
if (size_t(nDimPos) >= m_aCategoriesRowOrientation[i].size())
m_aCategoriesRowOrientation[i].resize(nDimPos + 1);
m_aCategoriesRowOrientation[i][nDimPos] = *pItem;
if (bIsDataLayout)
{
// Remember data fields to determine the number format of data
aDataFieldNamesVectors.push_back(rMember.Name);
eDataFieldOrientation = sheet::DataPilotFieldOrientation_ROW;
// Remember the caption name
aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
}
i++;
}
}
}
break;
case sheet::DataPilotFieldOrientation_PAGE:
{
m_aPageFields.push_back(chart2::data::PivotTableFieldEntry{xLevelName->getName(), nDim});
}
break;
case sheet::DataPilotFieldOrientation_DATA:
{
aDataFieldNumberFormatMap[xLevelName->getName()] = nNumberFormat;
aDataFieldPairs.push_back(std::pair<OUString, sal_Int32>(xLevelName->getName(), nDim));
}
break;
default:
break;
}
}
}
}
// Fill data field entry info
for (std::pair<OUString, sal_Int32> & rPair : aDataFieldPairs)
{
m_aDataFields.push_back(chart2::data::PivotTableFieldEntry{
aDataFieldCaptionNames[rPair.first],
rPair.second});
}
// Apply number format to the data
if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_ROW)
{
for (std::vector<ValueAndFormat> & rDataRow : m_aDataRowVector)
{
size_t i = 0;
for (ValueAndFormat & rItem : rDataRow)
{
OUString sName = aDataFieldNamesVectors[i];
sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName];
rItem.m_nNumberFormat = nNumberFormat;
i++;
}
}
}
else if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_COLUMN)
{
size_t i = 0;
for (std::vector<ValueAndFormat> & rDataRow : m_aDataRowVector)
{
OUString sName = aDataFieldNamesVectors[i];
sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName];
for (ValueAndFormat & rItem : rDataRow)
{
rItem.m_nNumberFormat = nNumberFormat;
}
i++;
}
}
m_bNeedsUpdate = false;
}
void PivotTableDataProvider::assignValuesToDataSequence(uno::Reference<chart2::data::XDataSequence> & rDataSequence,
size_t nIndex)
{
if (nIndex >= m_aDataRowVector.size())
return;
OUString sDataID = lcl_identifierForData(nIndex);
std::vector<ValueAndFormat> const & rRowOfData = m_aDataRowVector[size_t(nIndex)];
std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
sDataID, rRowOfData));
pSequence->setRole("values-y");
rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
}
void PivotTableDataProvider::assignLabelsToDataSequence(uno::Reference<chart2::data::XDataSequence> & rDataSequence,
size_t nIndex)
{
if (nIndex >= m_aLabels.size())
return;
OUString sLabelID = lcl_identifierForLabel(nIndex);
OUString aLabel;
bool bFirst = true;
for (ValueAndFormat const & rItem : m_aLabels[size_t(nIndex)])
{
if (bFirst)
{
aLabel += rItem.m_aString;
bFirst = false;
}
else
{
aLabel += " - " + rItem.m_aString;
}
}
std::vector<ValueAndFormat> aLabelVector { ValueAndFormat(aLabel) };
std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
sLabelID, aLabelVector));
pSequence->setRole("values-y");
rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
}
uno::Reference<chart2::data::XDataSource>
PivotTableDataProvider::createValuesDataSource(OUString const & rRangeRepresentation)
{
if (m_bNeedsUpdate)
collectPivotTableData();
uno::Reference<chart2::data::XDataSource> xDataSource;
std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
{
std::vector<ValueAndFormat> aFirstCategories;
if (!m_aCategoriesColumnOrientation.empty())
{
std::copy(m_aCategoriesColumnOrientation[0].begin(),
m_aCategoriesColumnOrientation[0].end(),
std::back_inserter(aFirstCategories));
}
uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
setLabeledDataSequenceValues(xResult, "categories", "Categories", aFirstCategories);
aLabeledSequences.push_back(xResult);
}
{
int i = 0;
for (std::vector<ValueAndFormat> const & rRowOfData : m_aDataRowVector)
{
OUString aValuesId = lcl_identifierForData(i);
OUString aLabelsId = lcl_identifierForLabel(i);
OUString aLabel;
bool bFirst = true;
for (ValueAndFormat const & rItem : m_aLabels[i])
{
if (bFirst)
{
aLabel += rItem.m_aString;
bFirst = false;
}
else
{
aLabel += " - " + rItem.m_aString;
}
}
std::vector<ValueAndFormat> aLabelVector { ValueAndFormat(aLabel) };
uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence();
setLabeledDataSequence(xResult, "values-y", aValuesId, rRowOfData,
"values-y", aLabelsId, aLabelVector);
aLabeledSequences.push_back(xResult);
i++;
}
}
xDataSource.set(new PivotTableDataSource(rRangeRepresentation, aLabeledSequences));
return xDataSource;
}
uno::Sequence<beans::PropertyValue> SAL_CALL PivotTableDataProvider::detectArguments(
const uno::Reference<chart2::data::XDataSource> & xDataSource)
{
uno::Sequence<beans::PropertyValue> aArguments;
if (!m_pDocument ||!xDataSource.is())
return aArguments;
aArguments.realloc(4);
aArguments[0] = beans::PropertyValue("CellRangeRepresentation", -1, uno::Any(OUString("PivotChart")),
beans::PropertyState_DIRECT_VALUE);
aArguments[1] = beans::PropertyValue("DataRowSource", -1, uno::Any(chart::ChartDataRowSource_COLUMNS),
beans::PropertyState_DIRECT_VALUE);
aArguments[2] = beans::PropertyValue("FirstCellAsLabel", -1, uno::Any(false),
beans::PropertyState_DIRECT_VALUE);
aArguments[3] = beans::PropertyValue("HasCategories", -1, uno::Any(true),
beans::PropertyState_DIRECT_VALUE);
return aArguments;
}
sal_Bool SAL_CALL PivotTableDataProvider::createDataSequenceByRangeRepresentationPossible(const OUString& /*aRangeRepresentation*/)
{
SolarMutexGuard aGuard;
return false;
}
uno::Reference<chart2::data::XDataSequence> SAL_CALL
PivotTableDataProvider::createDataSequenceByRangeRepresentation(const OUString& /*rRangeRepresentation*/)
{
SolarMutexGuard aGuard;
uno::Reference<chart2::data::XDataSequence> xDataSequence;
return xDataSequence;
}
uno::Reference<chart2::data::XDataSequence> SAL_CALL
PivotTableDataProvider::createDataSequenceByValueArray(const OUString& /*aRole*/,
const OUString& /*aRangeRepresentation*/)
{
return uno::Reference<chart2::data::XDataSequence>();
}
uno::Reference<sheet::XRangeSelection> SAL_CALL PivotTableDataProvider::getRangeSelection()
{
uno::Reference<sheet::XRangeSelection> xResult;
uno::Reference<frame::XModel> xModel(lcl_GetXModel(m_pDocument));
if (xModel.is())
xResult.set(xModel->getCurrentController(), uno::UNO_QUERY);
return xResult;
}
uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getColumnFields()
{
return comphelper::containerToSequence(m_aColumnFields);
}
uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getRowFields()
{
return comphelper::containerToSequence(m_aRowFields);
}
uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getPageFields()
{
return comphelper::containerToSequence(m_aPageFields);
}
uno::Sequence<chart2::data::PivotTableFieldEntry> PivotTableDataProvider::getDataFields()
{
return comphelper::containerToSequence(m_aDataFields);
}
OUString PivotTableDataProvider::getPivotTableName()
{
return m_sPivotTableName;
}
void PivotTableDataProvider::setPivotTableName(const OUString& sPivotTableName)
{
ScDPCollection* pDPCollection = m_pDocument->GetDPCollection();
ScDPObject* pDPObject = pDPCollection->GetByName(sPivotTableName);
if (pDPObject)
m_sPivotTableName = sPivotTableName;
}
uno::Reference<chart2::data::XDataSequence>
PivotTableDataProvider::createDataSequenceOfValuesByIndex(sal_Int32 nIndex)
{
SolarMutexGuard aGuard;
if (m_bNeedsUpdate)
collectPivotTableData();
uno::Reference<chart2::data::XDataSequence> xDataSequence;
assignValuesToDataSequence(xDataSequence, size_t(nIndex));
return xDataSequence;
}
uno::Reference<css::chart2::data::XDataSequence>
PivotTableDataProvider::createDataSequenceOfLabelsByIndex(sal_Int32 nIndex)
{
SolarMutexGuard aGuard;
if (m_bNeedsUpdate)
collectPivotTableData();
uno::Reference<chart2::data::XDataSequence> xDataSequence;
assignLabelsToDataSequence(xDataSequence, size_t(nIndex));
return xDataSequence;
}
uno::Reference<css::chart2::data::XDataSequence>
PivotTableDataProvider::createDataSequenceOfCategories()
{
SolarMutexGuard aGuard;
if (m_bNeedsUpdate)
collectPivotTableData();
uno::Reference<chart2::data::XDataSequence> xDataSequence;
if (m_aCategoriesColumnOrientation.empty())
return xDataSequence;
std::vector<ValueAndFormat> const & rCategories = m_aCategoriesColumnOrientation[0];
std::unique_ptr<PivotTableDataSequence> pSequence(new PivotTableDataSequence(m_pDocument, m_sPivotTableName,
"Categories", rCategories));
pSequence->setRole("categories");
xDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release()));
return xDataSequence;
}
// XModifyBroadcaster ========================================================
void SAL_CALL PivotTableDataProvider::addModifyListener(const uno::Reference< util::XModifyListener>& aListener)
{
SolarMutexGuard aGuard;
m_aValueListeners.push_back(uno::Reference<util::XModifyListener>(aListener));
}
void SAL_CALL PivotTableDataProvider::removeModifyListener(const uno::Reference<util::XModifyListener>& aListener )
{
SolarMutexGuard aGuard;
sal_uInt16 nCount = m_aValueListeners.size();
for (sal_uInt16 n = nCount; n--;)
{
uno::Reference<util::XModifyListener>& rObject = m_aValueListeners[n];
if (rObject == aListener)
{
m_aValueListeners.erase(m_aValueListeners.begin() + n);
}
}
}
// DataProvider XPropertySet -------------------------------------------------
uno::Reference< beans::XPropertySetInfo> SAL_CALL
PivotTableDataProvider::getPropertySetInfo()
{
SolarMutexGuard aGuard;
static uno::Reference<beans::XPropertySetInfo> aRef =
new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
return aRef;
}
void SAL_CALL PivotTableDataProvider::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
{
if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
{
if (!(rValue >>= m_bIncludeHiddenCells))
throw lang::IllegalArgumentException();
}
else
throw beans::UnknownPropertyException();
}
uno::Any SAL_CALL PivotTableDataProvider::getPropertyValue(const OUString& rPropertyName)
{
uno::Any aRet;
if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
aRet <<= m_bIncludeHiddenCells;
else if (rPropertyName == SC_UNONAME_USE_INTERNAL_DATA_PROVIDER)
{
// This is a read-only property.
aRet <<= m_pDocument->PastingDrawFromOtherDoc();
}
else
throw beans::UnknownPropertyException();
return aRet;
}
void SAL_CALL PivotTableDataProvider::addPropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataProvider::removePropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference<beans::XPropertyChangeListener>& /*rListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataProvider::addVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference<beans::XVetoableChangeListener>& /*rListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataProvider::removeVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference<beans::XVetoableChangeListener>& /*rListener*/ )
{
OSL_FAIL("Not yet implemented");
}
} // end sc namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataSequence.cxx b/sc/source/ui/unoobj/PivotTableDataSequence.cxx
new file mode 100644
index 0000000..da8bb26
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataSequence.cxx
@@ -0,0 +1,278 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "PivotTableDataSequence.hxx"
#include <sal/config.h>
#include "miscuno.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "hints.hxx"
#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
using namespace css;
namespace sc
{
SC_SIMPLE_SERVICE_INFO( PivotTableDataSequence, "PivotTableDataSequence", "com.sun.star.chart2.data.DataSequence")
const SfxItemPropertyMapEntry* lcl_GetDataSequencePropertyMap()
{
static const SfxItemPropertyMapEntry aDataSequencePropertyMap_Impl[] =
{
{ OUString(SC_UNONAME_HIDDENVALUES), 0, cppu::UnoType<uno::Sequence<sal_Int32>>::get(), 0, 0 },
{ OUString(SC_UNONAME_ROLE), 0, cppu::UnoType<css::chart2::data::DataSequenceRole>::get(), 0, 0 },
{ OUString(SC_UNONAME_INCLUDEHIDDENCELLS), 0, cppu::UnoType<bool>::get(), 0, 0 },
{ OUString(), 0, css::uno::Type(), 0, 0 }
};
return aDataSequencePropertyMap_Impl;
}
PivotTableDataSequence::PivotTableDataSequence(ScDocument* pDocument, OUString const & sPivotTableName, OUString const & sID,
std::vector<ValueAndFormat> const & rData)
: m_pDocument(pDocument)
, m_sPivotTableName(sPivotTableName)
, m_aID(sID)
, m_aData(rData)
, m_aPropSet(lcl_GetDataSequencePropertyMap())
{
if (m_pDocument)
m_pDocument->AddUnoObject(*this);
}
PivotTableDataSequence::~PivotTableDataSequence()
{
SolarMutexGuard g;
if (m_pDocument)
m_pDocument->RemoveUnoObject(*this);
}
void PivotTableDataSequence::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::Dying)
{
m_pDocument = nullptr;
}
}
uno::Sequence<uno::Any> SAL_CALL PivotTableDataSequence::getData()
{
SolarMutexGuard aGuard;
if (!m_pDocument)
throw uno::RuntimeException();
uno::Sequence<uno::Any> aSeq(m_aData.size());
size_t i = 0;
for (ValueAndFormat const & rItem : m_aData)
{
if (rItem.m_bIsValue)
aSeq[i] <<= double(rItem.m_fValue);
else
aSeq[i] <<= OUString(rItem.m_aString);
i++;
}
return aSeq;
}
// XNumericalDataSequence --------------------------------------------------
uno::Sequence<double> SAL_CALL PivotTableDataSequence::getNumericalData()
{
SolarMutexGuard aGuard;
if (!m_pDocument)
throw uno::RuntimeException();
uno::Sequence<double> aSeq(m_aData.size());
size_t i = 0;
for (ValueAndFormat const & rItem : m_aData)
{
aSeq[i] = rItem.m_fValue;
i++;
}
return aSeq;
}
// XTextualDataSequence --------------------------------------------------
uno::Sequence<OUString> SAL_CALL PivotTableDataSequence::getTextualData()
{
SolarMutexGuard aGuard;
if (!m_pDocument)
throw uno::RuntimeException();
uno::Sequence<OUString> aSeq(m_aData.size());
size_t i = 0;
for (ValueAndFormat const & rItem : m_aData)
{
if (!rItem.m_bIsValue)
aSeq[i] = rItem.m_aString;
i++;
}
return aSeq;
}
OUString SAL_CALL PivotTableDataSequence::getSourceRangeRepresentation()
{
SolarMutexGuard aGuard;
return m_aID;
}
uno::Sequence<OUString> SAL_CALL PivotTableDataSequence::generateLabel(chart2::data::LabelOrigin /*eOrigin*/)
{
SolarMutexGuard aGuard;
if (!m_pDocument)
throw uno::RuntimeException();
uno::Sequence<OUString> aSeq;
return aSeq;
}
sal_Int32 SAL_CALL PivotTableDataSequence::getNumberFormatKeyByIndex(sal_Int32 nIndex)
{
SolarMutexGuard aGuard;
if (nIndex == -1 && !m_aData.empty())
{
return m_aData[0].m_nNumberFormat;
}
else if (nIndex < 0 && size_t(nIndex) >= m_aData.size())
{
SAL_WARN("sc.ui", "Passed invalid index to getNumberFormatKeyByIndex(). Will return default value '0'.");
return 0;
}
return m_aData[size_t(nIndex)].m_nNumberFormat;
}
// XCloneable ================================================================
uno::Reference<util::XCloneable> SAL_CALL PivotTableDataSequence::createClone()
{
SolarMutexGuard aGuard;
std::unique_ptr<PivotTableDataSequence> pClone;
pClone.reset(new PivotTableDataSequence(m_pDocument, m_sPivotTableName, m_aID, m_aData));
pClone->setRole(m_aRole);
uno::Reference<util::XCloneable> xClone(pClone.release());
return xClone;
}
// XModifyBroadcaster ========================================================
void SAL_CALL PivotTableDataSequence::addModifyListener(const uno::Reference<util::XModifyListener>& aListener)
{
SolarMutexGuard aGuard;
m_aValueListeners.push_back(uno::Reference<util::XModifyListener>(aListener));
}
void SAL_CALL PivotTableDataSequence::removeModifyListener(const uno::Reference<util::XModifyListener>& aListener)
{
SolarMutexGuard aGuard;
sal_uInt16 nCount = m_aValueListeners.size();
for (sal_uInt16 n = nCount; n--; )
{
uno::Reference<util::XModifyListener>& rObj = m_aValueListeners[n];
if (rObj == aListener)
{
m_aValueListeners.erase(m_aValueListeners.begin() + n);
}
}
}
// DataSequence XPropertySet -------------------------------------------------
uno::Reference< beans::XPropertySetInfo> SAL_CALL PivotTableDataSequence::getPropertySetInfo()
{
SolarMutexGuard aGuard;
static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo(m_aPropSet.getPropertyMap());
return aRef;
}
void SAL_CALL PivotTableDataSequence::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
{
if (rPropertyName == SC_UNONAME_ROLE)
{
if (!(rValue >>= m_aRole))
throw lang::IllegalArgumentException();
}
else if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS
|| rPropertyName == SC_UNONAME_HIDDENVALUES
|| rPropertyName == SC_UNONAME_TIME_BASED
|| rPropertyName == SC_UNONAME_HAS_STRING_LABEL)
{}
else
throw beans::UnknownPropertyException();
}
uno::Any SAL_CALL PivotTableDataSequence::getPropertyValue(const OUString& rPropertyName)
{
uno::Any aReturn;
if (rPropertyName == SC_UNONAME_ROLE)
aReturn <<= m_aRole;
else if (rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS)
aReturn <<= false;
else if (rPropertyName == SC_UNONAME_HIDDENVALUES)
{
css::uno::Sequence<sal_Int32> aHiddenValues;
aReturn <<= aHiddenValues;
}
else if (rPropertyName == SC_UNONAME_TIME_BASED)
{
aReturn <<= false;
}
else if (rPropertyName == SC_UNONAME_HAS_STRING_LABEL)
{
aReturn <<= false;
}
else
throw beans::UnknownPropertyException();
return aReturn;
}
void SAL_CALL PivotTableDataSequence::addPropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataSequence::removePropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataSequence::addVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
{
OSL_FAIL("Not yet implemented");
}
void SAL_CALL PivotTableDataSequence::removeVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
{
OSL_FAIL("Not yet implemented");
}
} // end sc namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/PivotTableDataSource.cxx b/sc/source/ui/unoobj/PivotTableDataSource.cxx
new file mode 100644
index 0000000..752f8a4
--- /dev/null
+++ b/sc/source/ui/unoobj/PivotTableDataSource.cxx
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "PivotTableDataSource.hxx"
#include <sal/config.h>
#include "miscuno.hxx"
#include "docsh.hxx"
#include <comphelper/sequence.hxx>
using namespace css;
namespace sc
{
SC_SIMPLE_SERVICE_INFO(PivotTableDataSource, "PivotTableDataSource", "com.sun.star.chart2.data.DataSource")
PivotTableDataSource::PivotTableDataSource(OUString const & aRangeRepresentation,
std::vector<css::uno::Reference<css::chart2::data::XLabeledDataSequence>>& xLabeledSequence)
: m_xLabeledSequence(xLabeledSequence)
, m_aRangeRepresentation(aRangeRepresentation)
{
}
PivotTableDataSource::~PivotTableDataSource()
{
}
void PivotTableDataSource::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& /*rHint*/)
{
}
uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence>> SAL_CALL
PivotTableDataSource::getDataSequences()
{
SolarMutexGuard aGuard;
return comphelper::containerToSequence(m_xLabeledSequence);
}
} // end sc namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/TablePivotChart.cxx b/sc/source/ui/unoobj/TablePivotChart.cxx
new file mode 100644
index 0000000..64d2d87
--- /dev/null
+++ b/sc/source/ui/unoobj/TablePivotChart.cxx
@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <svx/charthelper.hxx>
#include <svtools/embedhlp.hxx>
#include "miscuno.hxx"
#include "docsh.hxx"
#include "TablePivotChart.hxx"
#include "ChartTools.hxx"
using namespace css;
namespace sc
{
SC_SIMPLE_SERVICE_INFO(TablePivotChart, "TablePivotChart", "com.sun.star.table.TablePivotChart")
TablePivotChart::TablePivotChart(ScDocShell* pDocShell, SCTAB nTab, const OUString& rName)
: TablePivotChart_Base(m_aMutex)
, m_pDocShell(pDocShell)
, m_nTab(nTab)
, m_aChartName(rName)
{
if (m_pDocShell)
m_pDocShell->GetDocument().AddUnoObject(*this);
}
TablePivotChart::~TablePivotChart()
{
SolarMutexGuard aGuard;
if (m_pDocShell)
m_pDocShell->GetDocument().RemoveUnoObject(*this);
}
void TablePivotChart::Notify(SfxBroadcaster&, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::Dying)
m_pDocShell = nullptr;
}
// XEmbeddedObjectSupplier
uno::Reference<lang::XComponent> SAL_CALL TablePivotChart::getEmbeddedObject()
{
SolarMutexGuard aGuard;
SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, m_aChartName, sc::tools::ChartSourceType::PIVOT_TABLE);
if (pObject && svt::EmbeddedObjectRef::TryRunningState(pObject->GetObjRef()))
return uno::Reference<lang::XComponent>(pObject->GetObjRef()->getComponent(), uno::UNO_QUERY);
return nullptr;
}
// XNamed
OUString SAL_CALL TablePivotChart::getName()
{
SolarMutexGuard aGuard;
return m_aChartName;
}
void SAL_CALL TablePivotChart::setName(OUString const & /* aName */)
{
SolarMutexGuard aGuard;
throw uno::RuntimeException(); // name cannot be changed
}
// XTablePivotChart
OUString SAL_CALL TablePivotChart::getPivotTableName()
{
SolarMutexGuard aGuard;
OUString aPivotTableName;
SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, m_aChartName, sc::tools::ChartSourceType::PIVOT_TABLE);
uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
if (xObject.is())
{
uno::Reference<chart2::XChartDocument> xChartDoc(xObject->getComponent(), uno::UNO_QUERY);
if (xChartDoc.is())
{
uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xChartDoc->getDataProvider(), uno::UNO_QUERY);
if (xPivotTableDataProvider.is())
{
aPivotTableName = xPivotTableDataProvider->getPivotTableName();
}
}
}
return aPivotTableName;
}
} // end sc namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/TablePivotCharts.cxx b/sc/source/ui/unoobj/TablePivotCharts.cxx
new file mode 100644
index 0000000..e76a88b
--- /dev/null
+++ b/sc/source/ui/unoobj/TablePivotCharts.cxx
@@ -0,0 +1,279 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <tools/gen.hxx>
#include <svx/svditer.hxx>
#include <svx/svdoole2.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdundo.hxx>
#include <svx/charthelper.hxx>
#include <sfx2/app.hxx>
#include <unotools/moduleoptions.hxx>
#include <comphelper/classids.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/globname.hxx>
#include <svtools/embedhlp.hxx>
#include <comphelper/sequence.hxx>
#include "TablePivotChart.hxx"
#include "TablePivotCharts.hxx"
#include "PivotTableDataProvider.hxx"
#include "ChartTools.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
#include "drwlayer.hxx"
#include "undodat.hxx"
#include "convuno.hxx"
using namespace css;
namespace sc
{
SC_SIMPLE_SERVICE_INFO(TablePivotCharts, "TablePivotCharts", "com.sun.star.table.TablePivotCharts")
TablePivotCharts::TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab)
: m_pDocShell(pDocShell)
, m_nTab(nTab)
{
m_pDocShell->GetDocument().AddUnoObject(*this);
}
TablePivotCharts::~TablePivotCharts()
{
SolarMutexGuard aGuard;
if (m_pDocShell)
m_pDocShell->GetDocument().RemoveUnoObject(*this);
}
void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::Dying)
m_pDocShell = nullptr;
}
// XTablePivotCharts
void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName,
const awt::Rectangle& aRect,
OUString const & rDataPilotName)
{
SolarMutexGuard aGuard;
if (!m_pDocShell)
return;
ScDocument& rDoc = m_pDocShell->GetDocument();
ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer();
SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
if (!pPage)
return;
// chart can't be inserted if any ole object with that name exists on any table
// (empty string: generate valid name)
OUString aName = rName;
SCTAB nDummy;
if (!aName.isEmpty() && pModel->GetNamedObject(aName, OBJ_OLE2, nDummy))
{
// object exists - only RuntimeException is specified
throw uno::RuntimeException();
}
uno::Reference<embed::XEmbeddedObject> xObject;
if (SvtModuleOptions().IsChart())
xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName);
if (xObject.is())
{
Point aRectPos(aRect.X, aRect.Y);
bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab);
if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL))
aRectPos.X() = 0;
if (aRectPos.Y() < 0)
aRectPos.Y() = 0;
Size aRectSize(aRect.Width, aRect.Height);
if (aRectSize.Width() <= 0)
aRectSize.Width() = 5000; // default size
if (aRectSize.Height() <= 0)
aRectSize.Height() = 5000;
::tools::Rectangle aInsRect(aRectPos, aRectSize);
sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject->getMapUnit(nAspect)));
Size aSize(aInsRect.GetSize());
aSize = vcl::Window::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit));
awt::Size aAwtSize;
aAwtSize.Width = aSize.Width();
aAwtSize.Height = aSize.Height();
std::unique_ptr<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(&rDoc));
pPivotTableDataProvider->setPivotTableName(rDataPilotName);
uno::Reference<chart2::data::XDataProvider> xDataProvider(pPivotTableDataProvider.release());
uno::Reference<chart2::data::XDataReceiver> xReceiver;
uno::Reference<embed::XComponentSupplier> xCompSupp(xObject, uno::UNO_QUERY);
if (xCompSupp.is())
xReceiver.set(xCompSupp->getComponent(), uno::UNO_QUERY);
if (xReceiver.is())
{
xReceiver->attachDataProvider(xDataProvider);
uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
uno::Sequence<beans::PropertyValue> aArgs(3);
aArgs[0] = beans::PropertyValue("CellRangeRepresentation", -1, uno::makeAny(OUString(rDataPilotName)), beans::PropertyState_DIRECT_VALUE);
aArgs[1] = beans::PropertyValue("HasCategories", -1, uno::makeAny(true), beans::PropertyState_DIRECT_VALUE);
aArgs[2] = beans::PropertyValue("DataRowSource", -1, uno::makeAny(chart::ChartDataRowSource_COLUMNS), beans::PropertyState_DIRECT_VALUE);
xReceiver->setArguments(aArgs);
}
SdrOle2Obj* pObject = new SdrOle2Obj(svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT),
aName, aInsRect);
if (xObject.is())
xObject->setVisualAreaSize(nAspect, aAwtSize);
pPage->InsertObject(pObject);
pModel->AddUndo(new SdrUndoInsertObj(*pObject));
}
}
void SAL_CALL TablePivotCharts::removeByName(const OUString& rName)
{
SolarMutexGuard aGuard;
SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE);
if (pObject)
{
ScDocument& rDoc = m_pDocShell->GetDocument();
ScDrawLayer* pModel = rDoc.GetDrawLayer();
SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
pModel->AddUndo(new SdrUndoDelObj(*pObject));
pPage->RemoveObject(pObject->GetOrdNum());
}
}
// XIndexAccess
sal_Int32 SAL_CALL TablePivotCharts::getCount()
{
SolarMutexGuard aGuard;
sal_Int32 nCount = 0;
if (!m_pDocShell)
return nCount;
sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
SdrOle2Obj* pOleObject = aIterator.next();
while (pOleObject)
{
if (pOleObject->GetObjRef().is())
nCount++;
pOleObject = aIterator.next();
}
return nCount;
}
uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex)
{
SolarMutexGuard aGuard;
SdrOle2Obj* pObject = sc::tools::getChartByIndex(m_pDocShell, m_nTab, nIndex,
sc::tools::ChartSourceType::PIVOT_TABLE);
if (!pObject)
throw lang::IndexOutOfBoundsException();
OUString aName;
uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
if (xObject.is())
aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
if (aName.isEmpty())
throw lang::IndexOutOfBoundsException();
uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName));
if (xChart.is())
return uno::makeAny(xChart);
else
throw lang::IndexOutOfBoundsException();
}
uno::Type SAL_CALL TablePivotCharts::getElementType()
{
SolarMutexGuard aGuard;
return cppu::UnoType<table::XTablePivotChart>::get();
}
sal_Bool SAL_CALL TablePivotCharts::hasElements()
{
SolarMutexGuard aGuard;
return getCount() != 0;
}
uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName)
{
SolarMutexGuard aGuard;
if (!sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE))
throw container::NoSuchElementException();
uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName));
if (xChart.is())
return uno::makeAny(xChart);
else
throw container::NoSuchElementException();
}
uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames()
{
SolarMutexGuard aGuard;
std::vector<OUString> aElements;
sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
SdrOle2Obj* pOleObject = aIterator.next();
while (pOleObject)
{
uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
if (xObject.is())
{
OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
aElements.push_back(aName);
}
pOleObject = aIterator.next();
}
return comphelper::containerToSequence(aElements);
}
sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName)
{
SolarMutexGuard aGuard;
return sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE) != nullptr;
}
} // end sc namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 0c597a8..6a4f610 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -130,6 +130,7 @@
#include "dputil.hxx"
#include <sortparam.hxx>
#include "condformatuno.hxx"
#include "TablePivotCharts.hxx"
#include <list>
#include <memory>
@@ -6726,6 +6727,7 @@ uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType )
SC_QUERYINTERFACE( sheet::XSheetLinkable )
SC_QUERYINTERFACE( sheet::XExternalSheetName )
SC_QUERYINTERFACE( document::XEventsSupplier )
SC_QUERYINTERFACE( table::XTablePivotChartsSupplier )
return ScCellRangeObj::queryInterface( rType );
}
@@ -6749,7 +6751,8 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes()
long nParentLen = aParentTypes.getLength();
const uno::Type* pParentPtr = aParentTypes.getConstArray();
aTypes.realloc( nParentLen + 18 );
aTypes.realloc(nParentLen + 19);
uno::Type* pPtr = aTypes.getArray();
pPtr[nParentLen + 0] = cppu::UnoType<sheet::XSpreadsheet>::get();
pPtr[nParentLen + 1] = cppu::UnoType<container::XNamed>::get();
@@ -6769,6 +6772,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes()
pPtr[nParentLen +15] = cppu::UnoType<sheet::XSheetLinkable>::get();
pPtr[nParentLen +16] = cppu::UnoType<sheet::XExternalSheetName>::get();
pPtr[nParentLen +17] = cppu::UnoType<document::XEventsSupplier>::get();
pPtr[nParentLen +18] = cppu::UnoType<table::XTablePivotChartsSupplier>::get();
for (long i=0; i<nParentLen; i++)
pPtr[i] = pParentPtr[i]; // parent types first
@@ -6808,6 +6812,17 @@ uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts()
return nullptr;
}
uno::Reference<table::XTablePivotCharts> SAL_CALL ScTableSheetObj::getPivotCharts()
{
SolarMutexGuard aGuard;
ScDocShell* pDocSh = GetDocShell();
if (pDocSh)
return new sc::TablePivotCharts(pDocSh, GetTab_Impl());
OSL_FAIL("no Document");
return nullptr;
}
uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables()
{
SolarMutexGuard aGuard;
diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx
index 7815270..20c3f9e 100644
--- a/sc/source/ui/unoobj/chartuno.cxx
+++ b/sc/source/ui/unoobj/chartuno.cxx
@@ -38,6 +38,7 @@
#include <svx/charthelper.hxx>
#include <svtools/embedhlp.hxx>
#include "ChartTools.hxx"
#include "chartuno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
@@ -48,47 +49,13 @@
#include "chart2uno.hxx"
#include "convuno.hxx"
using namespace com::sun::star;
using namespace css;
#define PROP_HANDLE_RELATED_CELLRANGES 1
SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" )
SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" )
static SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
{
if (pDocShell)
{
ScDocument& rDoc = pDocShell->GetDocument();
ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
if (pDrawLayer)
{
SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
OSL_ENSURE(pPage, "Page nicht gefunden");
if (pPage)
{
SdrObjListIter aIter( *pPage, SdrIterMode::DeepNoGroups );
SdrObject* pObject = aIter.Next();
while (pObject)
{
if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
{
uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
if ( xObj.is() )
{
OUString aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
if ( aObjName == rName )
return static_cast<SdrOle2Obj*>(pObject);
}
}
pObject = aIter.Next();
}
}
}
}
return nullptr;
}
ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
pDocShell( pDocSh ),
nTab( nT )
@@ -156,7 +123,7 @@ ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const
ScChartObj* ScChartsObj::GetObjectByName_Impl(const OUString& aName) const
{
if ( lcl_FindChartObj( pDocShell, nTab, aName ) )
if (sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE))
return new ScChartObj( pDocShell, nTab, aName );
return nullptr;
}
@@ -297,7 +264,7 @@ void SAL_CALL ScChartsObj::addNewByName( const OUString& rName,
void SAL_CALL ScChartsObj::removeByName( const OUString& aName )
{
SolarMutexGuard aGuard;
SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aName );
SdrOle2Obj* pObj = sc::tools::findChartsByName(pDocShell, nTab, aName, sc::tools::ChartSourceType::CELL_RANGE);
if (pObj)
{
ScDocument& rDoc = pDocShell->GetDocument();
@@ -429,7 +396,9 @@ uno::Sequence<OUString> SAL_CALL ScChartsObj::getElementNames()
sal_Bool SAL_CALL ScChartsObj::hasByName( const OUString& aName )
{
SolarMutexGuard aGuard;
return ( lcl_FindChartObj( pDocShell, nTab, aName ) != nullptr );
SdrOle2Obj* aOle2Obj = sc::tools::findChartsByName(pDocShell, nTab, aName,
sc::tools::ChartSourceType::CELL_RANGE);
return aOle2Obj != nullptr;
}
ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN)
@@ -742,7 +711,8 @@ void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress
uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject()
{
SolarMutexGuard aGuard;
SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName );
SdrOle2Obj* pObject = sc::tools::findChartsByName(pDocShell, nTab, aChartName,
sc::tools::ChartSourceType::CELL_RANGE);
if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) )
{
//TODO/LATER: is it OK that something is returned for *all* objects, not only own objects?
diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx
index 6b2fac6..04fb81f 100644
--- a/sc/source/ui/unoobj/servuno.cxx
+++ b/sc/source/ui/unoobj/servuno.cxx
@@ -44,6 +44,7 @@
#include "addruno.hxx"
#include "chart2uno.hxx"
#include "tokenuno.hxx"
#include "PivotTableDataProvider.hxx"
// Support creation of GraphicObjectResolver and EmbeddedObjectResolver
#include <svx/xmleohlp.hxx>
@@ -292,6 +293,7 @@ const ProvNamesId_Type aProvNamesId[] =
{ "com.sun.star.sheet.DocumentSettings",Type::SHEETDOCSET },
{ SC_SERVICENAME_CHDATAPROV, Type::CHDATAPROV },
{ SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER, Type::CHART_PIVOTTABLE_DATAPROVIDER },
{ SC_SERVICENAME_FORMULAPARS, Type::FORMULAPARS },
{ SC_SERVICENAME_OPCODEMAPPER, Type::OPCODEMAPPER },
{ "ooo.vba.VBAObjectModuleObjectProvider", Type::VBAOBJECTPROVIDER },
@@ -388,6 +390,7 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
Type nType, ScDocShell* pDocShell )
{
uno::Reference<uno::XInterface> xRet;
switch (nType)
{
case Type::SHEET:
@@ -523,6 +526,10 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
if (pDocShell)
xRet = *new ScChart2DataProvider( &pDocShell->GetDocument() );
break;
case Type::CHART_PIVOTTABLE_DATAPROVIDER:
if (pDocShell)
xRet = *new sc::PivotTableDataProvider(&pDocShell->GetDocument());
break;
case Type::FORMULAPARS:
if (pDocShell)
xRet.set(static_cast<sheet::XFormulaParser*>(new ScFormulaParserObj( pDocShell )));
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 84c5665..7120412 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -2469,27 +2469,23 @@ void ScTabView::DoChartSelection(
}
}
void ScTabView::DoDPFieldPopup(Point aPoint, Size /*aSize*/)
void ScTabView::DoDPFieldPopup(OUString const & rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize)
{
ScDocument& rDocument = aViewData.GetDocShell()->GetDocument();
ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
if (!pWin)
return;
ScDPCollection* pDPs = rDocument.GetDPCollection();
// TODO - DP name should be a parameter
ScDPObject* pDPObj = pDPs->GetByName("DataPilot1");
ScDPCollection* pDPCollection = rDocument.GetDPCollection();
ScDPObject* pDPObject = pDPCollection->GetByName(rPivotTableName);
pDPObj->BuildAllDimensionMembers();
//const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
//bool bIsDataLayout;
//OUString aDimName = pDPObj->GetDimName(0, bIsDataLayout);
pDPObject->BuildAllDimensionMembers();
Point aScreenPoint = pWin->OutputToScreenPixel(pWin->LogicToPixel(aPoint));
//Size aScreenSize = pWin->LogicToPixel(aSize);
Size aScreenSize = pWin->LogicToPixel(aSize);
pWin->DPLaunchFieldPopupMenu(aScreenPoint, Size(1, 1), 1, pDPObj);
pWin->DPLaunchFieldPopupMenu(aScreenPoint, aScreenSize, nDimensionIndex, pDPObject);
}
// PaintGrid - repaint data range
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
index 3dced27..52990c0 100644
--- a/sc/source/ui/view/tabvwshb.cxx
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -19,6 +19,8 @@
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/awt/XRequestCallback.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
@@ -111,10 +113,32 @@ public:
{}
// XCallback
virtual void SAL_CALL notify(const css::uno::Any& /*aData*/) override
virtual void SAL_CALL notify(const css::uno::Any& aData) override
{
tools::Rectangle aRect = m_pObject->GetLogicRect();
m_pViewShell->DoDPFieldPopup(aRect.TopLeft(), aRect.GetSize());
uno::Sequence<beans::PropertyValue> aProperties;
if (aData >>= aProperties)
{
awt::Rectangle xRectangle;
sal_Int32 dimensionIndex = 0;
OUString sPivotTableName("DataPilot1");
for (beans::PropertyValue const & rProperty : aProperties)
{
if (rProperty.Name == "Rectangle")
rProperty.Value >>= xRectangle;
if (rProperty.Name == "DimensionIndex")
rProperty.Value >>= dimensionIndex;
if (rProperty.Name == "PivotTableName")
rProperty.Value >>= sPivotTableName;
}
tools::Rectangle aChartRect = m_pObject->GetLogicRect();
Point aPoint(xRectangle.X + aChartRect.Left(), xRectangle.Y + aChartRect.Top());
Size aSize(xRectangle.Width, xRectangle.Height);
m_pViewShell->DoDPFieldPopup(sPivotTableName, dimensionIndex, aPoint, aSize);
}
}
};
@@ -209,7 +233,7 @@ void ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
new ScChartRangeSelectionListener( this ));
xRangeHightlighter->addSelectionChangeListener( xListener );
}
uno::Reference<chart2::data::XPopupRequest> xPopupRequest(xDataReceiver->getPopupRequest());
uno::Reference<awt::XRequestCallback> xPopupRequest(xDataReceiver->getPopupRequest());
if (xPopupRequest.is())
{
uno::Reference<awt::XCallback> xCallback(new PopupCallback(this, pObj));
diff --git a/xmloff/inc/SchXMLImport.hxx b/xmloff/inc/SchXMLImport.hxx
index 233ecde..a1c3f69 100644
--- a/xmloff/inc/SchXMLImport.hxx
+++ b/xmloff/inc/SchXMLImport.hxx
@@ -97,7 +97,8 @@ enum SchXMLChartAttrMap
XML_TOK_CHART_HEIGHT,
XML_TOK_CHART_STYLE_NAME,
XML_TOK_CHART_COL_MAPPING,
XML_TOK_CHART_ROW_MAPPING
XML_TOK_CHART_ROW_MAPPING,
XML_TOK_CHART_DATA_PILOT_SOURCE,
};
enum SchXMLPlotAreaAttrTokenMap
diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx
index 4ce3680..1dc1c14 100644
--- a/xmloff/source/chart/SchXMLChartContext.cxx
+++ b/xmloff/source/chart/SchXMLChartContext.cxx
@@ -52,11 +52,15 @@
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
using namespace com::sun::star;
using namespace ::xmloff::token;
using com::sun::star::uno::Reference;
@@ -237,10 +241,67 @@ SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper,
SchXMLChartContext::~SchXMLChartContext()
{}
void lcl_setDataProvider(uno::Reference<chart2::XChartDocument> const & xChartDoc, OUString const & sDataPilotSource)
{
if (!xChartDoc.is())
return;
try
{
uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY);
uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY);
if (xChild.is() && xDataReceiver.is())
{
bool bHasOwnData = true;
Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY);
if (xFact.is())
{
if (!xChartDoc->getDataProvider().is())
{
bool bHasDataPilotSource = !sDataPilotSource.isEmpty();
OUString aDataProviderServiceName("com.sun.star.chart2.data.DataProvider");
if (bHasDataPilotSource)
aDataProviderServiceName = "com.sun.star.chart2.data.PivotTableDataProvider";
const uno::Sequence<OUString> aServiceNames(xFact->getAvailableServiceNames());
if (std::find(aServiceNames.begin(), aServiceNames.end(), aDataProviderServiceName) != aServiceNames.end())
{
Reference<chart2::data::XDataProvider> xProvider(xFact->createInstance(aDataProviderServiceName), uno::UNO_QUERY);
if (xProvider.is())
{
xDataReceiver->attachDataProvider(xProvider);
if (bHasDataPilotSource)
{
Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xProvider, uno::UNO_QUERY);
xPivotTableDataProvider->setPivotTableName(sDataPilotSource);
}
bHasOwnData = false;
}
}
}
else
bHasOwnData = false;
}
// else we have no parent => we have our own data
if (bHasOwnData && ! xChartDoc->hasInternalDataProvider())
xChartDoc->createInternalDataProvider(false);
}
}
catch (const uno::Exception & rEx)
{
OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr);
}
}
void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
// parse attributes
sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetChartAttrTokenMap();
uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY);
@@ -264,10 +325,12 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut
switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
{
case XML_TOK_CHART_DATA_PILOT_SOURCE:
msDataPilotSource = aValue;
break;
case XML_TOK_CHART_HREF:
m_aXLinkHRefAttributeToIndicateDataProvider = aValue;
break;
case XML_TOK_CHART_CLASS:
{
OUString sClassName;
@@ -328,6 +391,11 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut
}
}
uno::Reference<chart::XChartDocument> xDoc = mrImportHelper.GetChartDocument();
uno::Reference<chart2::XChartDocument> xNewDoc(xDoc, uno::UNO_QUERY);
lcl_setDataProvider(xNewDoc, msDataPilotSource);
if( aOldChartTypeName.isEmpty() )
{
SAL_WARN("xmloff.chart", "need a charttype to create a diagram" );
diff --git a/xmloff/source/chart/SchXMLChartContext.hxx b/xmloff/source/chart/SchXMLChartContext.hxx
index 649c9b6..11b6998 100644
--- a/xmloff/source/chart/SchXMLChartContext.hxx
+++ b/xmloff/source/chart/SchXMLChartContext.hxx
@@ -104,6 +104,8 @@ private:
OUString msCategoriesAddress;
OUString msChartAddress;
OUString msDataPilotSource;
SeriesDefaultsAndStyles maSeriesDefaultsAndStyles;
tSchXMLLSequencesPerIndex maLSequencesPerIndex;
diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx
index 9b8c205..de3e32c 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -90,6 +90,7 @@
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
@@ -1213,6 +1214,13 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >
mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
}
Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xNewDoc->getDataProvider(), uno::UNO_QUERY);
if (xPivotTableDataProvider.is())
{
OUString sPivotTableName = xPivotTableDataProvider->getPivotTableName();
mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, sPivotTableName);
}
OUString sChartType( xDiagram->getDiagramType() );
// attributes
diff --git a/xmloff/source/chart/SchXMLImport.cxx b/xmloff/source/chart/SchXMLImport.cxx
index 5d33fc6..10d8fc1 100644
--- a/xmloff/source/chart/SchXMLImport.cxx
+++ b/xmloff/source/chart/SchXMLImport.cxx
@@ -249,6 +249,7 @@ const SvXMLTokenMap& SchXMLImportHelper::GetChartAttrTokenMap()
{ XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_CHART_STYLE_NAME },
{ XML_NAMESPACE_CHART, XML_COLUMN_MAPPING, XML_TOK_CHART_COL_MAPPING },
{ XML_NAMESPACE_CHART, XML_ROW_MAPPING, XML_TOK_CHART_ROW_MAPPING },
{ XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, XML_TOK_CHART_DATA_PILOT_SOURCE },
XML_TOKEN_MAP_END
};
@@ -574,65 +575,37 @@ SvXMLImportContext* SchXMLImport::CreateStylesContext(
return pStylesCtxt;
}
void SAL_CALL SchXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
void SAL_CALL SchXMLImport::setTargetDocument(const uno::Reference<lang::XComponent>& xDoc)
{
uno::Reference< chart2::XChartDocument > xOldDoc( GetModel(), uno::UNO_QUERY );
if( xOldDoc.is() && xOldDoc->hasControllersLocked() )
uno::Reference<chart2::XChartDocument> xOldDoc(GetModel(), uno::UNO_QUERY);
if (xOldDoc.is() && xOldDoc->hasControllersLocked())
xOldDoc->unlockControllers();
SvXMLImport::setTargetDocument( xDoc );
SvXMLImport::setTargetDocument(xDoc);
//set data provider and number formatter
// try to get an XDataProvider and set it
// @todo: if we have our own data, we must not use the parent as data provider
uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
uno::Reference<chart2::XChartDocument> xChartDoc(GetModel(), uno::UNO_QUERY);
if( xChartDoc.is() )
if (xChartDoc.is())
try
{
//prevent rebuild of view during load ( necesarry especially if loaded not via load api, which is the case for example if binary files are loaded )
// prevent rebuild of view during load (necesarry especially if loaded not
// via load api, which is the case for example if binary files are loaded)
xChartDoc->lockControllers();
uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
if( xChild.is() && xDataReceiver.is())
uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY);
uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY);
if (xChild.is() && xDataReceiver.is())
{
bool bHasOwnData = true;
Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
if( xFact.is() )
Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY);
if (xFact.is())
{
//if the parent has a number formatter we will use the numberformatter of the parent
Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xFact, uno::UNO_QUERY );
xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
if ( !xChartDoc->getDataProvider().is() )
{
const OUString aDataProviderServiceName( "com.sun.star.chart2.data.DataProvider");
const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames());
const OUString * pBegin = aServiceNames.getConstArray();
const OUString * pEnd = pBegin + aServiceNames.getLength();
if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
{
Reference< chart2::data::XDataProvider > xProvider(
xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
if( xProvider.is())
{
xDataReceiver->attachDataProvider( xProvider );
bHasOwnData = false;
}
}
}
else
bHasOwnData = false;
Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(xFact, uno::UNO_QUERY);
xDataReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
}
// else we have no parent => we have our own data
if( bHasOwnData && ! xChartDoc->hasInternalDataProvider() )
xChartDoc->createInternalDataProvider( false );
}
}
catch( const uno::Exception & rEx )
catch (const uno::Exception & rEx)
{
OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr);
diff --git a/xmloff/source/chart/SchXMLSeries2Context.cxx b/xmloff/source/chart/SchXMLSeries2Context.cxx
index 70eda52..82e3a7c 100644
--- a/xmloff/source/chart/SchXMLSeries2Context.cxx
+++ b/xmloff/source/chart/SchXMLSeries2Context.cxx
@@ -30,6 +30,7 @@
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart/ChartAxisAssign.hpp>
#include <com/sun/star/chart/ChartSymbolType.hpp>
@@ -407,20 +408,31 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib
uno::makeAny( true ));
}
// values
Reference< chart2::data::XDataSequence > xSeq;
if( bHasRange && !m_aSeriesRange.isEmpty() )
xSeq = SchXMLTools::CreateDataSequence( m_aSeriesRange, mxNewDoc );
Reference<chart2::data::XDataProvider> xDataProvider(mxNewDoc->getDataProvider());
Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
if( xSeqProp.is())
Reference<chart2::data::XDataSequence> xSequenceValues;
// values
if (xPivotTableDataProvider.is()) // is pivot chart
{
xSequenceValues.set(xPivotTableDataProvider->createDataSequenceOfValuesByIndex(mnSeriesIndex));
}
else
{
if (bHasRange && !m_aSeriesRange.isEmpty())
xSequenceValues = SchXMLTools::CreateDataSequence(m_aSeriesRange, mxNewDoc);
}
Reference<beans::XPropertySet> xSeqProp(xSequenceValues, uno::UNO_QUERY);
if (xSeqProp.is())
{
OUString aMainRole("values-y");
if ( maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType" )
if (maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType")
aMainRole = "values-size";
xSeqProp->setPropertyValue("Role", uno::makeAny( aMainRole ));
xSeqProp->setPropertyValue("Role", uno::makeAny(aMainRole));
}
xLabeledSeq->setValues( xSeq );
xLabeledSeq->setValues(xSequenceValues);
// register for setting local data if external data provider is not present
maPostponedSequences.insert(
@@ -428,18 +440,24 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib
tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_VALUES ), xLabeledSeq ));
// label
if( !aSeriesLabelRange.isEmpty() )
Reference<chart2::data::XDataSequence> xSequenceLabel;
if (xPivotTableDataProvider.is())
{
Reference< chart2::data::XDataSequence > xLabelSequence =
SchXMLTools::CreateDataSequence( aSeriesLabelRange, mxNewDoc );
xLabeledSeq->setLabel( xLabelSequence );
xSequenceLabel.set(xPivotTableDataProvider->createDataSequenceOfLabelsByIndex(mnSeriesIndex));
}
else if( !aSeriesLabelString.isEmpty() )
else
{
Reference< chart2::data::XDataSequence > xLabelSequence =
SchXMLTools::CreateDataSequenceWithoutConvert( aSeriesLabelString, mxNewDoc );
xLabeledSeq->setLabel( xLabelSequence );
if (!aSeriesLabelRange.isEmpty())
{
xSequenceLabel.set(SchXMLTools::CreateDataSequence(aSeriesLabelRange, mxNewDoc));
}
else if (!aSeriesLabelString.isEmpty())
{
xSequenceLabel.set(SchXMLTools::CreateDataSequenceWithoutConvert(aSeriesLabelString, mxNewDoc));
}
}
xLabeledSeq->setLabel(xSequenceLabel);
// Note: Even if we have no label, we have to register the label
// for creation, because internal data always has labels. If
diff --git a/xmloff/source/chart/SchXMLTools.cxx b/xmloff/source/chart/SchXMLTools.cxx
index 31c1ac1..f00ce12 100644
--- a/xmloff/source/chart/SchXMLTools.cxx
+++ b/xmloff/source/chart/SchXMLTools.cxx
@@ -36,6 +36,7 @@
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
@@ -488,11 +489,21 @@ void CreateCategories(
bRangeConverted = true;
}
}
Reference< chart2::data::XDataSequence > xSeq(
xDataProvider->createDataSequenceByRangeRepresentation( aConvertedRange ));
xLabeledSeq->setValues( xSeq );
if( bRangeConverted )
setXMLRangePropertyAtDataSequence( xSeq, rRangeAddress );
Reference<chart2::data::XDataSequence> xSequence;
Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
if (xPivotTableDataProvider.is())
{
xSequence.set(xPivotTableDataProvider->createDataSequenceOfCategories());
}
else
{
xSequence.set(xDataProvider->createDataSequenceByRangeRepresentation(aConvertedRange));
if (bRangeConverted)
setXMLRangePropertyAtDataSequence(xSequence, rRangeAddress);
}
xLabeledSeq->setValues(xSequence);
}
catch( const lang::IllegalArgumentException & ex )
{
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 5ee0ce8..166aa91 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -549,6 +549,7 @@ namespace xmloff { namespace token {
TOKEN( "data-label-number", XML_DATA_LABEL_NUMBER ),
TOKEN( "data-label-symbol", XML_DATA_LABEL_SYMBOL ),
TOKEN( "data-label-text", XML_DATA_LABEL_TEXT ),
TOKEN( "data-pilot-source", XML_DATA_PILOT_SOURCE ),
TOKEN( "data-pilot-field", XML_DATA_PILOT_FIELD ),
TOKEN( "data-pilot-grand-total", XML_DATA_PILOT_GRAND_TOTAL ),
TOKEN( "data-pilot-level", XML_DATA_PILOT_LEVEL ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index e8878d8..7038673 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -471,6 +471,7 @@ data-cell-range-address
data-label-number
data-label-symbol
data-label-text
data-pilot-source
data-pilot-field
data-pilot-grand-total
data-pilot-level
@@ -3050,4 +3051,4 @@ max-numerator-digits
zeros-numerator-digits
zeros-denominator-digits
integer-fraction-delimiter
TOKEN_END_DUMMY
\ No newline at end of file
TOKEN_END_DUMMY