/* -*- 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #pragma once #include "global.hxx" #include "dpfilteredcache.hxx" #include "calcmacros.hxx" #include "dpitemdata.hxx" #include "subtotal.hxx" #include #include #include #include #include #include #include #include namespace com::sun::star::sheet { struct DataResult; } namespace com::sun::star::sheet { struct MemberResult; } namespace com::sun::star::uno { template class Sequence; } class ScDPSource; class ScDPDimension; class ScDPLevel; class ScDPMember; class ScDPResultMember; class ScDPResultMemberFull; class ScDPResultVisibilityData; class ScTokenArray; struct ScDPValue; struct ScDPResultFilterContext; /** * Member names that are being processed for InitFrom/LateInitFrom (needed * for initialization of grouped items). */ class ScDPInitState { public: struct Member { tools::Long mnSrcIndex; SCROW mnNameIndex; Member(tools::Long nSrcIndex, SCROW nNameIndex); }; void AddMember(tools::Long nSourceIndex, SCROW nMember); void RemoveMember(); const std::vector& GetMembers() const { return maMembers; } private: std::vector maMembers; }; typedef ::std::vector ScMemberSortOrder; /** * Select subtotal information, passed down the dimensions. */ struct ScDPSubTotalState { ScSubTotalFunc eColForce; ScSubTotalFunc eRowForce; tools::Long nColSubTotalFunc; tools::Long nRowSubTotalFunc; ScDPSubTotalState() : eColForce( SUBTOTAL_FUNC_NONE ), eRowForce( SUBTOTAL_FUNC_NONE ), nColSubTotalFunc( -1 ), nRowSubTotalFunc( -1 ) {} }; /** * indexes when calculating running totals * * Col/RowVisible: simple counts from 0 - without sort order applied * - visible index (only used for running total / relative index) * * Col/RowSorted: with sort order applied - member index (used otherwise - * so other members' children can be accessed). */ class ScDPRunningTotalState { public: typedef std::vector IndexArray; /// array of sal_Int32 terminated by -1. ScDPRunningTotalState( ScDPResultMember* pColRoot, ScDPResultMember* pRowRoot ); ScDPResultMember* GetColResRoot() const { return pColResRoot; } ScDPResultMember* GetRowResRoot() const { return pRowResRoot; } const IndexArray& GetColVisible() const { return maColVisible;} const IndexArray& GetColSorted() const { return maColSorted;} const IndexArray& GetRowVisible() const { return maRowVisible;} const IndexArray& GetRowSorted() const { return maRowSorted;} void AddColIndex( sal_Int32 nVisible, tools::Long nSorted ); void AddRowIndex( sal_Int32 nVisible, tools::Long nSorted ); void RemoveColIndex(); void RemoveRowIndex(); private: ScDPResultMember* pColResRoot; ScDPResultMember* pRowResRoot; mutable IndexArray maColVisible; mutable IndexArray maColSorted; mutable IndexArray maRowVisible; mutable IndexArray maRowSorted; }; struct ScDPRelativePos { tools::Long nBasePos; // simple count, without sort order applied tools::Long nDirection; ScDPRelativePos( tools::Long nBase, tools::Long nDir ); }; // aggregated data //! separate header file? // Possible values for the nCount member: // (greater than 0 counts the collected values) const sal_Int64 SC_DPAGG_EMPTY = 0; // empty during data collection const sal_Int64 SC_DPAGG_DATA_ERROR = -1; // error during data collection const sal_Int64 SC_DPAGG_RESULT_EMPTY = -2; // empty result calculated const sal_Int64 SC_DPAGG_RESULT_VALID = -3; // valid result calculated const sal_Int64 SC_DPAGG_RESULT_ERROR = -4; // error in calculated result class ScDPAggData { private: WelfordRunner maWelford; double fVal; double fAux; sal_Int64 nCount; std::unique_ptr pChild; std::vector mSortedValues; public: ScDPAggData() : fVal(0.0), fAux(0.0), nCount(SC_DPAGG_EMPTY) {} void Update( const ScDPValue& rNext, ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState ); void Calculate( ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState ); bool IsCalculated() const; double GetResult() const; bool HasError() const; bool HasData() const; void SetResult( double fNew ); void SetCalculatedResult( double fNew ); void SetEmpty( bool bSet ); void SetError(); double GetAuxiliary() const; void SetAuxiliary( double fNew ); void Reset(); // also deletes children const ScDPAggData* GetExistingChild() const { return pChild.get(); } ScDPAggData* GetChild(); #if DUMP_PIVOT_TABLE void Dump(int nIndent) const; #endif }; // Row and grand total state, passed down (column total is at result member) class ScDPRowTotals { ScDPAggData aRowTotal; ScDPAggData aGrandTotal; bool bIsInColRoot; public: ScDPRowTotals(); ~ScDPRowTotals(); ScDPAggData* GetRowTotal( tools::Long nMeasure ); ScDPAggData* GetGrandTotal( tools::Long nMeasure ); bool IsInColRoot() const { return bIsInColRoot; } void SetInColRoot(bool bSet) { bIsInColRoot = bSet; } }; // results for a hierarchy dimension class ScDPResultDimension; class ScDPDataDimension; class ScDPDataMember; #define SC_DPMEASURE_ALL -1 #define SC_DPMEASURE_ANY -2 struct ScDPParentDimData { const SCROW mnOrder; //! Ref const ScDPDimension* mpParentDim; //! Ref const ScDPLevel* mpParentLevel; //! Ref const ScDPMember* mpMemberDesc; //! Ref ScDPParentDimData(); ScDPParentDimData(SCROW nIndex, const ScDPDimension* pDim, const ScDPLevel* pLev, const ScDPMember* pMember); }; class ResultMembers final { std::unordered_map maMemberHash; bool mbHasHideDetailsMember; public: const ScDPParentDimData* FindMember( SCROW nIndex ) const; void InsertMember( ScDPParentDimData const & rNew ); bool IsHasHideDetailsMembers() const { return mbHasHideDetailsMember; } void SetHasHideDetailsMembers( bool b ) { mbHasHideDetailsMember = b; } ResultMembers(); ~ResultMembers(); }; class LateInitParams { private: const ::std::vector& mppDim; const ::std::vector& mppLev; bool mbRow:1; bool mbInitChild:1; bool mbAllChildren:1; public: LateInitParams( const ::std::vector& ppDim, const ::std::vector& ppLev, bool bRow); void SetInitChild( bool b ) { mbInitChild = b; } void SetInitAllChildren( bool b ) { mbAllChildren = b; } ScDPDimension* GetDim( size_t nPos ) const { return mppDim[nPos];} ScDPLevel* GetLevel( size_t nPos ) const { return mppLev[nPos];} bool GetInitChild() const {return mbInitChild; } bool GetInitAllChild() const { return mbAllChildren; } bool IsRow() const { return mbRow; } bool IsEnd( size_t nPos ) const ; }; /** * The term 'measure' here roughly equals "data dimension" ? */ class ScDPResultData { ScDPSource& mrSource; //! keep things like measure lists here std::vector maMeasureFuncs; std::vector maMeasureRefs; std::vector maMeasureRefOrients; std::vector maMeasureNames; std::vector maMeasureIndexes; tools::Long mnVisibleMeasureCount; bool bLateInit:1; bool bDataAtCol:1; bool bDataAtRow:1; //! add "displayed values" settings mutable std::vector> maDimMembers; public: ScDPResultData( ScDPSource& rSrc ); ~ScDPResultData(); void SetMeasureData( std::vector& rFunctions, std::vector& rRefs, std::vector& rRefOrient, std::vector& rNames, std::vector& rIndexes, tools::Long nVisibleMeasureCount ); void SetDataLayoutOrientation( css::sheet::DataPilotFieldOrientation nOrient ); void SetLateInit( bool bSet ); tools::Long GetMeasureCount() const { return maMeasureFuncs.size(); } ScSubTotalFunc GetMeasureFunction(tools::Long nMeasure) const; OUString GetMeasureString(tools::Long nMeasure, bool bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const; OUString GetMeasureDimensionName(tools::Long nMeasure) const; const ScTokenArray* GetMeasureDimensionCalculationToken(tools::Long nMeasure) const; const css::sheet::DataPilotFieldReference& GetMeasureRefVal(tools::Long nMeasure) const; css::sheet::DataPilotFieldOrientation GetMeasureRefOrient(tools::Long nMeasure) const; bool IsLateInit() const { return bLateInit; } tools::Long GetColStartMeasure() const; tools::Long GetRowStartMeasure() const; tools::Long GetCountForMeasure( tools::Long nMeas ) const { return (nMeas == SC_DPMEASURE_ALL) ? maMeasureFuncs.size() : 1; } bool IsBaseForGroup( tools::Long nDim ) const; // any group tools::Long GetGroupBase( tools::Long nGroupDim ) const; bool IsNumOrDateGroup( tools::Long nDim ) const; bool IsInGroup( SCROW nGroupDataId, tools::Long nGroupIndex, const ScDPItemData& rBaseData, tools::Long nBaseIndex ) const; bool HasCommonElement( SCROW nFirstDataId, tools::Long nFirstIndex, const ScDPItemData& rSecondData, tools::Long nSecondIndex ) const; ResultMembers& GetDimResultMembers(tools::Long nDim, const ScDPDimension* pDim, ScDPLevel* pLevel) const; const ScDPSource& GetSource() const { return mrSource;} const std::vector& GetMeasureNames() const { return maMeasureNames; } }; class ScDPResultMember { public: virtual ~ScDPResultMember() = default; void InitFrom(const ::std::vector& ppDim, const ::std::vector& ppLev, size_t nPos, ScDPInitState& rInitState, bool bInitChild = true); virtual void LateInitFrom(LateInitParams& rParams, const ::std::vector& pItemData, size_t nPos, ScDPInitState& rInitState) = 0; virtual void ResetChildDimension() = 0; void CheckShowEmpty(bool bShow = false); OUString GetName() const; OUString GetDisplayName(bool bLocaleIndependent) const; virtual const ScDPResultData* GetResultData() const = 0; ScDPItemData FillItemData() const; virtual bool IsAutoHidden() const = 0; virtual bool GetForceSubTotal() const = 0; virtual bool IsInitialized() const = 0; bool IsValid() const; bool IsVisible() const; tools::Long GetSize(tools::Long nMeasure) const; virtual bool HasHiddenDetails() const = 0; virtual void SetHasHiddenDetails() = 0; bool IsSubTotalInTitle(tools::Long nMeasure) const; tools::Long GetSubTotalCount(tools::Long* pUserSubStart = nullptr) const; bool IsNamedItem(SCROW nIndex) const; bool IsValidEntry(const ::std::vector& aMembers) const; virtual bool GetHasElements() const = 0; virtual void SetHasElements() = 0; virtual void SetInitialized() = 0; virtual void SetAutoHidden() = 0; virtual sal_uInt16 GetMemberStep(void) = 0; virtual void SetMemberStep(sal_uInt16 nStep) = 0; virtual void ProcessData(const ::std::vector& aChildMembers, const ScDPResultDimension* pDataDim, const ::std::vector& aDataMembers, const ::std::vector& aValues) = 0; void FillMemberResults(css::uno::Sequence* pSequences, tools::Long& rPos, tools::Long nMeasure, bool bRoot, const OUString* pMemberName, const OUString* pMemberCaption); void FillDataResults(const ScDPResultMember* pRefMember, ScDPResultFilterContext& rFilterCxt, css::uno::Sequence>& rSequence, tools::Long nMeasure) const; void UpdateDataResults(const ScDPResultMember* pRefMember, tools::Long nMeasure) const; void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals) const; void SortMembers(ScDPResultMember* pRefMember); virtual void DoAutoShow(ScDPResultMember* pRefMember) = 0; virtual void ResetResults() = 0; #if DUMP_PIVOT_TABLE virtual void DumpState(const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos) const = 0; virtual void Dump(int nIndent) const = 0; #endif virtual const ScDPResultDimension* GetChildDimension() const = 0; virtual ScDPResultDimension* GetChildDimension() = 0; virtual ScDPDataMember* GetDataRoot() const = 0; virtual const ScDPDimension* GetParentDim() const = 0; virtual const ScDPLevel* GetParentLevel() const = 0; virtual const ScDPMember* GetDPMember() const = 0; virtual SCROW GetOrder() const = 0; bool IsRoot() const { return GetParentLevel() == nullptr; } SCROW GetDataId() const; virtual ScDPAggData* GetColTotal(tools::Long nMeasure) = 0; void FillVisibilityData(ScDPResultVisibilityData& rData); }; class ScDPResultMemberSlim : public ScDPResultMember { friend ScDPResultDimension; // For promotion private: // When adding fields here, update ScDPResultDimension::Promote ScDPResultDimension* mpOurDimension; const ScDPMember* mpMemberDesc; SCROW mnOrder; bool bmHasElements : 1; bool bmHasHiddenDetails : 1; bool bmInitialized : 1; bool bmPromoted : 1; // Called when 'mpPromoted' meaning someone with this object pointer is // calling a member even though a previous call has promoted it. // Note this is const since we know we're not changing the current (old) object ScDPResultMember* GetPromote() const; // Called when something decides it needs to be promoted, typically when something // is getting set. Note this is NOT const since the bmPromoted flag needs // to be set. // The 'sReason' is purely to let debugging be used to track the reason // for promotions ScDPResultMember* Promote(const char* sReason); public: ScDPResultMemberSlim(ScDPResultDimension* pRDimension, const ScDPParentDimData& rParentDimData); // Just for array new ScDPResultMemberSlim(); bool GetHasElements() const override { if (bmPromoted) return GetPromote()->GetHasElements(); return bmHasElements; }; bool HasHiddenDetails() const override { if (bmPromoted) return GetPromote()->HasHiddenDetails(); return bmHasHiddenDetails; } void LateInitFrom(LateInitParams& rParams, const ::std::vector& pItemData, size_t nPos, ScDPInitState& rInitState) override { Promote("LateInitFrom")->LateInitFrom(rParams, pItemData, nPos, rInitState); } void ResetChildDimension() override { // We don't store the child dimension, so promote Promote("ResetChildDimension")->ResetChildDimension(); } void SetAutoHidden() override { Promote("SetAutoHidden")->SetAutoHidden(); } void SetHasElements() override { if (bmPromoted) return GetPromote()->SetHasElements(); bmHasElements = true; } void SetHasHiddenDetails() override { if (bmPromoted) return GetPromote()->SetHasHiddenDetails(); bmHasHiddenDetails = true; } void SetInitialized() override { if (bmPromoted) return GetPromote()->SetInitialized(); bmInitialized = true; } bool GetForceSubTotal() const override { if (bmPromoted) return GetPromote()->GetForceSubTotal(); // Never set in Slim return false; } ScDPDataMember* GetDataRoot() const override { if (bmPromoted) return GetPromote()->GetDataRoot(); // Slim doesn't store the data root, if one was set we would have been promoted return nullptr; } bool IsAutoHidden() const override { if (bmPromoted) return GetPromote()->IsAutoHidden(); // Slim doesn't store Auto hidden return false; } sal_uInt16 GetMemberStep() override { if (bmPromoted) return GetPromote()->GetMemberStep(); // We don't store this in the slim version, it's always // 1 unless promoted return 1; } void SetMemberStep(sal_uInt16 nStep) override { if (bmPromoted) return GetPromote()->SetMemberStep(nStep); // We don't actually store this in the slim version, we just // promote if it's ever non-1 if (nStep != 1) return Promote("SetMemberStep")->SetMemberStep(nStep); // OK, it is 1 - do nothing } void ProcessData(const ::std::vector& aChildMembers, const ScDPResultDimension* pDataDim, const ::std::vector& aDataMembers, const ::std::vector& aValues) override { // Looks pretty complicated and needs pDataRoot, lets try // Promoting for now Promote("ProcessData")->ProcessData(aChildMembers, pDataDim, aDataMembers, aValues); } void DoAutoShow(ScDPResultMember* pRefMember) override { Promote("DoAutoShow")->DoAutoShow(pRefMember); } void ResetResults() override { Promote("ResetResults")->ResetResults(); } const ScDPResultDimension* GetChildDimension() const override { if (bmPromoted) return GetPromote()->GetChildDimension(); // Slim doesn't store a child pointer, if one was set we would have been promoted return nullptr; } ScDPResultDimension* GetChildDimension() override { if (bmPromoted) return GetPromote()->GetChildDimension(); // Slim doesn't store a child pointer, if one was set we would have been promoted return nullptr; } const ScDPDimension* GetParentDim() const override; const ScDPLevel* GetParentLevel() const override; const ScDPMember* GetDPMember() const override { if (bmPromoted) return GetPromote()->GetDPMember(); return mpMemberDesc; } bool IsInitialized() const override { if (bmPromoted) return GetPromote()->IsInitialized(); return bmInitialized; }; const ScDPResultData* GetResultData() const override; SCROW GetOrder() const override { // mnOrder is never changed, and on promotion is passed to new version return mnOrder; } ScDPAggData* GetColTotal(tools::Long nMeasure) override { return Promote("GetColTotal")->GetColTotal(nMeasure); } #if DUMP_PIVOT_TABLE void DumpState(const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos) const override; void Dump(int nIndent) const override; #endif }; class ScDPResultMemberFull : public ScDPResultMember { private: const ScDPResultData* pResultData; ScDPParentDimData aParentDimData; std::unique_ptr pChildDimension; std::unique_ptr pDataRoot; std::unique_ptr pColTotal; // to store column totals sal_uInt16 nMemberStep; // step to show details bool bHasElements:1; bool bForceSubTotal:1; bool bHasHiddenDetails:1; bool bInitialized:1; bool bAutoHidden:1; public: ScDPResultMemberFull(const ScDPResultData* pData, const ScDPParentDimData& rParentDimData); //! Ref ScDPResultMemberFull(const ScDPResultData* pData, bool bForceSub); ~ScDPResultMemberFull(); void LateInitFrom( LateInitParams& rParams, const ::std::vector< SCROW >& pItemData, size_t nPos, ScDPInitState& rInitState); const ScDPResultData* GetResultData() const { return pResultData; } bool IsAutoHidden() const { return bAutoHidden; }; bool GetForceSubTotal() const { return bForceSubTotal; }; bool IsInitialized() const { return bInitialized; }; // bHasHiddenDetails is set only if the "show details" flag is off, // and there was a child dimension to skip bool HasHiddenDetails() const { return bHasHiddenDetails; } void SetHasHiddenDetails() { bHasHiddenDetails = true; } bool GetHasElements() const { return bHasElements; }; void SetHasElements() { bHasElements = true; } void SetInitialized() { bInitialized = true; } void SetAutoHidden() { bAutoHidden = true; } sal_uInt16 GetMemberStep(void) { return nMemberStep; } void SetMemberStep(sal_uInt16 nStep) { nMemberStep = nStep; } void ProcessData( const ::std::vector& aChildMembers, const ScDPResultDimension* pDataDim, const ::std::vector& aDataMembers, const ::std::vector& aValues ); void DoAutoShow( ScDPResultMember* pRefMember ); void ResetResults(); #if DUMP_PIVOT_TABLE void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; void Dump(int nIndent) const; #endif //! this will be removed! const ScDPResultDimension* GetChildDimension() const { return pChildDimension.get(); } ScDPResultDimension* GetChildDimension() { return pChildDimension.get(); } void ResetChildDimension(); ScDPDataMember* GetDataRoot() const { return pDataRoot.get(); } const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref ScDPAggData* GetColTotal( tools::Long nMeasure ); }; class ScDPDataMember { private: const ScDPResultData* pResultData; const ScDPResultMember* pResultMember; //! Ref? std::unique_ptr pChildDimension; ScDPAggData aAggregate; void UpdateValues( const ::std::vector& aValues, const ScDPSubTotalState& rSubState ); public: ScDPDataMember( const ScDPResultData* pData, const ScDPResultMember* pRes ); ~ScDPDataMember(); void InitFrom( const ScDPResultDimension* pDim ); OUString GetName() const; bool IsVisible() const; bool HasData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; bool IsNamedItem( SCROW nRow ) const; bool HasHiddenDetails() const; void ProcessData( const ::std::vector< SCROW >& aChildMembers, const ::std::vector& aValues, const ScDPSubTotalState& rSubState ); bool HasError( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; double GetAggregate( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; const ScDPAggData* GetConstAggData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; ScDPAggData* GetAggData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ); void FillDataRow( const ScDPResultMember* pRefMember, ScDPResultFilterContext& rFilterCxt, css::uno::Sequence& rSequence, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState) const; void UpdateDataRow(const ScDPResultMember* pRefMember, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState); void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState, ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals, const ScDPResultMember& rRowParent); void SortMembers(ScDPResultMember* pRefMember); void DoAutoShow(ScDPResultMember* pRefMember); void ResetResults(); // function resolver static tools::Long FindMeasureIndex(const std::vector& rNames, const OUString& rName); std::unique_ptr ReplaceTokenMeasuresWithValues(const ScTokenArray* pArray, const ScDPSubTotalState& rSubState, std::unordered_set& rRecStack); #if DUMP_PIVOT_TABLE void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; void Dump(int nIndent) const; #endif //! this will be removed! const ScDPDataDimension* GetChildDimension() const { return pChildDimension.get(); } ScDPDataDimension* GetChildDimension() { return pChildDimension.get(); } }; // result dimension contains only members class ScDPResultDimension { public: typedef std::vector> MemberArray; typedef std::unique_ptr> MemberSlimArray; private: const ScDPResultData* pResultData; // Used when we allocate a full set of Slim MemberSlimArray mpaMemberSlimArray; // Used both in non-Slim cases and after Slim get promoted MemberArray maMemberArray; // Used during 'Promote' of ScDPResultMember ScDPDimension* mpDimension; ScDPLevel* mpLevel; OUString aDimensionName; //! or ptr to IntDimension? tools::Long nSortMeasure; ScMemberSortOrder aMemberOrder; // used when sorted by measure bool bIsDataLayout:1; //! or ptr to IntDimension? bool bSortByData:1; bool bSortAscending:1; bool bAutoShow:1; bool bAutoTopItems:1; bool bInitialized:1; tools::Long nAutoMeasure; tools::Long nAutoCount; ScDPResultMember* FindMember( SCROW iData ) const; ScDPResultMember* AddMember( const ScDPParentDimData& aData ); ScDPResultMember* InsertMember( const ScDPParentDimData* pMemberData ); void InitWithMembers( LateInitParams& rParams, const ::std::vector< SCROW >& pItemData, size_t nPos, ScDPInitState& rInitState ); public: ScDPResultDimension( const ScDPResultData* pData ); ~ScDPResultDimension(); // allocates new members void InitFrom( const ::std::vector& ppDim, const ::std::vector& ppLev, size_t nPos, ScDPInitState& rInitState, bool bInitChild = true ); void LateInitFrom( LateInitParams& rParams, const ::std::vector< SCROW >& pItemData, size_t nPos, ScDPInitState& rInitState ); void CheckShowEmpty( bool bShow = false ); tools::Long GetSize(tools::Long nMeasure) const; bool IsValidEntry( const ::std::vector& aMembers ) const; // modifies existing members, allocates data dimensions void ProcessData( const ::std::vector& aMembers, const ScDPResultDimension* pDataDim, const ::std::vector& aDataMembers, const ::std::vector& aValues ) const; //! Test void FillMemberResults( css::uno::Sequence< css::sheet::MemberResult>* pSequences, tools::Long nStart, tools::Long nMeasure ); void FillDataResults( const ScDPResultMember* pRefMember, ScDPResultFilterContext& rFilterCxt, css::uno::Sequence< css::uno::Sequence< css::sheet::DataResult> >& rSequence, tools::Long nMeasure) const; void UpdateDataResults(const ScDPResultMember* pRefMember, tools::Long nMeasure) const; void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals) const; void SortMembers(ScDPResultMember* pRefMember); tools::Long GetSortedIndex( tools::Long nUnsorted ) const; void DoAutoShow(ScDPResultMember* pRefMember); void ResetResults(); // called for the reference dimension ScDPDataMember* GetRowReferenceMember( const ScDPRelativePos* pMemberPos, const OUString* pName, const sal_Int32* pRowIndexes, const sal_Int32* pColIndexes ) const; // uses row root member from ScDPRunningTotalState static ScDPDataMember* GetColReferenceMember( const ScDPRelativePos* pMemberPos, const OUString* pName, sal_Int32 nRefDimPos, const ScDPRunningTotalState& rRunning ); #if DUMP_PIVOT_TABLE void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; void Dump(int nIndent) const; #endif // for ScDPDataDimension::InitFrom tools::Long GetMemberCount() const; const ScDPResultMember* GetMember(tools::Long n) const; ScDPResultMember* GetMember(tools::Long n); const ScMemberSortOrder& GetMemberOrder() const { return aMemberOrder; } ScMemberSortOrder& GetMemberOrder() { return aMemberOrder; } const ScDPResultData* GetResultData() const { return pResultData; } bool IsDataLayout() const { return bIsDataLayout; } const OUString& GetName() const { return aDimensionName; } bool IsSortByData() const { return bSortByData; } bool IsSortAscending() const { return bSortAscending; } tools::Long GetSortMeasure() const { return nSortMeasure; } bool IsAutoShow() const { return bAutoShow; } bool IsAutoTopItems() const { return bAutoTopItems; } tools::Long GetAutoMeasure() const { return nAutoMeasure; } tools::Long GetAutoCount() const { return nAutoCount; } ScDPResultDimension* GetFirstChildDimension(); void FillVisibilityData(ScDPResultVisibilityData& rData); // Called by an ScDPResultMemberSlim which has already been promoted // but something with an older pointer calls one of its member functions ScDPResultMember* GetPromote(SCROW nOrder) const; // Called by an ScDPResultMemberSlim when a member function needs // to do something which Slim can't represent ScDPResultMember* Promote(ScDPResultMemberSlim* pSlim, SCROW nOrder); // Called by an ScDPResultMemberSlim to get its parent information ScDPDimension* GetParentDimForResult() { return mpDimension; }; ScDPLevel* GetParentLevelForResult() { return mpLevel; }; }; class ScDPDataDimension { private: const ScDPResultData* pResultData; const ScDPResultDimension* pResultDimension; // column std::vector> maMembers; bool bIsDataLayout; //! or ptr to IntDimension? public: ScDPDataDimension( const ScDPResultData* pData ); ~ScDPDataDimension(); void InitFrom( const ScDPResultDimension* pDim ); // recursive void ProcessData( const ::std::vector< SCROW >& aDataMembers, const ::std::vector& aValues, const ScDPSubTotalState& rSubState ); void FillDataRow( const ScDPResultDimension* pRefDim, ScDPResultFilterContext& rFilterCxt, css::uno::Sequence& rSequence, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState) const; void UpdateDataRow( const ScDPResultDimension* pRefDim, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState ) const; void UpdateRunningTotals( ScDPResultDimension* pRefDim, tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState, ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals, const ScDPResultMember& rRowParent ) const; void SortMembers( ScDPResultDimension* pRefDim ); tools::Long GetSortedIndex( tools::Long nUnsorted ) const; void DoAutoShow( ScDPResultDimension* pRefDim ); void ResetResults(); #if DUMP_PIVOT_TABLE void DumpState( const ScDPResultDimension* pRefDim, ScDocument* pDoc, ScAddress& rPos ) const; void Dump(int nIndent) const; #endif tools::Long GetMemberCount() const; const ScDPDataMember* GetMember(tools::Long n) const; ScDPDataMember* GetMember(tools::Long n); }; /** * This class collects visible members of each dimension and uses that * information to create filtering criteria (e.g. for drill-down data). */ class ScDPResultVisibilityData { public: ScDPResultVisibilityData( ScDPSource* pSource); ~ScDPResultVisibilityData(); void addVisibleMember(const OUString& rDimName, const ScDPItemData& rMemberItem); void fillFieldFilters(::std::vector& rFilters) const; private: struct MemberHash { size_t operator()(const ScDPItemData& r) const; }; typedef std::unordered_set VisibleMemberType; typedef std::unordered_map DimMemberType; DimMemberType maDimensions; ScDPSource* mpSource; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */