swift
dbownmodelscomponent.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 <QAction>
7 #include <QDir>
8 #include <QFileDialog>
9 #include <QIcon>
10 #include <QMessageBox>
11 #include <QPointer>
12 #include <QtGlobal>
13 
14 #include "ui_dbownmodelscomponent.h"
15 
16 #include "config/buildconfig.h"
17 #include "core/db/databaseutils.h"
18 #include "core/webdataservices.h"
20 #include "gui/guiapplication.h"
21 #include "gui/menus/aircraftmodelmenus.h"
22 #include "gui/menus/menuaction.h"
25 #include "misc/icons.h"
26 #include "misc/logmessage.h"
27 #include "misc/processctrl.h"
29 #include "misc/statusmessage.h"
30 #include "misc/swiftdirectories.h"
31 
32 using namespace swift::config;
33 using namespace swift::misc;
34 using namespace swift::misc::simulation;
35 using namespace swift::core::db;
36 using namespace swift::gui::menus;
37 using namespace swift::gui::views;
38 using namespace swift::gui::models;
39 
40 namespace swift::gui::components
41 {
42  CDbOwnModelsComponent::CDbOwnModelsComponent(QWidget *parent)
43  : COverlayMessagesFrame(parent), ui(new Ui::CDbOwnModelsComponent)
44  {
45  ui->setupUi(this);
46  ui->comp_SimulatorSelector->setMode(CSimulatorSelector::RadioButtons);
47  ui->tvp_OwnAircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnAircraftModelMappingTool);
48  ui->tvp_OwnAircraftModels->addFilterDialog();
49  ui->tvp_OwnAircraftModels->setDisplayAutomatically(true);
50  ui->tvp_OwnAircraftModels->setCustomMenu(new CLoadModelsMenu(this));
51 
52  const CSimulatorInfo sim = ui->comp_SimulatorSelector->getValue();
53  ui->tvp_OwnAircraftModels->setCorrespondingSimulator(sim,
54  m_simulatorSettings.getSimulatorDirectoryOrDefault(sim));
55 
56  bool c = connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::requestUpdate, this,
57  &CDbOwnModelsComponent::requestOwnModelsUpdate);
58  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
59  c = connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::jsonLoadCompleted, this,
60  &CDbOwnModelsComponent::onViewDiskLoadingFinished, Qt::QueuedConnection);
61  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
62  c = connect(ui->comp_SimulatorSelector, &CSimulatorSelector::changed, this,
63  &CDbOwnModelsComponent::onSimulatorSelectorChanged);
64  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
65  c = connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
66  &CMultiAircraftModelLoaderProvider::loadingFinished, this,
67  &CDbOwnModelsComponent::onModelLoaderLoadingFinished, Qt::QueuedConnection);
68  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
69  c = connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
70  &CMultiAircraftModelLoaderProvider::diskLoadingStarted, this,
71  &CDbOwnModelsComponent::onModelLoaderDiskLoadingStarted, Qt::QueuedConnection);
72  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
73  c = connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
74  &CMultiAircraftModelLoaderProvider::loadingProgress, this,
75  &CDbOwnModelsComponent::onModelLoadingProgress, Qt::QueuedConnection);
76  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
77  c = connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
78  &CMultiAircraftModelLoaderProvider::cacheChanged, this, &CDbOwnModelsComponent::onCacheChanged,
80  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
81  c = connect(ui->pb_ForceReload, &QPushButton::released, this,
82  &CDbOwnModelsComponent::confirmedForcedReloadCurrentSimulator, Qt::QueuedConnection);
83  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
84 
85  // Last selection isPinned -> no sync needed
86  ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection();
87  const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
88  if (simulator.isSingleSimulator())
89  {
90  m_simulator = simulator;
91  this->setUiSimulatorString(simulator);
92  const bool success = this->initModelLoader(simulator, IAircraftModelLoader::CacheOnly);
93  if (!success) { CLogMessage(this).error(u"Init of model loader failed in component"); }
94  }
95 
96  // menu
97  ui->tvp_OwnAircraftModels->setCustomMenu(new CConsolidateWithDbDataMenu(ui->tvp_OwnAircraftModels, this));
98  }
99 
101 
103  {
104  static const QStringList l({ CLogCategories::modelGui(), CLogCategories::guiComponent() });
105  return l;
106  }
107 
108  CAircraftModelView *CDbOwnModelsComponent::view() const { return ui->tvp_OwnAircraftModels; }
109 
110  CAircraftModelListModel *CDbOwnModelsComponent::model() const { return ui->tvp_OwnAircraftModels->derivedModel(); }
111 
112  bool CDbOwnModelsComponent::requestModelsInBackground(const CSimulatorInfo &simulator, bool onlyIfNotEmpty)
113  {
114  this->setSimulator(simulator);
115  if (onlyIfNotEmpty && this->getOwnModelsCount() > 0) { return false; }
116  const IAircraftModelLoader::LoadMode mode =
117  onlyIfNotEmpty ? IAircraftModelLoader::InBackgroundNoCache : IAircraftModelLoader::LoadInBackground;
118  this->requestSimulatorModels(simulator, mode);
119  return true;
120  }
121 
123  {
124  return this->getOwnModels().findFirstByModelStringOrDefault(modelString);
125  }
126 
128  {
129  return this->getOwnCachedModels(this->getOwnModelsSimulator());
130  }
131 
133  {
134  static const CAircraftModelList empty;
135  if (!m_modelLoader) { return empty; }
136  return m_modelLoader->getCachedModels(simulator);
137  }
138 
140  {
141  return ui->tvp_OwnAircraftModels->selectedObjects();
142  }
143 
145  {
146  return ui->comp_SimulatorSelector->getValue();
147  }
148 
149  bool CDbOwnModelsComponent::setSimulator(const CSimulatorInfo &simulator, bool forced)
150  {
151  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
152 
153  const bool simUnchanged = (m_simulator == simulator);
154 
155  if (!simUnchanged) { emit this->ownModelsSimulatorChanged(simulator); }
156  if (!forced && simUnchanged) { return false; }
157 
158  // changed simulator
159  m_simulator = simulator;
160  this->requestSimulatorModelsWithCacheInBackground(simulator);
161  ui->comp_SimulatorSelector->setValue(simulator);
162  this->setUiSimulatorString(simulator);
163  ui->tvp_OwnAircraftModels->setCorrespondingSimulator(
164  simulator, m_simulatorSettings.getSimulatorDirectoryOrDefault(simulator));
165  return true;
166  }
167 
169  {
170  ui->comp_SimulatorSelector->setMode(mode);
171  }
172 
173  void CDbOwnModelsComponent::onSimulatorSelectorChanged()
174  {
175  const CSimulatorInfo simulator(ui->comp_SimulatorSelector->getValue());
176  this->setSimulator(simulator);
177  }
178 
180  {
181  if (!m_modelLoader) { return 0; }
182  return m_modelLoader->getCachedModelsCount(this->getOwnModelsSimulator());
183  }
184 
186  {
187  if (!m_modelLoader) { return {}; }
188  return m_modelLoader->getInfoString();
189  }
190 
192  {
193  if (!m_modelLoader) { return {}; }
194  return m_modelLoader->getInfoStringFsFamily();
195  }
196 
198  {
199  const CStatusMessage m = m_modelLoader->setCachedModels(models, this->getOwnModelsSimulator());
200  if (m.isSuccess()) { ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models); }
201  return m;
202  }
203 
204  void CDbOwnModelsComponent::clearView() { ui->tvp_OwnAircraftModels->clear(); }
205 
207  {
208  // void
209  }
210 
212  {
213  if (!m_modelLoader) { return; }
214  m_modelLoader->setCachedModels(models, simulator);
215  ui->tvp_OwnAircraftModels->replaceOrAddModelsWithString(models);
216  }
217 
219  const CSimulatorInfo &simulator)
220  {
221  if (!m_modelLoader) { return 0; }
222  const int c = m_modelLoader->updateModelsForSimulator(models, simulator);
223  const CAircraftModelList allModels(m_modelLoader->getCachedModels(simulator));
224  ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(allModels);
225  return c;
226  }
227 
228  bool CDbOwnModelsComponent::initModelLoader(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode load)
229  {
230  // called when simulator is changed / init
231  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
232 
233  // already loaded
234  if (!m_modelLoader || !m_modelLoader->supportsSimulator(simulator))
235  {
236  m_modelLoader = CMultiAircraftModelLoaderProvider::multiModelLoaderInstance().loaderInstance(simulator);
237  if (m_modelLoader) { m_modelLoader->startLoading(load); }
238  }
239  this->setSaveFileName(simulator);
240  return m_modelLoader && m_modelLoader->supportsSimulator(simulator);
241  }
242 
243  void CDbOwnModelsComponent::setSaveFileName(const CSimulatorInfo &sim)
244  {
245  Q_ASSERT_X(sim.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
246  const QString n("simulator models " + sim.toQString(true));
247  ui->tvp_OwnAircraftModels->setSaveFileName(n);
248  }
249 
250  QString CDbOwnModelsComponent::directorySelector(const CSimulatorInfo &simulatorInfo)
251  {
252  QString dir = m_directorySettings.get().getLastModelDirectoryOrDefault();
254  QStringLiteral("Open directory (%1)").arg(simulatorInfo.toQString()),
256  const QDir d(dir);
257  if (d.exists())
258  {
259  CDirectories dirs = m_directorySettings.get();
260  dirs.setLastModelDirectory(dir);
261  const CStatusMessage m = m_directorySettings.setAndSave(dirs);
262  CLogMessage::preformatted(m);
263  }
264  return dir;
265  }
266 
267  void CDbOwnModelsComponent::setUiSimulatorString(const CSimulatorInfo &simulatorInfo)
268  {
269  const QString s = simulatorInfo.toQString(true);
270  ui->le_Simulator->setText(s);
271  ui->pb_ForceReload->setText(QStringLiteral("force reload '%1'").arg(s));
272  }
273 
274  void CDbOwnModelsComponent::confirmedForcedReloadCurrentSimulator() { this->confirmedForcedReload(m_simulator); }
275 
276  void CDbOwnModelsComponent::confirmedForcedReload(const CSimulatorInfo &simulator)
277  {
278  QMessageBox msgBox(QMessageBox::Question, "Reload models from disk",
279  QStringLiteral("Completely reload '%1' models from disk?").arg(simulator.toQString(true)),
281  msgBox.setDefaultButton(QMessageBox::Cancel);
282  const auto reply = static_cast<QMessageBox::StandardButton>(msgBox.exec());
283  if (reply != QMessageBox::Ok) { return; }
284 
285  this->requestSimulatorModels(simulator, IAircraftModelLoader::InBackgroundNoCache);
286  }
287 
288  void CDbOwnModelsComponent::runScriptCSL2XSB()
289  {
290  static const QString script = QDir(CSwiftDirectories::shareDirectory()).filePath("CSL2XSB/CSL2XSB.exe");
291  for (const QString &modelDir : m_simulatorSettings.getModelDirectoriesOrDefault(CSimulatorInfo::xplane()))
292  {
293  CLogMessage(this).info(u"Running CSL2XSB on model directory %1") << modelDir;
294  CProcessCtrl::startDetached(script, { QDir::cleanPath(modelDir) }, true);
295  }
296  }
297 
298  void CDbOwnModelsComponent::CLoadModelsMenu::customMenu(CMenuActions &menuActions)
299  {
300  if (!sGui || sGui->isShuttingDown()) { return; }
301 
302  // for the moment I use all sims, I could restrict to CSimulatorInfo::getLocallyInstalledSimulators();
303  const CSimulatorInfo sims = CSimulatorInfo::allSimulators();
304  const bool noSims = sims.isNoSimulator() || sims.isUnspecified();
305  if (!noSims)
306  {
307  QPointer<CDbOwnModelsComponent> ownModelsComp(qobject_cast<CDbOwnModelsComponent *>(this->parent()));
308  Q_ASSERT_X(ownModelsComp, Q_FUNC_INFO, "Cannot access parent");
309 
310  menuActions.addMenuSimulator();
311 
312  if (sims.isXPlane() && CBuildConfig::isRunningOnWindowsNtPlatform() && CBuildConfig::buildWordSize() == 64)
313  {
314  if (!m_csl2xsbAction)
315  {
316  m_csl2xsbAction = new QAction(CIcons::appTerminal16(), "XPlane: run CSL2XSB on all models", this);
317  connect(m_csl2xsbAction, &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) {
318  if (!ownModelsComp) { return; }
319  Q_UNUSED(checked)
320  ownModelsComp->runScriptCSL2XSB();
321  });
322  }
323  menuActions.addAction(m_csl2xsbAction, CMenuAction::pathSimulator());
324  }
325  }
326  this->nestedCustomMenu(menuActions);
327  }
328 
329  void CDbOwnModelsComponent::requestOwnModelsUpdate()
330  {
331  if (!m_modelLoader) { return; }
332  ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(this->getOwnModels());
333  }
334 
335  void CDbOwnModelsComponent::loadInstalledModels(const CSimulatorInfo &simulator,
336  IAircraftModelLoader::LoadMode mode,
337  const QStringList &modelDirectories)
338  {
339  if (!m_modelLoader) { return; }
340 
341  // here m_modelLoader is still the "current" loader
342  if (m_modelLoader->isLoadingInProgress())
343  {
344  if (m_modelLoader->supportsSimulator(simulator))
345  {
346  const CStatusMessage msg =
347  CLogMessage(this).warning(u"Loading for '%1' already in progress, will NOT load.")
348  << simulator.toQString();
349  this->showOverlayMessage(msg);
350  return;
351  }
352  else
353  {
354  const CStatusMessage msg =
355  CLogMessage(this).warning(
356  u"Loading for another simulator '%1' already in progress. Loading might be slow.")
357  << simulator.toQString();
358  this->showOverlayMessage(msg);
359  }
360  }
361 
362  if (!this->initModelLoader(simulator))
363  {
364  const CStatusMessage msg = CLogMessage(this).error(u"Cannot init model loader for %1")
365  << simulator.toQString();
366  this->showOverlayMessage(msg);
367  return;
368  }
369 
370  // Do not check for empty models die here, as depending on mode we could still load
371  // will be checked in model loader
372  CLogMessage(this).info(u"Starting loading for '%1' in mode '%2'")
373  << simulator.toQString() << IAircraftModelLoader::enumToString(mode);
374  ui->tvp_OwnAircraftModels->showLoadIndicator();
375  Q_ASSERT_X(sGui && sGui->getWebDataServices(), Q_FUNC_INFO, "missing web data services");
376  m_modelLoader->startLoading(
377  mode, static_cast<int (*)(CAircraftModelList &, bool)>(&CDatabaseUtils::consolidateModelsWithDbData),
378  modelDirectories);
379  }
380 
381  void CDbOwnModelsComponent::onModelLoaderDiskLoadingStarted(const CSimulatorInfo &simulator,
382  IAircraftModelLoader::LoadMode mode)
383  {
384  using namespace std::chrono_literals;
385  const CStatusMessage msg = CLogMessage(this).info(u"Started disk loading for '%1' in mode '%2'")
386  << simulator.toQString(true) << IAircraftModelLoader::enumToString(mode);
387  this->showOverlayHTMLMessage(msg, 5s);
388  }
389 
390  void CDbOwnModelsComponent::onModelLoadingProgress(const CSimulatorInfo &simulator, const QString &message,
391  int progress)
392  {
393  using namespace std::chrono_literals;
394 
395  const CStatusMessage loadingMsg = CStatusMessage(this).info(u"%1 loading: %2")
396  << simulator.toQString(true) << message;
397  this->showOverlayHTMLMessage(loadingMsg, 5s);
398  ui->tvp_OwnAircraftModels->showLoadIndicatorWithTimeout(5s); // trigger new load indicator
399  Q_UNUSED(progress)
400  }
401 
402  void CDbOwnModelsComponent::onModelLoaderLoadingFinished(const CStatusMessageList &statusMessages,
403  const CSimulatorInfo &simulator,
405  {
406  using namespace std::chrono_literals;
407  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Expect single simulator");
408 
409  bool hideIndicator = false; // hide in case loading failed
410  CStatusMessage summaryMsg;
411 
412  if (IAircraftModelLoader::isLoadedInfo(info) && m_modelLoader)
413  {
414  const CAircraftModelList models(m_modelLoader->getCachedModels(simulator));
415  const int modelsLoaded = models.size();
416  ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
417 
418  if (modelsLoaded < 1)
419  {
420  // loading ok, but no data
421  summaryMsg = CLogMessage(this).warning(u"Loading completed for simulator '%1', but no models")
422  << simulator;
423  hideIndicator = true;
424  }
425  else
426  {
427  summaryMsg = CLogMessage(this).info(u"Loading completed for simulator '%1' with %2 models")
428  << simulator << modelsLoaded;
429  }
430 
431  // overlay
432  if (!summaryMsg.isEmpty() && info == IAircraftModelLoader::ParsedData)
433  {
434  this->showOverlayHTMLMessage(summaryMsg, 5s);
435  }
436 
437  // signal
438  emit this->successfullyLoadedModels(simulator, modelsLoaded);
439  }
440  else if (info == IAircraftModelLoader::LoadingSkipped)
441  {
442  CLogMessage(this).error(u"Loading of models skipped, simulator '%1'") << simulator.toQString();
443  hideIndicator = true;
444  }
445  else
446  {
447  ui->tvp_OwnAircraftModels->clear();
448  hideIndicator = true;
449  CLogMessage(this).error(u"Loading of models failed, simulator '%1'") << simulator.toQString();
450  }
451 
452  // with errors we make sure errors are on top
453  if (statusMessages.hasErrorMessages())
454  {
455  this->setOverlayMessagesSorting(CStatusMessage::IndexSeverityAsIcon, Qt::DescendingOrder);
456  this->showOverlayMessagesOrHTMLMessage(statusMessages, false, 0s);
457  }
458  else
459  {
460  // no issues, directly hide
461  const std::chrono::milliseconds timeout { statusMessages.hasWarningOrErrorMessages() ? 0 : 7500 };
462  if (statusMessages.size() < 50)
463  {
464  // small number of messages
465  this->showOverlayMessagesOrHTMLMessage(statusMessages, false, timeout);
466  }
467  else
468  {
469  QPointer<CDbOwnModelsComponent> myself(this);
470  const QString confirmMessage =
471  QStringLiteral("Do you want to see the %1 detailled messages?").arg(statusMessages.size());
472  this->showOverlayMessagesWithConfirmation(summaryMsg, false, confirmMessage, [=] {
473  if (!myself) { return; }
474  myself->showOverlayMessagesOrHTMLMessage(statusMessages);
475  });
476  }
477  }
478 
479  if (hideIndicator) { ui->tvp_OwnAircraftModels->hideLoadIndicatorForced(); }
480 
481  // cache loads may occur in background, do not adjust UI settings
482  if (info == IAircraftModelLoader::CacheLoaded) { return; }
483 
484  // parsed loads normally explicit displaying this simulator
485  this->setSimulator(simulator);
486  }
487 
488  void CDbOwnModelsComponent::onViewDiskLoadingFinished(const CStatusMessage &status)
489  {
490  if (status.isFailure()) { return; }
491  QMessageBox msgBox(
492  QMessageBox::Question, "Loaded models from disk",
493  "Loaded models from disk file.\nSave to cache or just temporarily keep them?\n\nHint: Saving them will "
494  "override the loaded models from the simulator.\nNormally you would not want that (cancel).",
496  msgBox.setDefaultButton(QMessageBox::Cancel);
497  const auto reply = static_cast<QMessageBox::StandardButton>(msgBox.exec());
498  if (reply != QMessageBox::Cancel) { return; }
499  const CAircraftModelList models = ui->tvp_OwnAircraftModels->container();
500  if (models.isEmpty()) { return; }
501  const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
502  m_modelLoader->setModelsForSimulator(models, simulator);
503  }
504 
505  void CDbOwnModelsComponent::onCacheChanged(const CSimulatorInfo &simulator)
506  {
507  const CAircraftModelList models(m_modelLoader->getCachedModels(simulator));
508  ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
509  }
510 
511  void CDbOwnModelsComponent::requestSimulatorModels(const CSimulatorInfo &simulator,
512  IAircraftModelLoader::LoadMode mode,
513  const QStringList &modelDirectories)
514  {
515  this->loadInstalledModels(simulator, mode, modelDirectories);
516  }
517 
518  void CDbOwnModelsComponent::requestSimulatorModelsWithCacheInBackground(const CSimulatorInfo &simulator)
519  {
520  this->requestSimulatorModels(simulator, IAircraftModelLoader::InBackgroundWithCache);
521  }
522 
523  void CDbOwnModelsComponent::clearSimulatorCache(const CSimulatorInfo &simulator)
524  {
525  if (!m_modelLoader) { return; }
526  m_modelLoader->clearCachedModels(simulator);
527  }
528 } // namespace swift::gui::components
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void showOverlayMessagesWithConfirmation(const swift::misc::CStatusMessageList &messages, bool appendOldMessages, const QString &confirmationMessage, std::function< void()> okLambda, QMessageBox::StandardButton defaultButton=QMessageBox::Cancel, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages with confirmation bar.
void setOverlayMessagesSorting(const swift::misc::CPropertyIndex &property, Qt::SortOrder order)
Set sorting of overlay messages.
void showOverlayMessagesOrHTMLMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message (HTML)
Using this class provides a QFrame with the overlay functionality already integrated.
Handling of own models on disk (the models installed for the simulator)
int updateModelsForSimulator(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Set models.
swift::misc::simulation::CAircraftModelList getOwnModels() const
Own models.
swift::misc::CStatusMessage updateViewAndCache(const swift::misc::simulation::CAircraftModelList &models)
Update view and cache.
models::CAircraftModelListModel * model() const
Access to aircraft model.
swift::misc::simulation::CAircraftModelList getOwnSelectedModels() const
Own models selected in view.
static const QStringList & getLogCategories()
Log categories.
int getOwnModelsCount() const
Number of own models.
bool requestModelsInBackground(const swift::misc::simulation::CSimulatorInfo &simulator, bool onlyIfNotEmpty)
Forced read for given simulator.
void setModelsForSimulator(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Set models.
swift::misc::simulation::CAircraftModelList getOwnCachedModels(const swift::misc::simulation::CSimulatorInfo &simulator) const
Own cached models from loader.
bool setSimulator(const swift::misc::simulation::CSimulatorInfo &simulator, bool forced=false)
Change current simulator for own models.
swift::misc::simulation::CAircraftModel getOwnModelForModelString(const QString &modelString) const
Own (installed) model for given model string.
void ownModelsSimulatorChanged(const swift::misc::simulation::CSimulatorInfo &simulator)
Own models simulator has changed.
void successfullyLoadedModels(const swift::misc::simulation::CSimulatorInfo &simulator, int count)
Models have been successfully loaded.
swift::misc::simulation::CSimulatorInfo getOwnModelsSimulator() const
Own models for simulator.
swift::gui::views::CAircraftModelView * view() const
Models view.
void setSimulatorSelectorMode(CSimulatorSelector::Mode mode)
How to display.
QString getInfoStringFsFamily() const
Info string without XPlane (FSX,P3D, FS9)
QString getInfoString() const
Info string about models in cache.
void changed(const swift::misc::simulation::CSimulatorInfo &simulator)
Value has been changed.
Bunch of CMenuAction objects.
Definition: menuaction.h:384
CMenuAction addMenuSimulator()
Simulator menu.
Definition: menuaction.cpp:428
CMenuAction addAction(const CMenuAction &menuAction)
Add menu action.
Definition: menuaction.cpp:210
CStatusMessage setAndSave(const T &value, qint64 timestamp=0)
Write and save in the same step. Must be called from the thread in which the owner lives.
Definition: valuecache.h:417
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
Directories (swift data directories)
Definition: directories.h:25
void setLastModelDirectory(const QString &dir)
Last view JSON model directory.
Definition: directories.cpp:31
Class for emitting a log message.
Definition: logmessage.h:27
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
bool isEmpty() const
Message empty.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
bool isSuccess() const
Operation considered successful.
bool isFailure() const
Operation considered unsuccessful.
Status messages, e.g. from Core -> GUI.
bool hasWarningOrErrorMessages() const
Warning or error messages.
bool hasErrorMessages() const
Error messages.
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:74
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
Value object encapsulating a list of aircraft models.
CAircraftModel findFirstByModelStringOrDefault(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Find first by model string.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
bool isSingleSimulator() const
Single simulator selected.
bool isNoSimulator() const
No simulator?
bool isUnspecified() const
Unspecified simulator.
void startLoading(LoadMode mode=InBackgroundWithCache, const ModelConsolidationCallback &modelConsolidation={}, const QStringList &modelDirectories={})
Start the loading process from disk. Optional DB models can be passed and used for data consolidation...
bool supportsSimulator(const CSimulatorInfo &simulator) const
Supported simulator.
bool isLoadingInProgress() const
Loading in progress.
QString getInfoStringFsFamily() const
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:590
CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:550
void setModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Set models.
Definition: modelcaches.h:597
CStatusMessage clearCachedModels(const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:554
QString getInfoString() const
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:586
int updateModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Set models.
Definition: modelcaches.h:603
CAircraftModelList getCachedModels(const CSimulatorInfo &simulator) const
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:537
int getCachedModelsCount(const CSimulatorInfo &simulator) const
Look like IMultiSimulatorModelCaches interface.
Definition: modelcaches.h:541
QStringList getModelDirectoriesOrDefault(const CSimulatorInfo &simulator) const
Model directory or default model path per simulator.
QString getSimulatorDirectoryOrDefault(const CSimulatorInfo &simulator) const
Simulator directory or default model path per simulator.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Classes interacting with the swift database (aka "datastore").
High level reusable GUI components.
Definition: aboutdialog.cpp:14
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.
void triggered(bool checked)
QString cleanPath(const QString &path)
QString filePath(const QString &fileName) const const
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString arg(Args &&... args) const const
void clear()
QueuedConnection
DescendingOrder
QFuture< QtFuture::ArgsType< Signal >> connect(Sender *sender, Signal signal)