File indexing completed on 2024-04-14 03:56:10

0001 /*
0002  *   SPDX-FileCopyrightText: 2008-2009 Petri Damstén <damu@iki.fi>
0003  *   SPDX-FileCopyrightText: 2014 John Layt <jlayt@kde.org>
0004  *
0005  *   SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "converter.h"
0009 
0010 #include "acceleration_p.h"
0011 #include "angle_p.h"
0012 #include "area_p.h"
0013 #include "binary_data_p.h"
0014 #include "currency_p.h"
0015 #include "density_p.h"
0016 #include "electrical_current_p.h"
0017 #include "electrical_resistance_p.h"
0018 #include "energy_p.h"
0019 #include "weight_per_area_p.h"
0020 #include "force_p.h"
0021 #include "frequency_p.h"
0022 #include "fuel_efficiency_p.h"
0023 #include "length_p.h"
0024 #include "mass_p.h"
0025 #include "permeability_p.h"
0026 #include "power_p.h"
0027 #include "pressure_p.h"
0028 #include "temperature_p.h"
0029 #include "thermal_conductivity_p.h"
0030 #include "thermal_flux_p.h"
0031 #include "thermal_generation_p.h"
0032 #include "timeunit_p.h"
0033 #include "unit.h"
0034 #include "velocity_p.h"
0035 #include "voltage_p.h"
0036 #include "volume_p.h"
0037 
0038 #include <KLocalizedString>
0039 
0040 namespace KUnitConversion
0041 {
0042 class ConverterPrivate : public QSharedData
0043 {
0044 public:
0045     ConverterPrivate()
0046     {
0047         m_categories[LengthCategory] = Length::makeCategory();
0048         m_categories[AreaCategory] = Area::makeCategory();
0049         m_categories[VolumeCategory] = Volume::makeCategory();
0050         m_categories[TemperatureCategory] = Temperature::makeCategory();
0051         m_categories[VelocityCategory] = Velocity::makeCategory();
0052         m_categories[MassCategory] = Mass::makeCategory();
0053         m_categories[PressureCategory] = Pressure::makeCategory();
0054         m_categories[EnergyCategory] = Energy::makeCategory();
0055         m_categories[CurrencyCategory] = Currency::makeCategory();
0056         m_categories[PowerCategory] = Power::makeCategory();
0057         m_categories[TimeCategory] = Time::makeCategory();
0058         m_categories[FuelEfficiencyCategory] = FuelEfficiency::makeCategory();
0059         m_categories[DensityCategory] = Density::makeCategory();
0060         m_categories[WeightPerAreaCategory] = WeightPerArea::makeCategory();
0061         m_categories[AccelerationCategory] = Acceleration::makeCategory();
0062         m_categories[ForceCategory] = Force::makeCategory();
0063         m_categories[AngleCategory] = Angle::makeCategory();
0064         m_categories[FrequencyCategory] = Frequency::makeCategory();
0065         m_categories[ThermalConductivityCategory] = ThermalConductivity::makeCategory();
0066         m_categories[ThermalFluxCategory] = ThermalFlux::makeCategory();
0067         m_categories[ThermalGenerationCategory] = ThermalGeneration::makeCategory();
0068         m_categories[VoltageCategory] = Voltage::makeCategory();
0069         m_categories[ElectricalCurrentCategory] = ElectricalCurrent::makeCategory();
0070         m_categories[ElectricalResistanceCategory] = ElectricalResistance::makeCategory();
0071         m_categories[PermeabilityCategory] = Permeability::makeCategory();
0072         m_categories[BinaryDataCategory] = BinaryData::makeCategory();
0073     }
0074 
0075     QMap<CategoryId, UnitCategory> m_categories;
0076 };
0077 
0078 class QConverterSingleton
0079 {
0080 public:
0081     QConverterSingleton()
0082         : d(new ConverterPrivate())
0083     {
0084     }
0085     QExplicitlySharedDataPointer<ConverterPrivate> d;
0086 };
0087 
0088 Q_GLOBAL_STATIC(QConverterSingleton, global_converter)
0089 
0090 Converter::Converter()
0091     : d(global_converter->d)
0092 {
0093 }
0094 
0095 Converter::~Converter()
0096 {
0097 }
0098 
0099 Converter::Converter(const Converter &other)
0100     : d(other.d)
0101 {
0102 }
0103 
0104 Converter &Converter::operator=(const Converter &other)
0105 {
0106     d = other.d;
0107     return *this;
0108 }
0109 
0110 Converter &Converter::operator=(Converter &&other)
0111 {
0112     d.swap(other.d);
0113     return *this;
0114 }
0115 
0116 Value Converter::convert(const Value &value, const QString &toUnit) const
0117 {
0118     if (d && value.unit().isValid()) {
0119         return value.unit().category().convert(value, toUnit);
0120     }
0121     return Value();
0122 }
0123 
0124 Value Converter::convert(const Value &value, UnitId toUnit) const
0125 {
0126     if (d && value.unit().isValid()) {
0127         return value.unit().category().convert(value, toUnit);
0128     }
0129     return Value();
0130 }
0131 
0132 Value Converter::convert(const Value &value, const Unit &toUnit) const
0133 {
0134     if (d && toUnit.isValid() && value.unit().isValid()) {
0135         return value.unit().category().convert(value, toUnit);
0136     }
0137     return Value();
0138 }
0139 
0140 UnitCategory Converter::categoryForUnit(const QString &unit) const
0141 {
0142     const auto lstCategories = categories();
0143     for (const UnitCategory &u : lstCategories) {
0144         if (u.hasUnit(unit)) {
0145             return u;
0146         }
0147     }
0148     return UnitCategory();
0149 }
0150 
0151 Unit Converter::unit(const QString &unitString) const
0152 {
0153     const auto lstCategories = categories();
0154     for (const UnitCategory &u : lstCategories) {
0155         Unit unitClass = u.unit(unitString);
0156         if (unitClass.isValid()) {
0157             return unitClass;
0158         }
0159     }
0160     return Unit();
0161 }
0162 
0163 Unit Converter::unit(UnitId unitId) const
0164 {
0165     const auto lstCategories = categories();
0166     for (const UnitCategory &u : lstCategories) {
0167         Unit unitClass = u.unit(unitId);
0168         if (unitClass.isValid()) {
0169             return unitClass;
0170         }
0171     }
0172     return Unit();
0173 }
0174 
0175 UnitCategory Converter::category(const QString &category) const
0176 {
0177     const auto lstCategories = categories();
0178     for (const UnitCategory &u : lstCategories) {
0179         if (u.name() == category) {
0180             return u;
0181         }
0182     }
0183     // not found
0184     return UnitCategory();
0185 }
0186 
0187 UnitCategory Converter::category(CategoryId categoryId) const
0188 {
0189     if (d && d->m_categories.contains(categoryId)) {
0190         return d->m_categories[categoryId];
0191     }
0192     // not found
0193     return UnitCategory();
0194 }
0195 
0196 QList<UnitCategory> Converter::categories() const
0197 {
0198     if (d) {
0199         return d->m_categories.values();
0200     }
0201     return QList<UnitCategory>();
0202 }
0203 
0204 }