1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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())
39 return (size_t)(rVal
.mfValue
);
46 if (rVal
.mbStringInterned
)
47 return reinterpret_cast<size_t>(rVal
.mpString
);
49 OUStringHash aStrHasher
;
50 return aStrHasher(*rVal
.mpString
);
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
65 return rA
.meType
< rB
.meType
? -1 : 1;
72 if (rA
.maGroupValue
.mnGroupType
== rB
.maGroupValue
.mnGroupType
)
74 if (rA
.maGroupValue
.mnValue
== rB
.maGroupValue
.mnValue
)
77 return rA
.maGroupValue
.mnValue
< rB
.maGroupValue
.mnValue
? -1 : 1;
80 return rA
.maGroupValue
.mnGroupType
< rB
.maGroupValue
.mnGroupType
? -1 : 1;
85 if (rA
.mfValue
== rB
.mfValue
)
88 return rA
.mfValue
< rB
.mfValue
? -1 : 1;
92 if (rA
.mpString
== rB
.mpString
)
93 // strings may be interned.
96 return ScGlobal::GetCollator()->compareString(rA
.GetString(), rB
.GetString());
103 ScDPItemData::ScDPItemData() :
104 mfValue(0.0), meType(Empty
), mbStringInterned(false) {}
106 ScDPItemData::ScDPItemData(const ScDPItemData
& r
) :
107 meType(r
.meType
), mbStringInterned(r
.mbStringInterned
)
113 mpString
= mbStringInterned
? r
.mpString
: new OUString(*r
.mpString
);
120 maGroupValue
.mnGroupType
= r
.maGroupValue
.mnGroupType
;
121 maGroupValue
.mnValue
= r
.maGroupValue
.mnValue
;
129 void ScDPItemData::DisposeString()
131 if (!mbStringInterned
)
133 if (meType
== String
|| meType
== Error
)
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()
155 void ScDPItemData::SetEmpty()
161 void ScDPItemData::SetString(const OUString
& rS
)
164 mpString
= new OUString(rS
);
168 void ScDPItemData::SetString(const OUString
* pS
)
173 mbStringInterned
= true;
176 void ScDPItemData::SetValue(double fVal
)
183 void ScDPItemData::SetRangeStart(double fVal
)
190 void ScDPItemData::SetRangeFirst()
193 rtl::math::setInf(&mfValue
, true);
197 void ScDPItemData::SetRangeLast()
200 rtl::math::setInf(&mfValue
, false);
204 void ScDPItemData::SetErrorString(const OUString
* pS
)
210 bool ScDPItemData::IsCaseInsEqual(const ScDPItemData
& r
) const
212 if (meType
!= r
.meType
)
219 return rtl::math::approxEqual(mfValue
, r
.mfValue
);
221 return maGroupValue
.mnGroupType
== r
.maGroupValue
.mnGroupType
&&
222 maGroupValue
.mnValue
== r
.maGroupValue
.mnValue
;
227 if (mpString
== r
.mpString
)
228 // Fast equality check for interned strings.
231 return ScGlobal::GetpTransliteration()->isEqual(GetString(), r
.GetString());
234 bool ScDPItemData::operator== (const ScDPItemData
& r
) const
236 if (meType
!= r
.meType
)
243 return rtl::math::approxEqual(mfValue
, r
.mfValue
);
245 return maGroupValue
.mnGroupType
== r
.maGroupValue
.mnGroupType
&&
246 maGroupValue
.mnValue
== r
.maGroupValue
.mnValue
;
251 // need exact equality until we have a safe case insensitive string hash
252 return GetString() == r
.GetString();
255 bool ScDPItemData::operator!= (const ScDPItemData
& r
) const
257 return !operator== (r
);
260 bool ScDPItemData::operator< (const ScDPItemData
& r
) const
262 return Compare(*this, r
) == -1;
265 ScDPItemData
& ScDPItemData::operator= (const ScDPItemData
& r
)
269 mbStringInterned
= false;
274 mpString
= r
.mbStringInterned
? r
.mpString
: new OUString(*r
.mpString
);
275 mbStringInterned
= r
.mbStringInterned
;
282 maGroupValue
.mnGroupType
= r
.maGroupValue
.mnGroupType
;
283 maGroupValue
.mnValue
= r
.maGroupValue
.mnValue
;
292 ScDPValue::Type
ScDPItemData::GetCellType() const
297 return ScDPValue::Error
;
299 return ScDPValue::Empty
;
301 return ScDPValue::Value
;
306 return ScDPValue::String
;
309 #if DEBUG_PIVOT_TABLE
311 void ScDPItemData::Dump(const char* msg
) const
313 printf("--- (%s)\n", msg
);
320 printf("error: %s\n",
321 OUStringToOString(*mpString
, RTL_TEXTENCODING_UTF8
).getStr());
324 printf("group value: group type = %d value = %d\n",
325 maGroupValue
.mnGroupType
, maGroupValue
.mnValue
);
328 printf("string: %s\n",
329 OUStringToOString(*mpString
, RTL_TEXTENCODING_UTF8
).getStr());
332 printf("value: %g\n", mfValue
);
335 printf("range start: %g\n", mfValue
);
338 printf("unknown type\n");
344 bool ScDPItemData::IsEmpty() const
346 return meType
== Empty
;
349 bool ScDPItemData::IsValue() const
351 return meType
== Value
;
354 OUString
ScDPItemData::GetString() const
363 return OUString::number(mfValue
);
365 return OUString::number(maGroupValue
.mnValue
);
374 double ScDPItemData::GetValue() const
376 if (meType
== Value
|| meType
== RangeStart
)
382 ScDPItemData::GroupValueAttr
ScDPItemData::GetGroupValue() const
384 if (meType
== GroupValue
)
388 aGV
.mnGroupType
= -1;
393 bool ScDPItemData::HasStringData() const
395 return meType
== String
|| meType
== Error
;
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */