Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License or as specified alternatively below. You may obtain a copy of
8 : : * the License at http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * Major Contributor(s):
16 : : * Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
17 : : *
18 : : * All Rights Reserved.
19 : : *
20 : : * For minor contributions see the git repository.
21 : : *
22 : : * Alternatively, the contents of this file may be used under the terms of
23 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : : * instead of those above.
27 : : */
28 : :
29 : : #include "dpitemdata.hxx"
30 : :
31 : : #include "document.hxx"
32 : : #include "dpobject.hxx"
33 : : #include "cell.hxx"
34 : : #include "globstr.hrc"
35 : : #include "dptabdat.hxx"
36 : : #include "rtl/math.hxx"
37 : :
38 : : const sal_Int32 ScDPItemData::DateFirst = -1;
39 : : const sal_Int32 ScDPItemData::DateLast = 10000;
40 : :
41 : 3527 : sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
42 : : {
43 [ + + ]: 3527 : if (rA.meType != rB.meType)
44 : : {
45 : : // group value, value and string in this order.
46 [ + + ]: 107 : return rA.meType < rB.meType ? -1 : 1;
47 : : }
48 : :
49 [ + + + + ]: 3420 : switch (rA.meType)
50 : : {
51 : : case GroupValue:
52 : : {
53 [ + - ]: 225 : if (rA.maGroupValue.mnGroupType == rB.maGroupValue.mnGroupType)
54 : : {
55 [ - + ]: 225 : if (rA.maGroupValue.mnValue == rB.maGroupValue.mnValue)
56 : 0 : return 0;
57 : :
58 [ + + ]: 225 : return rA.maGroupValue.mnValue < rB.maGroupValue.mnValue ? -1 : 1;
59 : : }
60 : :
61 [ # # ]: 0 : return rA.maGroupValue.mnGroupType < rB.maGroupValue.mnGroupType ? -1 : 1;
62 : : }
63 : : case Value:
64 : : case RangeStart:
65 : : {
66 [ + + ]: 2179 : if (rA.mfValue == rB.mfValue)
67 : 228 : return 0;
68 : :
69 [ + + ]: 1951 : return rA.mfValue < rB.mfValue ? -1 : 1;
70 : : }
71 : : case String:
72 : : case Error:
73 [ + + ]: 908 : if (rA.mpString == rB.mpString)
74 : : // strings may be interned.
75 : 177 : return 0;
76 : :
77 [ + - ][ + - ]: 731 : return ScGlobal::GetCollator()->compareString(rA.GetString(), rB.GetString());
[ + - ]
78 : : default:
79 : : ;
80 : : }
81 : 3527 : return 0;
82 : : }
83 : :
84 : 8583 : ScDPItemData::ScDPItemData() :
85 : 8583 : mfValue(0.0), meType(Empty), mbStringInterned(false) {}
86 : :
87 : 29641 : ScDPItemData::ScDPItemData(const ScDPItemData& r) :
88 : 29641 : meType(r.meType), mbStringInterned(r.mbStringInterned)
89 : : {
90 [ + + + + ]: 29641 : switch (r.meType)
91 : : {
92 : : case String:
93 : : case Error:
94 [ + + ]: 3302 : mpString = mbStringInterned ? r.mpString : new rtl::OUString(*r.mpString);
95 : 3302 : break;
96 : : case Value:
97 : : case RangeStart:
98 : 25416 : mfValue = r.mfValue;
99 : 25416 : break;
100 : : case GroupValue:
101 : 294 : maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
102 : 294 : maGroupValue.mnValue = r.maGroupValue.mnValue;
103 : 294 : break;
104 : : case Empty:
105 : : default:
106 : 629 : mfValue = 0.0;
107 : : }
108 : 29641 : }
109 : :
110 : 55828 : void ScDPItemData::DisposeString()
111 : : {
112 [ + + ]: 55828 : if (!mbStringInterned)
113 : : {
114 [ + + ][ - + ]: 50336 : if (meType == String || meType == Error)
115 [ + - ]: 721 : delete mpString;
116 : : }
117 : :
118 : 55828 : mbStringInterned = false;
119 : 55828 : }
120 : :
121 : 28 : ScDPItemData::ScDPItemData(const rtl::OUString& rStr) :
122 : 28 : mpString(new rtl::OUString(rStr)), meType(String), mbStringInterned(false) {}
123 : :
124 : 216 : ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
125 : 216 : meType(GroupValue), mbStringInterned(false)
126 : : {
127 : 216 : maGroupValue.mnGroupType = nGroupType;
128 : 216 : maGroupValue.mnValue = nValue;
129 : 216 : }
130 : :
131 : 38468 : ScDPItemData::~ScDPItemData()
132 : : {
133 : 38468 : DisposeString();
134 : 38468 : }
135 : :
136 : 3772 : ScDPItemData::Type ScDPItemData::GetType() const
137 : : {
138 : 3772 : return static_cast<Type>(meType);
139 : : }
140 : :
141 : 120 : void ScDPItemData::SetEmpty()
142 : : {
143 : 120 : DisposeString();
144 : 120 : meType = Empty;
145 : 120 : }
146 : :
147 : 261 : void ScDPItemData::SetString(const rtl::OUString& rS)
148 : : {
149 : 261 : DisposeString();
150 : 261 : mpString = new rtl::OUString(rS);
151 : 261 : meType = String;
152 : 261 : }
153 : :
154 : 454 : void ScDPItemData::SetString(const rtl::OUString* pS)
155 : : {
156 : 454 : DisposeString();
157 : 454 : mpString = pS;
158 : 454 : meType = String;
159 : 454 : mbStringInterned = true;
160 : 454 : }
161 : :
162 : 1114 : void ScDPItemData::SetValue(double fVal)
163 : : {
164 : 1114 : DisposeString();
165 : 1114 : mfValue = fVal;
166 : 1114 : meType = Value;
167 : 1114 : }
168 : :
169 : 63 : void ScDPItemData::SetRangeStart(double fVal)
170 : : {
171 : 63 : DisposeString();
172 : 63 : mfValue = fVal;
173 : 63 : meType = RangeStart;
174 : 63 : }
175 : :
176 : 3 : void ScDPItemData::SetRangeFirst()
177 : : {
178 : 3 : DisposeString();
179 : 3 : rtl::math::setInf(&mfValue, true);
180 : 3 : meType = RangeStart;
181 : 3 : }
182 : :
183 : 3 : void ScDPItemData::SetRangeLast()
184 : : {
185 : 3 : DisposeString();
186 : 3 : rtl::math::setInf(&mfValue, false);
187 : 3 : meType = RangeStart;
188 : 3 : }
189 : :
190 : 0 : void ScDPItemData::SetErrorString(const rtl::OUString* pS)
191 : : {
192 : 0 : SetString(pS);
193 : 0 : meType = Error;
194 : 0 : }
195 : :
196 : 3248 : bool ScDPItemData::IsCaseInsEqual(const ScDPItemData& r) const
197 : : {
198 [ + + ]: 3248 : if (meType != r.meType)
199 : 86 : return false;
200 : :
201 [ + - + ]: 3162 : switch (meType)
202 : : {
203 : : case Value:
204 : : case RangeStart:
205 : 1836 : return rtl::math::approxEqual(mfValue, r.mfValue);
206 : : case GroupValue:
207 : : return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
208 [ # # ][ # # ]: 0 : maGroupValue.mnValue == r.maGroupValue.mnValue;
209 : : default:
210 : : ;
211 : : }
212 : :
213 [ + + ][ + - ]: 1326 : if (mbStringInterned && r.mbStringInterned && mpString == r.mpString)
[ + + ]
214 : : // Fast equality check for interned strings.
215 : 261 : return true;
216 : :
217 [ + - ][ + - ]: 3248 : return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
218 : : }
219 : :
220 : 6485 : bool ScDPItemData::operator== (const ScDPItemData& r) const
221 : : {
222 [ + + ]: 6485 : if (meType != r.meType)
223 : 1248 : return false;
224 : :
225 [ + + + ]: 5237 : switch (meType)
226 : : {
227 : : case Value:
228 : : case RangeStart:
229 : 4483 : return rtl::math::approxEqual(mfValue, r.mfValue);
230 : : case GroupValue:
231 : : return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
232 [ + - ][ + + ]: 354 : maGroupValue.mnValue == r.maGroupValue.mnValue;
233 : : default:
234 : : ;
235 : : }
236 : :
237 : : // need exact equality until we have a safe case insensitive string hash
238 [ + - ]: 6485 : return GetString() == r.GetString();
239 : : }
240 : :
241 : 0 : bool ScDPItemData::operator!= (const ScDPItemData& r) const
242 : : {
243 : 0 : return !operator== (r);
244 : : }
245 : :
246 : 3100 : bool ScDPItemData::operator< (const ScDPItemData& r) const
247 : : {
248 : 3100 : return Compare(*this, r) == -1;
249 : : }
250 : :
251 : 15342 : ScDPItemData& ScDPItemData::operator= (const ScDPItemData& r)
252 : : {
253 : 15342 : DisposeString();
254 : 15342 : meType = r.meType;
255 : 15342 : mbStringInterned = false;
256 [ + + + + ]: 15342 : switch (r.meType)
257 : : {
258 : : case String:
259 : : case Error:
260 [ + + ]: 2168 : mpString = r.mbStringInterned ? r.mpString : new rtl::OUString(*r.mpString);
261 : 2168 : mbStringInterned = r.mbStringInterned;
262 : 2168 : break;
263 : : case Value:
264 : : case RangeStart:
265 : 12594 : mfValue = r.mfValue;
266 : 12594 : break;
267 : : case GroupValue:
268 : 147 : maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
269 : 147 : maGroupValue.mnValue = r.maGroupValue.mnValue;
270 : 147 : break;
271 : : case Empty:
272 : : default:
273 : 433 : mfValue = 0.0;
274 : : }
275 : 15342 : return *this;
276 : : }
277 : :
278 : 810 : sal_uInt8 ScDPItemData::GetCellType() const
279 : : {
280 [ - + + - ]: 810 : switch (meType)
281 : : {
282 : : case Error:
283 : 0 : return SC_VALTYPE_ERROR;
284 : : case Empty:
285 : 6 : return SC_VALTYPE_EMPTY;
286 : : case Value:
287 : 804 : return SC_VALTYPE_VALUE;
288 : : default:
289 : : ;
290 : : }
291 : :
292 : 810 : return SC_VALTYPE_STRING;
293 : : }
294 : :
295 : : #if DEBUG_PIVOT_TABLE
296 : : void ScDPItemData::Dump(const char* msg) const
297 : : {
298 : : printf("--- (%s)\n", msg);
299 : : switch (meType)
300 : : {
301 : : case Empty:
302 : : printf("empty\n");
303 : : break;
304 : : case Error:
305 : : printf("error: %s\n",
306 : : rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
307 : : break;
308 : : case GroupValue:
309 : : printf("group value: group type = %d value = %d\n",
310 : : maGroupValue.mnGroupType, maGroupValue.mnValue);
311 : : break;
312 : : case String:
313 : : printf("string: %s\n",
314 : : rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
315 : : break;
316 : : case Value:
317 : : printf("value: %g\n", mfValue);
318 : : break;
319 : : case RangeStart:
320 : : printf("range start: %g\n", mfValue);
321 : : break;
322 : : default:
323 : : printf("unknown type\n");
324 : : }
325 : : printf("---\n");
326 : : }
327 : : #endif
328 : :
329 : 1657 : bool ScDPItemData::IsEmpty() const
330 : : {
331 : 1657 : return meType == Empty;
332 : : }
333 : :
334 : 11308 : bool ScDPItemData::IsValue() const
335 : : {
336 : 11308 : return meType == Value;
337 : : }
338 : :
339 : 4961 : rtl::OUString ScDPItemData::GetString() const
340 : : {
341 [ + - - + ]: 4961 : switch (meType)
342 : : {
343 : : case String:
344 : : case Error:
345 : 4694 : return *mpString;
346 : : case Value:
347 : 0 : return rtl::OUString::valueOf(mfValue);
348 : : case GroupValue:
349 : : case RangeStart:
350 : 0 : return rtl::OUString::createFromAscii("fail");
351 : : case Empty:
352 : : default:
353 : : ;
354 : : }
355 : :
356 : 4961 : return rtl::OUString();
357 : : }
358 : :
359 : 13203 : double ScDPItemData::GetValue() const
360 : : {
361 [ + + ][ + - ]: 13203 : if (meType == Value || meType == RangeStart)
362 : 13203 : return mfValue;
363 : :
364 : 13203 : return 0.0;
365 : : }
366 : :
367 : 501 : ScDPItemData::GroupValueAttr ScDPItemData::GetGroupValue() const
368 : : {
369 [ + - ]: 501 : if (meType == GroupValue)
370 : 501 : return maGroupValue;
371 : :
372 : : GroupValueAttr aGV;
373 : 0 : aGV.mnGroupType = -1;
374 : 0 : aGV.mnValue = -1;
375 : 501 : return aGV;
376 : : }
377 : :
378 : 0 : bool ScDPItemData::HasStringData() const
379 : : {
380 [ # # ][ # # ]: 0 : return meType == String || meType == Error;
381 [ + - ][ + - ]: 153 : }
382 : :
383 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|