Line data Source code
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 :
10 : #include "dpresfilter.hxx"
11 : #include "global.hxx"
12 :
13 : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
14 :
15 : using namespace com::sun::star;
16 : using namespace std;
17 :
18 364 : ScDPResultFilter::ScDPResultFilter(const OUString& rDimName, bool bDataLayout) :
19 364 : maDimName(rDimName), mbHasValue(false), mbDataLayout(bDataLayout) {}
20 :
21 78 : ScDPResultFilterContext::ScDPResultFilterContext() :
22 78 : mnCol(0), mnRow(0) {}
23 :
24 355 : ScDPResultTree::DimensionNode::DimensionNode(const MemberNode* pParent) :
25 355 : mpParent(pParent) {}
26 :
27 710 : ScDPResultTree::DimensionNode::~DimensionNode()
28 : {
29 355 : MembersType::iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
30 1649 : for (; it != itEnd; ++it)
31 1294 : delete it->second;
32 355 : }
33 :
34 : #if DEBUG_PIVOT_TABLE
35 : void ScDPResultTree::DimensionNode::dump(int nLevel) const
36 : {
37 : string aIndent(nLevel*2, ' ');
38 : MembersType::const_iterator it = maChildMembers.begin(), itEnd = maChildMembers.end();
39 : for (; it != itEnd; ++it)
40 : {
41 : cout << aIndent << "member: ";
42 : const ScDPItemData& rVal = it->first;
43 : if (rVal.IsValue())
44 : cout << rVal.GetValue();
45 : else
46 : cout << rVal.GetString();
47 : cout << endl;
48 :
49 : it->second->dump(nLevel+1);
50 : }
51 : }
52 : #endif
53 :
54 1482 : ScDPResultTree::MemberNode::MemberNode(const DimensionNode* pParent) :
55 1482 : mpParent(pParent) {}
56 :
57 2964 : ScDPResultTree::MemberNode::~MemberNode()
58 : {
59 1482 : DimensionsType::iterator it = maChildDimensions.begin(), itEnd = maChildDimensions.end();
60 1837 : for (; it != itEnd; ++it)
61 355 : delete it->second;
62 1482 : }
63 :
64 : #if DEBUG_PIVOT_TABLE
65 : void ScDPResultTree::MemberNode::dump(int nLevel) const
66 : {
67 : string aIndent(nLevel*2, ' ');
68 : ValuesType::const_iterator itVal = maValues.begin(), itValEnd = maValues.end();
69 : for (; itVal != itValEnd; ++itVal)
70 : cout << aIndent << "value: " << *itVal << endl;
71 :
72 : DimensionsType::const_iterator it = maChildDimensions.begin(), itEnd = maChildDimensions.end();
73 : for (; it != itEnd; ++it)
74 : {
75 : cout << aIndent << "dimension: " << it->first << endl;
76 : it->second->dump(nLevel+1);
77 : }
78 : }
79 : #endif
80 :
81 180 : ScDPResultTree::ScDPResultTree() : mpRoot(new MemberNode(NULL)) {}
82 360 : ScDPResultTree::~ScDPResultTree()
83 : {
84 180 : delete mpRoot;
85 180 : }
86 :
87 1304 : void ScDPResultTree::add(
88 : const std::vector<ScDPResultFilter>& rFilters, long /*nCol*/, long /*nRow*/, double fVal)
89 : {
90 : // TODO: I'll work on the col / row to value node mapping later.
91 :
92 1304 : MemberNode* pMemNode = mpRoot;
93 :
94 1304 : std::vector<ScDPResultFilter>::const_iterator itFilter = rFilters.begin(), itFilterEnd = rFilters.end();
95 3497 : for (; itFilter != itFilterEnd; ++itFilter)
96 : {
97 2193 : const ScDPResultFilter& filter = *itFilter;
98 2193 : if (filter.mbDataLayout)
99 18 : continue;
100 :
101 2175 : if (maPrimaryDimName.isEmpty())
102 62 : maPrimaryDimName = filter.maDimName;
103 :
104 : // See if this dimension exists.
105 2175 : DimensionsType& rDims = pMemNode->maChildDimensions;
106 2175 : DimensionsType::iterator itDim = rDims.find(filter.maDimName);
107 2175 : if (itDim == rDims.end())
108 : {
109 : // New dimenison. Insert it.
110 : std::pair<DimensionsType::iterator, bool> r =
111 355 : rDims.insert(DimensionsType::value_type(filter.maDimName, new DimensionNode(pMemNode)));
112 :
113 355 : if (!r.second)
114 : // Insertion failed!
115 0 : return;
116 :
117 355 : itDim = r.first;
118 : }
119 :
120 : // Now, see if this dimension member exists.
121 2175 : DimensionNode* pDim = itDim->second;
122 2175 : MembersType& rMembers = pDim->maChildMembers;
123 2175 : MembersType::iterator itMem = rMembers.find(filter.maValue);
124 2175 : if (itMem == rMembers.end())
125 : {
126 : // New member. Insert it.
127 : std::pair<MembersType::iterator, bool> r =
128 : rMembers.insert(
129 1294 : MembersType::value_type(filter.maValue, new MemberNode(pDim)));
130 :
131 1294 : if (!r.second)
132 : // Insertion failed!
133 0 : return;
134 :
135 1294 : itMem = r.first;
136 : }
137 :
138 2175 : pMemNode = itMem->second;
139 : }
140 :
141 1304 : pMemNode->maValues.push_back(fVal);
142 : }
143 :
144 78 : void ScDPResultTree::swap(ScDPResultTree& rOther)
145 : {
146 78 : std::swap(maPrimaryDimName, rOther.maPrimaryDimName);
147 78 : std::swap(mpRoot, rOther.mpRoot);
148 78 : }
149 :
150 0 : bool ScDPResultTree::empty() const
151 : {
152 0 : return mpRoot->maChildDimensions.empty();
153 : }
154 :
155 8 : void ScDPResultTree::clear()
156 : {
157 8 : maPrimaryDimName = EMPTY_OUSTRING;
158 8 : delete mpRoot;
159 8 : mpRoot = new MemberNode(NULL);
160 8 : }
161 :
162 0 : const ScDPResultTree::ValuesType* ScDPResultTree::getResults(
163 : const uno::Sequence<sheet::DataPilotFieldFilter>& rFilters) const
164 : {
165 0 : const sheet::DataPilotFieldFilter* p = rFilters.getConstArray();
166 0 : const sheet::DataPilotFieldFilter* pEnd = p + static_cast<size_t>(rFilters.getLength());
167 0 : const MemberNode* pMember = mpRoot;
168 0 : for (; p != pEnd; ++p)
169 : {
170 0 : DimensionsType::const_iterator itDim = pMember->maChildDimensions.find(p->FieldName);
171 0 : if (itDim == pMember->maChildDimensions.end())
172 : // Specified dimension not found.
173 0 : return NULL;
174 :
175 0 : const DimensionNode* pDim = itDim->second;
176 0 : MembersType::const_iterator itMem = pDim->maChildMembers.find(p->MatchValue);
177 0 : if (itMem == pDim->maChildMembers.end())
178 : // Specified member not found.
179 0 : return NULL;
180 :
181 0 : pMember = itMem->second;
182 : }
183 :
184 0 : return &pMember->maValues;
185 : }
186 :
187 : #if DEBUG_PIVOT_TABLE
188 : void ScDPResultTree::dump() const
189 : {
190 : cout << "primary dimension name: " << maPrimaryDimName << endl;
191 : mpRoot->dump(0);
192 : }
193 : #endif
194 :
195 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|