mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-12 07:15:34 +08:00
refs #452, adjusted aircraft/aviation classes
* support for loading from datastore * improved timestamp handling * new color and country classes * new attributes * updates for missing parts in CUser
This commit is contained in:
committed by
Mathew Sutcliffe
parent
c5f7179588
commit
ae24700299
@@ -56,7 +56,6 @@ namespace BlackMisc
|
||||
clear();
|
||||
for (const auto &e : json.keys())
|
||||
{
|
||||
|
||||
CAircraftEngine engine;
|
||||
int number = e.toInt();
|
||||
engine.convertFromJson(json.value(e).toObject());
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
*/
|
||||
|
||||
#include "blackmisc/aviation/aircrafticaocode.h"
|
||||
#include "blackmisc/aviation/airlineicaocode.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
#include "blackmisc/variant.h"
|
||||
#include "blackmisc/datastoreutility.h"
|
||||
#include <tuple>
|
||||
#include <QThreadStorage>
|
||||
#include <QRegularExpression>
|
||||
|
||||
using namespace BlackMisc;
|
||||
@@ -25,20 +27,48 @@ namespace BlackMisc
|
||||
m_designator(designator), m_combinedType(combinedType)
|
||||
{}
|
||||
|
||||
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer, const QString &model, const QString &wtc, bool realworld, bool legacy, bool military)
|
||||
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer, const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank)
|
||||
: m_designator(icao.trimmed().toUpper()), m_combinedType(combinedType.trimmed().toUpper()), m_manufacturer(manufacturer.trimmed()),
|
||||
m_modelDescription(model.trimmed()), m_wtc(wtc.trimmed().toUpper()), m_realworld(realworld), m_legacy(legacy), m_military(military)
|
||||
{}
|
||||
m_modelDescription(model.trimmed()), m_wtc(wtc.trimmed().toUpper()), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
|
||||
{
|
||||
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; }
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::convertToQString(bool i18n) const
|
||||
{
|
||||
Q_UNUSED(i18n);
|
||||
QString s(this->m_designator);
|
||||
if (this->hasCombinedType()) { s.append(" ").append(this->m_combinedType); }
|
||||
if (this->hasValidCombinedType()) { s.append(" ").append(this->m_combinedType); }
|
||||
if (this->hasValidWtc()) { s.append(" ").append(this->m_wtc); }
|
||||
return s;
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::updateMissingParts(const CAircraftIcaoCode &otherIcaoCode)
|
||||
{
|
||||
if (!this->hasDesignator()) { this->setDesignator(otherIcaoCode.getDesignator()); }
|
||||
if (!this->hasValidWtc()) { this->setWtc(otherIcaoCode.getDesignator()); }
|
||||
if (!this->hasValidCombinedType()) { this->setCombinedType(otherIcaoCode.getCombinedType()); }
|
||||
if (this->m_manufacturer.isEmpty()) { this->setManufacturer(otherIcaoCode.getManufacturer());}
|
||||
if (this->m_modelDescription.isEmpty()) { this->setModelDescription(otherIcaoCode.getModelDescription()); }
|
||||
if (!this->hasValidDbKey())
|
||||
{
|
||||
this->setDbKey(otherIcaoCode.getDbKey());
|
||||
this->setUtcTimestamp(otherIcaoCode.getUtcTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
CStatusMessageList CAircraftIcaoCode::validate() const
|
||||
{
|
||||
static const CLogCategoryList cats( { CLogCategory("swift.blackmisc.aircrafticao"), CLogCategory::validation()});
|
||||
CStatusMessageList msg;
|
||||
if (!hasKnownDesignator()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Aircraft ICAO: unknown designator")); }
|
||||
if (!hasValidCombinedType()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Aircraft ICAO: invalid combined type")); }
|
||||
if (!hasValidWtc()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Aircraft ICAO: wrong WTC")); }
|
||||
if (!hasManufacturer()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Aircraft ICAO: missing manufacturer")); }
|
||||
if (!hasModelDescription()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Aircraft ICAO: no description")); }
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::hasDesignator() const
|
||||
{
|
||||
return !this->m_designator.isEmpty();
|
||||
@@ -49,12 +79,54 @@ namespace BlackMisc
|
||||
return (this->hasDesignator() && this->getDesignator() != "ZZZZ");
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::hasValidCombinedType() const
|
||||
{
|
||||
return isValidCombinedType(getCombinedType());
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getEngineType() const
|
||||
{
|
||||
if (this->m_combinedType.length() != 3) return "";
|
||||
return this->m_combinedType.right(1);
|
||||
}
|
||||
|
||||
int CAircraftIcaoCode::getEngineCount() const
|
||||
{
|
||||
if (this->m_combinedType.length() < 2) { return -1; }
|
||||
QString c(this->m_combinedType.mid(1, 1));
|
||||
if (c == "-") { return -1; }
|
||||
bool ok;
|
||||
int ec = c.toInt(&ok);
|
||||
if (ok && ec >= 0 && ec < 10) { return ec; }
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getEngineCountString() const
|
||||
{
|
||||
if (this->m_combinedType.length() < 2) { return ""; }
|
||||
return this->m_combinedType.mid(1, 1);
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getAircraftType() const
|
||||
{
|
||||
if (this->m_combinedType.length() < 1) { return ""; }
|
||||
QString c(this->m_combinedType.left(1));
|
||||
if (c == "-") { return ""; }
|
||||
return c;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getDesignatorManufacturer() const
|
||||
{
|
||||
QString d(getDesignator());
|
||||
if (this->hasManufacturer()) { d = d.append(" ").append(this->getManufacturer());}
|
||||
return d.trimmed();
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::hasManufacturer() const
|
||||
{
|
||||
return !m_manufacturer.isEmpty();
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::isVtol() const
|
||||
{
|
||||
// special designators
|
||||
@@ -79,9 +151,62 @@ namespace BlackMisc
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setCodeFlags(bool military, bool legacy, bool realWorld)
|
||||
{
|
||||
m_military = military;
|
||||
m_legacy = legacy;
|
||||
m_realWorld = realWorld;
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setMilitary(bool military)
|
||||
{
|
||||
m_military = military;
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setRealWorld(bool realWorld)
|
||||
{
|
||||
m_realWorld = realWorld;
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setLegacy(bool legacy)
|
||||
{
|
||||
m_legacy = legacy;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getRankString() const
|
||||
{
|
||||
return QString::number(getRank());
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setRank(int rank)
|
||||
{
|
||||
if (rank < 0 || rank >= 10)
|
||||
{
|
||||
m_rank = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rank = rank;
|
||||
}
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getCombinedStringWithKey() const
|
||||
{
|
||||
QString s(getDesignator());
|
||||
if (hasManufacturer()) { s = s.append(" ").append(getManufacturer()); }
|
||||
if (hasModelDescription()) { s = s.append(" ").append(getModelDescription()); }
|
||||
return s.append(" ").append(getDbKeyAsStringInParentheses());
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::hasCompleteData() const
|
||||
{
|
||||
return hasCombinedType() && hasDesignator() && hasValidWtc();
|
||||
return hasValidCombinedType() && hasDesignator() && hasValidWtc() && hasManufacturer();
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::matchesDesignator(const QString &designator) const
|
||||
{
|
||||
if (designator.isEmpty()) { return false; }
|
||||
return designator.trimmed().toUpper() == this->m_designator;
|
||||
}
|
||||
|
||||
CVariant CAircraftIcaoCode::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||
@@ -108,7 +233,11 @@ namespace BlackMisc
|
||||
case IndexIsMilitary:
|
||||
return CVariant::fromValue(this->m_military);
|
||||
case IndexIsRealworld:
|
||||
return CVariant::fromValue(this->m_realworld);
|
||||
return CVariant::fromValue(this->m_realWorld);
|
||||
case IndexRank:
|
||||
return CVariant::fromValue(this->m_rank);
|
||||
case IndexDesignatorManufacturer:
|
||||
return CVariant::fromValue(this->getDesignatorManufacturer());
|
||||
default:
|
||||
return CValueObject::propertyByIndex(index);
|
||||
}
|
||||
@@ -142,6 +271,9 @@ namespace BlackMisc
|
||||
case IndexIsMilitary:
|
||||
this->m_military = variant.toBool();
|
||||
break;
|
||||
case IndexRank:
|
||||
this->m_rank = variant.toInt();
|
||||
break;
|
||||
default:
|
||||
CValueObject::setPropertyByIndex(variant, index);
|
||||
break;
|
||||
@@ -162,50 +294,58 @@ namespace BlackMisc
|
||||
{
|
||||
if (combinedType.length() != 3) { return false; }
|
||||
|
||||
// Amphibian, Glider, Helicopter, Seaplane, Landplane, Tilt wing
|
||||
// Electric, Jet, Piston, Turpoprop
|
||||
static QThreadStorage<QRegularExpression> tsRegex;
|
||||
if (! tsRegex.hasLocalData()) { tsRegex.setLocalData(QRegularExpression("^[A-Z][0-9][A-Z]$")); }
|
||||
if (! tsRegex.hasLocalData()) { tsRegex.setLocalData(QRegularExpression("^[AGHSLT][0-9][EJPT]$")); }
|
||||
const QRegularExpression ®exp = tsRegex.localData();
|
||||
return (regexp.match(combinedType).hasMatch());
|
||||
}
|
||||
|
||||
CAircraftIcaoCode CAircraftIcaoCode::fromDatabaseJson(const QJsonObject &json)
|
||||
bool CAircraftIcaoCode::isValidWtc(const QString &candidate)
|
||||
{
|
||||
QJsonArray inner = json["cell"].toArray();
|
||||
Q_ASSERT_X(!inner.isEmpty(), Q_FUNC_INFO, "Missing JSON");
|
||||
if (inner.isEmpty()) { return CAircraftIcaoCode(); }
|
||||
if (candidate.isEmpty()) { return true; } // we accept unspecified
|
||||
if (candidate.length() == 1)
|
||||
{
|
||||
return candidate == "L" || candidate == "M" || candidate == "H";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int dbKey(inner.at(i++).toInt(-1));
|
||||
QString designator(inner.at(i++).toString());
|
||||
QString manufacturer(inner.at(i++).toString());
|
||||
QString model(inner.at(i++).toString());
|
||||
QString type(inner.at(i++).toString());
|
||||
QString engine(inner.at(i++).toString());
|
||||
QString engineCount(inner.at(i++).toString());
|
||||
CAircraftIcaoCode CAircraftIcaoCode::fromDatabaseJson(const QJsonObject &json, const QString &prefix)
|
||||
{
|
||||
if (!existsKey(json, prefix))
|
||||
{
|
||||
// when using relationship, this can be null
|
||||
return CAircraftIcaoCode();
|
||||
}
|
||||
|
||||
QString designator(json.value(prefix + "designator").toString());
|
||||
QString manufacturer(json.value(prefix + "manufacturer").toString());
|
||||
QString model(json.value(prefix + "model").toString());
|
||||
QString type(json.value(prefix + "type").toString());
|
||||
QString engine(json.value(prefix + "engine").toString());
|
||||
int engineCount(json.value(prefix + "enginecount").toInt(-1));
|
||||
QString combined(createdCombinedString(type, engineCount, engine));
|
||||
QString wtc(inner.at(i++).toString());
|
||||
QString wtc(json.value("wtc").toString());
|
||||
if (wtc.length() > 1 && wtc.contains("/"))
|
||||
{
|
||||
// "L/M" -> "M"
|
||||
wtc = wtc.right(1);
|
||||
}
|
||||
bool real = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
|
||||
bool legacy = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
|
||||
bool military = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
|
||||
bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "realworld").toString());
|
||||
bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "legacy").toString());
|
||||
bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString());
|
||||
int rank(json.value("rank").toInt(10));
|
||||
|
||||
Q_ASSERT_X(wtc.length() < 2, Q_FUNC_INFO, "WTC too long");
|
||||
|
||||
CAircraftIcaoCode code(
|
||||
designator,
|
||||
combined,
|
||||
manufacturer,
|
||||
model,
|
||||
wtc,
|
||||
real,
|
||||
legacy,
|
||||
military
|
||||
designator, combined,
|
||||
manufacturer, model, wtc,
|
||||
real, legacy, military, rank
|
||||
);
|
||||
code.setDbKey(dbKey);
|
||||
code.setKeyAndTimestampFromDatabaseJson(json, prefix);
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -235,5 +375,16 @@ namespace BlackMisc
|
||||
return c;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::createdCombinedString(const QString &type, int engineCount, const QString &engine)
|
||||
{
|
||||
if (engineCount >= 0 && engineCount < 10)
|
||||
{
|
||||
return createdCombinedString(type, QString::number(engineCount), engine);
|
||||
}
|
||||
else
|
||||
{
|
||||
return createdCombinedString(type, "", engine);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
#include "blackmisc/datastore.h"
|
||||
#include "blackmisc/statusmessagelist.h"
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Aviation
|
||||
{
|
||||
class CAirlineIcaoCode;
|
||||
|
||||
//! Value object for ICAO classification
|
||||
class BLACKMISC_EXPORT CAircraftIcaoCode :
|
||||
public CValueObject<CAircraftIcaoCode>,
|
||||
@@ -40,6 +43,8 @@ namespace BlackMisc
|
||||
IndexIsMilitary,
|
||||
IndexIsLegacy,
|
||||
IndexIsVtol,
|
||||
IndexRank,
|
||||
IndexDesignatorManufacturer
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
@@ -50,7 +55,7 @@ namespace BlackMisc
|
||||
|
||||
//! Constructor
|
||||
CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer,
|
||||
const QString &model, const QString &wtc, bool realworld, bool legacy, bool military);
|
||||
const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank);
|
||||
|
||||
//! Get ICAO designator, e.g. "B737"
|
||||
const QString &getDesignator() const { return m_designator; }
|
||||
@@ -68,26 +73,44 @@ namespace BlackMisc
|
||||
const QString &getCombinedType() const { return this->m_combinedType; }
|
||||
|
||||
//! Combined type available?
|
||||
bool hasCombinedType() const { return this->getCombinedType().length() == 3; }
|
||||
bool hasValidCombinedType() const;
|
||||
|
||||
//! Get engine type, e.g. "J"
|
||||
QString getEngineType() const;
|
||||
|
||||
//! Engine count if any, -1 if no value is set
|
||||
int getEngineCount() const;
|
||||
|
||||
//! Engine count as string, if not available ""
|
||||
QString getEngineCountString() const;
|
||||
|
||||
//! Aircraft type, such a L(andplane), S(eaplane), H(elicopter)
|
||||
QString getAircraftType() const;
|
||||
|
||||
//! Set type
|
||||
void setCombinedType(const QString &type) { this->m_combinedType = type.trimmed().toUpper(); }
|
||||
|
||||
//! Get model description, e.g. "A-330-200"
|
||||
const QString &getModelDescription() const { return m_modelDescription; }
|
||||
|
||||
//! Designator + Manufacturer
|
||||
QString getDesignatorManufacturer() const;
|
||||
|
||||
//! Set the model description
|
||||
void setModelDescription(const QString &modelDescription) { m_modelDescription = modelDescription.trimmed(); }
|
||||
|
||||
//! Has model description
|
||||
bool hasModelDescription() const { return !this->m_modelDescription.isEmpty(); }
|
||||
|
||||
//! Get manufacturer, e.g. "Airbus"
|
||||
const QString &getManufacturer() const { return m_manufacturer; }
|
||||
|
||||
//! Set the manufacturer
|
||||
void setManufacturer(const QString &manufacturer) { m_manufacturer = manufacturer.trimmed(); }
|
||||
|
||||
//! Manufacturer
|
||||
bool hasManufacturer() const;
|
||||
|
||||
//! Get WTC
|
||||
const QString &getWtc() const { return m_wtc; }
|
||||
|
||||
@@ -100,9 +123,45 @@ namespace BlackMisc
|
||||
//! Is VTOL aircraft (helicopter, tilt wing)
|
||||
bool isVtol() const;
|
||||
|
||||
//! Military?
|
||||
bool isMilitary() const { return m_military; }
|
||||
|
||||
//! Real world aircraft?
|
||||
bool isRealWorld() const { return m_realWorld; }
|
||||
|
||||
//! Legacy aircraft
|
||||
bool isLegacyAircraft() const { return m_legacy; }
|
||||
|
||||
//! Flags
|
||||
void setCodeFlags(bool military, bool legacy, bool realWorld);
|
||||
|
||||
//! Military
|
||||
void setMilitary(bool military);
|
||||
|
||||
//! Real world
|
||||
void setRealWorld(bool realWorld);
|
||||
|
||||
//! Legacy
|
||||
void setLegacy(bool legacy);
|
||||
|
||||
//! Ranking
|
||||
int getRank() const { return m_rank; }
|
||||
|
||||
//! Ranking
|
||||
QString getRankString() const;
|
||||
|
||||
//! Ranking
|
||||
void setRank(int rank);
|
||||
|
||||
//! Comined descriptive string with key
|
||||
QString getCombinedStringWithKey() const;
|
||||
|
||||
//! All data set?
|
||||
bool hasCompleteData() const;
|
||||
|
||||
//! Matches designator string?
|
||||
bool matchesDesignator(const QString &designator) const;
|
||||
|
||||
//! \copydoc CValueObject::propertyByIndex
|
||||
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
|
||||
|
||||
@@ -112,14 +171,23 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::convertToQString
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
|
||||
//! Update missing parts
|
||||
void updateMissingParts(const CAircraftIcaoCode &otherIcaoCode);
|
||||
|
||||
//! Validate data
|
||||
BlackMisc::CStatusMessageList validate() const;
|
||||
|
||||
//! Valid designator?
|
||||
static bool isValidDesignator(const QString &designator);
|
||||
|
||||
//! Valid combined type
|
||||
static bool isValidCombinedType(const QString &combinedType);
|
||||
|
||||
//! Valid WTC code?
|
||||
static bool isValidWtc(const QString &candidate);
|
||||
|
||||
//! From our database JSON format
|
||||
static CAircraftIcaoCode fromDatabaseJson(const QJsonObject &json);
|
||||
static CAircraftIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString());
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftIcaoCode)
|
||||
@@ -127,14 +195,17 @@ namespace BlackMisc
|
||||
QString m_combinedType; //!< "L2J"
|
||||
QString m_manufacturer; //!< "Airbus"
|
||||
QString m_modelDescription; //!< "A-330-200"
|
||||
QString m_wtc; //!< wake turbulence "M","H" "L/M", "L"
|
||||
bool m_realworld = true; //!< real world aircraft
|
||||
QString m_wtc; //!< wake turbulence "M","H" "L/M", "L", we only use the one letter versions
|
||||
bool m_realWorld = true; //!< real world aircraft
|
||||
bool m_legacy = false; //!< legacy code
|
||||
bool m_military = false; //!< military aircraft?
|
||||
int m_rank = 10; //!< rank among same codes
|
||||
|
||||
//! Create a combined string like L2J
|
||||
static QString createdCombinedString(const QString &type, const QString &engineCount, const QString &engine);
|
||||
|
||||
//! Create a combined string like L2J
|
||||
static QString createdCombinedString(const QString &type, int engineCount, const QString &engine);
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -142,14 +213,16 @@ namespace BlackMisc
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftIcaoCode)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAircraftIcaoCode, (
|
||||
o.m_dbKey,
|
||||
o.m_timestampMSecsSinceEpoch,
|
||||
o.m_designator,
|
||||
o.m_combinedType,
|
||||
o.m_manufacturer,
|
||||
o.m_modelDescription,
|
||||
o.m_wtc,
|
||||
o.m_military,
|
||||
o.m_realworld,
|
||||
o.m_legacy
|
||||
o.m_realWorld,
|
||||
o.m_legacy,
|
||||
o.m_rank
|
||||
))
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -18,6 +18,58 @@ namespace BlackMisc
|
||||
CSequence<CAircraftIcaoCode>(other)
|
||||
{ }
|
||||
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByDesignator(const QString &designator)
|
||||
{
|
||||
if (!CAircraftIcaoCode::isValidDesignator(designator)) { return CAircraftIcaoCodeList(); }
|
||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||
{
|
||||
return code.matchesDesignator(designator);
|
||||
});
|
||||
}
|
||||
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByManufacturer(const QString &manufacturer)
|
||||
{
|
||||
if (manufacturer.isEmpty()) { return CAircraftIcaoCodeList(); }
|
||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||
{
|
||||
return code.getManufacturer().startsWith(manufacturer, Qt::CaseInsensitive);
|
||||
});
|
||||
}
|
||||
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByDescription(const QString &description)
|
||||
{
|
||||
if (description.isEmpty()) { return CAircraftIcaoCodeList(); }
|
||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||
{
|
||||
return code.getModelDescription().startsWith(description, Qt::CaseInsensitive);
|
||||
});
|
||||
}
|
||||
|
||||
CAircraftIcaoCode CAircraftIcaoCodeList::findFirstByDesignatorAndRank(const QString &designator)
|
||||
{
|
||||
if (!CAircraftIcaoCode::isValidDesignator(designator)) { return CAircraftIcaoCode(); }
|
||||
CAircraftIcaoCodeList codes(findByDesignator(designator));
|
||||
if (codes.isEmpty()) { return CAircraftIcaoCode(); }
|
||||
if (codes.size() < 2) { return codes.front(); }
|
||||
codes.sortBy(&CAircraftIcaoCode::getRank, &CAircraftIcaoCode::getDbKey);
|
||||
return codes.front();
|
||||
}
|
||||
|
||||
void CAircraftIcaoCodeList::sortByRank()
|
||||
{
|
||||
this->sortBy(&CAircraftIcaoCode::getRank);
|
||||
}
|
||||
|
||||
QStringList CAircraftIcaoCodeList::toCompleterStrings() const
|
||||
{
|
||||
QStringList c;
|
||||
for (const CAircraftIcaoCode &icao : *this)
|
||||
{
|
||||
c.append(icao.getCombinedStringWithKey());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete)
|
||||
{
|
||||
CAircraftIcaoCodeList codes;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "aircrafticaocode.h"
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/datastoreobjectlist.h"
|
||||
#include "blackmisc/collection.h"
|
||||
#include "blackmisc/sequence.h"
|
||||
#include <initializer_list>
|
||||
@@ -25,6 +26,7 @@ namespace BlackMisc
|
||||
//! Value object encapsulating a list of ICAO codes.
|
||||
class BLACKMISC_EXPORT CAircraftIcaoCodeList :
|
||||
public CSequence<CAircraftIcaoCode>,
|
||||
public BlackMisc::IDatastoreObjectListWithIntegerKey<CAircraftIcaoCode, CAircraftIcaoCodeList>,
|
||||
public BlackMisc::Mixin::MetaType<CAircraftIcaoCodeList>
|
||||
{
|
||||
public:
|
||||
@@ -36,6 +38,24 @@ namespace BlackMisc
|
||||
//! Construct from a base class object.
|
||||
CAircraftIcaoCodeList(const CSequence<CAircraftIcaoCode> &other);
|
||||
|
||||
//! Find by designator
|
||||
CAircraftIcaoCodeList findByDesignator(const QString &designator);
|
||||
|
||||
//! Find by manufacturer
|
||||
CAircraftIcaoCodeList findByManufacturer(const QString &manufacturer);
|
||||
|
||||
//! Find by model description
|
||||
CAircraftIcaoCodeList findByDescription(const QString &description);
|
||||
|
||||
//! Find by designator, then best match by rank
|
||||
CAircraftIcaoCode findFirstByDesignatorAndRank(const QString &designator);
|
||||
|
||||
//! Sort by rank
|
||||
void sortByRank();
|
||||
|
||||
//! For selection completion
|
||||
QStringList toCompleterStrings() const;
|
||||
|
||||
//! From our database JSON format
|
||||
static CAircraftIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete = true);
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace BlackMisc
|
||||
s.append(" pitch: ").append(this->m_pitch.toQString(i18n));
|
||||
s.append(" gs: ").append(this->m_groundspeed.toQString(i18n));
|
||||
s.append(" heading: ").append(this->m_heading.toQString(i18n));
|
||||
s.append(" timestamp: ").append(this->getFormattedUtcTimestamp());
|
||||
s.append(" timestamp: ").append(this->getFormattedUtcTimestampDhms());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/aviation/aircraftsituation.h"
|
||||
#include "blackmisc/timestampobjectlist.h"
|
||||
#include "blackmisc/aviation/callsignobjectlist.h"
|
||||
#include "blackmisc/timestampobjectlist.h"
|
||||
#include "blackmisc/sequence.h"
|
||||
|
||||
namespace BlackMisc
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include "blackmisc/variant.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <QThreadStorage>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "blackmisc/logmessage.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
@@ -22,13 +23,12 @@ namespace BlackMisc
|
||||
{
|
||||
namespace Aviation
|
||||
{
|
||||
|
||||
CAirlineIcaoCode::CAirlineIcaoCode(const QString &airlineDesignator)
|
||||
: m_designator(airlineDesignator.trimmed().toUpper())
|
||||
{}
|
||||
|
||||
CAirlineIcaoCode::CAirlineIcaoCode(const QString &airlineDesignator, const QString &airlineName, const QString &countryIso, const QString &country, const QString &telephony, bool virtualAirline)
|
||||
: m_designator(airlineDesignator.trimmed().toUpper()), m_name(airlineName), m_countryIso(countryIso.trimmed().toUpper()), m_country(country), m_telephonyDesignator(telephony), m_isVa(virtualAirline)
|
||||
CAirlineIcaoCode::CAirlineIcaoCode(const QString &airlineDesignator, const QString &airlineName, const BlackMisc::CCountry &country, const QString &telephony, bool virtualAirline, bool operating)
|
||||
: m_designator(airlineDesignator.trimmed().toUpper()), m_name(airlineName), m_country(country), m_telephonyDesignator(telephony), m_isVa(virtualAirline), m_isOperating(operating)
|
||||
{}
|
||||
|
||||
const QString CAirlineIcaoCode::getVDesignator() const
|
||||
@@ -37,15 +37,60 @@ namespace BlackMisc
|
||||
return QString("V").append(this->m_designator);
|
||||
}
|
||||
|
||||
QString CAirlineIcaoCode::getDesignatorNameCountry() const
|
||||
{
|
||||
QString s(this->getDesignator());
|
||||
if (this->hasName()) { s = s.append(" ").append(this->getName()); }
|
||||
if (this->hasValidCountry()) { s = s.append(" ").append(this->getCountryIso()); }
|
||||
return s.trimmed();
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::hasValidCountry() const
|
||||
{
|
||||
return this->m_country.isValid();
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::hasValidDesignator() const
|
||||
{
|
||||
return isValidAirlineDesignator(m_designator);
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::matchesDesignator(const QString &designator) const
|
||||
{
|
||||
if (designator.isEmpty()) { return false; }
|
||||
return designator.trimmed().toUpper() == this->m_designator;
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::matchesVDesignator(const QString &designator) const
|
||||
{
|
||||
if (designator.isEmpty()) { return false; }
|
||||
return designator.trimmed().toUpper() == this->getVDesignator();
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::hasCompleteData() const
|
||||
{
|
||||
return this->hasDesignator() && this->hasCountryIso() && this->hasName();
|
||||
return this->hasValidDesignator() && this->hasValidCountry() && this->hasName();
|
||||
}
|
||||
|
||||
CIcon CAirlineIcaoCode::toIcon() const
|
||||
{
|
||||
if (this->m_designator.length() > 2)
|
||||
{
|
||||
return CIcon("images/airlines/" + m_designator.toLower() + ".png",
|
||||
this->convertToQString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return CIcon::iconByIndex(CIcons::StandardIconEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
QString CAirlineIcaoCode::convertToQString(bool i18n) const
|
||||
{
|
||||
Q_UNUSED(i18n);
|
||||
QString s(this->m_designator);
|
||||
if (this->m_name.isEmpty()) { return ""; }
|
||||
if (!this->m_name.isEmpty()) { s.append(" (").append(this->m_name).append(")"); }
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -59,15 +104,19 @@ namespace BlackMisc
|
||||
case IndexAirlineDesignator:
|
||||
return CVariant::fromValue(this->m_designator);
|
||||
case IndexAirlineCountryIso:
|
||||
return CVariant::fromValue(this->m_countryIso);
|
||||
return CVariant::fromValue(this->getCountryIso());
|
||||
case IndexAirlineCountry:
|
||||
return CVariant::fromValue(this->m_country);
|
||||
return this->m_country.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexAirlineName:
|
||||
return CVariant::fromValue(this->m_name);
|
||||
case IndexTelephonyDesignator:
|
||||
return CVariant::fromValue(this->m_telephonyDesignator);
|
||||
case IndexIsVirtualAirline:
|
||||
return CVariant::fromValue(this->m_isVa);
|
||||
case IndexIsOperating:
|
||||
return CVariant::fromValue(this->m_isOperating);
|
||||
case IndexDesignatorNameCountry:
|
||||
return CVariant::fromValue(this->getDesignatorNameCountry());
|
||||
default:
|
||||
return CValueObject::propertyByIndex(index);
|
||||
}
|
||||
@@ -83,11 +132,8 @@ namespace BlackMisc
|
||||
case IndexAirlineDesignator:
|
||||
this->setDesignator(variant.value<QString>());
|
||||
break;
|
||||
case IndexAirlineCountryIso:
|
||||
this->setCountryIso(variant.value<QString>());
|
||||
break;
|
||||
case IndexAirlineCountry:
|
||||
this->setCountry(variant.value<QString>());
|
||||
this->setCountry(variant.value<CCountry>());
|
||||
break;
|
||||
case IndexAirlineName:
|
||||
this->setName(variant.value<QString>());
|
||||
@@ -98,12 +144,25 @@ namespace BlackMisc
|
||||
case IndexIsVirtualAirline:
|
||||
this->setVirtualAirline(variant.toBool());
|
||||
break;
|
||||
case IndexIsOperating:
|
||||
this->setOperating(variant.toBool());
|
||||
break;
|
||||
default:
|
||||
CValueObject::setPropertyByIndex(variant, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CStatusMessageList CAirlineIcaoCode::validate() const
|
||||
{
|
||||
static const CLogCategoryList cats( { CLogCategory(this->getClassName()), CLogCategory::validation()});
|
||||
CStatusMessageList msgs;
|
||||
if (!hasValidDesignator()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Airline: missing designator")); }
|
||||
if (!hasValidCountry()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Airline: missing country")); }
|
||||
if (!hasName()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Airline: no name")); }
|
||||
return msgs;
|
||||
}
|
||||
|
||||
bool CAirlineIcaoCode::isValidAirlineDesignator(const QString &airline)
|
||||
{
|
||||
if (airline.length() < 2 || airline.length() > 5) return false;
|
||||
@@ -114,27 +173,47 @@ namespace BlackMisc
|
||||
return (regexp.match(airline).hasMatch());
|
||||
}
|
||||
|
||||
CAirlineIcaoCode CAirlineIcaoCode::fromDatabaseJson(const QJsonObject &json)
|
||||
QString CAirlineIcaoCode::getCombinedStringWithKey() const
|
||||
{
|
||||
// https://ubuntu12/vatrep/public/service/allairlineicao.php?rows=10
|
||||
QJsonArray inner = json["cell"].toArray();
|
||||
Q_ASSERT_X(!inner.isEmpty(), Q_FUNC_INFO, "Missing JSON");
|
||||
if (inner.isEmpty()) { return CAirlineIcaoCode(); }
|
||||
QString s(getVDesignator());
|
||||
if (hasName()) { s = s.append(" ").append(getName()); }
|
||||
return s.append(" ").append(getDbKeyAsStringInParentheses());
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int dbKey = inner.at(i++).toInt(-1);
|
||||
QString designator(inner.at(i++).toString());
|
||||
QString vDesignator(inner.at(i++).toString());
|
||||
Q_UNUSED(vDesignator);
|
||||
QString telephony(inner.at(i++).toString());
|
||||
QString name(inner.at(i++).toString());
|
||||
QString countryIso(inner.at(i++).toString());
|
||||
QString country(inner.at(i++).toString());
|
||||
bool va = inner.at(i++).toString().startsWith("Y", Qt::CaseInsensitive); // VA
|
||||
void CAirlineIcaoCode::updateMissingParts(const CAirlineIcaoCode &otherIcaoCode)
|
||||
{
|
||||
if (!this->hasValidDesignator()) { this->setDesignator(otherIcaoCode.getDesignator()); }
|
||||
if (!this->hasValidCountry()) { this->setCountry(otherIcaoCode.getCountry()); }
|
||||
if (!this->hasName()) { this->setName(otherIcaoCode.getName()); }
|
||||
if (!this->hasTelephonyDesignator()) { this->setTelephonyDesignator(otherIcaoCode.getTelephonyDesignator()); }
|
||||
if (!this->hasValidDbKey())
|
||||
{
|
||||
this->setDbKey(otherIcaoCode.getDbKey());
|
||||
this->setUtcTimestamp(otherIcaoCode.getUtcTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
CAirlineIcaoCode CAirlineIcaoCode::fromDatabaseJson(const QJsonObject &json, const QString &prefix)
|
||||
{
|
||||
if (!existsKey(json, prefix))
|
||||
{
|
||||
// when using relationship, this can be null
|
||||
return CAirlineIcaoCode();
|
||||
}
|
||||
|
||||
QString designator(json.value(prefix + "designator").toString());
|
||||
QString telephony(json.value(prefix + "callsign").toString());
|
||||
QString name(json.value(prefix + "name").toString());
|
||||
QString countryIso(json.value(prefix + "country").toString());
|
||||
QString countryName(json.value(prefix + "countryname").toString());
|
||||
bool va = json.value(prefix + "va").toString().startsWith("Y", Qt::CaseInsensitive); // VA
|
||||
bool operating = json.value(prefix + "operating").toString().startsWith("Y", Qt::CaseInsensitive); // operating
|
||||
CAirlineIcaoCode code(
|
||||
designator, name, countryIso, country, telephony, va
|
||||
designator, name,
|
||||
CCountry(countryIso, countryName),
|
||||
telephony, va, operating
|
||||
);
|
||||
code.setDbKey(dbKey);
|
||||
code.setKeyAndTimestampFromDatabaseJson(json, prefix);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
#define BLACKMISC_AVIATION_AIRLINEICAOCODE_H
|
||||
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/country.h"
|
||||
#include "blackmisc/datastore.h"
|
||||
#include "blackmisc/valueobject.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/statusmessagelist.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
|
||||
namespace BlackMisc
|
||||
@@ -36,7 +38,9 @@ namespace BlackMisc
|
||||
IndexAirlineCountryIso,
|
||||
IndexAirlineCountry,
|
||||
IndexTelephonyDesignator,
|
||||
IndexIsVirtualAirline
|
||||
IndexIsVirtualAirline,
|
||||
IndexIsOperating,
|
||||
IndexDesignatorNameCountry,
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
@@ -46,7 +50,7 @@ namespace BlackMisc
|
||||
CAirlineIcaoCode(const QString &airlineDesignator);
|
||||
|
||||
//! Constructor.
|
||||
CAirlineIcaoCode(const QString &airlineDesignator, const QString &airlineName, const QString &countryIso, const QString &country, const QString &telephony, bool virtualAirline);
|
||||
CAirlineIcaoCode(const QString &airlineDesignator, const QString &airlineName, const BlackMisc::CCountry &country, const QString &telephony, bool virtualAirline, bool operating);
|
||||
|
||||
//! Get airline, e.g. "DLH"
|
||||
const QString &getDesignator() const { return this->m_designator; }
|
||||
@@ -58,16 +62,16 @@ namespace BlackMisc
|
||||
void setDesignator(const QString &icaoDesignator) { this->m_designator = icaoDesignator.trimmed().toUpper(); }
|
||||
|
||||
//! Get country, e.g. "FR"
|
||||
const QString &getCountryIso() const { return this->m_countryIso; }
|
||||
const QString &getCountryIso() const { return this->m_country.getIsoCode(); }
|
||||
|
||||
//! Get country, e.g. "FRANCE"
|
||||
const QString &getCountry() const { return this->m_country; }
|
||||
const BlackMisc::CCountry &getCountry() const { return this->m_country; }
|
||||
|
||||
//! Set country ISO
|
||||
void setCountryIso(const QString &country) { this->m_countryIso = country.trimmed().toUpper(); }
|
||||
//! Combined string designator, name, country
|
||||
QString getDesignatorNameCountry() const;
|
||||
|
||||
//! Set country
|
||||
void setCountry(const QString &country) { this->m_country = country.trimmed(); }
|
||||
void setCountry(const BlackMisc::CCountry &country) { this->m_country = country; }
|
||||
|
||||
//! Get name, e.g. "Lufthansa"
|
||||
const QString &getName() const { return this->m_name; }
|
||||
@@ -87,11 +91,23 @@ namespace BlackMisc
|
||||
//! Virtual airline
|
||||
void setVirtualAirline(bool va) { m_isVa = va; }
|
||||
|
||||
//! Country?
|
||||
bool hasCountryIso() const { return !this->m_countryIso.isEmpty(); }
|
||||
//! Operating?
|
||||
bool isOperating() const { return m_isOperating; }
|
||||
|
||||
//! Airline available?
|
||||
bool hasDesignator() const { return !this->m_designator.isEmpty(); }
|
||||
//! Operating airline?
|
||||
void setOperating(bool operating) { m_isOperating = operating; }
|
||||
|
||||
//! Country?
|
||||
bool hasValidCountry() const;
|
||||
|
||||
//! Airline designator available?
|
||||
bool hasValidDesignator() const;
|
||||
|
||||
//! Matches designator string?
|
||||
bool matchesDesignator(const QString &designator) const;
|
||||
|
||||
//! Matches v-designator string?
|
||||
bool matchesVDesignator(const QString &designator) const;
|
||||
|
||||
//! Telephony designator?
|
||||
bool hasTelephonyDesignator() const { return !this->m_telephonyDesignator.isEmpty(); }
|
||||
@@ -102,6 +118,12 @@ namespace BlackMisc
|
||||
//! Complete data
|
||||
bool hasCompleteData() const;
|
||||
|
||||
//! Comined string with key
|
||||
QString getCombinedStringWithKey() const;
|
||||
|
||||
//! \copydoc CValueObject::toIcon
|
||||
CIcon toIcon() const;
|
||||
|
||||
//! \copydoc CValueObject::convertToQString
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
|
||||
@@ -111,20 +133,26 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::setPropertyByIndex
|
||||
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
|
||||
|
||||
//! Validate data
|
||||
BlackMisc::CStatusMessageList validate() const;
|
||||
|
||||
//! Update missing parts
|
||||
void updateMissingParts(const CAirlineIcaoCode &otherIcaoCode);
|
||||
|
||||
//! Valid designator?
|
||||
static bool isValidAirlineDesignator(const QString &airline);
|
||||
|
||||
//! From our DB JSON
|
||||
static CAirlineIcaoCode fromDatabaseJson(const QJsonObject &json);
|
||||
static CAirlineIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString());
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CAirlineIcaoCode)
|
||||
QString m_designator; //!< "DLH"
|
||||
QString m_name; //!< "Lufthansa"
|
||||
QString m_countryIso; //!< "FR"
|
||||
QString m_country; //!< clear text, "Germany"
|
||||
BlackMisc::CCountry m_country; //!< Country
|
||||
QString m_telephonyDesignator; //!< "Speedbird"
|
||||
bool m_isVa = false;
|
||||
bool m_isVa = false; //!< virtual airline
|
||||
bool m_isOperating = true; //!< still operating?
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -132,12 +160,13 @@ namespace BlackMisc
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAirlineIcaoCode)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAirlineIcaoCode, (
|
||||
o.m_dbKey,
|
||||
o.m_timestampMSecsSinceEpoch,
|
||||
o.m_designator,
|
||||
o.m_name,
|
||||
o.m_countryIso,
|
||||
o.m_country,
|
||||
o.m_telephonyDesignator,
|
||||
o.m_isVa
|
||||
o.m_isVa,
|
||||
o.m_isOperating
|
||||
))
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -17,6 +17,24 @@ namespace BlackMisc
|
||||
CSequence<CAirlineIcaoCode>(other)
|
||||
{ }
|
||||
|
||||
CAirlineIcaoCodeList CAirlineIcaoCodeList::findByDesignator(const QString &designator)
|
||||
{
|
||||
if (CAirlineIcaoCode::isValidAirlineDesignator(designator)) { return CAirlineIcaoCodeList(); }
|
||||
return this->findBy([&](const CAirlineIcaoCode & code)
|
||||
{
|
||||
return code.matchesDesignator(designator);
|
||||
});
|
||||
}
|
||||
|
||||
CAirlineIcaoCode CAirlineIcaoCodeList::findByVDesignator(const QString &designator)
|
||||
{
|
||||
if (CAirlineIcaoCode::isValidAirlineDesignator(designator)) { return CAirlineIcaoCode(); }
|
||||
return this->findFirstBy([&](const CAirlineIcaoCode & code)
|
||||
{
|
||||
return code.matchesVDesignator(designator);
|
||||
});
|
||||
}
|
||||
|
||||
CAirlineIcaoCodeList CAirlineIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete)
|
||||
{
|
||||
CAirlineIcaoCodeList codes;
|
||||
@@ -28,5 +46,17 @@ namespace BlackMisc
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
QStringList CAirlineIcaoCodeList::toCompleterStrings() const
|
||||
{
|
||||
QStringList c;
|
||||
for (const CAirlineIcaoCode &icao : *this)
|
||||
{
|
||||
QString cs(icao.getCombinedStringWithKey());
|
||||
c.append(cs);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "airlineicaocode.h"
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/datastoreobjectlist.h"
|
||||
#include "blackmisc/collection.h"
|
||||
#include "blackmisc/sequence.h"
|
||||
#include <initializer_list>
|
||||
@@ -25,6 +26,8 @@ namespace BlackMisc
|
||||
//! Value object encapsulating a list of ICAO codes.
|
||||
class BLACKMISC_EXPORT CAirlineIcaoCodeList :
|
||||
public CSequence<CAirlineIcaoCode>,
|
||||
public BlackMisc::IDatastoreObjectListWithIntegerKey<CAirlineIcaoCode, CAirlineIcaoCodeList>,
|
||||
|
||||
public BlackMisc::Mixin::MetaType<CAirlineIcaoCodeList>
|
||||
{
|
||||
public:
|
||||
@@ -36,6 +39,16 @@ namespace BlackMisc
|
||||
//! Construct from a base class object.
|
||||
CAirlineIcaoCodeList(const CSequence<CAirlineIcaoCode> &other);
|
||||
|
||||
//! Find by designator
|
||||
//! Not unique because of virtual airlines
|
||||
CAirlineIcaoCodeList findByDesignator(const QString &designator);
|
||||
|
||||
//! Find by v-designator, this should be unique
|
||||
CAirlineIcaoCode findByVDesignator(const QString &designator);
|
||||
|
||||
//! String list for completion
|
||||
QStringList toCompleterStrings() const;
|
||||
|
||||
//! From our DB JSON
|
||||
static CAirlineIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete = true);
|
||||
};
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace BlackMisc
|
||||
} // namespace
|
||||
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAirportIcaoCode, (
|
||||
attr(o.m_icaoCode, flags<CaseInsensitiveComparison>())
|
||||
))
|
||||
attr(o.m_icaoCode, flags<CaseInsensitiveComparison>())
|
||||
))
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAirportIcaoCode)
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -241,17 +241,17 @@ namespace BlackMisc
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CAtcStation)
|
||||
CCallsign m_callsign;
|
||||
BlackMisc::Network::CUser m_controller;
|
||||
CCallsign m_callsign;
|
||||
BlackMisc::Network::CUser m_controller;
|
||||
BlackMisc::PhysicalQuantities::CFrequency m_frequency;
|
||||
BlackMisc::Geo::CCoordinateGeodetic m_position;
|
||||
BlackMisc::PhysicalQuantities::CLength m_range;
|
||||
bool m_isOnline = false;
|
||||
QDateTime m_bookedFromUtc;
|
||||
QDateTime m_bookedUntilUtc;
|
||||
BlackMisc::Geo::CCoordinateGeodetic m_position;
|
||||
BlackMisc::PhysicalQuantities::CLength m_range;
|
||||
bool m_isOnline = false;
|
||||
QDateTime m_bookedFromUtc;
|
||||
QDateTime m_bookedUntilUtc;
|
||||
CInformationMessage m_atis { CInformationMessage::ATIS };
|
||||
CInformationMessage m_metar { CInformationMessage::METAR };
|
||||
BlackMisc::Audio::CVoiceRoom m_voiceRoom;
|
||||
BlackMisc::Audio::CVoiceRoom m_voiceRoom;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "blackmisc/aviation/atcstationlist.h"
|
||||
#include "blackmisc/aviation/aircrafticaocode.h"
|
||||
#include "blackmisc/aviation/aircrafticaocodelist.h"
|
||||
#include "blackmisc/aviation/aircraftlist.h"
|
||||
#include "blackmisc/aviation/aircraftsituation.h"
|
||||
#include "blackmisc/aviation/aircraftsituationlist.h"
|
||||
#include "blackmisc/aviation/airlineicaocode.h"
|
||||
|
||||
@@ -25,24 +25,65 @@ namespace BlackMisc
|
||||
CLivery::CLivery()
|
||||
{ }
|
||||
|
||||
CLivery::CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description) :
|
||||
CLivery(-1, combinedCode, airline, description, "", "", false)
|
||||
{ }
|
||||
|
||||
CLivery::CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const QString &colorFuselage, const QString &colorTail, bool isMilitary) :
|
||||
CLivery(-1, combinedCode, airline, description, colorFuselage, colorTail, isMilitary)
|
||||
{ }
|
||||
|
||||
CLivery::CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const CRgbColor &colorFuselage, const CRgbColor &colorTail, bool isMilitary) :
|
||||
CLivery(-1, combinedCode, airline, description, colorFuselage, colorTail, isMilitary)
|
||||
{ }
|
||||
|
||||
CLivery::CLivery(int dbKey, const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const QString &colorFuselage, const QString &colorTail, bool isMilitary) :
|
||||
m_dbKey(dbKey), m_airline(airline),
|
||||
IDatastoreObjectWithIntegerKey(dbKey),
|
||||
m_airline(airline),
|
||||
m_combinedCode(combinedCode.trimmed().toUpper()), m_description(description.trimmed()),
|
||||
m_colorFuselage(normalizeHexColor(colorFuselage)), m_colorTail(normalizeHexColor(colorTail)),
|
||||
m_colorFuselage(CRgbColor(colorFuselage)), m_colorTail(CRgbColor(colorTail)),
|
||||
m_military(isMilitary)
|
||||
{ }
|
||||
|
||||
CLivery::CLivery(int dbKey, const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const CRgbColor &colorFuselage, const CRgbColor &colorTail, bool isMilitary) :
|
||||
IDatastoreObjectWithIntegerKey(dbKey),
|
||||
m_airline(airline),
|
||||
m_combinedCode(combinedCode.trimmed().toUpper()), m_description(description.trimmed()),
|
||||
m_colorFuselage(colorFuselage), m_colorTail(colorTail),
|
||||
m_military(isMilitary)
|
||||
{ }
|
||||
|
||||
bool CLivery::setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao)
|
||||
{
|
||||
if (m_airline == airlineIcao) { return false; }
|
||||
m_airline = airlineIcao;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLivery::hasColorFuselage() const
|
||||
{
|
||||
return m_colorFuselage.isValid();
|
||||
}
|
||||
|
||||
bool CLivery::hasColorTail() const
|
||||
{
|
||||
return m_colorTail.isValid();
|
||||
}
|
||||
|
||||
bool CLivery::matchesCombinedCode(const QString &candidate) const
|
||||
{
|
||||
if (candidate.isEmpty() || !this->hasCombinedCode()) { return false; }
|
||||
QString c(candidate.trimmed().toUpper());
|
||||
return c == this->m_combinedCode;
|
||||
}
|
||||
|
||||
QString CLivery::convertToQString(bool i18n) const
|
||||
{
|
||||
QString s(i18n ? QCoreApplication::translate("Aviation", "Livery") : "Livery");
|
||||
s.append(m_combinedCode);
|
||||
if (!this->m_description.isEmpty()) { s.append(' ').append(this->m_description); }
|
||||
if (!this->m_colorFuselage.isEmpty()) { s.append(" F: ").append(this->m_colorFuselage); }
|
||||
if (!this->m_colorTail.isEmpty()) { s.append(" T: ").append(this->m_colorTail); }
|
||||
if (this->m_colorFuselage.isValid()) { s.append(" F: ").append(this->m_colorFuselage.hex()); }
|
||||
if (this->m_colorTail.isValid()) { s.append(" T: ").append(this->m_colorTail.hex()); }
|
||||
if (this->isMilitary()) { s.append(" Military");}
|
||||
return s;
|
||||
|
||||
@@ -55,38 +96,81 @@ namespace BlackMisc
|
||||
return !m_description.isEmpty() && !m_combinedCode.isEmpty();
|
||||
}
|
||||
|
||||
CLivery CLivery::fromDatabaseJson(const QJsonObject &json)
|
||||
CStatusMessageList CLivery::validate() const
|
||||
{
|
||||
QJsonArray inner = json["cell"].toArray();
|
||||
Q_ASSERT_X(!inner.isEmpty(), Q_FUNC_INFO, "Missing JSON");
|
||||
if (inner.isEmpty()) { return CLivery(); }
|
||||
static const CLogCategoryList cats( { CLogCategory(this->getClassName()), CLogCategory::validation()});
|
||||
CStatusMessageList msg;
|
||||
if (!hasCombinedCode()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Livery: missing livery code")); }
|
||||
if (!hasColorFuselage()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Livery: no fuselage color")); }
|
||||
if (!hasColorTail()) { msg.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Livery: no tail color")); }
|
||||
if (!getAirlineIcaoCodeDesignator().isEmpty()) { msg.push_back(m_airline.validate()); }
|
||||
return msg;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int dbKey = inner.at(i++).toInt(-1);
|
||||
QString code(inner.at(i++).toString());
|
||||
QString combinedCode(inner.at(i++).toString());
|
||||
QString airlineWithId(inner.at(i++).toString());
|
||||
QString airlineName(inner.at(i++).toString());
|
||||
QString description(inner.at(i++).toString());
|
||||
QString colorFuselage(normalizeHexColor(inner.at(i++).toString()));
|
||||
QString colorTail(normalizeHexColor(inner.at(i++).toString()));
|
||||
bool military = CDatastoreUtility::dbBoolStringToBool(inner.at(i++).toString());
|
||||
bool CLivery::hasValidAirlineDesignator() const
|
||||
{
|
||||
return m_airline.hasValidDesignator();
|
||||
}
|
||||
|
||||
int airlineId(CDatastoreUtility::extractIntegerKey(airlineWithId));
|
||||
CAirlineIcaoCode airline;
|
||||
airline.setDbKey(airlineId);
|
||||
airline.setName(airlineName);
|
||||
Q_ASSERT_X(code.length() > 0, Q_FUNC_INFO, "Missing code");
|
||||
bool CLivery::hasCombinedCode() const
|
||||
{
|
||||
Q_ASSERT_X(!m_combinedCode.startsWith("." + standardLiveryMarker()), Q_FUNC_INFO, "illegal combined code");
|
||||
return !m_combinedCode.isEmpty();
|
||||
}
|
||||
|
||||
bool CLivery::isAirlineLivery() const
|
||||
{
|
||||
return (this->m_airline.hasValidDesignator());
|
||||
}
|
||||
|
||||
bool CLivery::isAirlineStandardLivery() const
|
||||
{
|
||||
if (isColorLivery()) { return false; }
|
||||
return (this->m_airline.hasValidDesignator() && this->m_combinedCode.endsWith(standardLiveryMarker()));
|
||||
}
|
||||
|
||||
bool CLivery::isColorLivery() const
|
||||
{
|
||||
return m_combinedCode.startsWith(colorLiveryMarker());
|
||||
}
|
||||
|
||||
CLivery CLivery::fromDatabaseJson(const QJsonObject &json, const QString &prefix)
|
||||
{
|
||||
if (!existsKey(json, prefix))
|
||||
{
|
||||
// when using relationship, this can be null
|
||||
return CLivery();
|
||||
}
|
||||
|
||||
QString combinedCode(json.value(prefix + "combinedcode").toString());
|
||||
QString description(json.value(prefix + "description").toString());
|
||||
CRgbColor colorFuselage(json.value(prefix + "colorfuselage").toString());
|
||||
CRgbColor colorTail(json.value(prefix + "colortail").toString());
|
||||
bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString());
|
||||
CAirlineIcaoCode airline(CAirlineIcaoCode::fromDatabaseJson(json, "al_"));
|
||||
Q_ASSERT_X(description.length() > 0, Q_FUNC_INFO, "require description");
|
||||
CLivery livery(dbKey, combinedCode, airline, description, colorFuselage, colorTail, military);
|
||||
CLivery livery(combinedCode, airline, description, colorFuselage, colorTail, military);
|
||||
livery.setKeyAndTimestampFromDatabaseJson(json, prefix);
|
||||
return livery;
|
||||
}
|
||||
|
||||
QString CLivery::normalizeHexColor(const QString &color)
|
||||
bool CLivery::isValidCombinedCode(const QString &candidate)
|
||||
{
|
||||
if (color.isEmpty()) { return ""; }
|
||||
QString c = color.trimmed().replace('#', "").toUpper();
|
||||
return c;
|
||||
if (candidate.isEmpty()) { return false; }
|
||||
if (candidate.count('.') != 1) { return false; }
|
||||
return candidate.length() > 2;
|
||||
}
|
||||
|
||||
const QString &CLivery::standardLiveryMarker()
|
||||
{
|
||||
static const QString s("_STD");
|
||||
return s;
|
||||
}
|
||||
|
||||
const QString &CLivery::colorLiveryMarker()
|
||||
{
|
||||
static const QString s("_CC");
|
||||
return s;
|
||||
}
|
||||
|
||||
CVariant CLivery::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||
@@ -98,10 +182,12 @@ namespace BlackMisc
|
||||
{
|
||||
case IndexDescription:
|
||||
return CVariant::fromValue(m_description);
|
||||
case IndexAirlineIcaoCode:
|
||||
return m_airline.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexColorFuselage:
|
||||
return CVariant::fromValue(this->m_colorFuselage);
|
||||
return this->m_colorFuselage.propertyByIndex(index.copyFrontRemoved());;
|
||||
case IndexColorTail:
|
||||
return CVariant::fromValue(this->m_colorTail);
|
||||
return this->m_colorTail.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexCombinedCode:
|
||||
return CVariant::fromValue(this->m_combinedCode);
|
||||
case IndexIsMilitary:
|
||||
@@ -121,11 +207,14 @@ namespace BlackMisc
|
||||
case IndexDescription:
|
||||
this->m_description = variant.toQString(false);
|
||||
break;
|
||||
case IndexAirlineIcaoCode:
|
||||
this->m_airline.setPropertyByIndex(variant, index.copyFrontRemoved());
|
||||
break;
|
||||
case IndexColorFuselage:
|
||||
this->setColorFuselage(variant.toQString(false));
|
||||
this->m_colorFuselage.setPropertyByIndex(variant, index.copyFrontRemoved());
|
||||
break;
|
||||
case IndexColorTail:
|
||||
this->setColorTail(variant.toQString(false));
|
||||
this->m_colorTail.setPropertyByIndex(variant, index.copyFrontRemoved());
|
||||
break;
|
||||
case IndexCombinedCode:
|
||||
this->setCombinedCode(variant.toQString(false));
|
||||
@@ -139,5 +228,20 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
void CLivery::updateMissingParts(const CLivery &otherLivery)
|
||||
{
|
||||
if (!this->m_colorFuselage.isValid()) { this->setColorFuselage(otherLivery.getColorFuselage()); }
|
||||
if (!this->m_colorTail.isValid()) { this->setColorTail(otherLivery.getColorTail()); }
|
||||
if (this->m_combinedCode.isEmpty()) { this->setCombinedCode(otherLivery.getCombinedCode());}
|
||||
if (this->m_description.isEmpty()) { this->setDescription(otherLivery.getDescription());}
|
||||
|
||||
this->m_airline.updateMissingParts(otherLivery.getAirlineIcaoCode());
|
||||
if (!this->hasValidDbKey())
|
||||
{
|
||||
this->setDbKey(otherLivery.getDbKey());
|
||||
this->setUtcTimestamp(otherLivery.getUtcTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/aviation/airlineicaocode.h"
|
||||
#include "blackmisc/geo/coordinategeodetic.h"
|
||||
#include "blackmisc/rgbcolor.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/datastore.h"
|
||||
|
||||
@@ -32,6 +33,7 @@ namespace BlackMisc
|
||||
enum ColumnIndex
|
||||
{
|
||||
IndexDescription = BlackMisc::CPropertyIndex::GlobalIndexCLivery,
|
||||
IndexAirlineIcaoCode,
|
||||
IndexCombinedCode,
|
||||
IndexColorFuselage,
|
||||
IndexColorTail,
|
||||
@@ -41,14 +43,26 @@ namespace BlackMisc
|
||||
//! Default constructor.
|
||||
CLivery();
|
||||
|
||||
//! Constructor
|
||||
CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description);
|
||||
|
||||
//! Constructor
|
||||
CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const QString &colorFuselage, const QString &colorTail, bool isMilitary);
|
||||
|
||||
//! Constructor
|
||||
CLivery(const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const BlackMisc::CRgbColor &colorFuselage, const BlackMisc::CRgbColor &colorTail, bool isMilitary);
|
||||
|
||||
//! Constructor
|
||||
CLivery(int dbKey, const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const QString &colorFuselage, const QString &colorTail, bool isMilitary);
|
||||
|
||||
//! Constructor
|
||||
CLivery(int dbKey, const QString &combinedCode, const CAirlineIcaoCode &airline, const QString &description, const BlackMisc::CRgbColor &colorFuselage, const BlackMisc::CRgbColor &colorTail, bool isMilitary);
|
||||
|
||||
//! Corresponding airline, if any
|
||||
const CAirlineIcaoCode &getAirlineIcao() const { return m_airline; }
|
||||
const CAirlineIcaoCode &getAirlineIcaoCode() const { return m_airline; }
|
||||
|
||||
//! Corresponding airline designator, if any
|
||||
const QString &getAirlineIcaoCodeDesignator() const { return m_airline.getDesignator(); }
|
||||
|
||||
//! Combined code
|
||||
const QString &getCombinedCode() const { return m_combinedCode; }
|
||||
@@ -57,29 +71,41 @@ namespace BlackMisc
|
||||
const QString &getDescription() const { return m_description; }
|
||||
|
||||
//! Get fuselage color.
|
||||
const QString &getColorFuselage() const { return m_colorFuselage; }
|
||||
const BlackMisc::CRgbColor &getColorFuselage() const { return m_colorFuselage; }
|
||||
|
||||
//! Get tail color.
|
||||
const QString &getColorTails() const { return m_colorTail; }
|
||||
const BlackMisc::CRgbColor &getColorTail() const { return m_colorTail; }
|
||||
|
||||
//! Military livery
|
||||
bool isMilitary() const { return m_military; }
|
||||
|
||||
//! Airline ICAO code
|
||||
void setAirlineIcao(const CAirlineIcaoCode &airlineIcao) { m_airline = airlineIcao; }
|
||||
bool setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao);
|
||||
|
||||
//! Combined code
|
||||
void setCombinedCode(const QString &code) { m_combinedCode = code.trimmed().toUpper(); }
|
||||
|
||||
//! Set fuselage color
|
||||
void setColorFuselage(const QString &color) { this->m_colorFuselage = normalizeHexColor(color); }
|
||||
void setColorFuselage(const BlackMisc::CRgbColor &color) { this->m_colorFuselage = color; }
|
||||
|
||||
//! Set tail color
|
||||
void setColorTail(const QString &color) { this->m_colorTail = normalizeHexColor(color); }
|
||||
void setColorTail(const BlackMisc::CRgbColor &color) { this->m_colorTail = color; }
|
||||
|
||||
//! Fuselage color set?
|
||||
bool hasColorFuselage() const;
|
||||
|
||||
//! Tail color set?
|
||||
bool hasColorTail() const;
|
||||
|
||||
//! Set description
|
||||
void setDescription(const QString &description) { this->m_description = description; }
|
||||
|
||||
//! Military aircraft?
|
||||
void setMilitary(bool isMilitary) { this->m_military = isMilitary; }
|
||||
|
||||
//! Matches combined code
|
||||
bool matchesCombinedCode(const QString &candidate) const;
|
||||
|
||||
//! \copydoc CValueObject::propertyByIndex
|
||||
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
|
||||
|
||||
@@ -92,31 +118,59 @@ namespace BlackMisc
|
||||
//! Complete data?
|
||||
bool hasCompleteData() const;
|
||||
|
||||
//! Validate data
|
||||
BlackMisc::CStatusMessageList validate() const;
|
||||
|
||||
//! Airline available?
|
||||
bool hasValidAirlineDesignator() const;
|
||||
|
||||
//! Livery combined code available?
|
||||
bool hasCombinedCode() const;
|
||||
|
||||
//! Livery representing airline
|
||||
bool isAirlineLivery() const;
|
||||
|
||||
//! Livery representing airline standard livery
|
||||
bool isAirlineStandardLivery() const;
|
||||
|
||||
//! Color livery
|
||||
bool isColorLivery() const;
|
||||
|
||||
//! Update missing parts
|
||||
void updateMissingParts(const CLivery &otherLivery);
|
||||
|
||||
//! Object from JSON
|
||||
static CLivery fromDatabaseJson(const QJsonObject &json);
|
||||
static CLivery fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString("liv_"));
|
||||
|
||||
//! Valid combined code string?
|
||||
static bool isValidCombinedCode(const QString &candidate);
|
||||
|
||||
//! Standard livery marker
|
||||
static const QString &standardLiveryMarker();
|
||||
|
||||
//! Color livery marker
|
||||
static const QString &colorLiveryMarker();
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CLivery)
|
||||
int m_dbKey = -1; //!< optional DB key
|
||||
CAirlineIcaoCode m_airline; //!< corresponding airline, if any
|
||||
QString m_combinedCode; //!< livery code and pseudo airline ICAO code
|
||||
QString m_description;
|
||||
QString m_colorFuselage;
|
||||
QString m_colorTail;
|
||||
QString m_description; //!< describes the livery
|
||||
BlackMisc::CRgbColor m_colorFuselage; //! color of fuselage
|
||||
BlackMisc::CRgbColor m_colorTail; //! color of tail
|
||||
bool m_military = false; //! Military livery?
|
||||
|
||||
static QString normalizeHexColor(const QString &color);
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CLivery, (
|
||||
attr(o.m_dbKey),
|
||||
attr(o.m_timestampMSecsSinceEpoch),
|
||||
attr(o.m_airline),
|
||||
attr(o.m_combinedCode, flags <CaseInsensitiveComparison> ()),
|
||||
attr(o.m_description),
|
||||
attr(o.m_colorFuselage, flags <CaseInsensitiveComparison> ()),
|
||||
attr(o.m_colorTail, flags <CaseInsensitiveComparison> ())
|
||||
attr(o.m_colorFuselage),
|
||||
attr(o.m_colorTail)
|
||||
))
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CLivery)
|
||||
|
||||
@@ -23,11 +23,32 @@ namespace BlackMisc
|
||||
CSequence<CLivery>(other)
|
||||
{ }
|
||||
|
||||
CLiveryList CLiveryList::findByCombinedCode(const QString &combinedCode) const
|
||||
CLiveryList CLiveryList::findByAirlineIcaoDesignator(const QString &icao) const
|
||||
{
|
||||
QString cc(combinedCode.trimmed().toUpper());
|
||||
if (cc.isEmpty()) { return CLiveryList();}
|
||||
return this->findBy(&CLivery::getCombinedCode, cc);
|
||||
QString i(icao.trimmed().toUpper());
|
||||
if (i.isEmpty()) { return CLiveryList(); }
|
||||
return this->findBy(&CLivery::getAirlineIcaoCodeDesignator, i);
|
||||
}
|
||||
|
||||
CLivery CLiveryList::findByAirlineIcaoDesignatorStdLivery(const QString &icao) const
|
||||
{
|
||||
QString i(icao.trimmed().toUpper());
|
||||
if (i.isEmpty()) { return CLivery(); }
|
||||
return this->findFirstByOrDefault([&](const CLivery & livery)
|
||||
{
|
||||
return livery.getAirlineIcaoCodeDesignator() == icao &&
|
||||
livery.isAirlineStandardLivery();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
CLivery CLiveryList::findByCombinedCode(const QString &combinedCode) const
|
||||
{
|
||||
if (!CLivery::isValidCombinedCode(combinedCode)) { return CLivery(); }
|
||||
return this->findFirstByOrDefault([&](const CLivery & livery)
|
||||
{
|
||||
return livery.matchesCombinedCode(combinedCode);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -36,9 +36,14 @@ namespace BlackMisc
|
||||
//! Construct from a base class object.
|
||||
CLiveryList(const CSequence<CLivery> &other);
|
||||
|
||||
//! Find 0..n liveries by combined code
|
||||
CLiveryList findByCombinedCode(const QString &combinedCode) const;
|
||||
//! Find livery by airline
|
||||
CLiveryList findByAirlineIcaoDesignator(const QString &icao) const;
|
||||
|
||||
//! Find livery by airline
|
||||
CLivery findByAirlineIcaoDesignatorStdLivery(const QString &icao) const;
|
||||
|
||||
//! Find livery by combined code
|
||||
CLivery findByCombinedCode(const QString &combinedCode) const;
|
||||
};
|
||||
} //namespace
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user