summaryrefslogtreecommitdiff
path: root/sc/inc/dpresfilter.hxx
blob: 059e931fdc062fa7bbdfcbe14978e35e799fea7e (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
146
/* -*- 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 "dpitemdata.hxx"

#include <map>
#include <vector>
#include <boost/noncopyable.hpp>
#include <boost/unordered_map.hpp>

namespace com { namespace sun { namespace star { namespace sheet {
    struct DataPilotFieldFilter;
}}}}

struct ScDPResultFilter
{
    OUString maDimName;
    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 : boost::noncopyable
{
public:
    typedef std::vector<double> ValuesType;

private:

    struct MemberNode;
    struct DimensionNode;
    typedef std::map<OUString, MemberNode*> MembersType;
    typedef std::map<OUString, DimensionNode*> DimensionsType;

    struct DimensionNode : boost::noncopyable
    {
        const MemberNode* mpParent;
        MembersType maChildMembers;

        DimensionNode(const MemberNode* pParent);
        ~DimensionNode();

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

    struct MemberNode : boost::noncopyable
    {
        const DimensionNode* mpParent;
        ValuesType maValues;
        DimensionsType maChildDimensions;

        MemberNode(const DimensionNode* pParent);
        ~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 boost::unordered_map<NamePairType, double, NamePairHash> LeafValuesType;
    LeafValuesType maLeafValues;

    OUString maPrimaryDimName;
    MemberNode* mpRoot;

public:

    ScDPResultTree();
    ~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 nCol column position relative to the top-left cell within the
     *             data field range.
     * @param nRow row position relative to the top-left cell within the data
     *             field range.
     * @param fVal result value, as displayed in the table output.
     */
    void add(const std::vector<ScDPResultFilter>& rFilter, long nCol, long nRow, double fVal);

    void swap(ScDPResultTree& rOther);

    bool empty() const;
    void clear();

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

    double getLeafResult(const com::sun::star::sheet::DataPilotFieldFilter& rFilter) const;

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

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

    ScDPResultFilterContext();
};

#endif

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