Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */