KUnitConversion

unitcategory.cpp
1/*
2 * SPDX-FileCopyrightText: 2007-2009 Petri Damstén <damu@iki.fi>
3 * SPDX-FileCopyrightText: 2014 John Layt <jlayt@kde.org>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#include "unitcategory.h"
9#include "unit_p.h"
10#include "unitcategory_p.h"
11
12#include <KLocalizedString>
13
14#include <QNetworkReply>
15
16#include <QNetworkAccessManager>
17#include <QStandardPaths>
18
19namespace KUnitConversion
20{
21UnitCategoryPrivate::UnitCategoryPrivate()
22 : m_id(InvalidCategory)
23{
24}
25
26UnitCategoryPrivate::UnitCategoryPrivate(CategoryId id, const QString &name, const QString &description)
27 : m_id(id)
28 , m_name(name)
29 , m_description(description)
30{
31}
32
33UnitCategoryPrivate::~UnitCategoryPrivate()
34{
35}
36
37UnitCategoryPrivate *UnitCategoryPrivate::clone()
38{
39 return new UnitCategoryPrivate(*this);
40}
41
42bool UnitCategoryPrivate::operator==(const UnitCategoryPrivate &other) const
43{
44 return (m_id == other.m_id);
45}
46
47bool UnitCategoryPrivate::operator!=(const UnitCategoryPrivate &other) const
48{
49 return !(*this == other);
50}
51
52QNetworkAccessManager *UnitCategoryPrivate::nam()
53{
54 static std::unique_ptr<QNetworkAccessManager> s_nam;
55 if (!s_nam) {
56 s_nam = std::make_unique<QNetworkAccessManager>();
57 s_nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
58 s_nam->setStrictTransportSecurityEnabled(true);
59 s_nam->enableStrictTransportSecurityStore(true, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/org.kde.unitconversion/hsts/"));
60 }
61 return s_nam.get();
62}
63
64Value UnitCategoryPrivate::convert(const Value &value, const Unit &toUnit)
65{
66 qreal v = value.unit().toDefault(value.number());
67 return Value(toUnit.fromDefault(v), toUnit);
68}
69
70UnitCategory::UnitCategory()
71 : d(nullptr)
72{
73}
74
75UnitCategory::UnitCategory(UnitCategoryPrivate *dd)
76 : d(dd)
77{
78}
79
81 : d(other.d)
82{
83}
84
85UnitCategory::~UnitCategory()
86{
87}
88
90{
91 d = other.d;
92 return *this;
93}
94
96{
97 d.swap(other.d);
98 return *this;
99}
100
102{
103 if (d && other.d) {
104 return (*d == *other.d);
105 } else {
106 return (d == other.d);
107 }
108}
109
111{
112 if (d && other.d) {
113 return (*d != *other.d);
114 } else {
115 return (d != other.d);
116 }
117}
118
120{
121 return !d;
122}
123
124CategoryId UnitCategory::id() const
125{
126 if (d) {
127 return d->m_id;
128 }
129 return InvalidCategory;
130}
131
133{
134 if (d) {
135 return d->m_units;
136 }
137 return QList<Unit>();
138}
139
141{
142 if (d) {
143 return d->m_mostCommonUnits;
144 }
145 return QList<Unit>();
146}
147
149{
150 if (d) {
151 return d->m_unitMap.keys();
152 }
153 return QStringList();
154}
155
156bool UnitCategory::hasUnit(const QString &unit) const
157{
158 if (d) {
159 return d->m_unitMap.contains(unit);
160 }
161 return false;
162}
163
164Value UnitCategory::convert(const Value &value, const QString &toUnit) const
165{
166 if (d && (toUnit.isEmpty() || d->m_unitMap.contains(toUnit)) && value.unit().isValid()) {
167 Unit to = toUnit.isEmpty() ? defaultUnit() : d->m_unitMap[toUnit];
168 return convert(value, to);
169 }
170 return Value();
171}
172
173Value UnitCategory::convert(const Value &value, UnitId toUnit) const
174{
175 if (d && d->m_idMap.contains(toUnit) && value.unit().isValid()) {
176 return convert(value, d->m_idMap[toUnit]);
177 }
178 return Value();
179}
180
181Value UnitCategory::convert(const Value &value, const Unit &toUnit) const
182{
183 if (d && !toUnit.isNull()) {
184 return d->convert(value, toUnit);
185 }
186 return Value();
187}
188
190{
191 if (d) {
192 return d->m_unitMap.value(s);
193 }
194 return Unit();
195}
196
197Unit UnitCategory::unit(UnitId unitId) const
198{
199 if (d && d->m_idMap.contains(unitId)) {
200 return d->m_idMap[unitId];
201 }
202 return Unit();
203}
204
206{
207 if (d) {
208 return d->m_name;
209 }
210 return QString();
211}
212
214{
215 if (d) {
216 return d->m_defaultUnit;
217 }
218 return Unit();
219}
220
222{
223 if (d) {
224 return d->m_description;
225 }
226 return QString();
227}
228
229void UnitCategoryPrivate::addDefaultUnit(const Unit &unit)
230{
231 addCommonUnit(unit);
232 m_defaultUnit = unit;
233}
234
235void UnitCategoryPrivate::addCommonUnit(const Unit &unit)
236{
237 addUnit(unit);
238 m_mostCommonUnits.append(unit);
239}
240
241void UnitCategoryPrivate::addUnit(const Unit &unit)
242{
243 // ### this is emulating a weak_ptr to break a reference cycle between Unit and UnitCategory
244 // ### even without that, this is slicing the polymorphic part of UnitCategory
245 // this only works by chance as apart from the ctors those parts contain no logic or data it seems
246 unit.d->m_category = this;
247 const QStringList list = unit.d->m_matchString.split(QLatin1Char(';'), Qt::SkipEmptyParts);
248 Q_ASSERT_X(!list.isEmpty(),
249 "UnitCategoryPrivate::addUnit",
250 QLatin1String("Empty match string for unit symbol: '%1' '%2' - fix translation?").arg(unit.symbol(), unit.description()).toUtf8().constData());
251
252 for (const QString &name : list) {
253 m_unitMap[name] = unit;
254 }
255 m_idMap[unit.id()] = unit;
256 m_units.append(unit);
257}
258
260{
261 return d->hasOnlineConversionTable();
262}
263
264UpdateJob* UnitCategory::syncConversionTable(std::chrono::seconds updateSkipPeriod)
265{
266 return d->syncConversionTable(updateSkipPeriod);
267}
268
269
270UpdateJob::UpdateJob(QNetworkReply *reply)
271 : d(reply)
272{
273 connect(d, &QNetworkReply::finished, this, &UpdateJob::finished);
275}
276
277UpdateJob::~UpdateJob() = default;
278
279}
280
281#include "moc_unitcategory.cpp"
Class to define a category of units of measurement.
QStringList allUnits() const
Return all unit names, short names and unit synonyms in this category.
UnitCategory()
Null constructor.
bool operator!=(const UnitCategory &other) const
UpdateJob * syncConversionTable(std::chrono::seconds updateSkipPeriod=std::chrono::hours(24))
Request an update of the online conversion table when it is older than updateSkipPeriod.
QList< Unit > units() const
Return units in this category.
bool operator==(const UnitCategory &other) const
Value convert(const Value &value, const QString &toUnit=QString()) const
Convert value to another unit selected by string.
Unit unit(const QString &s) const
Return unit for string.
Unit defaultUnit() const
Returns default unit.
QString name() const
Returns name for the unit category.
UnitCategory & operator=(const UnitCategory &other)
Assignment operator, assign other to this.
QList< Unit > mostCommonUnits() const
Return most common units in this category.
bool hasUnit(const QString &unit) const
Check if unit category has a unit.
Class to define a unit of measurement.
Definition unit.h:764
bool isNull() const
Definition unit.cpp:132
bool isValid() const
Definition unit.cpp:137
Dynamic conversion data update job.
Class to hold a value in a unit of measurement.
Definition value.h:36
Unit unit() const
Unit part of the value.
Definition value.cpp:156
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardAction id)
void swap(QExplicitlySharedDataPointer< T > &other)
bool isEmpty() const const
QNetworkReply * get(const QNetworkRequest &request)
void deleteLater()
QString writableLocation(StandardLocation type)
bool isEmpty() const const
SkipEmptyParts
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:06:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.