1 #include "DefaultAircraftLocator.hxx"
2
3 #include <simgear/props/props_io.hxx>
4 #include <simgear/debug/logstream.hxx>
5 #include <simgear/structure/exception.hxx>
6
7 #include <Main/globals.hxx>
8 #include <Main/locale.hxx>
9
loadXMLDefaults()10 static SGPropertyNode_ptr loadXMLDefaults()
11 {
12 SGPropertyNode_ptr root(new SGPropertyNode);
13 const SGPath defaultsXML = globals->get_fg_root() / "defaults.xml";
14 if (!defaultsXML.exists()) {
15 SG_LOG(SG_GUI, SG_POPUP, "Failed to find required data file (defaults.xml)");
16 return {};
17 }
18
19 try {
20 readProperties(defaultsXML, root);
21 } catch (sg_exception& e) {
22 SG_LOG(SG_GUI, SG_POPUP, "Failed to read required data file (defaults.xml)");
23 return {};
24 }
25
26 if (!root->hasChild("sim")) {
27 SG_LOG(SG_GUI, SG_POPUP, "Failed to find /sim node in defaults.xml, broken");
28 return {};
29 }
30
31 return root;
32 }
33
34
35 namespace flightgear
36 {
37
defaultAirportICAO()38 std::string defaultAirportICAO()
39 {
40 SGPropertyNode_ptr root = loadXMLDefaults();
41 if (!root) {
42 return {};
43 }
44
45 std::string airportCode = root->getStringValue("/sim/presets/airport-id");
46 return airportCode;
47 }
48
defaultSplashScreenPaths()49 string_list defaultSplashScreenPaths()
50 {
51 string_list result;
52 SGPath tpath = globals->get_fg_root() / "Textures";
53 auto paths = simgear::Dir(tpath).children(simgear::Dir::TYPE_FILE);
54 paths.erase(std::remove_if(paths.begin(), paths.end(), [](const SGPath& p) {
55 const auto f = p.file();
56 if (f.find("Splash") != 0) return true;
57 const auto ext = p.extension();
58 return ext != "png" && ext != "jpg";
59 }), paths.end());
60
61 for (auto c : paths) {
62 result.push_back(c.utf8Str());
63 }
64
65 return result;
66 }
67
DefaultAircraftLocator()68 DefaultAircraftLocator::DefaultAircraftLocator()
69 {
70 SGPropertyNode_ptr root = loadXMLDefaults();
71 if (root) {
72 _aircraftId = root->getStringValue("/sim/aircraft");
73 } else {
74 SG_LOG(SG_GUI, SG_WARN, "failed to load default aircraft identifier");
75 _aircraftId = "ufo"; // last ditch fallback
76 }
77
78 _aircraftId += "-set.xml";
79 const SGPath rootAircraft = globals->get_fg_root() / "Aircraft";
80 visitDir(rootAircraft, 0);
81 }
82
foundPath() const83 SGPath DefaultAircraftLocator::foundPath() const
84 {
85 return _foundPath;
86 }
87
88 AircraftDirVistorBase::VisitResult
visit(const SGPath & p)89 DefaultAircraftLocator::visit(const SGPath& p)
90 {
91 if (p.file() == _aircraftId) {
92 _foundPath = p;
93 return VISIT_DONE;
94 }
95
96 return VISIT_CONTINUE;
97 }
98
WeatherScenariosModel(QObject * pr)99 WeatherScenariosModel::WeatherScenariosModel(QObject *pr) :
100 QAbstractListModel(pr)
101 {
102 SGPropertyNode_ptr root = loadXMLDefaults();
103 if (root) {
104 SGPropertyNode_ptr scenarios = root->getNode("environment/weather-scenarios");
105 Q_ASSERT(scenarios);
106 int nChildren = scenarios->nChildren();
107 for (int i = 0; i < nChildren; i++) {
108 SGPropertyNode_ptr scenario = scenarios->getChild(i);
109 if (strcmp(scenario->getName(), "scenario") != 0) {
110 continue;
111 }
112
113 // omit the 'live data' option, we have a distinct UI for that, we'll
114 // pass --real-wxr option on launch
115 if (scenario->getStringValue("local-weather/tile-type") == std::string("live")) {
116 continue;
117 }
118
119 WeatherScenario ws;
120 const string wsId = scenario->getStringValue("id");
121 if (!wsId.empty()) {
122 // translated
123 auto locale = globals->get_locale();
124 ws.name = QString::fromStdString(locale->getLocalizedString(wsId + "-name", "weather-scenarios"));
125 ws.description = QString::fromStdString(locale->getLocalizedString(wsId + "-desc", "weather-scenarios"));
126 } else {
127 ws.name = QString::fromStdString(scenario->getStringValue("name"));
128 ws.description = QString::fromStdString(scenario->getStringValue("description")).simplified();
129 }
130
131 ws.metar = QString::fromStdString(scenario->getStringValue("metar"));
132 if (scenario->hasChild("local-weather")) {
133 ws.localWeatherTileManagement = QString::fromStdString(scenario->getStringValue("local-weather/tile-management"));
134 ws.localWeatherTileType = QString::fromStdString(scenario->getStringValue("local-weather/tile-type"));
135 }
136 m_scenarios.push_back(ws);
137 }
138 }
139 }
140
rowCount(const QModelIndex &) const141 int WeatherScenariosModel::rowCount(const QModelIndex&) const
142 {
143 return static_cast<int>(m_scenarios.size());
144 }
145
data(const QModelIndex & index,int role) const146 QVariant WeatherScenariosModel::data(const QModelIndex &index, int role) const
147 {
148 const int row = index.row();
149 if ((row < 0) || (row >= m_scenarios.size())) {
150 return QVariant();
151 }
152
153 const WeatherScenario& scenario(m_scenarios.at(row));
154 if ((role == Qt::DisplayRole) || (role == NameRole)) {
155 return scenario.name;
156 } else if (role == DescriptionRole) {
157 return scenario.description;
158 } else if (role == MetarRole) {
159 return scenario.metar;
160 }
161
162 return QVariant();
163 }
164
roleNames() const165 QHash<int, QByteArray> WeatherScenariosModel::roleNames() const
166 {
167 QHash<int, QByteArray> result;
168 result[NameRole] = "name";
169 result[DescriptionRole] = "description";
170 result[MetarRole] = "metar";
171 return result;
172 }
173
metarForItem(quint32 index) const174 QString WeatherScenariosModel::metarForItem(quint32 index) const
175 {
176 if (index >= m_scenarios.size()) {
177 return {};
178 }
179
180 return m_scenarios.at(index).metar;
181 }
182
descriptionForItem(quint32 index) const183 QString WeatherScenariosModel::descriptionForItem(quint32 index) const
184 {
185 if (index >= m_scenarios.size()) {
186 return {};
187 }
188
189 return m_scenarios.at(index).description;
190 }
191
localWeatherData(quint32 index) const192 QStringList WeatherScenariosModel::localWeatherData(quint32 index) const
193 {
194 if (index >= m_scenarios.size()) {
195 return {};
196 }
197
198 const auto& s = m_scenarios.at(index);
199 if (s.localWeatherTileManagement.isEmpty() || s.localWeatherTileType.isEmpty()) {
200 return {};
201 }
202
203 return QStringList() << s.localWeatherTileManagement << s.localWeatherTileType;
204 }
205
nameForItem(quint32 index) const206 QString WeatherScenariosModel::nameForItem(quint32 index) const
207 {
208 if (index >= m_scenarios.size()) {
209 return {};
210 }
211
212 return m_scenarios.at(index).name;
213 }
214
215 } // of namespace flightgear
216