/src/libreoffice/sc/inc/dptabres.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include "global.hxx" |
23 | | #include "dpfilteredcache.hxx" |
24 | | #include "calcmacros.hxx" |
25 | | #include "dpitemdata.hxx" |
26 | | #include "subtotal.hxx" |
27 | | |
28 | | #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> |
29 | | #include <com/sun/star/sheet/DataPilotFieldReference.hpp> |
30 | | |
31 | | #include <map> |
32 | | #include <unordered_map> |
33 | | #include <unordered_set> |
34 | | #include <memory> |
35 | | #include <vector> |
36 | | |
37 | | namespace com::sun::star::sheet { struct DataResult; } |
38 | | namespace com::sun::star::sheet { struct MemberResult; } |
39 | | namespace com::sun::star::uno { template <typename > class Sequence; } |
40 | | |
41 | | class ScDPSource; |
42 | | class ScDPDimension; |
43 | | class ScDPLevel; |
44 | | class ScDPMember; |
45 | | class ScDPResultMember; |
46 | | class ScDPResultMemberFull; |
47 | | class ScDPResultVisibilityData; |
48 | | class ScTokenArray; |
49 | | |
50 | | struct ScDPValue; |
51 | | struct ScDPResultFilterContext; |
52 | | |
53 | | /** |
54 | | * Member names that are being processed for InitFrom/LateInitFrom (needed |
55 | | * for initialization of grouped items). |
56 | | */ |
57 | | class ScDPInitState |
58 | | { |
59 | | public: |
60 | | struct Member |
61 | | { |
62 | | tools::Long mnSrcIndex; |
63 | | SCROW mnNameIndex; |
64 | | |
65 | | Member(tools::Long nSrcIndex, SCROW nNameIndex); |
66 | | }; |
67 | | |
68 | | void AddMember(tools::Long nSourceIndex, SCROW nMember); |
69 | | void RemoveMember(); |
70 | | |
71 | 27 | const std::vector<Member>& GetMembers() const { return maMembers; } |
72 | | |
73 | | private: |
74 | | std::vector<Member> maMembers; |
75 | | }; |
76 | | |
77 | | typedef ::std::vector<sal_Int32> ScMemberSortOrder; |
78 | | |
79 | | /** |
80 | | * Select subtotal information, passed down the dimensions. |
81 | | */ |
82 | | struct ScDPSubTotalState |
83 | | { |
84 | | ScSubTotalFunc eColForce; |
85 | | ScSubTotalFunc eRowForce; |
86 | | tools::Long nColSubTotalFunc; |
87 | | tools::Long nRowSubTotalFunc; |
88 | | |
89 | | ScDPSubTotalState() : |
90 | 80.7M | eColForce( SUBTOTAL_FUNC_NONE ), |
91 | 80.7M | eRowForce( SUBTOTAL_FUNC_NONE ), |
92 | 80.7M | nColSubTotalFunc( -1 ), |
93 | 80.7M | nRowSubTotalFunc( -1 ) |
94 | 80.7M | {} |
95 | | }; |
96 | | |
97 | | /** |
98 | | * indexes when calculating running totals |
99 | | * |
100 | | * Col/RowVisible: simple counts from 0 - without sort order applied |
101 | | * - visible index (only used for running total / relative index) |
102 | | * |
103 | | * Col/RowSorted: with sort order applied - member index (used otherwise - |
104 | | * so other members' children can be accessed). |
105 | | */ |
106 | | class ScDPRunningTotalState |
107 | | { |
108 | | public: |
109 | | typedef std::vector<sal_Int32> IndexArray; /// array of sal_Int32 terminated by -1. |
110 | | |
111 | | ScDPRunningTotalState( ScDPResultMember* pColRoot, ScDPResultMember* pRowRoot ); |
112 | | |
113 | 0 | ScDPResultMember* GetColResRoot() const { return pColResRoot; } |
114 | 0 | ScDPResultMember* GetRowResRoot() const { return pRowResRoot; } |
115 | | |
116 | 0 | const IndexArray& GetColVisible() const { return maColVisible;} |
117 | 0 | const IndexArray& GetColSorted() const { return maColSorted;} |
118 | 0 | const IndexArray& GetRowVisible() const { return maRowVisible;} |
119 | 0 | const IndexArray& GetRowSorted() const { return maRowSorted;} |
120 | | |
121 | | void AddColIndex( sal_Int32 nVisible, tools::Long nSorted ); |
122 | | void AddRowIndex( sal_Int32 nVisible, tools::Long nSorted ); |
123 | | void RemoveColIndex(); |
124 | | void RemoveRowIndex(); |
125 | | |
126 | | private: |
127 | | ScDPResultMember* pColResRoot; |
128 | | ScDPResultMember* pRowResRoot; |
129 | | |
130 | | mutable IndexArray maColVisible; |
131 | | mutable IndexArray maColSorted; |
132 | | mutable IndexArray maRowVisible; |
133 | | mutable IndexArray maRowSorted; |
134 | | }; |
135 | | |
136 | | struct ScDPRelativePos |
137 | | { |
138 | | tools::Long nBasePos; // simple count, without sort order applied |
139 | | tools::Long nDirection; |
140 | | |
141 | | ScDPRelativePos( tools::Long nBase, tools::Long nDir ); |
142 | | }; |
143 | | |
144 | | // aggregated data |
145 | | //! separate header file? |
146 | | |
147 | | // Possible values for the nCount member: |
148 | | // (greater than 0 counts the collected values) |
149 | | const sal_Int64 SC_DPAGG_EMPTY = 0; // empty during data collection |
150 | | const sal_Int64 SC_DPAGG_DATA_ERROR = -1; // error during data collection |
151 | | const sal_Int64 SC_DPAGG_RESULT_EMPTY = -2; // empty result calculated |
152 | | const sal_Int64 SC_DPAGG_RESULT_VALID = -3; // valid result calculated |
153 | | const sal_Int64 SC_DPAGG_RESULT_ERROR = -4; // error in calculated result |
154 | | |
155 | | class ScDPAggData |
156 | | { |
157 | | private: |
158 | | WelfordRunner maWelford; |
159 | | double fVal; |
160 | | double fAux; |
161 | | sal_Int64 nCount; |
162 | | std::unique_ptr<ScDPAggData> pChild; |
163 | | std::vector<double> mSortedValues; |
164 | | |
165 | | public: |
166 | 9.99k | ScDPAggData() : fVal(0.0), fAux(0.0), nCount(SC_DPAGG_EMPTY) {} |
167 | | |
168 | | void Update( const ScDPValue& rNext, ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState ); |
169 | | void Calculate( ScSubTotalFunc eFunc, const ScDPSubTotalState& rSubState ); |
170 | | bool IsCalculated() const; |
171 | | |
172 | | double GetResult() const; |
173 | | bool HasError() const; |
174 | | bool HasData() const; |
175 | | |
176 | | void SetResult( double fNew ); |
177 | | void SetCalculatedResult( double fNew ); |
178 | | void SetEmpty( bool bSet ); |
179 | | void SetError(); |
180 | | |
181 | | double GetAuxiliary() const; |
182 | | void SetAuxiliary( double fNew ); |
183 | | |
184 | | void Reset(); // also deletes children |
185 | | |
186 | 1.07k | const ScDPAggData* GetExistingChild() const { return pChild.get(); } |
187 | | ScDPAggData* GetChild(); |
188 | | |
189 | | #if DUMP_PIVOT_TABLE |
190 | | void Dump(int nIndent) const; |
191 | | #endif |
192 | | }; |
193 | | |
194 | | // Row and grand total state, passed down (column total is at result member) |
195 | | |
196 | | class ScDPRowTotals |
197 | | { |
198 | | ScDPAggData aRowTotal; |
199 | | ScDPAggData aGrandTotal; |
200 | | bool bIsInColRoot; |
201 | | |
202 | | public: |
203 | | ScDPRowTotals(); |
204 | | ~ScDPRowTotals(); |
205 | | |
206 | | ScDPAggData* GetRowTotal( tools::Long nMeasure ); |
207 | | ScDPAggData* GetGrandTotal( tools::Long nMeasure ); |
208 | | |
209 | 78 | bool IsInColRoot() const { return bIsInColRoot; } |
210 | 1.36k | void SetInColRoot(bool bSet) { bIsInColRoot = bSet; } |
211 | | }; |
212 | | |
213 | | // results for a hierarchy dimension |
214 | | |
215 | | class ScDPResultDimension; |
216 | | class ScDPDataDimension; |
217 | | class ScDPDataMember; |
218 | | |
219 | 56.7k | #define SC_DPMEASURE_ALL -1 |
220 | 1.24k | #define SC_DPMEASURE_ANY -2 |
221 | | |
222 | | struct ScDPParentDimData |
223 | | { |
224 | | const SCROW mnOrder; //! Ref |
225 | | const ScDPDimension* mpParentDim; //! Ref |
226 | | const ScDPLevel* mpParentLevel; //! Ref |
227 | | const ScDPMember* mpMemberDesc; //! Ref |
228 | | |
229 | | ScDPParentDimData(); |
230 | | ScDPParentDimData(SCROW nIndex, const ScDPDimension* pDim, const ScDPLevel* pLev, const ScDPMember* pMember); |
231 | | }; |
232 | | |
233 | | class ResultMembers final |
234 | | { |
235 | | std::unordered_map<SCROW, ScDPParentDimData> maMemberHash; |
236 | | bool mbHasHideDetailsMember; |
237 | | public: |
238 | | const ScDPParentDimData* FindMember( SCROW nIndex ) const; |
239 | | void InsertMember( ScDPParentDimData const & rNew ); |
240 | 1.07M | bool IsHasHideDetailsMembers() const { return mbHasHideDetailsMember; } |
241 | 1.07M | void SetHasHideDetailsMembers( bool b ) { mbHasHideDetailsMember = b; } |
242 | | ResultMembers(); |
243 | | ~ResultMembers(); |
244 | | }; |
245 | | |
246 | | class LateInitParams |
247 | | { |
248 | | private: |
249 | | const ::std::vector<ScDPDimension*>& mppDim; |
250 | | const ::std::vector<ScDPLevel*>& mppLev; |
251 | | |
252 | | bool mbRow:1; |
253 | | bool mbInitChild:1; |
254 | | bool mbAllChildren:1; |
255 | | public: |
256 | | LateInitParams( const ::std::vector<ScDPDimension*>& ppDim, const ::std::vector<ScDPLevel*>& ppLev, |
257 | | bool bRow); |
258 | | |
259 | 159M | void SetInitChild( bool b ) { mbInitChild = b; } |
260 | 159M | void SetInitAllChildren( bool b ) { mbAllChildren = b; } |
261 | | |
262 | 1.07M | ScDPDimension* GetDim( size_t nPos ) const { return mppDim[nPos];} |
263 | 1.07M | ScDPLevel* GetLevel( size_t nPos ) const { return mppLev[nPos];} |
264 | | |
265 | 1.07M | bool GetInitChild() const {return mbInitChild; } |
266 | 1.07M | bool GetInitAllChild() const { return mbAllChildren; } |
267 | 1.07M | bool IsRow() const { return mbRow; } |
268 | | bool IsEnd( size_t nPos ) const ; |
269 | | }; |
270 | | |
271 | | /** |
272 | | * The term 'measure' here roughly equals "data dimension" ? |
273 | | */ |
274 | | class ScDPResultData |
275 | | { |
276 | | ScDPSource& mrSource; |
277 | | //! keep things like measure lists here |
278 | | |
279 | | std::vector<ScSubTotalFunc> maMeasureFuncs; |
280 | | std::vector<css::sheet::DataPilotFieldReference> maMeasureRefs; |
281 | | std::vector<css::sheet::DataPilotFieldOrientation> maMeasureRefOrients; |
282 | | std::vector<OUString> maMeasureNames; |
283 | | std::vector<sal_Int32> maMeasureIndexes; |
284 | | |
285 | | tools::Long mnVisibleMeasureCount; |
286 | | |
287 | | bool bLateInit:1; |
288 | | bool bDataAtCol:1; |
289 | | bool bDataAtRow:1; |
290 | | |
291 | | //! add "displayed values" settings |
292 | | mutable std::vector<std::unique_ptr<ResultMembers>> maDimMembers; |
293 | | public: |
294 | | ScDPResultData( ScDPSource& rSrc ); |
295 | | ~ScDPResultData(); |
296 | | |
297 | | void SetMeasureData( |
298 | | std::vector<ScSubTotalFunc>& rFunctions, |
299 | | std::vector<css::sheet::DataPilotFieldReference>& rRefs, |
300 | | std::vector<css::sheet::DataPilotFieldOrientation>& rRefOrient, |
301 | | std::vector<OUString>& rNames, std::vector<sal_Int32>& rIndexes, |
302 | | tools::Long nVisibleMeasureCount ); |
303 | | |
304 | | void SetDataLayoutOrientation( css::sheet::DataPilotFieldOrientation nOrient ); |
305 | | void SetLateInit( bool bSet ); |
306 | | |
307 | 335 | tools::Long GetMeasureCount() const { return maMeasureFuncs.size(); } |
308 | | ScSubTotalFunc GetMeasureFunction(tools::Long nMeasure) const; |
309 | | OUString GetMeasureString(tools::Long nMeasure, bool bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const; |
310 | | OUString GetMeasureDimensionName(tools::Long nMeasure) const; |
311 | | const ScTokenArray* GetMeasureDimensionCalculationToken(tools::Long nMeasure) const; |
312 | | const css::sheet::DataPilotFieldReference& GetMeasureRefVal(tools::Long nMeasure) const; |
313 | | css::sheet::DataPilotFieldOrientation GetMeasureRefOrient(tools::Long nMeasure) const; |
314 | | |
315 | 241M | bool IsLateInit() const { return bLateInit; } |
316 | | |
317 | | tools::Long GetColStartMeasure() const; |
318 | | tools::Long GetRowStartMeasure() const; |
319 | | |
320 | 20.0k | tools::Long GetCountForMeasure( tools::Long nMeas ) const { return (nMeas == SC_DPMEASURE_ALL) ? maMeasureFuncs.size() : 1; } |
321 | | |
322 | | bool IsBaseForGroup( tools::Long nDim ) const; // any group |
323 | | tools::Long GetGroupBase( tools::Long nGroupDim ) const; |
324 | | bool IsNumOrDateGroup( tools::Long nDim ) const; |
325 | | bool IsInGroup( SCROW nGroupDataId, tools::Long nGroupIndex, |
326 | | const ScDPItemData& rBaseData, tools::Long nBaseIndex ) const; |
327 | | bool HasCommonElement( SCROW nFirstDataId, tools::Long nFirstIndex, |
328 | | const ScDPItemData& rSecondData, tools::Long nSecondIndex ) const; |
329 | | |
330 | | ResultMembers& GetDimResultMembers(tools::Long nDim, const ScDPDimension* pDim, ScDPLevel* pLevel) const; |
331 | | |
332 | 11.0k | const ScDPSource& GetSource() const { return mrSource;} |
333 | 0 | const std::vector<OUString>& GetMeasureNames() const { return maMeasureNames; } |
334 | | }; |
335 | | |
336 | | class ScDPResultMember |
337 | | { |
338 | | public: |
339 | 3.65k | virtual ~ScDPResultMember() = default; |
340 | | |
341 | | void InitFrom(const ::std::vector<ScDPDimension*>& ppDim, |
342 | | const ::std::vector<ScDPLevel*>& ppLev, size_t nPos, ScDPInitState& rInitState, |
343 | | bool bInitChild = true); |
344 | | |
345 | | virtual void LateInitFrom(LateInitParams& rParams, const ::std::vector<SCROW>& pItemData, |
346 | | size_t nPos, ScDPInitState& rInitState) = 0; |
347 | | |
348 | | virtual void ResetChildDimension() = 0; |
349 | | |
350 | | void CheckShowEmpty(bool bShow = false); |
351 | | |
352 | | OUString GetName() const; |
353 | | |
354 | | OUString GetDisplayName(bool bLocaleIndependent) const; |
355 | | |
356 | | virtual const ScDPResultData* GetResultData() const = 0; |
357 | | |
358 | | ScDPItemData FillItemData() const; |
359 | | |
360 | | virtual bool IsAutoHidden() const = 0; |
361 | | |
362 | | virtual bool GetForceSubTotal() const = 0; |
363 | | |
364 | | virtual bool IsInitialized() const = 0; |
365 | | |
366 | | bool IsValid() const; |
367 | | |
368 | | bool IsVisible() const; |
369 | | |
370 | | tools::Long GetSize(tools::Long nMeasure) const; |
371 | | |
372 | | virtual bool HasHiddenDetails() const = 0; |
373 | | |
374 | | virtual void SetHasHiddenDetails() = 0; |
375 | | |
376 | | bool IsSubTotalInTitle(tools::Long nMeasure) const; |
377 | | |
378 | | tools::Long GetSubTotalCount(tools::Long* pUserSubStart = nullptr) const; |
379 | | |
380 | | bool IsNamedItem(SCROW nIndex) const; |
381 | | |
382 | | bool IsValidEntry(const ::std::vector<SCROW>& aMembers) const; |
383 | | |
384 | | virtual bool GetHasElements() const = 0; |
385 | | |
386 | | virtual void SetHasElements() = 0; |
387 | | |
388 | | virtual void SetInitialized() = 0; |
389 | | |
390 | | virtual void SetAutoHidden() = 0; |
391 | | |
392 | | virtual sal_uInt16 GetMemberStep(void) = 0; |
393 | | |
394 | | virtual void SetMemberStep(sal_uInt16 nStep) = 0; |
395 | | |
396 | | virtual void |
397 | | ProcessData(const ::std::vector<SCROW>& aChildMembers, const ScDPResultDimension* pDataDim, |
398 | | const ::std::vector<SCROW>& aDataMembers, const ::std::vector<ScDPValue>& aValues) = 0; |
399 | | |
400 | | void FillMemberResults(css::uno::Sequence<css::sheet::MemberResult>* pSequences, |
401 | | tools::Long& rPos, tools::Long nMeasure, bool bRoot, |
402 | | const OUString* pMemberName, const OUString* pMemberCaption); |
403 | | |
404 | | void FillDataResults(const ScDPResultMember* pRefMember, ScDPResultFilterContext& rFilterCxt, |
405 | | css::uno::Sequence<css::uno::Sequence<css::sheet::DataResult>>& rSequence, |
406 | | tools::Long nMeasure) const; |
407 | | |
408 | | void UpdateDataResults(const ScDPResultMember* pRefMember, tools::Long nMeasure) const; |
409 | | |
410 | | void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, |
411 | | ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals) const; |
412 | | |
413 | | void SortMembers(ScDPResultMember* pRefMember); |
414 | | |
415 | | virtual void DoAutoShow(ScDPResultMember* pRefMember) = 0; |
416 | | |
417 | | virtual void ResetResults() = 0; |
418 | | |
419 | | #if DUMP_PIVOT_TABLE |
420 | | virtual void DumpState(const ScDPResultMember* pRefMember, ScDocument* pDoc, |
421 | | ScAddress& rPos) const = 0; |
422 | | virtual void Dump(int nIndent) const = 0; |
423 | | #endif |
424 | | |
425 | | virtual const ScDPResultDimension* GetChildDimension() const = 0; |
426 | | virtual ScDPResultDimension* GetChildDimension() = 0; |
427 | | |
428 | | virtual ScDPDataMember* GetDataRoot() const = 0; |
429 | | |
430 | | virtual const ScDPDimension* GetParentDim() const = 0; |
431 | | virtual const ScDPLevel* GetParentLevel() const = 0; |
432 | | virtual const ScDPMember* GetDPMember() const = 0; |
433 | | |
434 | | virtual SCROW GetOrder() const = 0; |
435 | | |
436 | 2.65k | bool IsRoot() const { return GetParentLevel() == nullptr; } |
437 | | |
438 | | SCROW GetDataId() const; |
439 | | |
440 | | virtual ScDPAggData* GetColTotal(tools::Long nMeasure) = 0; |
441 | | |
442 | | void FillVisibilityData(ScDPResultVisibilityData& rData) const; |
443 | | }; |
444 | | |
445 | | class ScDPResultMemberSlim : public ScDPResultMember |
446 | | { |
447 | | friend ScDPResultDimension; // For promotion |
448 | | private: |
449 | | // When adding fields here, update ScDPResultDimension::Promote |
450 | | ScDPResultDimension* mpOurDimension; |
451 | | const ScDPMember* mpMemberDesc; |
452 | | const ScDPResultData* pResultData; |
453 | | const SCROW mnOrder; |
454 | | bool bmHasElements : 1; |
455 | | bool bmHasHiddenDetails : 1; |
456 | | bool bmInitialized : 1; |
457 | | bool bmPromoted : 1; |
458 | | |
459 | | // Called when 'mpPromoted' meaning someone with this object pointer is |
460 | | // calling a member even though a previous call has promoted it. |
461 | | // Note this is const since we know we're not changing the current (old) object |
462 | | ScDPResultMember* GetPromote() const; |
463 | | |
464 | | // Called when something decides it needs to be promoted, typically when something |
465 | | // is getting set. Note this is NOT const since the bmPromoted flag needs |
466 | | // to be set. |
467 | | // The 'sReason' is purely to let debugging be used to track the reason |
468 | | // for promotions |
469 | | ScDPResultMember* Promote(const char* sReason); |
470 | | |
471 | | public: |
472 | | ScDPResultMemberSlim(ScDPResultDimension* pRDimension, const ScDPResultData* pData, |
473 | | const ScDPParentDimData& rParentDimData); |
474 | | |
475 | | bool GetHasElements() const override |
476 | 71 | { |
477 | 71 | if (bmPromoted) |
478 | 0 | return GetPromote()->GetHasElements(); |
479 | 71 | return bmHasElements; |
480 | 71 | }; |
481 | | |
482 | | bool HasHiddenDetails() const override |
483 | 0 | { |
484 | 0 | if (bmPromoted) |
485 | 0 | return GetPromote()->HasHiddenDetails(); |
486 | 0 | return bmHasHiddenDetails; |
487 | 0 | } |
488 | | |
489 | | void LateInitFrom(LateInitParams& rParams, const ::std::vector<SCROW>& pItemData, size_t nPos, |
490 | | ScDPInitState& rInitState) override |
491 | 1.47k | { |
492 | 1.47k | Promote("LateInitFrom")->LateInitFrom(rParams, pItemData, nPos, rInitState); |
493 | 1.47k | } |
494 | | |
495 | | void ResetChildDimension() override |
496 | 0 | { |
497 | | // We don't store the child dimension, so promote |
498 | 0 | Promote("ResetChildDimension")->ResetChildDimension(); |
499 | 0 | } |
500 | | |
501 | 0 | void SetAutoHidden() override { Promote("SetAutoHidden")->SetAutoHidden(); } |
502 | | |
503 | | void SetHasElements() override |
504 | 0 | { |
505 | 0 | if (bmPromoted) |
506 | 0 | return GetPromote()->SetHasElements(); |
507 | 0 | bmHasElements = true; |
508 | 0 | } |
509 | | |
510 | | void SetHasHiddenDetails() override |
511 | 0 | { |
512 | 0 | if (bmPromoted) |
513 | 0 | return GetPromote()->SetHasHiddenDetails(); |
514 | 0 | bmHasHiddenDetails = true; |
515 | 0 | } |
516 | | |
517 | | void SetInitialized() override |
518 | 0 | { |
519 | 0 | if (bmPromoted) |
520 | 0 | return GetPromote()->SetInitialized(); |
521 | 0 | bmInitialized = true; |
522 | 0 | } |
523 | | |
524 | | bool GetForceSubTotal() const override |
525 | 9.84k | { |
526 | 9.84k | if (bmPromoted) |
527 | 9.76k | return GetPromote()->GetForceSubTotal(); |
528 | | // Never set in Slim |
529 | 83 | return false; |
530 | 9.84k | } |
531 | | |
532 | | ScDPDataMember* GetDataRoot() const override |
533 | 0 | { |
534 | 0 | if (bmPromoted) |
535 | 0 | return GetPromote()->GetDataRoot(); |
536 | | // Slim doesn't store the data root, if one was set we would have been promoted |
537 | 0 | return nullptr; |
538 | 0 | } |
539 | | |
540 | | bool IsAutoHidden() const override |
541 | 71 | { |
542 | 71 | if (bmPromoted) |
543 | 0 | return GetPromote()->IsAutoHidden(); |
544 | | // Slim doesn't store Auto hidden |
545 | 71 | return false; |
546 | 71 | } |
547 | | |
548 | | sal_uInt16 GetMemberStep() override |
549 | 0 | { |
550 | 0 | if (bmPromoted) |
551 | 0 | return GetPromote()->GetMemberStep(); |
552 | | // We don't store this in the slim version, it's always |
553 | | // 1 unless promoted |
554 | 0 | return 1; |
555 | 0 | } |
556 | | |
557 | | void SetMemberStep(sal_uInt16 nStep) override |
558 | 0 | { |
559 | 0 | if (bmPromoted) |
560 | 0 | return GetPromote()->SetMemberStep(nStep); |
561 | | // We don't actually store this in the slim version, we just |
562 | | // promote if it's ever non-1 |
563 | 0 | if (nStep != 1) |
564 | 0 | return Promote("SetMemberStep")->SetMemberStep(nStep); |
565 | | // OK, it is 1 - do nothing |
566 | 0 | } |
567 | | |
568 | | void ProcessData(const ::std::vector<SCROW>& aChildMembers, const ScDPResultDimension* pDataDim, |
569 | | const ::std::vector<SCROW>& aDataMembers, |
570 | | const ::std::vector<ScDPValue>& aValues) override |
571 | 0 | { |
572 | | // Looks pretty complicated and needs pDataRoot, lets try |
573 | | // Promoting for now |
574 | 0 | Promote("ProcessData")->ProcessData(aChildMembers, pDataDim, aDataMembers, aValues); |
575 | 0 | } |
576 | | |
577 | | void DoAutoShow(ScDPResultMember* pRefMember) override |
578 | 0 | { |
579 | 0 | Promote("DoAutoShow")->DoAutoShow(pRefMember); |
580 | 0 | } |
581 | | |
582 | 0 | void ResetResults() override { Promote("ResetResults")->ResetResults(); } |
583 | | |
584 | | const ScDPResultDimension* GetChildDimension() const override |
585 | 9.84k | { |
586 | 9.84k | if (bmPromoted) |
587 | 9.76k | return GetPromote()->GetChildDimension(); |
588 | | // Slim doesn't store a child pointer, if one was set we would have been promoted |
589 | 83 | return nullptr; |
590 | 9.84k | } |
591 | | |
592 | | ScDPResultDimension* GetChildDimension() override |
593 | 0 | { |
594 | 0 | if (bmPromoted) |
595 | 0 | return GetPromote()->GetChildDimension(); |
596 | | // Slim doesn't store a child pointer, if one was set we would have been promoted |
597 | 0 | return nullptr; |
598 | 0 | } |
599 | | |
600 | | const ScDPDimension* GetParentDim() const override; |
601 | | const ScDPLevel* GetParentLevel() const override; |
602 | | |
603 | | const ScDPMember* GetDPMember() const override |
604 | 45.3k | { |
605 | 45.3k | if (bmPromoted) |
606 | 40.0k | return GetPromote()->GetDPMember(); |
607 | 5.29k | return mpMemberDesc; |
608 | 45.3k | } |
609 | | |
610 | | bool IsInitialized() const override |
611 | 839 | { |
612 | 839 | if (bmPromoted) |
613 | 0 | return GetPromote()->IsInitialized(); |
614 | 839 | return bmInitialized; |
615 | 839 | }; |
616 | | |
617 | | const ScDPResultData* GetResultData() const override |
618 | 3.07k | { |
619 | | // pResultData is never changed, and on promotion is passed to new version |
620 | 3.07k | return pResultData; |
621 | 3.07k | } |
622 | | |
623 | | SCROW GetOrder() const override |
624 | 14.2k | { |
625 | | // mnOrder is never changed, and on promotion is passed to new version |
626 | 14.2k | return mnOrder; |
627 | 14.2k | } |
628 | | |
629 | | ScDPAggData* GetColTotal(tools::Long nMeasure) override |
630 | 0 | { |
631 | 0 | return Promote("GetColTotal")->GetColTotal(nMeasure); |
632 | 0 | } |
633 | | |
634 | | #if DUMP_PIVOT_TABLE |
635 | | void DumpState(const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos) const override; |
636 | | void Dump(int nIndent) const override; |
637 | | #endif |
638 | | }; |
639 | | |
640 | | class ScDPResultMemberFull : public ScDPResultMember |
641 | | { |
642 | | private: |
643 | | const ScDPResultData* pResultData; |
644 | | ScDPParentDimData aParentDimData; |
645 | | std::unique_ptr<ScDPResultDimension> pChildDimension; |
646 | | std::unique_ptr<ScDPDataMember> pDataRoot; |
647 | | std::unique_ptr<ScDPAggData> pColTotal; // to store column totals |
648 | | sal_uInt16 nMemberStep; // step to show details |
649 | | bool bHasElements:1; |
650 | | bool bForceSubTotal:1; |
651 | | bool bHasHiddenDetails:1; |
652 | | bool bInitialized:1; |
653 | | bool bAutoHidden:1; |
654 | | |
655 | | public: |
656 | | ScDPResultMemberFull(const ScDPResultData* pData, |
657 | | const ScDPParentDimData& rParentDimData); //! Ref |
658 | | ScDPResultMemberFull(const ScDPResultData* pData, bool bForceSub); |
659 | | ~ScDPResultMemberFull(); |
660 | | |
661 | | void LateInitFrom( |
662 | | LateInitParams& rParams, |
663 | | const ::std::vector< SCROW >& pItemData, |
664 | | size_t nPos, |
665 | | ScDPInitState& rInitState); |
666 | | void CheckShowEmpty( bool bShow = false ); |
667 | 16.9k | const ScDPResultData* GetResultData() const { return pResultData; } |
668 | | |
669 | 1.10M | bool IsAutoHidden() const { return bAutoHidden; }; |
670 | 80.8M | bool GetForceSubTotal() const { return bForceSubTotal; }; |
671 | 29.6k | bool IsInitialized() const { return bInitialized; }; |
672 | | // bHasHiddenDetails is set only if the "show details" flag is off, |
673 | | // and there was a child dimension to skip |
674 | 0 | bool HasHiddenDetails() const { return bHasHiddenDetails; } |
675 | 0 | void SetHasHiddenDetails() { bHasHiddenDetails = true; } |
676 | | |
677 | 31.4k | bool GetHasElements() const { return bHasElements; }; |
678 | 80.7M | void SetHasElements() { bHasElements = true; } |
679 | 0 | void SetInitialized() { bInitialized = true; } |
680 | 0 | void SetAutoHidden() { bAutoHidden = true; } |
681 | | |
682 | 78 | sal_uInt16 GetMemberStep(void) { return nMemberStep; } |
683 | 0 | void SetMemberStep(sal_uInt16 nStep) { nMemberStep = nStep; } |
684 | | |
685 | | void ProcessData( const ::std::vector<SCROW>& aChildMembers, |
686 | | const ScDPResultDimension* pDataDim, |
687 | | const ::std::vector<SCROW>& aDataMembers, |
688 | | const ::std::vector<ScDPValue>& aValues ); |
689 | | |
690 | | void DoAutoShow( ScDPResultMember* pRefMember ); |
691 | | |
692 | | void ResetResults(); |
693 | | |
694 | | #if DUMP_PIVOT_TABLE |
695 | | void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; |
696 | | |
697 | | void Dump(int nIndent) const; |
698 | | #endif |
699 | | |
700 | | //! this will be removed! |
701 | 1.12M | const ScDPResultDimension* GetChildDimension() const { return pChildDimension.get(); } |
702 | 319M | ScDPResultDimension* GetChildDimension() { return pChildDimension.get(); } |
703 | | |
704 | | void ResetChildDimension(); |
705 | | |
706 | 8.79k | ScDPDataMember* GetDataRoot() const { return pDataRoot.get(); } |
707 | | |
708 | 23.0k | const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref |
709 | 161M | const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref |
710 | 6.56M | const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref |
711 | 10.0M | SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref |
712 | | ScDPAggData* GetColTotal( tools::Long nMeasure ); |
713 | | }; |
714 | | |
715 | | class ScDPDataMember |
716 | | { |
717 | | private: |
718 | | const ScDPResultData* pResultData; |
719 | | const ScDPResultMember* pResultMember; //! Ref? |
720 | | std::unique_ptr<ScDPDataDimension> |
721 | | pChildDimension; |
722 | | ScDPAggData aAggregate; |
723 | | |
724 | | void UpdateValues( const ::std::vector<ScDPValue>& aValues, const ScDPSubTotalState& rSubState ); |
725 | | |
726 | | public: |
727 | | ScDPDataMember( const ScDPResultData* pData, const ScDPResultMember* pRes ); |
728 | | ~ScDPDataMember(); |
729 | | |
730 | | void InitFrom( const ScDPResultDimension* pDim ); |
731 | | |
732 | | OUString GetName() const; |
733 | | bool IsVisible() const; |
734 | | bool HasData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; |
735 | | |
736 | | bool IsNamedItem( SCROW nRow ) const; |
737 | | bool HasHiddenDetails() const; |
738 | | |
739 | | void ProcessData( const ::std::vector< SCROW >& aChildMembers, const ::std::vector<ScDPValue>& aValues, |
740 | | const ScDPSubTotalState& rSubState ); |
741 | | bool HasError( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; |
742 | | double GetAggregate( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; |
743 | | const ScDPAggData* GetConstAggData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ) const; |
744 | | ScDPAggData* GetAggData( tools::Long nMeasure, const ScDPSubTotalState& rSubState ); |
745 | | |
746 | | void FillDataRow( |
747 | | const ScDPResultMember* pRefMember, |
748 | | ScDPResultFilterContext& rFilterCxt, |
749 | | css::uno::Sequence<css::sheet::DataResult>& rSequence, |
750 | | tools::Long nMeasure, bool bIsSubTotalRow, |
751 | | const ScDPSubTotalState& rSubState) const; |
752 | | |
753 | | void UpdateDataRow(const ScDPResultMember* pRefMember, tools::Long nMeasure, |
754 | | bool bIsSubTotalRow, const ScDPSubTotalState& rSubState); |
755 | | void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, |
756 | | bool bIsSubTotalRow, const ScDPSubTotalState& rSubState, |
757 | | ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals, |
758 | | const ScDPResultMember& rRowParent); |
759 | | |
760 | | void SortMembers(ScDPResultMember* pRefMember); |
761 | | void DoAutoShow(ScDPResultMember* pRefMember); |
762 | | |
763 | | void ResetResults(); |
764 | | |
765 | | // function resolver |
766 | | static tools::Long FindMeasureIndex(const std::vector<OUString>& rNames, const OUString& rName); |
767 | | std::unique_ptr<ScTokenArray> ReplaceTokenMeasuresWithValues(const ScTokenArray* pArray, |
768 | | const ScDPSubTotalState& rSubState, std::unordered_set<tools::Long>& rRecStack); |
769 | | |
770 | | #if DUMP_PIVOT_TABLE |
771 | | void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; |
772 | | void Dump(int nIndent) const; |
773 | | #endif |
774 | | |
775 | | //! this will be removed! |
776 | 4.85k | const ScDPDataDimension* GetChildDimension() const { return pChildDimension.get(); } |
777 | 11.6k | ScDPDataDimension* GetChildDimension() { return pChildDimension.get(); } |
778 | | }; |
779 | | |
780 | | // result dimension contains only members |
781 | | |
782 | | class ScDPResultDimension |
783 | | { |
784 | | public: |
785 | | typedef std::vector<std::unique_ptr<ScDPResultMember>> MemberArray; |
786 | | private: |
787 | | const ScDPResultData* pResultData; |
788 | | MemberArray maMemberArray; |
789 | | // Used during 'Promote' of ScDPResultMember |
790 | | ScDPDimension* mpDimension; |
791 | | ScDPLevel* mpLevel; |
792 | | MemberArray maPromotedMembers; |
793 | | |
794 | | OUString aDimensionName; //! or ptr to IntDimension? |
795 | | tools::Long nSortMeasure; |
796 | | ScMemberSortOrder aMemberOrder; // used when sorted by measure |
797 | | bool bIsDataLayout:1; //! or ptr to IntDimension? |
798 | | bool bSortByData:1; |
799 | | bool bSortAscending:1; |
800 | | bool bAutoShow:1; |
801 | | bool bAutoTopItems:1; |
802 | | bool bInitialized:1; |
803 | | tools::Long nAutoMeasure; |
804 | | tools::Long nAutoCount; |
805 | | |
806 | | ScDPResultMember* FindMember( SCROW iData ) const; |
807 | | ScDPResultMember* AddMember( const ScDPParentDimData& aData ); |
808 | | ScDPResultMember* InsertMember( const ScDPParentDimData* pMemberData ); |
809 | | void InitWithMembers( LateInitParams& rParams, |
810 | | const ::std::vector< SCROW >& pItemData, |
811 | | size_t nPos, |
812 | | ScDPInitState& rInitState ); |
813 | | public: |
814 | | ScDPResultDimension( const ScDPResultData* pData ); |
815 | | ~ScDPResultDimension(); |
816 | | |
817 | | // allocates new members |
818 | | void InitFrom( |
819 | | const ::std::vector<ScDPDimension*>& ppDim, const ::std::vector<ScDPLevel*>& ppLev, |
820 | | size_t nPos, ScDPInitState& rInitState, bool bInitChild = true ); |
821 | | void LateInitFrom( LateInitParams& rParams, |
822 | | const ::std::vector< SCROW >& pItemData, |
823 | | size_t nPos, |
824 | | ScDPInitState& rInitState ); |
825 | | void CheckShowEmpty( bool bShow = false ); |
826 | | |
827 | | tools::Long GetSize(tools::Long nMeasure) const; |
828 | | |
829 | | bool IsValidEntry( const ::std::vector<SCROW>& aMembers ) const; |
830 | | |
831 | | // modifies existing members, allocates data dimensions |
832 | | void ProcessData( const ::std::vector<SCROW>& aMembers, |
833 | | const ScDPResultDimension* pDataDim, |
834 | | const ::std::vector<SCROW>& aDataMembers, |
835 | | const ::std::vector<ScDPValue>& aValues ) const; //! Test |
836 | | void FillMemberResults( css::uno::Sequence< |
837 | | css::sheet::MemberResult>* pSequences, |
838 | | tools::Long nStart, tools::Long nMeasure ); |
839 | | |
840 | | void FillDataResults( |
841 | | const ScDPResultMember* pRefMember, |
842 | | ScDPResultFilterContext& rFilterCxt, |
843 | | css::uno::Sequence< |
844 | | css::uno::Sequence< |
845 | | css::sheet::DataResult> >& rSequence, |
846 | | tools::Long nMeasure) const; |
847 | | |
848 | | void UpdateDataResults(const ScDPResultMember* pRefMember, tools::Long nMeasure) const; |
849 | | void UpdateRunningTotals(ScDPResultMember* pRefMember, tools::Long nMeasure, |
850 | | ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals) const; |
851 | | |
852 | | void SortMembers(ScDPResultMember* pRefMember); |
853 | | tools::Long GetSortedIndex( tools::Long nUnsorted ) const; |
854 | | |
855 | | void DoAutoShow(ScDPResultMember* pRefMember); |
856 | | |
857 | | void ResetResults(); |
858 | | |
859 | | // called for the reference dimension |
860 | | ScDPDataMember* GetRowReferenceMember( |
861 | | const ScDPRelativePos* pMemberPos, const OUString* pName, |
862 | | const sal_Int32* pRowIndexes, const sal_Int32* pColIndexes ) const; |
863 | | |
864 | | // uses row root member from ScDPRunningTotalState |
865 | | static ScDPDataMember* GetColReferenceMember( |
866 | | const ScDPRelativePos* pMemberPos, const OUString* pName, |
867 | | sal_Int32 nRefDimPos, const ScDPRunningTotalState& rRunning ); |
868 | | |
869 | | #if DUMP_PIVOT_TABLE |
870 | | void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; |
871 | | void Dump(int nIndent) const; |
872 | | #endif |
873 | | |
874 | | // for ScDPDataDimension::InitFrom |
875 | | tools::Long GetMemberCount() const; |
876 | | const ScDPResultMember* GetMember(tools::Long n) const; |
877 | | ScDPResultMember* GetMember(tools::Long n); |
878 | | |
879 | 751 | const ScMemberSortOrder& GetMemberOrder() const { return aMemberOrder; } |
880 | 4.08k | ScMemberSortOrder& GetMemberOrder() { return aMemberOrder; } |
881 | | |
882 | 1.52k | bool IsDataLayout() const { return bIsDataLayout; } |
883 | 987 | const OUString& GetName() const { return aDimensionName; } |
884 | | |
885 | 96 | bool IsSortByData() const { return bSortByData; } |
886 | 0 | bool IsSortAscending() const { return bSortAscending; } |
887 | 0 | tools::Long GetSortMeasure() const { return nSortMeasure; } |
888 | | |
889 | 0 | bool IsAutoShow() const { return bAutoShow; } |
890 | 0 | bool IsAutoTopItems() const { return bAutoTopItems; } |
891 | 0 | tools::Long GetAutoMeasure() const { return nAutoMeasure; } |
892 | 0 | tools::Long GetAutoCount() const { return nAutoCount; } |
893 | | |
894 | | ScDPResultDimension* GetFirstChildDimension() const; |
895 | | |
896 | | void FillVisibilityData(ScDPResultVisibilityData& rData) const; |
897 | | |
898 | | // Called by an ScDPResultMemberSlim which has already been promoted |
899 | | // but something with an older pointer calls one of its member functions |
900 | | ScDPResultMember* GetPromote(SCROW nOrder) const; |
901 | | |
902 | | // Called by an ScDPResultMemberSlim when a member function needs |
903 | | // to do something which Slim can't represent |
904 | | ScDPResultMember* Promote(ScDPResultMemberSlim* pSlim, SCROW nOrder); |
905 | | |
906 | | // Called by an ScDPResultMemberSlim to get it's parent information |
907 | 0 | ScDPDimension* GetParentDimForResult() { return mpDimension; }; |
908 | 83 | ScDPLevel* GetParentLevelForResult() { return mpLevel; }; |
909 | | }; |
910 | | |
911 | | class ScDPDataDimension |
912 | | { |
913 | | private: |
914 | | const ScDPResultData* pResultData; |
915 | | const ScDPResultDimension* pResultDimension; // column |
916 | | std::vector<std::unique_ptr<ScDPDataMember>> maMembers; |
917 | | bool bIsDataLayout; //! or ptr to IntDimension? |
918 | | |
919 | | public: |
920 | | ScDPDataDimension( const ScDPResultData* pData ); |
921 | | ~ScDPDataDimension(); |
922 | | |
923 | | void InitFrom( const ScDPResultDimension* pDim ); // recursive |
924 | | void ProcessData( const ::std::vector< SCROW >& aDataMembers, const ::std::vector<ScDPValue>& aValues, |
925 | | const ScDPSubTotalState& rSubState ); |
926 | | void FillDataRow( |
927 | | const ScDPResultDimension* pRefDim, |
928 | | ScDPResultFilterContext& rFilterCxt, |
929 | | css::uno::Sequence<css::sheet::DataResult>& rSequence, |
930 | | tools::Long nMeasure, bool bIsSubTotalRow, const ScDPSubTotalState& rSubState) const; |
931 | | |
932 | | void UpdateDataRow( const ScDPResultDimension* pRefDim, tools::Long nMeasure, bool bIsSubTotalRow, |
933 | | const ScDPSubTotalState& rSubState ) const; |
934 | | void UpdateRunningTotals( ScDPResultDimension* pRefDim, tools::Long nMeasure, bool bIsSubTotalRow, |
935 | | const ScDPSubTotalState& rSubState, ScDPRunningTotalState& rRunning, |
936 | | ScDPRowTotals& rTotals, const ScDPResultMember& rRowParent ) const; |
937 | | |
938 | | void SortMembers( ScDPResultDimension* pRefDim ); |
939 | | tools::Long GetSortedIndex( tools::Long nUnsorted ) const; |
940 | | |
941 | | void DoAutoShow( ScDPResultDimension* pRefDim ); |
942 | | |
943 | | void ResetResults(); |
944 | | |
945 | | #if DUMP_PIVOT_TABLE |
946 | | void DumpState( const ScDPResultDimension* pRefDim, ScDocument* pDoc, ScAddress& rPos ) const; |
947 | | void Dump(int nIndent) const; |
948 | | #endif |
949 | | |
950 | | tools::Long GetMemberCount() const; |
951 | | const ScDPDataMember* GetMember(tools::Long n) const; |
952 | | ScDPDataMember* GetMember(tools::Long n); |
953 | | }; |
954 | | |
955 | | /** |
956 | | * This class collects visible members of each dimension and uses that |
957 | | * information to create filtering criteria (e.g. for drill-down data). |
958 | | */ |
959 | | class ScDPResultVisibilityData |
960 | | { |
961 | | public: |
962 | | ScDPResultVisibilityData( ScDPSource* pSource); |
963 | | ~ScDPResultVisibilityData(); |
964 | | |
965 | | void addVisibleMember(const OUString& rDimName, const ScDPItemData& rMemberItem); |
966 | | void fillFieldFilters(::std::vector<ScDPFilteredCache::Criterion>& rFilters) const; |
967 | | |
968 | | private: |
969 | | struct MemberHash |
970 | | { |
971 | | size_t operator()(const ScDPItemData& r) const; |
972 | | }; |
973 | | typedef std::unordered_set<ScDPItemData, MemberHash> VisibleMemberType; |
974 | | typedef std::unordered_map<OUString, VisibleMemberType> DimMemberType; |
975 | | DimMemberType maDimensions; |
976 | | |
977 | | ScDPSource* mpSource; |
978 | | }; |
979 | | |
980 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |