swift
simulatorsettings.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QStringBuilder>
7 
8 #include "config/buildconfig.h"
13 #include "misc/stringutils.h"
14 #include "misc/verify.h"
15 
16 using namespace swift::config;
17 using namespace swift::misc::physical_quantities;
18 using namespace swift::misc::simulation::fscommon;
19 using namespace swift::misc::simulation::xplane;
20 using namespace swift::misc::simulation::flightgear;
21 
22 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::simulation::settings, CSimulatorSettings)
23 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::simulation::settings, CFsxP3DSettings)
24 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::simulation::settings, CSimulatorMessagesSettings)
25 
26 namespace swift::misc::simulation::settings
27 {
28  const QString &CSimulatorSettings::cgSourceAsString(CSimulatorSettings::CGSource source)
29  {
30  static const QString sf("simulator 1st");
31  static const QString dbf("DB 1st");
32  static const QString so("simulator only");
33  static const QString dbo("DB only");
34 
35  switch (source)
36  {
37  case CGFromSimulatorFirst: return sf;
38  case CGFromDBFirst: return dbf;
39  case CGFromSimulatorOnly: return so;
40  case CGFromDBOnly: return dbo;
41  default: break;
42  }
43  static const QString u("unknown");
44  return u;
45  }
46 
47  void CSimulatorSettings::setSimulatorDirectory(const QString &simulatorDirectory)
48  {
49  m_simulatorDirectory = simulatorDirectory.trimmed();
50  }
51 
52  const QString &CSimulatorSettings::getSimulatorDirectory() const { return m_simulatorDirectory; }
53 
54  void CSimulatorSettings::setModelDirectories(const QStringList &modelDirectories)
55  {
56  m_modelDirectories = modelDirectories;
57  m_modelDirectories.removeAll({}); // empty values
58  m_modelDirectories.removeDuplicates(); // duplicates
59  }
60 
61  void CSimulatorSettings::clearModelDirectories() { m_modelDirectories.clear(); }
62 
63  void CSimulatorSettings::setModelDirectory(const QString &modelDirectory)
64  {
65  m_modelDirectories = QStringList({ modelDirectory });
66  }
67 
68  bool CSimulatorSettings::addModelDirectory(const QString &modelDirectory)
69  {
70  const Qt::CaseSensitivity cs =
72  if (m_modelDirectories.contains(modelDirectory, cs)) { return false; }
73  m_modelDirectories.push_back(modelDirectory);
74  m_modelDirectories.removeAll({});
75  m_modelDirectories.removeDuplicates();
76  return true;
77  }
78 
79  const QStringList &CSimulatorSettings::getModelDirectories() const { return m_modelDirectories; }
80 
81  void CSimulatorSettings::setModelExcludeDirectories(const QStringList &excludeDirectories)
82  {
83  m_excludeDirectoryPatterns = excludeDirectories;
84  m_excludeDirectoryPatterns.removeAll({});
85  m_excludeDirectoryPatterns.removeDuplicates();
86  }
87 
88  const QStringList &CSimulatorSettings::getModelExcludeDirectoryPatterns() const
89  {
90  return m_excludeDirectoryPatterns;
91  }
92 
93  bool CSimulatorSettings::setComIntegrated(bool integrated)
94  {
95  if (integrated == m_comIntegration) { return false; }
96  m_comIntegration = integrated;
97  return true;
98  }
99 
100  bool CSimulatorSettings::setCGSource(CSimulatorSettings::CGSource source)
101  {
102  const int s = static_cast<int>(source);
103  if (m_cgSource == s) { return false; }
104  m_cgSource = s;
105  return true;
106  }
107 
108  bool CSimulatorSettings::setRecordOwnAircraftGnd(bool record)
109  {
110  if (record == m_recordGnd) { return false; }
111  m_recordGnd = record;
112  return true;
113  }
114 
115  bool CSimulatorSettings::setRecordedGndRadius(const CLength &radius)
116  {
117  if (radius == m_recordedGndRadius) { return false; }
118  m_recordedGndRadius = radius;
119  return true;
120  }
121 
122  void CSimulatorSettings::resetPaths()
123  {
124  m_excludeDirectoryPatterns.clear();
125  m_modelDirectories.clear();
126  m_simulatorDirectory.clear();
127  }
128 
129  QString CSimulatorSettings::convertToQString(bool i18n) const { return convertToQString(", ", i18n); }
130 
131  QString CSimulatorSettings::convertToQString(const QString &separator, bool i18n) const
132  {
133  Q_UNUSED(i18n)
134  return u"model directories: " % m_modelDirectories.join(',') % separator % u"exclude directories: " %
135  m_excludeDirectoryPatterns.join(',');
136  }
137 
138  QVariant CSimulatorSettings::propertyByIndex(CPropertyIndexRef index) const
139  {
140  if (index.isMyself()) { return QVariant::fromValue(*this); }
141  const auto i = index.frontCasted<ColumnIndex>();
142  switch (i)
143  {
144  case IndexSimulatorDirectory: return QVariant::fromValue(m_simulatorDirectory);
145  case IndexModelDirectories: return QVariant::fromValue(m_modelDirectories);
146  case IndexModelExcludeDirectoryPatterns: return QVariant::fromValue(m_excludeDirectoryPatterns);
147  case IndexComIntegration: return QVariant::fromValue(m_comIntegration);
148  case IndexRecordOwnAircraftGnd: return QVariant::fromValue(m_recordGnd);
149  case IndexCGSource: return QVariant::fromValue(m_cgSource);
150  case IndexRecordOwnAircraftGndRadius: return m_recordedGndRadius.propertyByIndex(index.copyFrontRemoved());
151  default: return CValueObject::propertyByIndex(index);
152  }
153  }
154 
155  void CSimulatorSettings::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
156  {
157  if (index.isMyself())
158  {
159  (*this) = variant.value<CSimulatorSettings>();
160  return;
161  }
162  const auto i = index.frontCasted<ColumnIndex>();
163  switch (i)
164  {
165  case IndexSimulatorDirectory: this->setSimulatorDirectory(variant.toString()); break;
166  case IndexModelDirectories: this->setModelDirectories(variant.toStringList()); break;
167  case IndexComIntegration: this->setComIntegrated(variant.toBool()); break;
168  case IndexRecordOwnAircraftGnd: this->setRecordOwnAircraftGnd(variant.toBool()); break;
169  case IndexModelExcludeDirectoryPatterns: m_excludeDirectoryPatterns = variant.value<QStringList>(); break;
170  case IndexCGSource: m_cgSource = variant.toInt(); break;
171  case IndexRecordOwnAircraftGndRadius:
172  m_recordedGndRadius.setPropertyByIndex(index.copyFrontRemoved(), variant);
173  break;
174  default: CValueObject::setPropertyByIndex(index, variant); break;
175  }
176  }
177 
178  CMultiSimulatorSettings::CMultiSimulatorSettings(QObject *parent) : QObject(parent)
179  {
180  // void
181  }
182 
184  {
185  if (!simulator.isSingleSimulator())
186  {
187  // mostly happening with emulated driver, VERIFY for better debugging
188  SWIFT_VERIFY_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
189  return {};
190  }
191  switch (simulator.getSimulator())
192  {
193  case CSimulatorInfo::FG: return m_simSettingsFG.get();
194  case CSimulatorInfo::P3D: return m_simSettingsP3D.get();
195  case CSimulatorInfo::MSFS: return m_simSettingsMsfs.get();
196  case CSimulatorInfo::MSFS2024: return m_simSettingsMsfs2024.get();
197  case CSimulatorInfo::XPLANE: return m_simSettingsXP.get();
198 
199  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
200  }
201  return {};
202  }
203 
205  {
206  return { this->getSettings(simulator), simulator };
207  }
208 
210  const CSimulatorInfo &simulator)
211  {
212  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
213  switch (simulator.getSimulator())
214  {
215  case CSimulatorInfo::FG: return m_simSettingsFG.set(settings);
216  case CSimulatorInfo::P3D: return m_simSettingsP3D.set(settings);
217  case CSimulatorInfo::MSFS: return m_simSettingsMsfs.set(settings);
218  case CSimulatorInfo::MSFS2024: return m_simSettingsMsfs2024.set(settings);
219  case CSimulatorInfo::XPLANE: return m_simSettingsXP.set(settings);
220  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
221  }
222  return CStatusMessage({ CLogCategories::settings() }, CStatusMessage::SeverityError, u"wrong simulator");
223  }
224 
226  const CSimulatorInfo &simulator)
227  {
228  CSimulatorSettings s = this->getSettings(simulator);
229  if (!s.addModelDirectory(modelDirectory))
230  {
232  u"directory already existing");
233  }
234  return this->setSettings(s, simulator);
235  }
236 
238  {
239  CSimulatorSettings s = this->getSettings(simulator);
241  return this->setSettings(s, simulator);
242  }
243 
245  const CSimulatorInfo &simulator)
246  {
247  this->setSettings(settings, simulator);
248  CStatusMessageList msgs;
249  switch (simulator.getSimulator())
250  {
251  case CSimulatorInfo::FG: break;
252  case CSimulatorInfo::P3D: break;
253  case CSimulatorInfo::MSFS: break;
254  case CSimulatorInfo::MSFS2024: break;
255  case CSimulatorInfo::XPLANE:
256  {
257  if (settings.hasModelDirectories())
258  {
259  const QString simDir = this->getSimulatorDirectoryOrDefault(simulator);
260  msgs = CXPlaneUtil::validateModelDirectories(simDir, settings.getModelDirectories());
261  }
262  }
263  break;
264  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
265  }
266  return msgs;
267  }
268 
270  const CSimulatorInfo &simulator)
271  {
272  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
273  switch (simulator.getSimulator())
274  {
275  case CSimulatorInfo::FG: return m_simSettingsFG.setAndSave(settings);
276  case CSimulatorInfo::P3D: return m_simSettingsP3D.setAndSave(settings);
277  case CSimulatorInfo::MSFS: return m_simSettingsMsfs.setAndSave(settings);
278  case CSimulatorInfo::MSFS2024: return m_simSettingsMsfs2024.setAndSave(settings);
279  case CSimulatorInfo::XPLANE: return m_simSettingsXP.setAndSave(settings);
280  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
281  }
282  return CStatusMessage({ CLogCategories::settings() }, CStatusMessage::SeverityError, u"wrong simulator");
283  }
284 
286  const CSimulatorInfo &simulator)
287  {
288  return this->setAndSaveSettings(settings.getGenericSettings(), simulator);
289  }
290 
292  {
293  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
294  switch (simulator.getSimulator())
295  {
296  case CSimulatorInfo::FG: return m_simSettingsFG.save();
297  case CSimulatorInfo::P3D: return m_simSettingsP3D.save();
298  case CSimulatorInfo::MSFS: return m_simSettingsMsfs.save();
299  case CSimulatorInfo::MSFS2024: return m_simSettingsMsfs2024.save();
300  case CSimulatorInfo::XPLANE: return m_simSettingsXP.save();
301  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
302  }
303  return CStatusMessage({ CLogCategories::settings() }, CStatusMessage::SeverityError, u"wrong simulator");
304  }
305 
307  {
308  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
310  }
311 
313  {
314  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
316  }
317 
319  {
320  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
321  return s.getModelDirectoriesOrDefault();
322  }
323 
325  {
326  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
328  }
329 
331  {
332  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
334  }
335 
338  {
339  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
341  }
342 
345  {
346  const CSpecializedSimulatorSettings s = this->getSpecializedSettings(simulator);
348  }
349 
351  {
352  CSimulatorSettings s = this->getSettings(simulator);
353  s.resetPaths();
354  this->setAndSaveSettings(s, simulator);
355  }
356 
358  {
360  }
361 
362  void CMultiSimulatorSettings::onP3DSettingsChanged() { this->emitSettingsChanged(CSimulatorInfo::p3d()); }
363 
364  void CMultiSimulatorSettings::onMsfsSettingsChanged() { this->emitSettingsChanged(CSimulatorInfo::msfs()); }
365 
366  void CMultiSimulatorSettings::onMsfs2024SettingsChanged() { this->emitSettingsChanged(CSimulatorInfo::msfs2024()); }
367 
368  void CMultiSimulatorSettings::onXPSettingsChanged() { this->emitSettingsChanged(CSimulatorInfo::xplane()); }
369 
370  void CMultiSimulatorSettings::onFGSettingsChanged() { this->emitSettingsChanged(CSimulatorInfo::fg()); }
371 
372  void CMultiSimulatorSettings::emitSettingsChanged(const CSimulatorInfo &simInfo)
373  {
374  emit this->settingsChanged(simInfo);
375  }
376 
378  {
379  m_technicalLogLevel = static_cast<int>(severity);
380  }
381 
382  void CSimulatorMessagesSettings::disableTechnicalMessages() { m_technicalLogLevel = -1; }
383 
385  {
386  if (m_technicalLogLevel < 0) { return false; }
387  return (m_technicalLogLevel <= CStatusMessage::SeverityError);
388  }
389 
391  {
392  if (m_technicalLogLevel < 0) { return false; }
393  return (m_technicalLogLevel <= CStatusMessage::SeverityWarning);
394  }
395 
397  {
398  if (m_technicalLogLevel < 0) { return false; }
399  return (m_technicalLogLevel <= CStatusMessage::SeverityInfo);
400  }
401 
402  bool CSimulatorMessagesSettings::isRelayTechnicalMessages() const { return (m_technicalLogLevel >= 0); }
403 
404  void CSimulatorMessagesSettings::setRelayTextMessages(CSimulatorMessagesSettings::TextMessageType messageType)
405  {
406  m_messageType = static_cast<int>(messageType);
407  }
408 
410  {
411  return this->getRelayedTextMessageTypes().testFlag(TextMessageSupervisor);
412  }
413 
415  {
416  return this->getRelayedTextMessageTypes().testFlag(TextMessagePrivate);
417  }
418 
420  {
421  return this->getRelayedTextMessageTypes().testFlag(TextMessagesUnicom);
422  }
423 
425  {
426  return this->getRelayedTextMessageTypes().testFlag(TextMessagesCom1);
427  }
428 
430  {
431  return this->getRelayedTextMessageTypes().testFlag(TextMessagesCom2);
432  }
433 
435  {
436  if (message.isEmpty()) { return false; }
437  if (!this->isRelayGloballyEnabled()) { return false; }
438  if (!this->isRelayTechnicalMessages()) { return false; }
439  const int s = static_cast<int>(message.getSeverity());
440  return (s >= m_technicalLogLevel);
441  }
442 
443  bool
445  const swift::misc::simulation::CSimulatedAircraft &aircraft) const
446  {
447  if (msg.isEmpty()) { return false; }
448  if (!this->isRelayGloballyEnabled()) { return false; }
449  if (m_messageType == NoTextMessages) { return false; }
450 
451  const TextMessageType mt = static_cast<TextMessageType>(m_messageType);
452  if (msg.isPrivateMessage() && mt.testFlag(TextMessagePrivate)) { return true; }
453  if (msg.isSupervisorMessage() && (mt.testFlag(TextMessagePrivate) || mt.testFlag(TextMessageSupervisor)))
454  {
455  return true;
456  }
457  if (msg.isSendToUnicom() && mt.testFlag(TextMessagesUnicom)) { return true; }
458 
459  if (msg.isRadioMessage())
460  {
461  const CFrequency f(msg.getFrequency());
462  if (mt.testFlag(TextMessagesCom1))
463  {
464  if (aircraft.getCom1System().isActiveFrequencySameFrequency(f)) { return true; }
465  }
466  if (mt.testFlag(TextMessagesCom2))
467  {
468  if (aircraft.getCom2System().isActiveFrequencySameFrequency(f)) { return true; }
469  }
470  }
471  return false;
472  }
473 
474  CSimulatorMessagesSettings::TextMessageType CSimulatorMessagesSettings::getRelayedTextMessageTypes() const
475  {
476  return static_cast<CSimulatorMessagesSettings::TextMessageType>(m_messageType);
477  }
478 
480  {
481  Q_UNUSED(i18n)
482  static const QString s("Enabled %1, text messages: %2, severity: %3");
483  QString severity;
484  if (this->isRelayTechnicalMessages()) { severity = QStringLiteral("No tech. msgs"); }
485  else
486  {
487  severity =
488  CStatusMessage::severityToString(static_cast<CStatusMessage::StatusSeverity>(m_technicalLogLevel));
489  }
490  return s.arg(boolToOnOff(m_relayGloballyEnabled)).arg(m_messageType).arg(severity);
491  }
492 
494  {
495  if (index.isMyself()) { return QVariant::fromValue(*this); }
496  const auto i = index.frontCasted<ColumnIndex>();
497  switch (i)
498  {
499  case IndexTechnicalLogSeverity: return QVariant::fromValue(m_technicalLogLevel);
500  case IndexRelayTextMessage: return QVariant::fromValue(m_messageType);
501  case IndexRelayGloballyEnabled: return QVariant::fromValue(m_relayGloballyEnabled);
502  default: return CValueObject::propertyByIndex(index);
503  }
504  }
505 
507  {
508  if (index.isMyself())
509  {
510  (*this) = variant.value<CSimulatorMessagesSettings>();
511  return;
512  }
513  const auto i = index.frontCasted<ColumnIndex>();
514  switch (i)
515  {
516  case IndexTechnicalLogSeverity:
517  this->setTechnicalLogSeverity(static_cast<CStatusMessage::StatusSeverity>(variant.toInt()));
518  break;
519  case IndexRelayTextMessage:
520  this->setRelayTextMessages(static_cast<CSimulatorMessagesSettings::TextMessageType>(variant.toInt()));
521  break;
522  case IndexRelayGloballyEnabled: this->setRelayGloballyEnabled(variant.toBool()); break;
523  default: CValueObject::setPropertyByIndex(index, variant); break;
524  }
525  }
526 
528  {
530  }
531 
533  {
534  static const QString empty;
535  if (!m_genericSettings.hasSimulatorDirectory()) { return empty; }
538  {
539  return empty;
540  }
542  }
543 
545  {
549  }
550 
552  {
555  }
556 
558  {
559  if (!m_genericSettings.hasSimulatorDirectory()) { return {}; }
561  QStringList dirs;
562  switch (m_simulator.getSimulator())
563  {
564  case CSimulatorInfo::FG: dirs = QStringList(CFlightgearUtil::modelDirectoriesFromSimDir(s)); break;
565  case CSimulatorInfo::P3D:
566  {
567  const QString versionHint = CFsDirectories::guessP3DVersion(s);
568  dirs = CFsDirectories::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(
569  CFsDirectories::p3dSimObjectsDirFromSimDir(s), versionHint);
570  }
571  break;
572  case CSimulatorInfo::XPLANE: dirs = QStringList({ CXPlaneUtil::modelDirectoriesFromSimDir(s) }); break;
573  case CSimulatorInfo::MSFS: dirs = QStringList({ CFsDirectories::msfsSimObjectsDir() }); break;
574  case CSimulatorInfo::MSFS2024: dirs = QStringList({ CFsDirectories::msfs2024SimObjectsDir() }); break;
575  default: break;
576  }
577 
578  dirs.removeAll({}); // remove empty
579  dirs.removeDuplicates();
580  return dirs;
581  }
582 
584  {
586  {
588  }
590  }
591 
593  {
594  static const QStringList empty;
595  if (!m_genericSettings.hasModelDirectories()) { return empty; }
597  if (CFileUtils::sameDirectories(m_genericSettings.getModelDirectories(), defaultDirectories)) { return empty; }
599  }
600 
602  {
604  }
605 
607  {
608  static const QString empty;
609  if (this->getModelDirectoriesOrDefault().isEmpty()) { return empty; }
610  return this->getModelDirectoriesOrDefault().constFirst();
611  }
612 
614  {
616  }
617 
619  {
620  static const QStringList empty;
621  if (!m_genericSettings.hasModelExcludeDirectoryPatterns()) { return empty; }
624  {
625  return empty;
626  }
628  }
629 
631  {
635  }
636 
638  {
639  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
640  static const QStringList e;
641  switch (simulator.getSimulator())
642  {
643  case CSimulatorInfo::FG:
644  {
645  return CFlightgearUtil::flightgearModelDirectories();
646  }
647  case CSimulatorInfo::P3D:
648  {
649  static const QString p3d = CFsDirectories::p3dSimObjectsDir();
650  if (p3d.isEmpty()) { return e; }
651  static const QString versionHint = CFsDirectories::guessP3DVersion(p3d);
652  static const QStringList md = CFsDirectories::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(p3d, versionHint);
653  return md;
654  }
655  case CSimulatorInfo::MSFS:
656  {
657  static const QString msfs = CFileUtils::normalizeFilePathToQtStandard(CFsDirectories::msfsPackagesDir());
658  if (msfs.isEmpty()) { return e; }
659  static const QStringList md { msfs };
660  return md;
661  }
662  case CSimulatorInfo::MSFS2024:
663  {
664  static const QString msfs2024 =
665  CFileUtils::normalizeFilePathToQtStandard(CFsDirectories::msfs2024PackagesDir());
666  if (msfs2024.isEmpty()) { return e; }
667  static const QStringList md { msfs2024 };
668  return md;
669  }
670  case CSimulatorInfo::XPLANE:
671  {
672  return CXPlaneUtil::xplaneModelDirectories();
673  }
674  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
675  }
676  return e;
677  }
678 
680  {
681  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
682  static const QString empty;
683  switch (simulator.getSimulator())
684  {
685  case CSimulatorInfo::FG: return CFlightgearUtil::flightgearRootDir();
686  case CSimulatorInfo::P3D: return CFsDirectories::p3dDir();
687  case CSimulatorInfo::MSFS: return CFsDirectories::msfsDir();
688  case CSimulatorInfo::MSFS2024: return CFsDirectories::msfs2024Dir();
689  case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneRootDir();
690  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
691  }
692  return empty;
693  }
694 
695  const QStringList &
697  {
698  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
699  static const QStringList empty;
700  switch (simulator.getSimulator())
701  {
702  case CSimulatorInfo::FG: return CFlightgearUtil::flightgearModelExcludeDirectoryPatterns();
703  case CSimulatorInfo::P3D: return CFsDirectories::p3dSimObjectsExcludeDirectoryPatterns();
704  case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneModelExcludeDirectoryPatterns();
705  case CSimulatorInfo::MSFS: return CFsDirectories::msfs20SimObjectsExcludeDirectoryPatterns();
706  case CSimulatorInfo::MSFS2024: return CFsDirectories::msfs2024SimObjectsExcludeDirectoryPatterns();
707  default: Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); break;
708  }
709  return empty;
710  }
711 
713  {
715  CXPlaneUtil::xplanePluginPathName());
716  }
717 
719  {
720  Q_UNUSED(i18n)
721  return u"SimulatedObject: " % boolToYesNo(m_useSimulatedObjectAdding) % u" SB offsets: " %
722  boolToYesNo(m_useSbOffsets);
723  }
724 
726  {
727  Q_UNUSED(index)
728  return {};
729  }
730 
732  {
733  Q_UNUSED(index)
734  Q_UNUSED(variant)
735  }
736 
738  {
739  Q_ASSERT_X(sim.isFsxP3DFamily(), Q_FUNC_INFO, "Only for FSX/P3D");
740  if (sim == CSimulatorInfo::p3d()) { return m_simP3D.get(); }
741  return m_simFsx.get();
742  }
743 
745  const CSimulatorInfo &simulator)
746  {
747  Q_ASSERT_X(simulator.isFsxP3DFamily(), Q_FUNC_INFO, "Only for FSX/P3D");
748  if (simulator == CSimulatorInfo::p3d()) { return m_simP3D.set(settings); }
749  return m_simFsx.set(settings);
750  }
751 
753  const CSimulatorInfo &simulator)
754  {
755  Q_ASSERT_X(simulator.isFsxP3DFamily(), Q_FUNC_INFO, "Only for FSX/P3D");
756  if (simulator == CSimulatorInfo::p3d()) { return m_simP3D.setAndSave(settings); }
757  return m_simFsx.setAndSave(settings);
758  }
759 
761  {
762  const QString simDir = value.hasSimulatorDirectory() ?
763  value.getSimulatorDirectory() :
765  const CStatusMessageList msgs = CXPlaneUtil::validateModelDirectories(simDir, value.getModelDirectories());
766  if (msgs.isSuccess()) { return true; }
767  reason = msgs.getErrorMessages().toSingleMessage().toQString(true);
768  return false;
769  }
770 
771 } // namespace swift::misc::simulation::settings
static constexpr bool isRunningOnWindowsNtPlatform()
Running on Windows NT platform?
static bool sameDirectories(const QStringList &dirs1, const QStringList &dirs2, Qt::CaseSensitivity cs=osFileNameCaseSensitivity())
Same directories, order in list does not matter and lists are cleaned up.
Definition: fileutils.cpp:206
static QString appendFilePathsAndFixUnc(const QString &path1, const QString &path2)
Append file paths.
Definition: fileutils.cpp:108
static QString normalizeFilePathToQtStandard(const QString &filePath)
Normalize file path to Qt standard, e.g by turning \ to /.
Definition: fileutils.cpp:179
static const QString & settings()
Settings.
bool isEmpty() const
Message empty.
Non-owning reference to a CPropertyIndex with a subset of its features.
Q_REQUIRED_RESULT CPropertyIndexRef copyFrontRemoved() const
Copy with first element removed.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
Streamable status message, e.g.
constexpr static auto SeverityError
Status severities.
static const QString & severityToString(StatusSeverity severity)
Severity as string.
StatusSeverity getSeverity() const
Message severity.
constexpr static auto SeverityInfo
Status severities.
constexpr static auto SeverityWarning
Status severities.
Status messages, e.g. from Core -> GUI.
CStatusMessage toSingleMessage() const
Merge into a single message.
CStatusMessageList getErrorMessages() const
Get all error messages.
bool isSuccess() const
All messages are marked as success.
bool isActiveFrequencySameFrequency(const physical_quantities::CFrequency &comFrequency) const
Is active frequency the same frequency.
Definition: comsystem.cpp:53
ColumnIndex
Base class enums.
Definition: mixinindex.h:44
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:158
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:165
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:74
Value object encapsulating information of a text message.
Definition: textmessage.h:31
bool isPrivateMessage() const
Is private message?
Definition: textmessage.cpp:53
bool isEmpty() const
Empty message.
Definition: textmessage.h:90
bool isSendToUnicom() const
Send to UNICOM?
bool isRadioMessage() const
Is radio message?
const physical_quantities::CFrequency & getFrequency() const
Get frequency.
Definition: textmessage.h:96
bool isSupervisorMessage() const
Supervisor message?
Definition: textmessage.cpp:58
Physical unit length (length)
Definition: length.h:18
Comprehensive information of an aircraft.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
bool isSingleSimulator() const
Single simulator selected.
Simulator getSimulator() const
Simulator.
static const CSimulatorInfo & msfs()
Const simulator info objects.
bool isFsxP3DFamily() const
FSX family, i.e. FSX or P3D?
static const CSimulatorInfo & p3d()
Const simulator info objects.
static const CSimulatorInfo & xplane()
Const simulator info objects.
static const CSimulatorInfo & msfs2024()
Const simulator info objects.
static const CSimulatorInfo & fg()
Const simulator info objects.
QString convertToQString(bool i18n=false) const
Cast as QString.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
CFsxP3DSettings getSettings(const CSimulatorInfo &sim) const
Settings per simulator.
CStatusMessage setSettings(const CFsxP3DSettings &settings, const CSimulatorInfo &simulator)
Set settings per simulator.
CStatusMessage setAndSaveSettings(const CFsxP3DSettings &settings, const CSimulatorInfo &simulator)
Set settings per simulator.
CStatusMessage addModelDirectory(const QString &modelDirectory, const CSimulatorInfo &simulator)
Set model directory per simulator.
QString getFirstModelDirectoryOrDefault(const CSimulatorInfo &simulator) const
First model directoy.
void resetToDefaults(const CSimulatorInfo &simulator)
Reset to defaults.
CStatusMessage setAndSaveSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator)
Set settings per simulator.
CStatusMessage saveSettings(const CSimulatorInfo &simulator)
Set settings per simulator.
CSpecializedSimulatorSettings getSpecializedSettings(const CSimulatorInfo &simulator) const
Specialized simulator settings.
CStatusMessageList setAndValidateSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator)
Set settings per simulator, but do NOT save yet, but validate.
CStatusMessage setSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator)
Set settings per simulator.
QStringList getModelDirectoriesIfNotDefault(const CSimulatorInfo &simulator) const
Model directory or or empty if default.
QString getSimulatorDirectoryIfNotDefault(const CSimulatorInfo &simulator) const
Simulator directory or empty if default dir.
QStringList getModelDirectoriesOrDefault(const CSimulatorInfo &simulator) const
Model directory or default model path per simulator.
const QStringList & defaultModelDirectories(const CSimulatorInfo &simulator) const
Default model path per simulator.
CSimulatorSettings getSettings(const CSimulatorInfo &simulator) const
Settings per simulator.
QStringList getModelExcludeDirectoryPatternsOrDefault(const CSimulatorInfo &simulator) const
Model exclude patterns per simulator.
QStringList getModelExcludeDirectoryPatternsIfNotDefault(const CSimulatorInfo &simulator) const
Model exclude patterns or empty if default.
CStatusMessage clearModelDirectories(const CSimulatorInfo &simulator)
Clear the model directory.
QString getSimulatorDirectoryOrDefault(const CSimulatorInfo &simulator) const
Simulator directory or default model path per simulator.
void settingsChanged(const swift::misc::simulation::CSimulatorInfo &simulator)
Simulator settings have been changed.
Settings regarding message handling. Driver independent part, related to network.
bool isRelayErrorsMessages() const
Relay (technical) error messages.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
void setRelayGloballyEnabled(bool enabled)
Globally enable / disable.
bool isRelayWarningMessages() const
Relay (technical) warning messages.
QString convertToQString(bool i18n=false) const
Cast as QString.
CSimulatorMessagesSettings::TextMessageType getRelayedTextMessageTypes() const
Relayed text messages.
bool isRelayInfoMessages() const
Relay (technical) info messages.
bool relayThisTextMessage(const network::CTextMessage &msg, const CSimulatedAircraft &aircraft) const
Relay given text message.
bool relayThisStatusMessage(const CStatusMessage &message) const
Relay this particular message.
bool isRelaySupervisorTextMessages() const
Relay supervisor messages.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
void setTechnicalLogSeverity(CStatusMessage::StatusSeverity severity)
Log severity.
void setRelayTextMessages(CSimulatorMessagesSettings::TextMessageType messageType)
Relay the following message types.
Settings for simulator Driver independent parts (such as directories), also used in model loaders.
void clearModelDirectories()
Clear the model directories.
bool hasSimulatorDirectory() const
Setting has simulator setting.
bool addModelDirectory(const QString &modelDirectory)
Add (if not exists) model directory.
bool hasModelDirectories() const
Having model directories?
bool hasModelExcludeDirectoryPatterns() const
Having model exclude directoy patterns?
CGSource
Where we get the CG (aka vertical offset) from.
const QStringList & getModelExcludeDirectoryPatterns() const
Model exclude directoy patterns.
const QString & getSimulatorDirectory() const
Simulator directory.
const QStringList & getModelDirectories() const
Model directory.
Allows to have specific utility functions for each simulator.
const QStringList & getModelExcludeDirectoryPatternsIfNotDefault() const
Model exclude patterns or empty if default.
static const QStringList & defaultModelDirectories(const CSimulatorInfo &simulator)
Default model path per simulator.
const QStringList & getDefaultModelDirectories() const
Model exclude patterns or empty if default.
const QStringList & getModelExcludeDirectoryPatternsOrDefault() const
Model exclude patterns or empty if default.
QStringList getModelDirectoriesFromSimulatorDirectoy() const
Model directories.
const QString & getSimulatorDirectoryIfNotDefault() const
Simulator directory or empty if default dir.
QStringList getModelDirectoriesOrDefault() const
Model directories or default.
const CSimulatorSettings & getGenericSettings() const
Get the generic settings.
const QStringList & getModelDirectoriesIfNotDefault() const
Model directories or empty if default.
QStringList getModelDirectoriesFromSimulatorDirectoryOrDefault() const
Model directories, then from simulator directory, then default.
const QStringList & getDefaultModelExcludeDirectoryPatterns() const
Default model exclude patterns.
static const QStringList & defaultModelExcludeDirectoryPatterns(const CSimulatorInfo &simulator)
Default model exclude patterns per simulator.
const QString & getSimulatorDirectoryOrDefault() const
Simulator directory or default path.
static const QString & defaultSimulatorDirectory(const CSimulatorInfo &simulator)
Default simulator path per simulator.
const QString & getDefaultSimulatorDirectory() const
Default simulator path per simulator.
QString getPluginDirOrDefault() const
Plugin directory or default plugin dir.
SWIFT_MISC_EXPORT const QString & boolToOnOff(bool v)
Bool to on/off.
StatusSeverity
Status severities.
Definition: statusmessage.h:35
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
const T & constFirst() const const
qsizetype removeAll(const AT &t)
QString arg(Args &&... args) const const
bool isEmpty() const const
QString trimmed() const const
qsizetype removeDuplicates()
CaseSensitivity
QVariant fromValue(T &&value)
bool toBool() const const
int toInt(bool *ok) const const
QString toString() const const
QStringList toStringList() const const
T value() const &const
static bool isValid(const CSimulatorSettings &value, QString &reason)
Validator function. Return true if the argument is valid, false otherwise. Default implementation jus...
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26