diff --git a/src/GUI/QmlAircraftInfo.cxx b/src/GUI/QmlAircraftInfo.cxx index 1d7e0d2e0..bdbaa49d0 100644 --- a/src/GUI/QmlAircraftInfo.cxx +++ b/src/GUI/QmlAircraftInfo.cxx @@ -49,6 +49,7 @@ protected: void installProgress(InstallRef aInstall, unsigned int bytes, unsigned int total) override { + Q_UNUSED(total) if (aInstall->package() == p->packageRef()) { p->setDownloadBytes(bytes); } @@ -58,6 +59,7 @@ protected: { Q_UNUSED(aReason); if (aInstall->package() == p->packageRef()) { + p->_cachedProps.reset(); p->checkForStates(); p->infoChanged(); } @@ -135,19 +137,6 @@ static AircraftStateVec readAircraftStates(const SGPath& setXMLPath) return result; } -static SGPropertyNode_ptr readAircraftAuthors(const SGPath& setXMLPath) -{ - SGPropertyNode_ptr root(new SGPropertyNode); - try { - readProperties(setXMLPath, root); - } catch (sg_exception&) { - return {}; // malformed include or XML, just bail - } - - const auto authors = root->getNode("sim/authors"); - return authors; -} - QString humanNameFromStateTag(const std::string& tag) { if (tag == "approach") return QObject::tr("On approach"); @@ -214,12 +203,12 @@ public: if (it == _data.end()) return -1; - return std::distance(_data.begin(), it); + return static_cast(std::distance(_data.begin(), it)); } - int rowCount(const QModelIndex &parent) const override + int rowCount(const QModelIndex &) const override { - return _data.size(); + return static_cast(_data.size()); } QVariant data(const QModelIndex &index, int role) const override @@ -320,7 +309,7 @@ int QmlAircraftInfo::numVariants() const return _item->variants.size() + 1; } else if (_package) { // whereas for packaged aircraft we do - return _package->variants().size(); + return static_cast(_package->variants().size()); } return 0; @@ -353,8 +342,10 @@ QString QmlAircraftInfo::authors() const { SGPropertyNode_ptr structuredAuthors; if (_item) { - std::string path = pathOnDisk().toUtf8().toStdString(); - structuredAuthors = readAircraftAuthors(SGPath::fromUtf8(path)); + validateLocalProps(); + if (_cachedProps) + structuredAuthors = _cachedProps->getNode("sim/authors"); + if (!structuredAuthors) return resolveItem()->authors; } else if (_package) { @@ -531,7 +522,7 @@ QString QmlAircraftInfo::packageId() const int QmlAircraftInfo::packageSize() const { if (_package) { - return _package->fileSizeBytes(); + return static_cast(_package->fileSizeBytes()); } return 0; @@ -596,6 +587,31 @@ void QmlAircraftInfo::checkForStates() emit infoChanged(); } +void QmlAircraftInfo::validateLocalProps() const +{ + if (!_cachedProps) { + SGPath path; + if (_item) { + path = resolveItem()->path.toUtf8().toStdString(); + } else if (_package) { + auto install = _package->existingInstall(); + if (!install.valid()) + return; + + path = install->path(); + } + + if (!path.exists()) + return; + _cachedProps = new SGPropertyNode; + try { + readProperties(path, _cachedProps); + } catch (sg_exception&) { + _cachedProps.reset(); + } + } +} + void QmlAircraftInfo::setUri(QUrl u) { if (uri() == u) @@ -604,6 +620,7 @@ void QmlAircraftInfo::setUri(QUrl u) _item.clear(); _package.clear(); _statesModel.reset(new StatesModel); + _cachedProps.clear(); if (u.isLocalFile()) { _item = LocalAircraftCache::instance()->findItemWithUri(u); @@ -651,27 +668,14 @@ void QmlAircraftInfo::setVariant(int variant) return; _variant = variant; + _cachedProps.clear(); + checkForStates(); emit infoChanged(); emit variantChanged(_variant); } -void QmlAircraftInfo::requestInstallUpdate() -{ - -} - -void QmlAircraftInfo::requestUninstall() -{ - -} - -void QmlAircraftInfo::requestInstallCancel() -{ - -} - QVariant QmlAircraftInfo::packageAircraftStatus(simgear::pkg::PackageRef p) { if (p->hasTag("needs-maintenance")) { @@ -774,5 +778,75 @@ StatesModel *QmlAircraftInfo::statesModel() return _statesModel.data(); } +QuantityValue QmlAircraftInfo::cruiseSpeed() const +{ + validateLocalProps(); + if (!_cachedProps) { + return {}; + } + + if (_cachedProps->hasValue("aircraft/performance/cruise/mach")) { + return QuantityValue{Units::Mach, _cachedProps->getDoubleValue("aircraft/performance/cruise/mach")}; + } + + if (_cachedProps->hasValue("aircraft/performance/cruise/airpseed-knots")) { + return QuantityValue{Units::Knots, _cachedProps->getIntValue("aircraft/performance/cruise/airpseed-knots")}; + } + + return {}; +} + +QuantityValue QmlAircraftInfo::approachSpeed() const +{ + validateLocalProps(); + if (!_cachedProps) { + return {}; + } + + if (_cachedProps->hasValue("aircraft/performance/approach/airpseed-knots")) { + return QuantityValue{Units::Knots, _cachedProps->getIntValue("aircraft/performance/approach/airpseed-knots")}; + } + + return {}; +} + +QuantityValue QmlAircraftInfo::cruiseAltitude() const +{ + validateLocalProps(); + if (!_cachedProps) { + return {}; + } + + if (_cachedProps->hasValue("aircraft/performance/cruise/flight-level")) { + return QuantityValue{Units::FlightLevel, _cachedProps->getIntValue("aircraft/performance/cruise/flight-level")}; + } + + if (_cachedProps->hasValue("aircraft/performance/cruise/airpseed-knots")) { + return QuantityValue{Units::FeetMSL, _cachedProps->getIntValue("aircraft/performance/cruise/altitude-ft")}; + } + + return {}; +} + +QString QmlAircraftInfo::icaoType() const +{ + validateLocalProps(); + if (!_cachedProps) { + return {}; + } + + return QString::fromStdString(_cachedProps->getStringValue("aircraft/icao/type")); +} + +bool QmlAircraftInfo::isSpeedBelowLimits(QuantityValue speed) const +{ + return true; +} + +bool QmlAircraftInfo::isAltitudeBelowLimits(QuantityValue speed) const +{ + return true; +} + #include "QmlAircraftInfo.moc" diff --git a/src/GUI/QmlAircraftInfo.hxx b/src/GUI/QmlAircraftInfo.hxx index 2b429a006..37855db46 100644 --- a/src/GUI/QmlAircraftInfo.hxx +++ b/src/GUI/QmlAircraftInfo.hxx @@ -11,6 +11,8 @@ #include #include +#include "UnitsModel.hxx" + struct AircraftItem; typedef QSharedPointer AircraftItemPtr; @@ -25,20 +27,19 @@ class QmlAircraftInfo : public QObject Q_PROPERTY(QVariantList previews READ previews NOTIFY infoChanged) Q_PROPERTY(int numVariants READ numVariants NOTIFY infoChanged) + Q_PROPERTY(QStringList variantNames READ variantNames NOTIFY infoChanged) Q_PROPERTY(QString name READ name NOTIFY infoChanged) Q_PROPERTY(QString description READ description NOTIFY infoChanged) Q_PROPERTY(QString authors READ authors NOTIFY infoChanged) - Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY infoChanged) + Q_PROPERTY(QVariantList ratings READ ratings NOTIFY infoChanged) Q_PROPERTY(QString pathOnDisk READ pathOnDisk NOTIFY infoChanged) - Q_PROPERTY(QString packageId READ packageId NOTIFY infoChanged) - Q_PROPERTY(int packageSize READ packageSize NOTIFY infoChanged) - Q_PROPERTY(int downloadedBytes READ downloadedBytes NOTIFY downloadChanged) + Q_PROPERTY(bool isPackaged READ isPackaged NOTIFY infoChanged) Q_PROPERTY(QVariant status READ status NOTIFY infoChanged) Q_PROPERTY(QVariant installStatus READ installStatus NOTIFY downloadChanged) @@ -49,21 +50,13 @@ class QmlAircraftInfo : public QObject Q_PROPERTY(QUrl supportUrl READ supportUrl NOTIFY infoChanged) Q_PROPERTY(QUrl wikipediaUrl READ wikipediaUrl NOTIFY infoChanged) + Q_PROPERTY(QuantityValue cruiseSpeed READ cruiseSpeed NOTIFY infoChanged) + Q_PROPERTY(QuantityValue cruiseAltitude READ cruiseAltitude NOTIFY infoChanged) + Q_PROPERTY(QuantityValue approachSpeed READ approachSpeed NOTIFY infoChanged) - Q_INVOKABLE void requestInstallUpdate(); - - Q_INVOKABLE void requestUninstall(); - - Q_INVOKABLE void requestInstallCancel(); - - Q_PROPERTY(QVariantList ratings READ ratings NOTIFY infoChanged) - - Q_PROPERTY(QStringList variantNames READ variantNames NOTIFY infoChanged) - - Q_PROPERTY(bool isPackaged READ isPackaged NOTIFY infoChanged) + Q_PROPERTY(QString icaoType READ icaoType NOTIFY infoChanged) Q_PROPERTY(bool hasStates READ hasStates NOTIFY infoChanged) - Q_PROPERTY(StatesModel* statesModel READ statesModel NOTIFY infoChanged) public: @@ -123,6 +116,16 @@ public: static const int StateExplicitRole; StatesModel* statesModel(); + + QuantityValue cruiseSpeed() const; + QuantityValue approachSpeed() const; + QuantityValue cruiseAltitude() const; + + QString icaoType() const; + + Q_INVOKABLE bool isSpeedBelowLimits(QuantityValue speed) const; + Q_INVOKABLE bool isAltitudeBelowLimits(QuantityValue speed) const; + signals: void uriChanged(); void infoChanged(); @@ -139,14 +142,20 @@ private: AircraftItemPtr resolveItem() const; void checkForStates(); + void validateLocalProps() const; + class Delegate; std::unique_ptr _delegate; simgear::pkg::PackageRef _package; AircraftItemPtr _item; - int _variant = 0; + quint32 _variant = 0; int _downloadBytes = 0; QScopedPointer _statesModel; + + /// if the aircraft is locally installed, this is the cached + /// parsed contents of the -set.xml. + mutable SGPropertyNode_ptr _cachedProps; }; #endif // QMLAIRCRAFTINFO_HXX diff --git a/src/GUI/UnitsModel.cxx b/src/GUI/UnitsModel.cxx index bdb2f7edf..0f81e72d8 100644 --- a/src/GUI/UnitsModel.cxx +++ b/src/GUI/UnitsModel.cxx @@ -287,6 +287,14 @@ QuantityValue::QuantityValue(Units::Type u, double v) : { } +QuantityValue::QuantityValue(Units::Type u, int v) : + value(static_cast(v)), + unit(u) +{ + assert(static_unitData.at(u).decimals == 0); +} + + QuantityValue QuantityValue::convertToUnit(Units::Type u) const { // special case a no-change @@ -331,6 +339,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const // use the value at sea level for now return {u, value / 667.0}; } + break; } case Units::Knots: @@ -340,6 +349,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const // use the value at sea level for now return {u, value * 667.0}; } + break; } case Units::DegreesMagnetic: @@ -350,6 +360,7 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const if ((unit == Units::DegreesMagnetic) || (unit == Units::DegreesTrue)) { return {u, value}; } + break; } case Units::FlightLevel: diff --git a/src/GUI/UnitsModel.hxx b/src/GUI/UnitsModel.hxx index 845becc11..cfc44afcf 100644 --- a/src/GUI/UnitsModel.hxx +++ b/src/GUI/UnitsModel.hxx @@ -86,6 +86,8 @@ public: QuantityValue(Units::Type u, double v); + QuantityValue(Units::Type u, int v); + QuantityValue convertToUnit(Units::Type u) const; Q_INVOKABLE QuantityValue convertToUnit(int u) const;