10 #include <QMessageBox>
14 #include "ui_dbownmodelscomponent.h"
21 #include "gui/menus/aircraftmodelmenus.h"
22 #include "gui/menus/menuaction.h"
32 using namespace swift::config;
34 using namespace swift::misc::simulation;
36 using namespace swift::gui::menus;
42 CDbOwnModelsComponent::CDbOwnModelsComponent(
QWidget *parent)
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));
53 ui->tvp_OwnAircraftModels->setCorrespondingSimulator(sim,
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,
61 Q_ASSERT_X(c, Q_FUNC_INFO,
"Connect failed");
63 &CDbOwnModelsComponent::onSimulatorSelectorChanged);
64 Q_ASSERT_X(c, Q_FUNC_INFO,
"Connect failed");
65 c =
connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
66 &CMultiAircraftModelLoaderProvider::loadingFinished,
this,
68 Q_ASSERT_X(c, Q_FUNC_INFO,
"Connect failed");
69 c =
connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
70 &CMultiAircraftModelLoaderProvider::diskLoadingStarted,
this,
72 Q_ASSERT_X(c, Q_FUNC_INFO,
"Connect failed");
73 c =
connect(&CMultiAircraftModelLoaderProvider::multiModelLoaderInstance(),
74 &CMultiAircraftModelLoaderProvider::loadingProgress,
this,
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");
83 Q_ASSERT_X(c, Q_FUNC_INFO,
"Connect failed");
86 ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection();
87 const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
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"); }
104 static const QStringList l({ CLogCategories::modelGui(), CLogCategories::guiComponent() });
116 const IAircraftModelLoader::LoadMode mode =
117 onlyIfNotEmpty ? IAircraftModelLoader::InBackgroundNoCache : IAircraftModelLoader::LoadInBackground;
118 this->requestSimulatorModels(simulator, mode);
135 if (!m_modelLoader) {
return empty; }
141 return ui->tvp_OwnAircraftModels->selectedObjects();
146 return ui->comp_SimulatorSelector->getValue();
153 const bool simUnchanged = (m_simulator == simulator);
156 if (!forced && simUnchanged) {
return false; }
159 m_simulator = simulator;
160 this->requestSimulatorModelsWithCacheInBackground(simulator);
161 ui->comp_SimulatorSelector->setValue(simulator);
162 this->setUiSimulatorString(simulator);
163 ui->tvp_OwnAircraftModels->setCorrespondingSimulator(
170 ui->comp_SimulatorSelector->setMode(mode);
173 void CDbOwnModelsComponent::onSimulatorSelectorChanged()
175 const CSimulatorInfo simulator(ui->comp_SimulatorSelector->getValue());
181 if (!m_modelLoader) {
return 0; }
187 if (!m_modelLoader) {
return {}; }
193 if (!m_modelLoader) {
return {}; }
200 if (m.
isSuccess()) { ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models); }
213 if (!m_modelLoader) {
return; }
215 ui->tvp_OwnAircraftModels->replaceOrAddModelsWithString(models);
221 if (!m_modelLoader) {
return 0; }
224 ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(allModels);
228 bool CDbOwnModelsComponent::initModelLoader(
const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode load)
236 m_modelLoader = CMultiAircraftModelLoaderProvider::multiModelLoaderInstance().loaderInstance(simulator);
237 if (m_modelLoader) { m_modelLoader->
startLoading(load); }
239 this->setSaveFileName(simulator);
243 void CDbOwnModelsComponent::setSaveFileName(
const CSimulatorInfo &sim)
247 ui->tvp_OwnAircraftModels->setSaveFileName(n);
252 QString dir = m_directorySettings.
get().getLastModelDirectoryOrDefault();
254 QStringLiteral(
"Open directory (%1)").arg(simulatorInfo.
toQString()),
262 CLogMessage::preformatted(m);
267 void CDbOwnModelsComponent::setUiSimulatorString(
const CSimulatorInfo &simulatorInfo)
270 ui->le_Simulator->setText(s);
271 ui->pb_ForceReload->setText(QStringLiteral(
"force reload '%1'").arg(s));
274 void CDbOwnModelsComponent::confirmedForcedReloadCurrentSimulator() { this->confirmedForcedReload(m_simulator); }
276 void CDbOwnModelsComponent::confirmedForcedReload(
const CSimulatorInfo &simulator)
279 QStringLiteral(
"Completely reload '%1' models from disk?").arg(simulator.
toQString(
true)),
285 this->requestSimulatorModels(simulator, IAircraftModelLoader::InBackgroundNoCache);
288 void CDbOwnModelsComponent::runScriptCSL2XSB()
290 static const QString script =
QDir(CSwiftDirectories::shareDirectory()).
filePath(
"CSL2XSB/CSL2XSB.exe");
293 CLogMessage(
this).
info(u
"Running CSL2XSB on model directory %1") << modelDir;
294 CProcessCtrl::startDetached(script, {
QDir::cleanPath(modelDir) },
true);
298 void CDbOwnModelsComponent::CLoadModelsMenu::customMenu(
CMenuActions &menuActions)
308 Q_ASSERT_X(ownModelsComp, Q_FUNC_INFO,
"Cannot access parent");
312 if (sims.
isXPlane() && CBuildConfig::isRunningOnWindowsNtPlatform() && CBuildConfig::buildWordSize() == 64)
314 if (!m_csl2xsbAction)
316 m_csl2xsbAction =
new QAction(CIcons::appTerminal16(),
"XPlane: run CSL2XSB on all models",
this);
318 if (!ownModelsComp) {
return; }
320 ownModelsComp->runScriptCSL2XSB();
323 menuActions.
addAction(m_csl2xsbAction, CMenuAction::pathSimulator());
326 this->nestedCustomMenu(menuActions);
329 void CDbOwnModelsComponent::requestOwnModelsUpdate()
331 if (!m_modelLoader) {
return; }
332 ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(this->
getOwnModels());
335 void CDbOwnModelsComponent::loadInstalledModels(
const CSimulatorInfo &simulator,
336 IAircraftModelLoader::LoadMode mode,
339 if (!m_modelLoader) {
return; }
356 u
"Loading for another simulator '%1' already in progress. Loading might be slow.")
362 if (!this->initModelLoader(simulator))
373 << simulator.
toQString() << IAircraftModelLoader::enumToString(mode);
374 ui->tvp_OwnAircraftModels->showLoadIndicator();
377 mode,
static_cast<int (*)(
CAircraftModelList &,
bool)
>(&CDatabaseUtils::consolidateModelsWithDbData),
381 void CDbOwnModelsComponent::onModelLoaderDiskLoadingStarted(
const CSimulatorInfo &simulator,
382 IAircraftModelLoader::LoadMode mode)
384 using namespace std::chrono_literals;
386 << simulator.
toQString(
true) << IAircraftModelLoader::enumToString(mode);
390 void CDbOwnModelsComponent::onModelLoadingProgress(
const CSimulatorInfo &simulator,
const QString &message,
393 using namespace std::chrono_literals;
398 ui->tvp_OwnAircraftModels->showLoadIndicatorWithTimeout(5s);
402 void CDbOwnModelsComponent::onModelLoaderLoadingFinished(
const CStatusMessageList &statusMessages,
406 using namespace std::chrono_literals;
407 Q_ASSERT_X(simulator.
isSingleSimulator(), Q_FUNC_INFO,
"Expect single simulator");
409 bool hideIndicator =
false;
412 if (IAircraftModelLoader::isLoadedInfo(info) && m_modelLoader)
415 const int modelsLoaded = models.size();
416 ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
418 if (modelsLoaded < 1)
421 summaryMsg =
CLogMessage(
this).
warning(u
"Loading completed for simulator '%1', but no models")
423 hideIndicator =
true;
427 summaryMsg =
CLogMessage(
this).
info(u
"Loading completed for simulator '%1' with %2 models")
428 << simulator << modelsLoaded;
432 if (!summaryMsg.
isEmpty() && info == IAircraftModelLoader::ParsedData)
440 else if (info == IAircraftModelLoader::LoadingSkipped)
443 hideIndicator =
true;
447 ui->tvp_OwnAircraftModels->
clear();
448 hideIndicator =
true;
462 if (statusMessages.
size() < 50)
471 QStringLiteral(
"Do you want to see the %1 detailled messages?").
arg(statusMessages.
size());
473 if (!myself) {
return; }
474 myself->showOverlayMessagesOrHTMLMessage(statusMessages);
479 if (hideIndicator) { ui->tvp_OwnAircraftModels->hideLoadIndicatorForced(); }
482 if (info == IAircraftModelLoader::CacheLoaded) {
return; }
488 void CDbOwnModelsComponent::onViewDiskLoadingFinished(
const CStatusMessage &status)
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).",
500 if (models.
isEmpty()) {
return; }
501 const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
505 void CDbOwnModelsComponent::onCacheChanged(
const CSimulatorInfo &simulator)
508 ui->tvp_OwnAircraftModels->updateContainerMaybeAsync(models);
511 void CDbOwnModelsComponent::requestSimulatorModels(
const CSimulatorInfo &simulator,
512 IAircraftModelLoader::LoadMode mode,
515 this->loadInstalledModels(simulator, mode, modelDirectories);
518 void CDbOwnModelsComponent::requestSimulatorModelsWithCacheInBackground(
const CSimulatorInfo &simulator)
520 this->requestSimulatorModels(simulator, IAircraftModelLoader::InBackgroundWithCache);
523 void CDbOwnModelsComponent::clearSimulatorCache(
const CSimulatorInfo &simulator)
525 if (!m_modelLoader) {
return; }
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.
~CDbOwnModelsComponent()
Destructor.
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.
void clearView()
Clear the view.
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.
void gracefulShutdown()
Graceful shutdown.
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.
Aircraft model list model.
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.
T get() const
Get a copy of the current value.
Directories (swift data directories)
void setLastModelDirectory(const QString &dir)
Last view JSON model directory.
Class for emitting a log message.
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.
bool isEmpty() const
Synonym for empty.
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.
Aircraft model (used by another pilot, my models on disk)
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.
bool isSingleSimulator() const
Single simulator selected.
bool isNoSimulator() const
No simulator?
bool isUnspecified() const
Unspecified simulator.
bool isXPlane() const
XPlane.
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.
LoadFinishedInfo
Load mode.
QString getInfoStringFsFamily() const
Look like IMultiSimulatorModelCaches interface.
CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
void setModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Set models.
CStatusMessage clearCachedModels(const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
QString getInfoString() const
Look like IMultiSimulatorModelCaches interface.
int updateModelsForSimulator(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Set models.
CAircraftModelList getCachedModels(const CSimulatorInfo &simulator) const
Look like IMultiSimulatorModelCaches interface.
int getCachedModelsCount(const CSimulatorInfo &simulator) const
Look like IMultiSimulatorModelCaches interface.
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.
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
QFuture< QtFuture::ArgsType< Signal >> connect(Sender *sender, Signal signal)