diff --git a/src/blackgui/components/dbownmodelscomponent.cpp b/src/blackgui/components/dbownmodelscomponent.cpp index 866ee4dd1..30792c6b3 100644 --- a/src/blackgui/components/dbownmodelscomponent.cpp +++ b/src/blackgui/components/dbownmodelscomponent.cpp @@ -23,6 +23,7 @@ #include #include #include +#include using namespace BlackMisc; using namespace BlackMisc::Simulation; @@ -192,6 +193,15 @@ namespace BlackGui this->ui->tvp_OwnAircraftModels->setSaveFileName(n); } + QString CDbOwnModelsComponent::directorySelector(const CSimulatorInfo &simulatorInfo) + { + const QString text("Open directory (%1)"); + const QString dir = QFileDialog::getExistingDirectory(nullptr, text.arg(simulatorInfo.toQString()), + "", + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + return dir; + } + void CDbOwnModelsComponent::CLoadModelsMenu::customMenu(CMenuActions &menuActions) { // for the moment I use all sims, I could restrict to CSimulatorInfo::getLocallyInstalledSimulators(); @@ -261,7 +271,7 @@ namespace BlackGui // I need those models because I want to merge with DM data in the loader if (sGui->getWebDataServices() && sGui->getWebDataServices()->getModelsCount() > 0) { - if (this->m_reloadActions.isEmpty()) { this->m_reloadActions = QList({nullptr, nullptr, nullptr, nullptr}); } + if (this->m_reloadActions.isEmpty()) { this->m_reloadActions = QList({nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}); } menuActions.addMenu(CIcons::refresh16(), "Force model reload", CMenuAction::pathSimulatorModelsReload()); if (sims.fsx()) { @@ -273,47 +283,98 @@ namespace BlackGui Q_UNUSED(checked); ownModelsComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FSX), IAircraftModelLoader::InBackgroundNoCache); }); + + this->m_reloadActions[1] = new QAction(CIcons::appModels16(), "FSX models from directory", this); + connect(this->m_reloadActions[1], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + { + Q_UNUSED(checked); + const CSimulatorInfo sim(CSimulatorInfo::FSX); + const QString dir = CDbOwnModelsComponent::directorySelector(sim); + if (!dir.isEmpty()) + { + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + } + }); } menuActions.addAction(this->m_reloadActions[0], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[1], CMenuAction::pathSimulatorModelsReload()); } if (sims.p3d()) { - if (!this->m_reloadActions[1]) + if (!this->m_reloadActions[2]) { - this->m_reloadActions[1] = new QAction(CIcons::appModels16(), "P3D models", this); - connect(this->m_reloadActions[1], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + this->m_reloadActions[2] = new QAction(CIcons::appModels16(), "P3D models", this); + connect(this->m_reloadActions[2], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) { Q_UNUSED(checked); ownModelsComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::P3D), IAircraftModelLoader::InBackgroundNoCache); }); + + this->m_reloadActions[3] = new QAction(CIcons::appModels16(), "P3D models from directoy", this); + connect(this->m_reloadActions[3], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + { + Q_UNUSED(checked); + const CSimulatorInfo sim(CSimulatorInfo::P3D); + const QString dir = CDbOwnModelsComponent::directorySelector(sim); + if (!dir.isEmpty()) + { + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + } + }); } - menuActions.addAction(this->m_reloadActions[1], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[2], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[3], CMenuAction::pathSimulatorModelsReload()); } if (sims.fs9()) { - if (!this->m_reloadActions[2]) + if (!this->m_reloadActions[4]) { - this->m_reloadActions[2] = new QAction(CIcons::appModels16(), "FS9 models", this); - connect(this->m_reloadActions[2], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + this->m_reloadActions[4] = new QAction(CIcons::appModels16(), "FS9 models", this); + connect(this->m_reloadActions[4], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) { Q_UNUSED(checked); ownModelsComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::FS9), IAircraftModelLoader::InBackgroundNoCache); }); + + this->m_reloadActions[5] = new QAction(CIcons::appModels16(), "FS9 models from directoy", this); + connect(this->m_reloadActions[5], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + { + Q_UNUSED(checked); + const CSimulatorInfo sim(CSimulatorInfo::FS9); + const QString dir = CDbOwnModelsComponent::directorySelector(sim); + if (!dir.isEmpty()) + { + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + } + }); } - menuActions.addAction(this->m_reloadActions[2], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[4], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[5], CMenuAction::pathSimulatorModelsReload()); } if (sims.xplane()) { - if (!this->m_reloadActions[3]) + if (!this->m_reloadActions[6]) { - this->m_reloadActions[3] = new QAction(CIcons::appModels16(), "XPlane models", this); + this->m_reloadActions[6] = new QAction(CIcons::appModels16(), "XPlane models", this); connect(this->m_reloadActions[3], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) { Q_UNUSED(checked); ownModelsComp->ps_requestSimulatorModels(CSimulatorInfo(CSimulatorInfo::XPLANE), IAircraftModelLoader::InBackgroundNoCache); }); + this->m_reloadActions[7] = new QAction(CIcons::appModels16(), "XPlane models from directoy", this); + connect(this->m_reloadActions[7], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) + { + Q_UNUSED(checked); + const CSimulatorInfo sim(CSimulatorInfo::XPLANE); + const QString dir = CDbOwnModelsComponent::directorySelector(sim); + if (!dir.isEmpty()) + { + ownModelsComp->ps_requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, dir); + } + }); } - menuActions.addAction(this->m_reloadActions[3], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[6], CMenuAction::pathSimulatorModelsReload()); + menuActions.addAction(this->m_reloadActions[7], CMenuAction::pathSimulatorModelsReload()); } } else @@ -334,7 +395,7 @@ namespace BlackGui ); } - void CDbOwnModelsComponent::ps_loadInstalledModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode) + void CDbOwnModelsComponent::ps_loadInstalledModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QString &directory) { if (!this->initModelLoader(simulator)) { @@ -351,7 +412,7 @@ namespace BlackGui CLogMessage(this).info("Starting loading for %1") << simulator.toQString(); this->ui->tvp_OwnAircraftModels->showLoadIndicator(); Q_ASSERT_X(sGui && sGui->getWebDataServices(), Q_FUNC_INFO, "missing web data services"); - this->m_modelLoader->startLoading(mode, &CDatabaseUtils::consolidateModelsWithDbData); + this->m_modelLoader->startLoading(mode, &CDatabaseUtils::consolidateModelsWithDbData, directory); } void CDbOwnModelsComponent::ps_onOwnModelsLoadingFinished(bool success, const CSimulatorInfo &simulator) @@ -376,9 +437,9 @@ namespace BlackGui this->ui->tvp_OwnAircraftModels->hideLoadIndicator(); } - void CDbOwnModelsComponent::ps_requestSimulatorModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode) + void CDbOwnModelsComponent::ps_requestSimulatorModels(const CSimulatorInfo &simulator, IAircraftModelLoader::LoadMode mode, const QString &directory) { - this->ps_loadInstalledModels(simulator, mode); + this->ps_loadInstalledModels(simulator, mode, directory); } } // ns } // ns diff --git a/src/blackgui/components/dbownmodelscomponent.h b/src/blackgui/components/dbownmodelscomponent.h index 42755120c..b2752f59b 100644 --- a/src/blackgui/components/dbownmodelscomponent.h +++ b/src/blackgui/components/dbownmodelscomponent.h @@ -110,13 +110,13 @@ namespace BlackGui void ps_requestOwnModelsUpdate(); //! Load the models - void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode); + void ps_loadInstalledModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QString &directory = ""); //! Model loading finished void ps_onOwnModelsLoadingFinished(bool success, const BlackMisc::Simulation::CSimulatorInfo &simulator); //! Request simulator models - void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode); + void ps_requestSimulatorModels(const BlackMisc::Simulation::CSimulatorInfo &simulator, BlackMisc::Simulation::IAircraftModelLoader::LoadMode mode, const QString &directory = ""); private: QScopedPointer ui; @@ -129,6 +129,9 @@ namespace BlackGui //! File name for savinf void setSaveFileName(const BlackMisc::Simulation::CSimulatorInfo &sim); + //! Directory selector + static QString directorySelector(const BlackMisc::Simulation::CSimulatorInfo &simulatorInfo); + //! The menu for loading and handling own models for mapping tasks //! \note This is specific for that very component class CLoadModelsMenu : public BlackGui::Menus::IMenuDelegate diff --git a/src/blackmisc/simulation/aircraftmodelloader.cpp b/src/blackmisc/simulation/aircraftmodelloader.cpp index aae78ec8d..85db93854 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.cpp +++ b/src/blackmisc/simulation/aircraftmodelloader.cpp @@ -38,15 +38,6 @@ namespace BlackMisc this->gracefulShutdown(); } - bool IAircraftModelLoader::existsDir(const QString &directory) const - { - if (directory.isEmpty()) { return false; } - QDir dir(directory); - - //! \todo not available network dir can make this hang here, however there is no obvious solution to that - return dir.exists(); - } - CStatusMessage IAircraftModelLoader::setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator) { const CSimulatorInfo sim = simulator.isSingleSimulator() ? simulator : this->getSimulator(); // support default value @@ -119,7 +110,7 @@ namespace BlackMisc return this->setCachedModels(CAircraftModelList()); } - void IAircraftModelLoader::startLoading(LoadMode mode, const ModelConsolidation &modelConsolidation) + void IAircraftModelLoader::startLoading(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) { if (this->m_loadingInProgress) { return; } this->m_loadingInProgress = true; @@ -144,7 +135,7 @@ namespace BlackMisc emit loadingFinished(false, this->getSimulator()); return; } - this->startLoadingFromDisk(mode, modelConsolidation); + this->startLoadingFromDisk(mode, modelConsolidation, directory); } const CSimulatorInfo IAircraftModelLoader::getSimulator() const diff --git a/src/blackmisc/simulation/aircraftmodelloader.h b/src/blackmisc/simulation/aircraftmodelloader.h index acbf25522..3edd51bd4 100644 --- a/src/blackmisc/simulation/aircraftmodelloader.h +++ b/src/blackmisc/simulation/aircraftmodelloader.h @@ -75,7 +75,7 @@ namespace BlackMisc //! Start the loading process from disk. //! Optional DB models can be passed and used for data consolidation. - void startLoading(LoadMode mode = InBackgroundWithCache, const ModelConsolidation &modelConsolidation = {}); + void startLoading(LoadMode mode = InBackgroundWithCache, const ModelConsolidation &modelConsolidation = {}, const QString &directory = {}); //! Loading finished? virtual bool isLoadingFinished() const = 0; @@ -153,11 +153,8 @@ namespace BlackMisc //! Clear cache BlackMisc::CStatusMessage clearCache(); - //! Check if directory exists - bool existsDir(const QString &directory) const; - //! Start the loading process from disk - virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation) = 0; + virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) = 0; std::atomic m_cancelLoading { false }; //!< flag std::atomic m_loadingInProgress { false }; //!< Loading in progress diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp index ad429b400..e904bd5ad 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.cpp @@ -63,10 +63,10 @@ namespace BlackMisc if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); } } - void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation) + void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) { const CSimulatorInfo simulator = this->getSimulator(); - const QString modelDirectory(this->m_settings.getFirstModelDirectoryOrDefault(simulator)); // expect only one directory + const QString modelDirectory(!directory.isEmpty() ? directory : this->m_settings.getFirstModelDirectoryOrDefault(simulator)); // expect only one directory const QStringList excludedDirectoryPatterns(this->m_settings.getModelExcludeDirectoryPatternsOrDefault(simulator)); // copy if (mode.testFlag(LoadInBackground)) diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h index 5591c506a..a027f68cd 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgparser.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgparser.h @@ -61,7 +61,7 @@ namespace BlackMisc protected: //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation) override; + virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) override; //! @} private slots: diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp index 33562edba..b281314c4 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.cpp @@ -68,11 +68,11 @@ namespace BlackMisc if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); } } - void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation) + void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) { //! \todo according to meeting XP needs to support multiple directories const CSimulatorInfo simulator = this->getSimulator(); - const QString modelDirectory(this->getFirstModelDirectoryOrDefault()); // directory + const QString modelDirectory(!directory.isEmpty() ? directory : this->getFirstModelDirectoryOrDefault()); // directory const QStringList excludedDirectoryPatterns(this->m_settings.getModelExcludeDirectoryPatternsOrDefault(simulator)); // copy if (modelDirectory.isEmpty()) diff --git a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h index 6c11e9a66..032c19e8e 100644 --- a/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h +++ b/src/blackmisc/simulation/xplane/aircraftmodelloaderxplane.h @@ -60,7 +60,7 @@ namespace BlackMisc protected: //! \name Interface functions //! @{ - virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation) override; + virtual void startLoadingFromDisk(LoadMode mode, const ModelConsolidation &modelConsolidation, const QString &directory) override; //! @} private: