File indexing completed on 2024-04-21 03:58:32

0001 /*
0002  *   SPDX-FileCopyrightText: 2007-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 "value.h"
0009 #include "converter.h"
0010 
0011 #include <QVariant>
0012 #include <qmath.h>
0013 
0014 namespace KUnitConversion
0015 {
0016 class ValuePrivate : public QSharedData
0017 {
0018 public:
0019     ValuePrivate()
0020         : m_number(0)
0021     {
0022     }
0023 
0024     ValuePrivate(qreal number, UnitId unitId = InvalidUnit)
0025         : m_number(number)
0026     {
0027         m_unit = m_converter.unit(unitId);
0028     }
0029 
0030     ValuePrivate(qreal number, const Unit &unit)
0031         : m_number(number)
0032         , m_unit(unit)
0033     {
0034     }
0035 
0036     ValuePrivate(qreal number, const QString &unitString)
0037         : m_number(number)
0038     {
0039         m_unit = m_converter.unit(unitString);
0040     }
0041 
0042     ValuePrivate(const ValuePrivate &other)
0043         : QSharedData(other)
0044         , m_number(other.m_number)
0045         , m_unit(other.m_unit)
0046     {
0047     }
0048 
0049     virtual ~ValuePrivate()
0050     {
0051     }
0052 
0053     ValuePrivate &operator=(const ValuePrivate &other)
0054     {
0055         m_number = other.m_number;
0056         m_unit = other.m_unit;
0057         return *this;
0058     }
0059 
0060     ValuePrivate *clone()
0061     {
0062         return new ValuePrivate(*this);
0063     }
0064 
0065     bool operator==(const ValuePrivate &other) const
0066     {
0067         return (m_number == other.m_number && m_unit == other.m_unit);
0068     }
0069 
0070     bool operator!=(const ValuePrivate &other) const
0071     {
0072         return !(*this == other);
0073     }
0074 
0075     qreal m_number;
0076     Unit m_unit;
0077     Converter m_converter;
0078 };
0079 
0080 Value::Value()
0081     : d(nullptr)
0082 {
0083 }
0084 
0085 Value::Value(const Value &other)
0086     : d(other.d)
0087 {
0088 }
0089 
0090 Value::Value(qreal number, const Unit &unit)
0091     : d(new ValuePrivate(number, unit))
0092 {
0093 }
0094 
0095 Value::Value(qreal number, const QString &unitString)
0096     : d(new ValuePrivate(number, unitString))
0097 {
0098 }
0099 
0100 Value::Value(qreal number, UnitId unitId)
0101     : d(new ValuePrivate(number, unitId))
0102 {
0103 }
0104 
0105 Value::Value(const QVariant &number, const QString &unitString)
0106     : d(new ValuePrivate(number.toReal(), unitString))
0107 {
0108 }
0109 
0110 Value::~Value()
0111 {
0112 }
0113 
0114 Value &Value::operator=(const Value &other)
0115 {
0116     d = other.d;
0117     return *this;
0118 }
0119 
0120 bool Value::operator==(const Value &other) const
0121 {
0122     if (d && other.d) {
0123         return (*d == *other.d);
0124     } else {
0125         return (d == other.d);
0126     }
0127 }
0128 
0129 bool Value::operator!=(const Value &other) const
0130 {
0131     if (d && other.d) {
0132         return (*d != *other.d);
0133     } else {
0134         return (d != other.d);
0135     }
0136 }
0137 
0138 bool Value::isNull() const
0139 {
0140     return !d;
0141 }
0142 
0143 bool Value::isValid() const
0144 {
0145     return (d && d->m_unit.isValid() && !qIsNaN(d->m_number));
0146 }
0147 
0148 qreal Value::number() const
0149 {
0150     if (d) {
0151         return d->m_number;
0152     }
0153     return 0;
0154 }
0155 
0156 Unit Value::unit() const
0157 {
0158     if (d) {
0159         return d->m_unit;
0160     }
0161     return Unit();
0162 }
0163 
0164 QString Value::toString(int fieldWidth, char format, int precision, const QChar &fillChar) const
0165 {
0166     if (isValid()) {
0167         return d->m_unit.toString(d->m_number, fieldWidth, format, precision, fillChar);
0168     }
0169     return QString();
0170 }
0171 
0172 QString Value::toSymbolString(int fieldWidth, char format, int precision, const QChar &fillChar) const
0173 {
0174     if (isValid()) {
0175         return d->m_unit.toSymbolString(d->m_number, fieldWidth, format, precision, fillChar);
0176     }
0177     return QString();
0178 }
0179 
0180 Value &Value::round(uint decimals)
0181 {
0182     if (!isValid()) {
0183         return *this;
0184     }
0185 
0186     uint div = qPow(10, decimals);
0187     qreal add = 0.5 / (qreal)div;
0188 
0189     d->m_number = (int)((d->m_number + add) * div) / (qreal)div;
0190     return *this;
0191 }
0192 
0193 Value Value::convertTo(const Unit &unit) const
0194 {
0195     if (d) {
0196         return d->m_converter.convert(*this, unit);
0197     }
0198     return Value();
0199 }
0200 
0201 Value Value::convertTo(UnitId unitId) const
0202 {
0203     if (d) {
0204         return d->m_converter.convert(*this, unitId);
0205     }
0206     return Value();
0207 }
0208 
0209 Value Value::convertTo(const QString &unitString) const
0210 {
0211     if (d) {
0212         return d->m_converter.convert(*this, unitString);
0213     }
0214     return Value();
0215 }
0216 
0217 }