1 // UnitsModel.cxx - part of GUI launcher using Qt5 2 // 3 // Written by James Turner, started July 2018 4 // 5 // Copyright (C) 2018 James Turner <james@flightgear.org> 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License as 9 // published by the Free Software Foundation; either version 2 of the 10 // License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, but 13 // WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 21 #ifndef UNITSMODEL_HXX 22 #define UNITSMODEL_HXX 23 24 #include <vector> 25 26 #include <QAbstractListModel> 27 28 class QValidator; 29 class QDataStream; 30 31 class Units : public QObject 32 { 33 Q_OBJECT 34 public: 35 36 37 /** 38 * @brief This enum stores units / types of values used in the 39 * simulator. They're not strictly all units, but they map to the 40 * same concept for the user: selecting the dimension of values they 41 * are inputting 42 */ 43 enum Type 44 { 45 NoUnits = 0, 46 FeetMSL, 47 FeetAGL, 48 FeetAboveFieldElevation, 49 FlightLevel, 50 MetersMSL, 51 Knots, 52 Mach, 53 KilometersPerHour, 54 DegreesTrue, 55 DegreesMagnetic, 56 TimeUTC, 57 TimeLocal, 58 NauticalMiles, 59 Kilometers, 60 FreqMHz, // for VORs, LOCs 61 FreqKHz // for NDBs 62 }; 63 64 enum Mode 65 { 66 Altitude = 0, // MSL, FlightLevel 67 AltitudeIncludingAGL, 68 AltitudeIncludingMeters, 69 Speed, // Mach or knots or KM/H 70 SpeedWithoutMach = 4, 71 Heading, // degrees true or magnetic 72 Timezone, 73 Distance = 7, // Nm or Kilometers only for now 74 AltitudeIncludingMetersAndAboveField, 75 HeadingOnlyTrue 76 }; 77 78 Q_ENUMS(Mode) 79 Q_ENUMS(Type) 80 }; 81 82 83 class QuantityValue 84 { 85 Q_GADGET 86 87 Q_PROPERTY(double value MEMBER value) 88 Q_PROPERTY(Units::Type unit MEMBER unit) 89 90 public: 91 QuantityValue(); 92 93 QuantityValue(Units::Type u, double v); 94 95 QuantityValue(Units::Type u, int v); 96 97 QuantityValue convertToUnit(Units::Type u) const; 98 99 Q_INVOKABLE QuantityValue convertToUnit(int u) const; 100 101 Q_INVOKABLE QString toString() const; 102 103 Q_INVOKABLE bool isValid() const; 104 105 // precision aware comparisom 106 bool operator==(const QuantityValue& v) const; 107 bool operator!=(const QuantityValue& v) const; 108 109 double value = 0.0; 110 Units::Type unit = Units::NoUnits; 111 }; 112 113 QDataStream &operator<<(QDataStream &out, const QuantityValue &value); 114 QDataStream &operator>>(QDataStream &in, QuantityValue &value); 115 116 Q_DECLARE_METATYPE(QuantityValue) 117 118 class UnitsModel : public QAbstractListModel 119 { 120 Q_OBJECT 121 122 Q_PROPERTY(Units::Mode mode READ mode WRITE setMode NOTIFY modeChanged) 123 124 Q_PROPERTY(int numChoices READ numChoices NOTIFY modeChanged) 125 126 Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectionChanged) 127 Q_PROPERTY(int selectedUnit READ selectedUnit WRITE setSelectedUnit NOTIFY selectionChanged) 128 129 Q_PROPERTY(double minValue READ minValue NOTIFY selectionChanged) 130 Q_PROPERTY(double maxValue READ maxValue NOTIFY selectionChanged) 131 Q_PROPERTY(double stepSize READ stepSize NOTIFY selectionChanged) 132 Q_PROPERTY(int numDecimals READ numDecimals NOTIFY selectionChanged) 133 Q_PROPERTY(QString maxTextForMetrics READ maxTextForMetrics NOTIFY selectionChanged) 134 Q_PROPERTY(QString shortText READ shortText NOTIFY selectionChanged) 135 Q_PROPERTY(bool isPrefix READ isPrefix NOTIFY selectionChanged) 136 Q_PROPERTY(bool wraps READ doesWrap NOTIFY selectionChanged) 137 138 Q_PROPERTY(QValidator* validator READ validator NOTIFY selectionChanged) 139 public: 140 UnitsModel(); 141 142 using UnitVec = std::vector<Units::Type>; 143 144 int rowCount(const QModelIndex &parent) const override; 145 146 QVariant data(const QModelIndex &index, int role) const override; 147 148 QHash<int, QByteArray> roleNames() const override; 149 mode() const150 Units::Mode mode() const 151 { 152 return m_mode; 153 } 154 selectedIndex() const155 int selectedIndex() const 156 { 157 return static_cast<int>(m_activeIndex); 158 } 159 160 double minValue() const; 161 double maxValue() const; 162 double stepSize() const; 163 int numDecimals() const; 164 QValidator *validator() const; 165 QString maxTextForMetrics() const; 166 bool isPrefix() const; 167 bool doesWrap() const; 168 169 QString shortText() const; 170 Units::Type selectedUnit() const; 171 int numChoices() const; 172 173 Q_INVOKABLE bool isUnitInMode(int unit) const; 174 public slots: 175 void setMode(Units::Mode mode); 176 177 void setSelectedIndex(int selectedIndex); 178 void setSelectedUnit(int u); 179 180 signals: 181 void modeChanged(Units::Mode mode); 182 183 void selectionChanged(int selectedIndex); 184 185 private: 186 Units::Mode m_mode = Units::Altitude; 187 quint32 m_activeIndex = 0; 188 UnitVec m_enabledUnits; 189 }; 190 191 #endif // UNITSMODEL_HXX 192