1/*
2 * SPDX-FileCopyrightText: 2008-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 "converter.h"
9
10#include "acceleration_p.h"
11#include "angle_p.h"
12#include "area_p.h"
13#include "binary_data_p.h"
14#include "currency_p.h"
15#include "density_p.h"
16#include "electrical_current_p.h"
17#include "electrical_resistance_p.h"
18#include "energy_p.h"
19#include "weight_per_area_p.h"
20#include "force_p.h"
21#include "frequency_p.h"
22#include "fuel_efficiency_p.h"
23#include "length_p.h"
24#include "mass_p.h"
25#include "permeability_p.h"
26#include "power_p.h"
27#include "pressure_p.h"
28#include "temperature_p.h"
29#include "thermal_conductivity_p.h"
30#include "thermal_flux_p.h"
31#include "thermal_generation_p.h"
32#include "timeunit_p.h"
33#include "unit.h"
34#include "velocity_p.h"
35#include "voltage_p.h"
36#include "volume_p.h"
37
38#include <KLocalizedString>
39
40namespace KUnitConversion
41{
42class ConverterPrivate : public QSharedData
43{
44public:
45 ConverterPrivate()
46 {
47 m_categories[LengthCategory] = Length::makeCategory();
48 m_categories[AreaCategory] = Area::makeCategory();
49 m_categories[VolumeCategory] = Volume::makeCategory();
50 m_categories[TemperatureCategory] = Temperature::makeCategory();
51 m_categories[VelocityCategory] = Velocity::makeCategory();
52 m_categories[MassCategory] = Mass::makeCategory();
53 m_categories[PressureCategory] = Pressure::makeCategory();
54 m_categories[EnergyCategory] = Energy::makeCategory();
55 m_categories[CurrencyCategory] = Currency::makeCategory();
56 m_categories[PowerCategory] = Power::makeCategory();
57 m_categories[TimeCategory] = Time::makeCategory();
58 m_categories[FuelEfficiencyCategory] = FuelEfficiency::makeCategory();
59 m_categories[DensityCategory] = Density::makeCategory();
60 m_categories[WeightPerAreaCategory] = WeightPerArea::makeCategory();
61 m_categories[AccelerationCategory] = Acceleration::makeCategory();
62 m_categories[ForceCategory] = Force::makeCategory();
63 m_categories[AngleCategory] = Angle::makeCategory();
64 m_categories[FrequencyCategory] = Frequency::makeCategory();
65 m_categories[ThermalConductivityCategory] = ThermalConductivity::makeCategory();
66 m_categories[ThermalFluxCategory] = ThermalFlux::makeCategory();
67 m_categories[ThermalGenerationCategory] = ThermalGeneration::makeCategory();
68 m_categories[VoltageCategory] = Voltage::makeCategory();
69 m_categories[ElectricalCurrentCategory] = ElectricalCurrent::makeCategory();
70 m_categories[ElectricalResistanceCategory] = ElectricalResistance::makeCategory();
71 m_categories[PermeabilityCategory] = Permeability::makeCategory();
72 m_categories[BinaryDataCategory] = BinaryData::makeCategory();
73 }
74
75 QMap<CategoryId, UnitCategory> m_categories;
76};
77
78class QConverterSingleton
79{
80public:
81 QConverterSingleton()
82 : d(new ConverterPrivate())
83 {
84 }
85 QExplicitlySharedDataPointer<ConverterPrivate> d;
86};
87
88Q_GLOBAL_STATIC(QConverterSingleton, global_converter)
89
90Converter::Converter()
91 : d(global_converter->d)
92{
93}
94
95Converter::~Converter()
96{
97}
98
99Converter::Converter(const Converter &other)
100 : d(other.d)
101{
102}
103
104Converter &Converter::operator=(const Converter &other)
105{
106 d = other.d;
107 return *this;
108}
109
110Converter &Converter::operator=(Converter &&other)
111{
112 d.swap(other&: other.d);
113 return *this;
114}
115
116Value Converter::convert(const Value &value, const QString &toUnit) const
117{
118 if (d && value.unit().isValid()) {
119 return value.unit().category().convert(value, toUnit);
120 }
121 return Value();
122}
123
124Value Converter::convert(const Value &value, UnitId toUnit) const
125{
126 if (d && value.unit().isValid()) {
127 return value.unit().category().convert(value, toUnit);
128 }
129 return Value();
130}
131
132Value Converter::convert(const Value &value, const Unit &toUnit) const
133{
134 if (d && toUnit.isValid() && value.unit().isValid()) {
135 return value.unit().category().convert(value, toUnit);
136 }
137 return Value();
138}
139
140UnitCategory Converter::categoryForUnit(const QString &unit) const
141{
142 const auto lstCategories = categories();
143 for (const UnitCategory &u : lstCategories) {
144 if (u.hasUnit(unit)) {
145 return u;
146 }
147 }
148 return UnitCategory();
149}
150
151Unit Converter::unit(const QString &unitString) const
152{
153 const auto lstCategories = categories();
154 for (const UnitCategory &u : lstCategories) {
155 Unit unitClass = u.unit(s: unitString);
156 if (unitClass.isValid()) {
157 return unitClass;
158 }
159 }
160 return Unit();
161}
162
163Unit Converter::unit(UnitId unitId) const
164{
165 const auto lstCategories = categories();
166 for (const UnitCategory &u : lstCategories) {
167 Unit unitClass = u.unit(unitId);
168 if (unitClass.isValid()) {
169 return unitClass;
170 }
171 }
172 return Unit();
173}
174
175UnitCategory Converter::category(const QString &category) const
176{
177 const auto lstCategories = categories();
178 for (const UnitCategory &u : lstCategories) {
179 if (u.name() == category) {
180 return u;
181 }
182 }
183 // not found
184 return UnitCategory();
185}
186
187UnitCategory Converter::category(CategoryId categoryId) const
188{
189 if (d && d->m_categories.contains(key: categoryId)) {
190 return d->m_categories[categoryId];
191 }
192 // not found
193 return UnitCategory();
194}
195
196QList<UnitCategory> Converter::categories() const
197{
198 if (d) {
199 return d->m_categories.values();
200 }
201 return QList<UnitCategory>();
202}
203
204}
205

source code of kunitconversion/src/converter.cpp