19#include <document.hxx>
20#include <unonames.hxx>
34#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
35#include <com/sun/star/chart/ChartDataRowSource.hpp>
36#include <com/sun/star/frame/XModel.hpp>
38#include <com/sun/star/sheet/XDataPilotResults.hpp>
39#include <com/sun/star/sheet/DataResultFlags.hpp>
41#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
42#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
43#include <com/sun/star/sheet/XLevelsSupplier.hpp>
44#include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
45#include <com/sun/star/sheet/MemberResultFlags.hpp>
46#include <com/sun/star/sheet/XMembersSupplier.hpp>
48#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
49#include <com/sun/star/container/XNamed.hpp>
51#include <unordered_map>
59constexpr OUStringLiteral constIdCategories(u
"categories");
60constexpr OUStringLiteral constIdLabel(u
"label");
61constexpr OUStringLiteral constIdData(u
"data");
70 return aDataProviderPropertyMap_Impl;
73uno::Reference<frame::XModel> lcl_GetXModel(
const ScDocument * pDoc)
75 uno::Reference<frame::XModel>
xModel;
78 xModel.set(pObjSh->GetModel());
82OUString lcl_identifierForData(sal_Int32 index)
84 return "PT@" + constIdData +
" " + OUString::number(index);
87OUString lcl_identifierForLabel(sal_Int32 index)
89 return "PT@" + constIdLabel +
" " + OUString::number(index);
92OUString lcl_identifierForCategories()
94 return "PT@" + constIdCategories;
97std::vector<OUString> lcl_getVisiblePageMembers(
const uno::Reference<uno::XInterface> & xLevel)
99 std::vector<OUString> aResult;
103 uno::Reference<sheet::XMembersSupplier> xMembersSupplier(xLevel, uno::UNO_QUERY);
104 if (!xMembersSupplier.is())
107 uno::Reference<sheet::XMembersAccess> xMembersAccess = xMembersSupplier->getMembers();
108 if (!xMembersAccess.is())
111 const css::uno::Sequence<OUString> aMembersNames = xMembersAccess->getElementNames();
112 for (OUString
const & rMemberNames : aMembersNames)
114 uno::Reference<beans::XPropertySet> xProperties(xMembersAccess->getByName(rMemberNames), uno::UNO_QUERY);
115 if (!xProperties.is())
119 if (aCaption.isEmpty())
120 aCaption = rMemberNames;
125 aResult.push_back(aCaption);
139 , m_aPropSet(lcl_GetDataProviderPropertyMap())
140 , m_bIncludeHiddenCells(true)
141 , m_bNeedsUpdate(true)
142 , m_xContext(
comphelper::getProcessComponentContext())
144 rDoc.AddUnoObject(*
this);
157 if (rHint.
GetId() == SfxHintId::Dying)
168 for (uno::Reference<util::XModifyListener>
const & xListener :
m_aValueListeners)
170 css::chart::ChartDataChangeEvent
aEvent(getXWeak(),
171 css::chart::ChartDataChangeType_ALL,
173 xListener->modified(
aEvent);
193uno::Reference<chart2::data::XDataSource> SAL_CALL
199 throw uno::RuntimeException();
201 bool bOrientCol =
true;
202 OUString aRangeRepresentation;
204 for (beans::PropertyValue
const & rProperty :
aArguments)
206 if (rProperty.Name ==
"DataRowSource")
208 chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
209 if (!(rProperty.Value >>= eSource))
211 sal_Int32 nSource(0);
212 if (rProperty.Value >>= nSource)
213 eSource = chart::ChartDataRowSource(nSource);
215 bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
217 else if (rProperty.Name ==
"CellRangeRepresentation")
218 rProperty.Value >>= aRangeRepresentation;
221 uno::Reference<chart2::data::XDataSource> xResult;
223 if (aRangeRepresentation == lcl_identifierForCategories())
231uno::Reference<chart2::data::XLabeledDataSequence>
234 uno::Reference<chart2::data::XLabeledDataSequence> xResult;
237 xResult.set(chart2::data::LabeledDataSequence::create(
m_xContext), uno::UNO_QUERY_THROW);
241uno::Reference<chart2::data::XDataSource>
247 uno::Reference<chart2::data::XDataSource> xDataSource;
248 std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
253 for (std::vector<ValueAndFormat>
const & rCategories : rCategoriesVector)
257 lcl_identifierForCategories(), std::vector(rCategories)));
258 pSequence->setRole(
"categories");
259 xResult->setValues(uno::Reference<chart2::data::XDataSequence>(pSequence));
261 aLabeledSequences.push_back(xResult);
285 uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->
GetSource(), uno::UNO_QUERY);
286 if (!xDPResults.is())
288 const uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults();
290 std::unordered_set<size_t> aValidRowIndex;
292 size_t nRowIndex = 0;
293 for (uno::Sequence<sheet::DataResult>
const & xDataResults : xDataResultsSequence)
295 std::vector<ValueAndFormat> aRow;
296 bool bRowEmpty =
true;
298 for (sheet::DataResult
const & rDataResult : xDataResults)
300 if (rDataResult.Flags & css::sheet::DataResultFlags::SUBTOTAL)
302 if (rDataResult.Flags == 0 || rDataResult.Flags & css::sheet::DataResultFlags::HASDATA)
304 aRow.emplace_back(rDataResult.Flags ? rDataResult.Value
305 : std::numeric_limits<double>::quiet_NaN(), 0);
306 if (rDataResult.Flags != 0)
310 aValidRowIndex.insert(nRowIndex);
317 size_t nColumnIndex = 0;
329 uno::Reference<sheet::XDimensionsSupplier> xDimensionsSupplier(pDPObject->
GetSource());
330 uno::Reference<container::XIndexAccess> xDims =
new ScNameToIndexAccess(xDimensionsSupplier->getDimensions());
332 std::unordered_map<OUString, sal_Int32> aDataFieldNumberFormatMap;
333 std::vector<OUString> aDataFieldNamesVectors;
335 std::unordered_map<OUString, OUString> aDataFieldCaptionNames;
337 sheet::DataPilotFieldOrientation eDataFieldOrientation = sheet::DataPilotFieldOrientation_HIDDEN;
339 for (sal_Int32 nDim = 0; nDim < xDims->getCount(); nDim++)
341 uno::Reference<uno::XInterface> xDim(xDims->getByIndex(nDim), uno::UNO_QUERY);
342 uno::Reference<beans::XPropertySet> xDimProp(xDim, uno::UNO_QUERY);
343 uno::Reference<sheet::XHierarchiesSupplier> xDimSupp(xDim, uno::UNO_QUERY);
345 if (!xDimProp.is() || !xDimSupp.is())
348 sheet::DataPilotFieldOrientation eDimOrient =
350 sheet::DataPilotFieldOrientation_HIDDEN);
352 if (eDimOrient == sheet::DataPilotFieldOrientation_HIDDEN)
355 uno::Reference<container::XIndexAccess> xHierarchies =
new ScNameToIndexAccess(xDimSupp->getHierarchies());
357 if (nHierarchy >= xHierarchies->getCount())
360 uno::Reference<sheet::XLevelsSupplier> xLevelsSupplier(xHierarchies->getByIndex(nHierarchy),
363 if (!xLevelsSupplier.is())
366 uno::Reference<container::XIndexAccess> xLevels =
new ScNameToIndexAccess(xLevelsSupplier->getLevels());
368 for (
tools::Long nLevel = 0; nLevel < xLevels->getCount(); nLevel++)
370 uno::Reference<uno::XInterface> xLevel(xLevels->getByIndex(nLevel), uno::UNO_QUERY);
371 uno::Reference<container::XNamed> xLevelName(xLevel, uno::UNO_QUERY);
372 uno::Reference<sheet::XDataPilotMemberResults> xLevelResult(xLevel, uno::UNO_QUERY );
374 if (xLevelName.is() && xLevelResult.is())
383 case sheet::DataPilotFieldOrientation_COLUMN:
385 m_aColumnFields.emplace_back(xLevelName->getName(), nDim, nDimPos, bHasHiddenMember);
387 const uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
391 for (sheet::MemberResult
const & rMember : aSequence)
394 if (rMember.Flags & sheet::MemberResultFlags::SUBTOTAL ||
395 rMember.Flags & sheet::MemberResultFlags::GRANDTOTAL)
397 if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER ||
398 rMember.Flags & sheet::MemberResultFlags::CONTINUE)
400 if (!(rMember.Flags & sheet::MemberResultFlags::CONTINUE))
402 sCaption = rMember.Caption;
403 sName = rMember.Name;
416 aDataFieldNamesVectors.push_back(
sName);
417 eDataFieldOrientation = sheet::DataPilotFieldOrientation_COLUMN;
419 aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
427 case sheet::DataPilotFieldOrientation_ROW:
429 m_aRowFields.emplace_back(xLevelName->getName(), nDim, nDimPos, bHasHiddenMember);
431 const uno::Sequence<sheet::MemberResult> aSequence = xLevelResult->getResults();
434 size_t nEachIndex = 0;
435 std::unique_ptr<ValueAndFormat> pItem;
437 for (sheet::MemberResult
const & rMember : aSequence)
439 bool bFound = aValidRowIndex.find(nEachIndex) != aValidRowIndex.end();
443 bool bHasContinueFlag = rMember.Flags & sheet::MemberResultFlags::CONTINUE;
445 if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER || bHasContinueFlag)
447 if (!bHasContinueFlag)
455 assert(pItem &&
"bHasContinueFlag must be false on this or some preceding element");
471 aDataFieldNamesVectors.push_back(rMember.Name);
472 eDataFieldOrientation = sheet::DataPilotFieldOrientation_ROW;
475 aDataFieldCaptionNames[rMember.Name] = rMember.Caption;
487 case sheet::DataPilotFieldOrientation_PAGE:
489 m_aPageFields.emplace_back(xLevelName->getName(), nDim, nDimPos, bHasHiddenMember);
492 OUString aFieldOutputDescription;
493 if (bHasHiddenMember)
495 std::vector<OUString> aMembers = lcl_getVisiblePageMembers(xLevel);
497 if (aMembers.size() == 1)
498 aFieldOutputDescription = aMembers[0];
500 aFieldOutputDescription =
ScResId(SCSTR_MULTIPLE);
504 aFieldOutputDescription =
ScResId(SCSTR_ALL);
510 case sheet::DataPilotFieldOrientation_DATA:
512 aDataFieldNumberFormatMap[xLevelName->getName()] = nNumberFormat;
513 m_aDataFields.emplace_back(xLevelName->getName(), nDim, nDimPos, bHasHiddenMember);
525 for (chart2::data::PivotTableFieldEntry& rDataFields :
m_aDataFields)
527 rDataFields.Name = aDataFieldCaptionNames[rDataFields.Name];
531 if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_ROW)
538 OUString
sName = aDataFieldNamesVectors[
i];
539 sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[
sName];
540 rItem.m_nNumberFormat = nNumberFormat;
545 else if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_COLUMN)
550 OUString
sName = aDataFieldNamesVectors[
i];
551 sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[
sName];
554 rItem.m_nNumberFormat = nNumberFormat;
562 auto funcDimensionPositionSortCompare = [] (chart2::data::PivotTableFieldEntry
const & entry1,
563 chart2::data::PivotTableFieldEntry
const & entry2)
565 return entry1.DimensionPositionIndex < entry2.DimensionPositionIndex;
577uno::Reference<chart2::data::XDataSequence>
580 uno::Reference<chart2::data::XDataSequence> xDataSequence;
582 return xDataSequence;
584 OUString sDataID = lcl_identifierForData(
nIndex);
588 pSequence->setRole(
"values-y");
589 xDataSequence = pSequence;
590 return xDataSequence;
593uno::Reference<chart2::data::XDataSequence>
596 uno::Reference<chart2::data::XDataSequence> xDataSequence;
598 OUString sLabelID = lcl_identifierForLabel(
nIndex);
613 aLabel.append(rItem.m_aString);
618 aLabel.append(
" - " + rItem.m_aString);
626 sLabelID, std::move(aLabelVector)));
627 pSequence->setRole(
"values-y");
628 xDataSequence = pSequence;
629 return xDataSequence;
632css::uno::Reference<css::chart2::data::XDataSequence>
635 uno::Reference<chart2::data::XDataSequence> xDataSequence;
638 return xDataSequence;
643 lcl_identifierForCategories(), std::vector(rCategories)));
644 pSequence->setRole(
"categories");
645 xDataSequence = pSequence;
647 return xDataSequence;
650uno::Reference<chart2::data::XDataSource>
656 uno::Reference<chart2::data::XDataSource> xDataSource;
657 std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences;
663 aLabeledSequences.push_back(xResult);
673 aLabeledSequences.push_back(xResult);
683 const uno::Reference<chart2::data::XDataSource> & xDataSource)
686 return uno::Sequence<beans::PropertyValue>();
689 {
"CellRangeRepresentation",
uno::Any(OUString(
"PivotChart")) },
690 {
"DataRowSource",
uno::Any(chart::ChartDataRowSource_COLUMNS) },
691 {
"FirstCellAsLabel",
uno::Any(
false) },
701uno::Reference<chart2::data::XDataSequence> SAL_CALL
704 uno::Reference<chart2::data::XDataSequence> xDataSequence;
705 return xDataSequence;
708uno::Reference<chart2::data::XDataSequence> SAL_CALL
713 return uno::Reference<chart2::data::XDataSequence>();
718 uno::Reference<sheet::XRangeSelection> xResult;
722 xResult.set(
xModel->getCurrentController(), uno::UNO_QUERY);
776uno::Reference<chart2::data::XDataSequence>
787uno::Reference<css::chart2::data::XDataSequence>
798uno::Reference<css::chart2::data::XDataSequence>
811 if (nDimensionIndex < 0)
833 if (rObject == aListener)
842uno::Reference< beans::XPropertySetInfo> SAL_CALL
846 static uno::Reference<beans::XPropertySetInfo> aRef =
854 throw beans::UnknownPropertyException(rPropertyName);
857 throw lang::IllegalArgumentException();
871 throw beans::UnknownPropertyException(rPropertyName);
877 const uno::Reference<beans::XPropertyChangeListener>& )
879 OSL_FAIL(
"Not yet implemented");
884 const uno::Reference<beans::XPropertyChangeListener>& )
886 OSL_FAIL(
"Not yet implemented");
891 const uno::Reference<beans::XVetoableChangeListener>& )
893 OSL_FAIL(
"Not yet implemented");
898 const uno::Reference<beans::XVetoableChangeListener>& )
900 OSL_FAIL(
"Not yet implemented");
ScDPObject * GetByName(std::u16string_view rName) const
css::uno::Reference< css::sheet::XDimensionsSupplier > const & GetSource()
bool PastingDrawFromOtherDoc() const
SfxObjectShell * GetDocumentShell() const
void RemoveUnoObject(SfxListener &rObject)
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
static bool GetBoolProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, bool bDefault=false)
static EnumT GetEnumProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, EnumT nDefault)
static OUString GetStringProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, const OUString &rDefault)
static sal_Int32 GetLongProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName)
const SfxItemPropertyMap & getPropertyMap() const
css::uno::Type const & get()
SfxItemPropertySet m_aPropSet
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &rListener) override
css::uno::Reference< css::chart2::data::XDataSequence > assignValuesToDataSequence(size_t nIndex)
virtual css::uno::Sequence< css::chart2::data::PivotTableFieldEntry > SAL_CALL getRowFields() override
virtual sal_Bool SAL_CALL hasPivotTable() override
css::uno::Reference< css::chart2::data::XLabeledDataSequence > newLabeledDataSequence()
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceOfCategories() override
virtual css::uno::Sequence< css::chart2::data::PivotTableFieldEntry > SAL_CALL getDataFields() override
std::vector< css::chart2::data::PivotTableFieldEntry > m_aDataFields
std::unordered_map< sal_Int32, OUString > m_aFieldOutputDescriptionMap
bool m_bIncludeHiddenCells
virtual void SAL_CALL setPivotTableName(const OUString &sPivotTableName) override
virtual css::uno::Reference< css::chart2::data::XDataSource > SAL_CALL createDataSource(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
virtual sal_Bool SAL_CALL createDataSequenceByRangeRepresentationPossible(const OUString &aRangeRepresentation) override
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual OUString SAL_CALL getFieldOutputDescription(sal_Int32 nPageFieldIndex) override
std::vector< std::vector< ValueAndFormat > > m_aDataRowVector
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceOfValuesByIndex(sal_Int32 nIndex) override
std::vector< std::vector< ValueAndFormat > > m_aLabels
virtual sal_Bool SAL_CALL createDataSourcePossible(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceOfLabelsByIndex(sal_Int32 nIndex) override
std::vector< css::chart2::data::PivotTableFieldEntry > m_aColumnFields
virtual ~PivotTableDataProvider() override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByRangeRepresentation(const OUString &aRangeRepresentation) override
OUString m_sPivotTableName
css::uno::Reference< css::chart2::data::XDataSource > createValuesDataSource()
virtual css::uno::Sequence< css::chart2::data::PivotTableFieldEntry > SAL_CALL getColumnFields() override
css::uno::Reference< css::chart2::data::XDataSequence > assignLabelsToDataSequence(size_t nIndex)
std::vector< css::chart2::data::PivotTableFieldEntry > m_aRowFields
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
void collectPivotTableData()
std::vector< css::uno::Reference< css::util::XModifyListener > > m_aValueListeners
std::vector< std::vector< ValueAndFormat > > m_aCategoriesRowOrientation
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
virtual css::uno::Sequence< css::chart2::data::PivotTableFieldEntry > SAL_CALL getPageFields() override
std::vector< std::vector< ValueAndFormat > > m_aCategoriesColumnOrientation
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
css::uno::Reference< css::chart2::data::XDataSource > createCategoriesDataSource(bool bOrientationIsColumn)
virtual OUString SAL_CALL getPivotTableName() override
css::uno::Reference< css::chart2::data::XDataSequence > assignFirstCategoriesToDataSequence()
std::vector< css::chart2::data::PivotTableFieldEntry > m_aPageFields
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByValueArray(const OUString &aRole, const OUString &aRangeRepresentation, const OUString &aRoleQualifier) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL detectArguments(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource) override
Sequence< PropertyValue > aArguments
#define SC_SIMPLE_SERVICE_INFO(ClassName, ClassNameAscii, ServiceAscii)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
CAUTION! The following defines must be in the same namespace as the respective type.
OUString ScResId(TranslateId aId)
Reference< XModel > xModel
constexpr OUStringLiteral SC_UNO_DP_HAS_HIDDEN_MEMBER
constexpr OUStringLiteral SC_UNO_DP_POSITION
constexpr OUStringLiteral SC_UNO_DP_ISDATALAYOUT
constexpr OUStringLiteral SC_UNO_DP_LAYOUTNAME
constexpr OUStringLiteral SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER
#define SC_UNO_DP_NUMBERFO
constexpr OUStringLiteral SC_UNONAME_USE_INTERNAL_DATA_PROVIDER
constexpr OUStringLiteral SC_UNO_DP_USEDHIERARCHY
constexpr OUStringLiteral SC_UNO_DP_ORIENTATION
constexpr OUStringLiteral SC_UNONAME_INCLUDEHIDDENCELLS
constexpr OUStringLiteral SC_UNO_DP_ISVISIBLE