summaryrefslogtreecommitdiff
path: root/sc/inc/dpresfilter.hxx
blob: 2f283837200af477e0524556c89bec14501f108e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDED_SC_INC_DPRESFILTER_HXX
#define INCLUDED_SC_INC_DPRESFILTER_HXX

#include <rtl/ustring.hxx>
#include <tools/long.hxx>
#include "calcmacros.hxx"

#include <memory>
#include <map>
#include <vector>
#include <unordered_map>

namespace com::sun::star::uno { template <typename > class Sequence; }
namespace com::sun::star::sheet { struct DataPilotFieldFilter; }

struct ScDPResultFilter
{
    OUString maDimName;
    OUString maValueName;
    OUString maValue;

    bool mbHasValue:1;
    bool mbDataLayout:1;

    ScDPResultFilter(const OUString& rDimName, bool bDataLayout);
};

/**
 * This class maintains pivot table calculation result in a tree structure
 * which represents the logical structure of pivot table result layout as
 * presented in the sheet.
 *
 * <p>The root node has two child nodes if the pivot table consists of both
 * column and row dimensions. The first child stores the result tree that is
 * first filtered by row dimensions then by column dimensions. The second
 * child stores the result tree that is filtered by column dimensions only
 * (for column grand totals).</p>
 *
 * <p>If the pivot table layout only consists of either column or row
 * dimensions, the root node only has one child node.</p>
 */
class ScDPResultTree
{
public:
    typedef std::vector<double> ValuesType;

private:

    struct MemberNode;
    typedef std::map<OUString, std::shared_ptr<MemberNode> > MembersType;

    struct DimensionNode
    {
        MembersType maChildMembersValueNames;
        MembersType maChildMembersValues;

        DimensionNode();
        DimensionNode(const DimensionNode&) = delete;
        const DimensionNode& operator=(const DimensionNode&) = delete;
        ~DimensionNode();

#if DEBUG_PIVOT_TABLE
        void dump(int nLevel) const;
#endif
    };

    struct MemberNode
    {
        ValuesType maValues;
        std::map<OUString, std::unique_ptr<DimensionNode>> maChildDimensions;

        MemberNode();
        MemberNode(const MemberNode&) = delete;
        const MemberNode& operator=(const MemberNode&) = delete;
        ~MemberNode();

#if DEBUG_PIVOT_TABLE
        void dump(int nLevel) const;
#endif
    };

    typedef std::pair<OUString, OUString> NamePairType;

    struct NamePairHash
    {
        size_t operator() (const NamePairType& rPair) const;
    };
    typedef std::unordered_map<NamePairType, double, NamePairHash> LeafValuesType;
    LeafValuesType maLeafValues;

    OUString maPrimaryDimName;
    std::unique_ptr<MemberNode> mpRoot;

public:

    ScDPResultTree();
    ScDPResultTree(const ScDPResultTree&) = delete;
    const ScDPResultTree& operator=(const ScDPResultTree&) = delete;
    ~ScDPResultTree();
    /**
     * Add a single value filter path.  The filters are expected to be sorted
     * by row dimension order then by column dimension order.
     *
     * @param rFilter set of filters.
     * @param fVal result value, as displayed in the table output.
     */
    void add(const std::vector<ScDPResultFilter>& rFilter, double fVal);

    void swap(ScDPResultTree& rOther);

    bool empty() const;
    void clear();

    const ValuesType* getResults(
        const css::uno::Sequence< css::sheet::DataPilotFieldFilter>& rFilters) const;

    double getLeafResult(const css::sheet::DataPilotFieldFilter& rFilter) const;

#if DEBUG_PIVOT_TABLE
    void dump() const;
#endif
};

struct ScDPResultFilterContext
{
    ScDPResultTree maFilterSet;
    std::vector<ScDPResultFilter> maFilters;
    tools::Long mnCol;
    tools::Long mnRow;

    ScDPResultFilterContext();
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */