Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / dpitemdata.cxx
blob0598379dc586d901e15c0cbb54632b3f07a26389
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "dpitemdata.hxx"
22 #include "document.hxx"
23 #include "dpobject.hxx"
24 #include "formulacell.hxx"
25 #include "globstr.hrc"
26 #include "dptabdat.hxx"
27 #include "rtl/math.hxx"
29 const sal_Int32 ScDPItemData::DateFirst = -1;
30 const sal_Int32 ScDPItemData::DateLast = 10000;
32 size_t ScDPItemData::Hash::operator() (const ScDPItemData& rVal) const
34 switch (rVal.GetType())
36 case GroupValue:
37 case Value:
38 case RangeStart:
39 return (size_t)(rVal.mfValue);
40 case String:
41 case Error:
43 if (!rVal.mpString)
44 return 0;
46 if (rVal.mbStringInterned)
47 return reinterpret_cast<size_t>(rVal.mpString);
49 OUStringHash aStrHasher;
50 return aStrHasher(*rVal.mpString);
52 default:
56 return 0;
59 sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
61 if (rA.meType != rB.meType)
63 // group value, value and string in this order. Ensure that the empty
64 // type comes last.
65 return rA.meType < rB.meType ? -1 : 1;
68 switch (rA.meType)
70 case GroupValue:
72 if (rA.maGroupValue.mnGroupType == rB.maGroupValue.mnGroupType)
74 if (rA.maGroupValue.mnValue == rB.maGroupValue.mnValue)
75 return 0;
77 return rA.maGroupValue.mnValue < rB.maGroupValue.mnValue ? -1 : 1;
80 return rA.maGroupValue.mnGroupType < rB.maGroupValue.mnGroupType ? -1 : 1;
82 case Value:
83 case RangeStart:
85 if (rA.mfValue == rB.mfValue)
86 return 0;
88 return rA.mfValue < rB.mfValue ? -1 : 1;
90 case String:
91 case Error:
92 if (rA.mpString == rB.mpString)
93 // strings may be interned.
94 return 0;
96 return ScGlobal::GetCollator()->compareString(rA.GetString(), rB.GetString());
97 default:
100 return 0;
103 ScDPItemData::ScDPItemData() :
104 mfValue(0.0), meType(Empty), mbStringInterned(false) {}
106 ScDPItemData::ScDPItemData(const ScDPItemData& r) :
107 meType(r.meType), mbStringInterned(r.mbStringInterned)
109 switch (r.meType)
111 case String:
112 case Error:
113 mpString = mbStringInterned ? r.mpString : new OUString(*r.mpString);
114 break;
115 case Value:
116 case RangeStart:
117 mfValue = r.mfValue;
118 break;
119 case GroupValue:
120 maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
121 maGroupValue.mnValue = r.maGroupValue.mnValue;
122 break;
123 case Empty:
124 default:
125 mfValue = 0.0;
129 void ScDPItemData::DisposeString()
131 if (!mbStringInterned)
133 if (meType == String || meType == Error)
134 delete mpString;
137 mbStringInterned = false;
140 ScDPItemData::ScDPItemData(const OUString& rStr) :
141 mpString(new OUString(rStr)), meType(String), mbStringInterned(false) {}
143 ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
144 meType(GroupValue), mbStringInterned(false)
146 maGroupValue.mnGroupType = nGroupType;
147 maGroupValue.mnValue = nValue;
150 ScDPItemData::~ScDPItemData()
152 DisposeString();
155 ScDPItemData::Type ScDPItemData::GetType() const
157 return static_cast<Type>(meType);
160 void ScDPItemData::SetEmpty()
162 DisposeString();
163 meType = Empty;
166 void ScDPItemData::SetString(const OUString& rS)
168 DisposeString();
169 mpString = new OUString(rS);
170 meType = String;
173 void ScDPItemData::SetString(const OUString* pS)
175 DisposeString();
176 mpString = pS;
177 meType = String;
178 mbStringInterned = true;
181 void ScDPItemData::SetValue(double fVal)
183 DisposeString();
184 mfValue = fVal;
185 meType = Value;
188 void ScDPItemData::SetRangeStart(double fVal)
190 DisposeString();
191 mfValue = fVal;
192 meType = RangeStart;
195 void ScDPItemData::SetRangeFirst()
197 DisposeString();
198 rtl::math::setInf(&mfValue, true);
199 meType = RangeStart;
202 void ScDPItemData::SetRangeLast()
204 DisposeString();
205 rtl::math::setInf(&mfValue, false);
206 meType = RangeStart;
209 void ScDPItemData::SetErrorString(const OUString* pS)
211 SetString(pS);
212 meType = Error;
215 bool ScDPItemData::IsCaseInsEqual(const ScDPItemData& r) const
217 if (meType != r.meType)
218 return false;
220 switch (meType)
222 case Value:
223 case RangeStart:
224 return rtl::math::approxEqual(mfValue, r.mfValue);
225 case GroupValue:
226 return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
227 maGroupValue.mnValue == r.maGroupValue.mnValue;
228 default:
232 if (mpString == r.mpString)
233 // Fast equality check for interned strings.
234 return true;
236 return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
239 bool ScDPItemData::operator== (const ScDPItemData& r) const
241 if (meType != r.meType)
242 return false;
244 switch (meType)
246 case Value:
247 case RangeStart:
248 return rtl::math::approxEqual(mfValue, r.mfValue);
249 case GroupValue:
250 return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
251 maGroupValue.mnValue == r.maGroupValue.mnValue;
252 default:
256 // need exact equality until we have a safe case insensitive string hash
257 return GetString() == r.GetString();
260 bool ScDPItemData::operator!= (const ScDPItemData& r) const
262 return !operator== (r);
265 bool ScDPItemData::operator< (const ScDPItemData& r) const
267 return Compare(*this, r) == -1;
270 ScDPItemData& ScDPItemData::operator= (const ScDPItemData& r)
272 DisposeString();
273 meType = r.meType;
274 mbStringInterned = false;
275 switch (r.meType)
277 case String:
278 case Error:
279 mpString = r.mbStringInterned ? r.mpString : new OUString(*r.mpString);
280 mbStringInterned = r.mbStringInterned;
281 break;
282 case Value:
283 case RangeStart:
284 mfValue = r.mfValue;
285 break;
286 case GroupValue:
287 maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
288 maGroupValue.mnValue = r.maGroupValue.mnValue;
289 break;
290 case Empty:
291 default:
292 mfValue = 0.0;
294 return *this;
297 ScDPValue::Type ScDPItemData::GetCellType() const
299 switch (meType)
301 case Error:
302 return ScDPValue::Error;
303 case Empty:
304 return ScDPValue::Empty;
305 case Value:
306 return ScDPValue::Value;
307 default:
311 return ScDPValue::String;
314 #if DEBUG_PIVOT_TABLE
316 void ScDPItemData::Dump(const char* msg) const
318 printf("--- (%s)\n", msg);
319 switch (meType)
321 case Empty:
322 printf("empty\n");
323 break;
324 case Error:
325 printf("error: %s\n",
326 OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
327 break;
328 case GroupValue:
329 printf("group value: group type = %d value = %d\n",
330 maGroupValue.mnGroupType, maGroupValue.mnValue);
331 break;
332 case String:
333 printf("string: %s\n",
334 OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
335 break;
336 case Value:
337 printf("value: %g\n", mfValue);
338 break;
339 case RangeStart:
340 printf("range start: %g\n", mfValue);
341 break;
342 default:
343 printf("unknown type\n");
345 printf("---\n");
347 #endif
349 bool ScDPItemData::IsEmpty() const
351 return meType == Empty;
354 bool ScDPItemData::IsValue() const
356 return meType == Value;
359 OUString ScDPItemData::GetString() const
361 switch (meType)
363 case String:
364 case Error:
365 return *mpString;
366 case Value:
367 case RangeStart:
368 return OUString::number(mfValue);
369 case GroupValue:
370 return OUString::number(maGroupValue.mnValue);
371 case Empty:
372 default:
376 return OUString();
379 double ScDPItemData::GetValue() const
381 if (meType == Value || meType == RangeStart)
382 return mfValue;
384 return 0.0;
387 ScDPItemData::GroupValueAttr ScDPItemData::GetGroupValue() const
389 if (meType == GroupValue)
390 return maGroupValue;
392 GroupValueAttr aGV;
393 aGV.mnGroupType = -1;
394 aGV.mnValue = -1;
395 return aGV;
398 bool ScDPItemData::HasStringData() const
400 return meType == String || meType == Error;
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */