mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
refs #189 , PQ string class which allows parsing strings like 100m/s.
pqbase contains template method to determine a valid unit.
This commit is contained in:
@@ -30,6 +30,7 @@ void BlackMisc::PhysicalQuantities::registerMetadata()
|
||||
CSpeed::registerMetadata();
|
||||
CTemperature::registerMetadata();
|
||||
CTime::registerMetadata();
|
||||
CPqString::registerMetadata();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
#include "blackmisc/pqtime.h"
|
||||
#include "blackmisc/pqacceleration.h"
|
||||
#include "blackmisc/pqunits.h"
|
||||
#include "blackmisc/pqstring.h"
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -386,16 +386,18 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Valid unit symbol
|
||||
* \param symbol must be a valid unit symbol (without i18n) or empty string (empty means default unit)
|
||||
* \brief Valid unit symbol?
|
||||
* \param symbol to be tested
|
||||
* \param caseSensitivity check case sensitiv?
|
||||
*/
|
||||
template <class U> static bool isValidUnitSymbol(const QString &symbol)
|
||||
template <class U> static bool isValidUnitSymbol(const QString &symbol, Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive)
|
||||
{
|
||||
if (symbol.isEmpty()) return false;
|
||||
const QList<U> &units = U::allUnits();
|
||||
for (int i = 0; i < units.size(); ++i)
|
||||
{
|
||||
if (units.at(i).getSymbol() == symbol) return true;
|
||||
if (caseSensitivity == Qt::CaseSensitive && units.at(i).getSymbol() == symbol) return true;
|
||||
if (units.at(i).getSymbol().compare(symbol, Qt::CaseInsensitive) == 0) return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
155
src/blackmisc/pqstring.cpp
Normal file
155
src/blackmisc/pqstring.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "pqstring.h"
|
||||
#include "tuple.h"
|
||||
#include "pqallquantities.h"
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace PhysicalQuantities
|
||||
{
|
||||
/*
|
||||
* Convert to string
|
||||
*/
|
||||
QString CPqString::convertToQString(bool /** i18n **/) const
|
||||
{
|
||||
return this->m_string;
|
||||
}
|
||||
|
||||
/*
|
||||
* is a
|
||||
*/
|
||||
bool CPqString::isA(int metaTypeId) const
|
||||
{
|
||||
if (metaTypeId == qMetaTypeId<CPqString>()) { return true; }
|
||||
return this->CValueObject::isA(metaTypeId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare
|
||||
*/
|
||||
int CPqString::compareImpl(const CValueObject &otherBase) const
|
||||
{
|
||||
const auto &other = static_cast<const CPqString &>(otherBase);
|
||||
return compare(TupleConverter<CPqString>::toTuple(*this), TupleConverter<CPqString>::toTuple(other));
|
||||
}
|
||||
|
||||
/*
|
||||
* Marshall to DBus
|
||||
*/
|
||||
void CPqString::marshallToDbus(QDBusArgument &argument) const
|
||||
{
|
||||
argument << TupleConverter<CPqString>::toTuple(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmarshall from DBus
|
||||
*/
|
||||
void CPqString::unmarshallFromDbus(const QDBusArgument &argument)
|
||||
{
|
||||
argument >> TupleConverter<CPqString>::toTuple(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Equal?
|
||||
*/
|
||||
bool CPqString::operator ==(const CPqString &other) const
|
||||
{
|
||||
if (this == &other) return true;
|
||||
return TupleConverter<CPqString>::toTuple(*this) == TupleConverter<CPqString>::toTuple(other);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unequal?
|
||||
*/
|
||||
bool CPqString::operator !=(const CPqString &other) const
|
||||
{
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash
|
||||
*/
|
||||
uint CPqString::getValueHash() const
|
||||
{
|
||||
return qHash(TupleConverter<CPqString>::toTuple(*this));
|
||||
}
|
||||
|
||||
/*
|
||||
* Register metadata
|
||||
*/
|
||||
void CPqString::registerMetadata()
|
||||
{
|
||||
qRegisterMetaType<CPqString>();
|
||||
qDBusRegisterMetaType<CPqString>();
|
||||
}
|
||||
|
||||
QVariant CPqString::parse(const QString &value)
|
||||
{
|
||||
QVariant v;
|
||||
if (value.isEmpty()) return v;
|
||||
QRegExp rx("^([-+]?[0-9]*\\.?[0-9]+)\\s*(\\D*)$");
|
||||
if (rx.indexIn(value) < 0) return v;
|
||||
QString number = rx.cap(1);
|
||||
QString unit = rx.cap(2);
|
||||
if (unit.isEmpty() || number.isEmpty()) return v;
|
||||
bool success;
|
||||
double numberD = number.toDouble(&success);
|
||||
if (!success) return v;
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CAccelerationUnit>(unit))
|
||||
{
|
||||
CAcceleration pq(numberD, CMeasurementUnit::unitFromSymbol<CAccelerationUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CAngleUnit>(unit))
|
||||
{
|
||||
CAngle pq(numberD, CMeasurementUnit::unitFromSymbol<CAngleUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CFrequencyUnit>(unit))
|
||||
{
|
||||
CFrequency pq(numberD, CMeasurementUnit::unitFromSymbol<CFrequencyUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CLengthUnit>(unit))
|
||||
{
|
||||
CLength pq(numberD, CMeasurementUnit::unitFromSymbol<CLengthUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CMassUnit>(unit))
|
||||
{
|
||||
CMass pq(numberD, CMeasurementUnit::unitFromSymbol<CMassUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CPressureUnit>(unit))
|
||||
{
|
||||
CPressure pq(numberD, CMeasurementUnit::unitFromSymbol<CPressureUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CSpeedUnit>(unit))
|
||||
{
|
||||
CSpeed pq(numberD, CMeasurementUnit::unitFromSymbol<CSpeedUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CTimeUnit>(unit))
|
||||
{
|
||||
CTime pq(numberD, CMeasurementUnit::unitFromSymbol<CTimeUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CTemperatureUnit>(unit))
|
||||
{
|
||||
CTemperature pq(numberD, CMeasurementUnit::unitFromSymbol<CTemperatureUnit>(unit, false));
|
||||
return pq.toQVariant();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
103
src/blackmisc/pqstring.h
Normal file
103
src/blackmisc/pqstring.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / contributors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKMISC_PQSTRING_H
|
||||
#define BLACKMISC_PQSTRING_H
|
||||
|
||||
#include "blackmisc/valueobject.h"
|
||||
#include <QVariant>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace PhysicalQuantities
|
||||
{
|
||||
|
||||
/*!
|
||||
* \brief Represents a physical quantity by a string
|
||||
* \details Used to parse strings into physical quantities, validate strings
|
||||
* \sa BlackMisc::PhysicalQuantity
|
||||
*/
|
||||
class CPqString : public BlackMisc::CValueObject
|
||||
{
|
||||
public:
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CPqString)
|
||||
QString m_string;
|
||||
|
||||
protected:
|
||||
//! \copydoc CValueObject::convertToQString
|
||||
virtual QString convertToQString(bool i18n = false) const override;
|
||||
|
||||
//! \copydoc CValueObject::marshallFromDbus()
|
||||
virtual void marshallToDbus(QDBusArgument &argument) const override;
|
||||
|
||||
//! \copydoc CValueObject::unmarshallFromDbus()
|
||||
virtual void unmarshallFromDbus(const QDBusArgument &argument) override;
|
||||
|
||||
//! \copydoc CValueObject::compareImpl
|
||||
virtual int compareImpl(const CValueObject &other) const override;
|
||||
|
||||
//! \copydoc CValueObject::isA
|
||||
virtual bool isA(int metaTypeId) const override;
|
||||
|
||||
public:
|
||||
//! \brief Default constructor
|
||||
CPqString() {}
|
||||
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param value such as 10km/h
|
||||
*/
|
||||
CPqString(const QString &value) : m_string(value) {}
|
||||
|
||||
//! \copydoc CValueObject::toQVariant
|
||||
virtual QVariant toQVariant() const override
|
||||
{
|
||||
return QVariant::fromValue(*this);
|
||||
}
|
||||
|
||||
//! \copydoc CValueObject::getMetaTypeId
|
||||
int getMetaTypeId() const
|
||||
{
|
||||
return qMetaTypeId<CPqString>();
|
||||
}
|
||||
|
||||
//! \copydoc CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override;
|
||||
|
||||
//! \brief Equal operator ==
|
||||
bool operator ==(const CPqString &other) const;
|
||||
|
||||
//! \brief Unequal operator !=
|
||||
bool operator !=(const CPqString &other) const;
|
||||
|
||||
//! \brief Register metadata
|
||||
static void registerMetadata();
|
||||
|
||||
//! \brief parse a string value like "100m", "10.3Mhz"
|
||||
static QVariant parse(const QString &value);
|
||||
|
||||
//! \brief parse into concrete type
|
||||
template <class PQ> static const PQ parse(const QString &symbol)
|
||||
{
|
||||
PQ invalid;
|
||||
if (symbol.isEmpty()) return invalid;
|
||||
QVariant qv = CPqString::parse(symbol);
|
||||
if (!qv.isNull() && qv.canConvert<PQ>())
|
||||
{
|
||||
return qv.value<PQ>();
|
||||
}
|
||||
return invalid;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::PhysicalQuantities::CPqString, (o.m_string))
|
||||
Q_DECLARE_METATYPE(BlackMisc::PhysicalQuantities::CPqString)
|
||||
|
||||
#endif // guard
|
||||
Reference in New Issue
Block a user