diff --git a/src/blackgui/components/configurationwizard.cpp b/src/blackgui/components/configurationwizard.cpp index bfb83bd0f..2c135e288 100644 --- a/src/blackgui/components/configurationwizard.cpp +++ b/src/blackgui/components/configurationwizard.cpp @@ -8,8 +8,12 @@ */ #include "configurationwizard.h" -#include "blackgui/guiapplication.h" #include "ui_configurationwizard.h" +#include "blackgui/guiapplication.h" +#include "blackmisc/directoryutils.h" +#include + +using namespace BlackMisc; namespace BlackGui { @@ -20,6 +24,7 @@ namespace BlackGui ui(new Ui::CConfigurationWizard) { ui->setupUi(this); + ui->wp_CopyModels->setConfigComponent(ui->comp_CopyModels); ui->wp_CopyCaches->setConfigComponent(ui->comp_CopyCaches); ui->wp_CopySettings->setConfigComponent(ui->comp_CopySettings); ui->wp_Simulator->setConfigComponent(ui->comp_Simulator); @@ -30,7 +35,7 @@ namespace BlackGui this->setButtonText(CustomButton1, "skip"); // no other versions, skip copy pages - if (!ui->comp_CopySettings->hasOtherVersionData()) + if (!CDirectoryUtils::hasOtherSwiftDataDirectories()) { this->setStartId(ConfigSimulator); } @@ -46,8 +51,11 @@ namespace BlackGui connect(this, &QWizard::accepted, this, &CConfigurationWizard::ended); Q_ASSERT_X(sGui, Q_FUNC_INFO, "missing sGui"); + const QPointer myself(this); connect(this, &QWizard::helpRequested, sGui, [ = ] { + if (!myself) { return; } + if (!sGui || sGui->isShuttingDown()) { return; } sGui->showHelp(this); }); } diff --git a/src/blackgui/components/configurationwizard.h b/src/blackgui/components/configurationwizard.h index 93b1fe671..1a3989b1c 100644 --- a/src/blackgui/components/configurationwizard.h +++ b/src/blackgui/components/configurationwizard.h @@ -32,6 +32,7 @@ namespace BlackGui //! Page ids enum Pages { + CopyModels, CopySettings, CopyCaches, ConfigSimulator, diff --git a/src/blackgui/components/configurationwizard.ui b/src/blackgui/components/configurationwizard.ui index 4efd5a414..18e798e5c 100644 --- a/src/blackgui/components/configurationwizard.ui +++ b/src/blackgui/components/configurationwizard.ui @@ -28,6 +28,31 @@ QWizard::HaveCustomButton1 + + + Copy models + + + Copy model data from other swift versions. Here you can copy your model set or model cache from another swift version. + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + Copy configuration from another installation @@ -339,6 +364,18 @@
blackgui/components/firstmodelsetcomponent.h
1 + + BlackGui::Components::CCopyModelsFromOtherSwiftVersionsWizardPage + QWizardPage +
blackgui/components/copymodelsfromotherswiftversionscomponent.h
+ 1 +
+ + BlackGui::Components::CCopyModelsFromOtherSwiftVersionsComponent + QFrame +
blackgui/components/copymodelsfromotherswiftversionscomponent.h
+ 1 +
diff --git a/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp new file mode 100644 index 000000000..4e1f1cb6c --- /dev/null +++ b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp @@ -0,0 +1,168 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "copymodelsfromotherswiftversionscomponent.h" +#include "ui_copymodelsfromotherswiftversionscomponent.h" +#include "blackgui/models/aircraftmodellistmodel.h" +#include "blackcore/application.h" +#include "blackmisc/stringutils.h" +#include "blackmisc/fileutils.h" +#include "blackmisc/directoryutils.h" + +#include +#include +#include + +using namespace BlackCore; +using namespace BlackMisc; +using namespace BlackMisc::Simulation; +using namespace BlackGui::Models; + +namespace BlackGui +{ + namespace Components + { + CCopyModelsFromOtherSwiftVersionsComponent::CCopyModelsFromOtherSwiftVersionsComponent(QWidget *parent) : + COverlayMessagesFrame(parent), + ui(new Ui::CCopyModelsFromOtherSwiftVersionsComponent) + { + ui->setupUi(this); + ui->comp_SimulatorSelector->setMode(CSimulatorSelector::CheckBoxes); + ui->tvp_AircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnModelSet); + connect(ui->pb_StartCopying, &QPushButton::clicked, this, &CCopyModelsFromOtherSwiftVersionsComponent::copy); + } + + CCopyModelsFromOtherSwiftVersionsComponent::~CCopyModelsFromOtherSwiftVersionsComponent() + { } + + void CCopyModelsFromOtherSwiftVersionsComponent::copy() + { + const QSet sims = ui->comp_SimulatorSelector->getValue().asSingleSimulatorSet(); + if (sims.isEmpty()) + { + static const CStatusMessage m = CStatusMessage(this).validationError("No simulators selected"); + this->showOverlayMessage(m); + return; + } + + const bool set = ui->cb_ModelSet->isChecked(); + const bool cache = ui->cb_ModelCache->isChecked(); + if (!cache && !set) + { + static const CStatusMessage m = CStatusMessage(this).validationError("No simulators selected"); + this->showOverlayMessage(m); + return; + } + + if (!ui->comp_OtherSwiftVersions->hasSelection()) + { + static const CStatusMessage m = CStatusMessage(this).validationError("No other version selected"); + this->showOverlayMessage(m); + return; + } + + const CApplicationInfo otherVersion = ui->comp_OtherSwiftVersions->selectedOtherVersion(); + for (const CSimulatorInfo &sim : sims) + { + if (set) + { + // inits current version cache + m_modelSetCaches.setCurrentSimulator(sim); + m_modelSetCaches.synchronizeCurrentCache(); + + // get file name + CAircraftModelList otherSet; + const QString thisVersionModelSetFile = m_modelSetCaches.getFilename(sim); + if (this->readDataFile(thisVersionModelSetFile, otherSet, otherVersion, sim) && !otherSet.isEmpty()) + { + CApplication::processEventsFor(250); + if (this->confirmOverride(QString("Override model set for '%1'").arg(sim.toQString()))) + { + m_modelSetCaches.setModels(otherSet, sim); + } + } + } // set + + if (cache) + { + // inits current version cache + m_modelCaches.setCurrentSimulator(sim); + m_modelCaches.synchronizeCurrentCache(); + + // get file name + CAircraftModelList otherCache; + const QString thisVersionModelCacheFile = m_modelCaches.getFilename(sim); + if (this->readDataFile(thisVersionModelCacheFile, otherCache, otherVersion, sim) && !otherCache.isEmpty()) + { + CApplication::processEventsFor(250); + if (this->confirmOverride(QString("Override model cache for '%1'").arg(sim.toQString()))) + { + m_modelCaches.setModels(otherCache, sim); + } + } + } + } // all sims + } + + bool CCopyModelsFromOtherSwiftVersionsComponent::readDataFile(const QString &thisVersionModelFile, CAircraftModelList &models, const CApplicationInfo &otherVersion, const CSimulatorInfo &sim) + { + // init + models.clear(); + + // create relative file name + QString relativeModelFile = thisVersionModelFile; + relativeModelFile = relativeModelFile.replace(CDirectoryUtils::applicationDataDirectory(), "", Qt::CaseInsensitive); + if (relativeModelFile.length() < 2) { return false; } + relativeModelFile = relativeModelFile.mid(relativeModelFile.indexOf('/', 1)); + + const QString otherModelFile = CFileUtils::appendFilePathsAndFixUnc(otherVersion.getApplicationDataDirectory(), relativeModelFile); + const QFileInfo fiOtherModelFile(otherModelFile); + if (!fiOtherModelFile.exists()) + { + static const QString noSet("No models here: '%1'"); + ui->le_Status->setText(noSet.arg(fiOtherModelFile.absoluteFilePath())); + return false; + } + + // read other file + const QString jsonString = CFileUtils::readFileToString(fiOtherModelFile.absoluteFilePath()); + if (jsonString.isEmpty()) { return false; } + try + { + models = CAircraftModelList::fromMultipleJsonFormats(jsonString); + ui->tvp_AircraftModels->updateContainerAsync(models); + static const QString importSet("Imported models: '%1'"); + ui->le_Status->setText(importSet.arg(fiOtherModelFile.absoluteFilePath())); + } + catch (const CJsonException &ex) + { + static const QString m("JSON format error. '%1'"); + this->showOverlayMessage(ex.toStatusMessage(this, m.arg(fiOtherModelFile.absoluteFilePath()))); + return false; + } + + static const QString importSet("Imported %1 models '%2' for %3"); + ui->le_Status->setText(importSet.arg(models.size()).arg(fiOtherModelFile.fileName(), sim.toQString())); + return true; + } + + bool CCopyModelsFromOtherSwiftVersionsComponent::confirmOverride(const QString &msg) + { + if (ui->cb_Silent->isChecked()) { return true; } + const QMessageBox::StandardButton reply = QMessageBox::question(this, QStringLiteral("Confirm override"), withQUestionMark(msg), QMessageBox::Yes | QMessageBox::No); + return reply == QMessageBox::Yes; + } + + bool CCopyModelsFromOtherSwiftVersionsWizardPage::validatePage() + { + Q_ASSERT_X(m_copyModels, Q_FUNC_INFO, "Missing widget"); + return true; + } + } // ns +} // ns diff --git a/src/blackgui/components/copymodelsfromotherswiftversionscomponent.h b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.h new file mode 100644 index 000000000..8dd5ab151 --- /dev/null +++ b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_COMPONENTS_COPYMODELSFROMOTHERSWIFTVERSIONS_H +#define BLACKGUI_COMPONENTS_COPYMODELSFROMOTHERSWIFTVERSIONS_H + +#include "blackgui/overlaymessagesframe.h" +#include "blackmisc/simulation/data/modelcaches.h" +#include "blackmisc/applicationinfo.h" +#include +#include +#include + +namespace Ui { class CCopyModelsFromOtherSwiftVersionsComponent; } +namespace BlackGui +{ + namespace Components + { + /** + * Copy models from another swift version + */ + class CCopyModelsFromOtherSwiftVersionsComponent : public COverlayMessagesFrame + { + Q_OBJECT + + public: + //! Ctor + explicit CCopyModelsFromOtherSwiftVersionsComponent(QWidget *parent = nullptr); + + //! Dtor + virtual ~CCopyModelsFromOtherSwiftVersionsComponent(); + + private: + //! Copy as per UI settings + void copy(); + + //! Read data file + bool readDataFile(const QString &modelFile, BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::CApplicationInfo &otherVersion, const BlackMisc::Simulation::CSimulatorInfo &sim); + + //! Confirm override + bool confirmOverride(const QString &msg); + + QScopedPointer ui; + + // caches will be explicitly initialized in copy + BlackMisc::Simulation::Data::CModelCaches m_modelCaches { false, this }; + BlackMisc::Simulation::Data::CModelSetCaches m_modelSetCaches { false, this }; + }; + + /** + * Wizard page for CCopyModelsFromOtherSwiftVersionsComponent + */ + class CCopyModelsFromOtherSwiftVersionsWizardPage : public QWizardPage + { + public: + //! Constructors + using QWizardPage::QWizardPage; + + //! Set config + void setConfigComponent(CCopyModelsFromOtherSwiftVersionsComponent *config) { m_copyModels = config; } + + //! \copydoc QWizardPage::validatePage + virtual bool validatePage() override; + + private: + CCopyModelsFromOtherSwiftVersionsComponent *m_copyModels = nullptr; + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/components/copymodelsfromotherswiftversionscomponent.ui b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.ui new file mode 100644 index 000000000..4f501cbfb --- /dev/null +++ b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.ui @@ -0,0 +1,191 @@ + + + CCopyModelsFromOtherSwiftVersionsComponent + + + + 0 + 0 + 508 + 420 + + + + Copy models from other swift versions + + + + + + Select the version to copy from + + + + + + + 0 + 50 + + + + + + + + + + + Select what to copy + + + + + + Model set + + + true + + + + + + + Model cache + + + + + + + of simulator: + + + + + + + + 100 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + silent + + + + + + + start + + + + + + + + + + Progress + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Status: + + + + + + + true + + + + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + + + + + + + + + BlackGui::Components::COtherSwiftVersionsComponent + QFrame +
blackgui/components/otherswiftversionscomponent.h
+ 1 +
+ + BlackGui::Components::CSimulatorSelector + QFrame +
blackgui/components/simulatorselector.h
+ 1 +
+ + BlackGui::Views::CAircraftModelView + QTableView +
blackgui/views/aircraftmodelview.h
+
+
+ + cb_ModelSet + cb_ModelCache + cb_Silent + pb_StartCopying + le_Status + tvp_AircraftModels + + + +