mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-16 18:35:35 +08:00
refs #618, functions allowing to validate and modify loaded JSON data
* models can be reduced to one simulator * a JSON model list can be loaded and the simulator derived from the distribution
This commit is contained in:
@@ -35,12 +35,14 @@ namespace BlackGui
|
||||
ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuRemoveSelectedRows | CAircraftModelView::MenuClear);
|
||||
ui->tvp_OwnModelSet->addFilterDialog();
|
||||
ui->tvp_OwnModelSet->setCustomMenu(new CLoadModelsMenu(this));
|
||||
ui->tvp_OwnModelSet->setJsonLoad(CAircraftModelView::AllowOnlySingleSimulator | CAircraftModelView::ReduceToOneSimulator);
|
||||
|
||||
connect(ui->pb_CreateNewSet, &QPushButton::clicked, this, &CDbOwnModelSetComponent::ps_buttonClicked);
|
||||
connect(ui->pb_LoadExistingSet, &QPushButton::clicked, this, &CDbOwnModelSetComponent::ps_buttonClicked);
|
||||
connect(ui->pb_SaveAsSetForSimulator, &QPushButton::clicked, this, &CDbOwnModelSetComponent::ps_buttonClicked);
|
||||
connect(&this->m_modelSetLoader, &CModelSetLoader::simulatorChanged, this, &CDbOwnModelSetComponent::ps_onSimulatorChanged);
|
||||
connect(ui->tvp_OwnModelSet, &CAircraftModelView::rowCountChanged, this, &CDbOwnModelSetComponent::ps_onRowCountChanged);
|
||||
connect(ui->tvp_OwnModelSet, &CAircraftModelView::jsonModelsForSimulatorLoaded, this, &CDbOwnModelSetComponent::ps_onJsonDataLoaded);
|
||||
|
||||
this->ps_onRowCountChanged(ui->tvp_OwnModelSet->rowCount(), ui->tvp_OwnModelSet->hasFilter());
|
||||
}
|
||||
@@ -163,7 +165,6 @@ namespace BlackGui
|
||||
}
|
||||
else if (sender == ui->pb_LoadExistingSet)
|
||||
{
|
||||
this->ui->tvp_OwnModelSet->setLoadValidation(CAircraftModelView::AllowOnlySingeSimulator);
|
||||
this->ui->tvp_OwnModelSet->showFileLoadDialog();
|
||||
}
|
||||
else if (sender == ui->pb_SaveAsSetForSimulator)
|
||||
@@ -210,6 +211,14 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
void CDbOwnModelSetComponent::ps_onJsonDataLoaded(const CSimulatorInfo &simulator)
|
||||
{
|
||||
if (simulator.isSingleSimulator())
|
||||
{
|
||||
this->setSimulator(simulator);
|
||||
}
|
||||
}
|
||||
|
||||
void CDbOwnModelSetComponent::setSaveFileName(const CSimulatorInfo &sim)
|
||||
{
|
||||
Q_ASSERT_X(sim.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
|
||||
|
||||
@@ -83,6 +83,9 @@ namespace BlackGui
|
||||
//! View has changed row count
|
||||
void ps_onRowCountChanged(int count, bool withFilter);
|
||||
|
||||
//! JSON data have been loaded from disk
|
||||
void ps_onJsonDataLoaded(const BlackMisc::Simulation::CSimulatorInfo &simulator);
|
||||
|
||||
private:
|
||||
//! Default file name
|
||||
void setSaveFileName(const BlackMisc::Simulation::CSimulatorInfo &sim);
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
#include "blackmisc/aviation/aircrafticaocodelist.h"
|
||||
#include "blackmisc/aviation/airlineicaocodelist.h"
|
||||
#include "blackmisc/aviation/liverylist.h"
|
||||
#include "blackmisc/simulation//distributorlist.h"
|
||||
#include "blackmisc/simulation/distributorlist.h"
|
||||
#include "blackmisc/simulation/simulatorinfolist.h"
|
||||
#include "blackgui/shortcut.h"
|
||||
#include "blackgui/guiapplication.h"
|
||||
#include "blackgui/guiutility.h"
|
||||
@@ -292,17 +293,64 @@ namespace BlackGui
|
||||
CViewWithDbObjects::customMenu(menu);
|
||||
}
|
||||
|
||||
CStatusMessage CAircraftModelView::validateLoadedData(const CAircraftModelList &models) const
|
||||
CStatusMessage CAircraftModelView::modifyLoadedJsonData(CAircraftModelList &models) const
|
||||
{
|
||||
if (!this->m_jsonLoad.testFlag(ReduceToOneSimulator)) { return {}; }
|
||||
if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityDebug, "Empty models", true); }
|
||||
const CSimulatorInfo maxSims = models.simulatorsWithMaxEntries();
|
||||
if (maxSims.isNoSimulator())
|
||||
{
|
||||
return CStatusMessage(this, CStatusMessage::SeverityError, "No simulator with maximum, cannot reduce");
|
||||
}
|
||||
|
||||
if (maxSims.isSingleSimulator())
|
||||
{
|
||||
int rm = models.removeIfNotMatchingSimulator(maxSims);
|
||||
return rm < 1 ?
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Now only for " + maxSims.toQString(true), true) :
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Reduced by % 1 to only use %2", true) << rm << maxSims.toQString(true);
|
||||
}
|
||||
|
||||
// one simulator dominating
|
||||
if (maxSims.isSingleSimulator())
|
||||
{
|
||||
int rm = models.removeIfNotMatchingSimulator(maxSims);
|
||||
return rm < 1 ?
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Now only for " + maxSims.toQString(true), true) :
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Reduced by % 1 to only use %2", true) << rm << maxSims.toQString(true);
|
||||
}
|
||||
|
||||
// multiple sims with same count
|
||||
const CSimulatorInfo first = CSimulatorInfoList::splitIntoSingleSimulators(maxSims).front();
|
||||
int d = models.removeIfNotMatchingSimulator(first);
|
||||
return d < 1 ?
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Now only for " + maxSims.toQString(true), true) :
|
||||
CStatusMessage(this, CStatusMessage::SeverityInfo, "Reduced by % 1 to only use %2", true) << d << maxSims.toQString(true);
|
||||
}
|
||||
|
||||
CStatusMessage CAircraftModelView::validateLoadedJsonData(const CAircraftModelList &models) const
|
||||
{
|
||||
static const CStatusMessage ok(this, CStatusMessage::SeverityInfo, "model validation passed", true);
|
||||
if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityInfo, "no data", true); }
|
||||
if (this->m_validation == AllowOnlySingeSimulator)
|
||||
if (this->m_jsonLoad == AllowOnlySingleSimulator)
|
||||
{
|
||||
const CSimulatorInfo sim = models.simulatorsSupported();
|
||||
if (sim.isSingleSimulator()) { return ok; }
|
||||
return CStatusMessage(this, CStatusMessage::SeverityError, "data need to be from one simulator");
|
||||
}
|
||||
return CViewWithDbObjects::validateLoadedData(models);
|
||||
return CViewWithDbObjects::validateLoadedJsonData(models);
|
||||
}
|
||||
|
||||
void CAircraftModelView::jsonLoadedAndModelUpdated(const CAircraftModelList &models)
|
||||
{
|
||||
if (models.isEmpty())
|
||||
{
|
||||
emit jsonModelsForSimulatorLoaded(CSimulatorInfo());
|
||||
}
|
||||
else
|
||||
{
|
||||
emit jsonModelsForSimulatorLoaded(models.simulatorsWithMaxEntries());
|
||||
}
|
||||
}
|
||||
|
||||
void CAircraftModelView::ps_toggleHighlightStashedModels()
|
||||
|
||||
@@ -29,12 +29,13 @@ namespace BlackGui
|
||||
|
||||
public:
|
||||
//! How to validate loaded JSON data
|
||||
enum LoadValidationFlag
|
||||
enum JsonLoadFlag
|
||||
{
|
||||
NoValidation,
|
||||
AllowOnlySingeSimulator
|
||||
NotSet = 0,
|
||||
AllowOnlySingleSimulator = 1 << 0,
|
||||
ReduceToOneSimulator = 1 << 1
|
||||
};
|
||||
Q_DECLARE_FLAGS(LoadValidation, LoadValidationFlag)
|
||||
Q_DECLARE_FLAGS(JsonLoad, JsonLoadFlag)
|
||||
|
||||
//! Constructor
|
||||
explicit CAircraftModelView(QWidget *parent = nullptr);
|
||||
@@ -88,7 +89,7 @@ namespace BlackGui
|
||||
bool highlightModelStrings() const;
|
||||
|
||||
//! Load validation
|
||||
void setLoadValidation(LoadValidation validation) { m_validation = validation; }
|
||||
void setJsonLoad(JsonLoad jsonLoad) { m_jsonLoad = jsonLoad; }
|
||||
|
||||
signals:
|
||||
//! Request to stash if applicable
|
||||
@@ -100,6 +101,9 @@ namespace BlackGui
|
||||
//! Request further handling of drops I cannot handle on my own
|
||||
void requestHandlingOfStashDrop(const BlackMisc::Aviation::CAirlineIcaoCode &airlineIcao);
|
||||
|
||||
//! Models for simulator loaded (JSON)
|
||||
void jsonModelsForSimulatorLoaded(const BlackMisc::Simulation::CSimulatorInfo &simulator);
|
||||
|
||||
protected:
|
||||
//! \copydoc QTableView::dropEvent
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
@@ -107,7 +111,9 @@ namespace BlackGui
|
||||
//! \name View base class overrides
|
||||
//! @{
|
||||
virtual void customMenu(QMenu &menu) const override;
|
||||
virtual BlackMisc::CStatusMessage validateLoadedData(const BlackMisc::Simulation::CAircraftModelList &models) const override;
|
||||
virtual BlackMisc::CStatusMessage modifyLoadedJsonData(BlackMisc::Simulation::CAircraftModelList &models) const override;
|
||||
virtual BlackMisc::CStatusMessage validateLoadedJsonData(const BlackMisc::Simulation::CAircraftModelList &models) const override;
|
||||
virtual void jsonLoadedAndModelUpdated(const BlackMisc::Simulation::CAircraftModelList &models) override;
|
||||
//! @}
|
||||
|
||||
private slots:
|
||||
@@ -124,14 +130,14 @@ namespace BlackGui
|
||||
void ps_requestStash();
|
||||
|
||||
private:
|
||||
bool m_stashingClearsSelection = true; //!< stashing unselects
|
||||
LoadValidation m_validation = NoValidation; //!< Loaded JSON validation
|
||||
bool m_stashingClearsSelection = true; //!< stashing unselects
|
||||
JsonLoad m_jsonLoad = NotSet; //!< Loaded JSON validation
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
Q_DECLARE_METATYPE(BlackGui::Views::CAircraftModelView::LoadValidation)
|
||||
Q_DECLARE_METATYPE(BlackGui::Views::CAircraftModelView::LoadValidationFlag)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(BlackGui::Views::CAircraftModelView::LoadValidation)
|
||||
Q_DECLARE_METATYPE(BlackGui::Views::CAircraftModelView::JsonLoad)
|
||||
Q_DECLARE_METATYPE(BlackGui::Views::CAircraftModelView::JsonLoadFlag)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(BlackGui::Views::CAircraftModelView::JsonLoad)
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -956,7 +956,7 @@ namespace BlackGui
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
CStatusMessage CViewBase<ModelClass, ContainerType, ObjectType>::modifyLoadedData(ContainerType &data) const
|
||||
CStatusMessage CViewBase<ModelClass, ContainerType, ObjectType>::modifyLoadedJsonData(ContainerType &data) const
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
static const CStatusMessage e(this, CStatusMessage::SeverityInfo, "no modification", true);
|
||||
@@ -964,31 +964,54 @@ namespace BlackGui
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
CStatusMessage CViewBase<ModelClass, ContainerType, ObjectType>::validateLoadedData(const ContainerType &data) const
|
||||
CStatusMessage CViewBase<ModelClass, ContainerType, ObjectType>::validateLoadedJsonData(const ContainerType &data) const
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
static const CStatusMessage e(this, CStatusMessage::SeverityInfo, "no validation", true);
|
||||
return e;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::jsonLoadedAndModelUpdated(const ContainerType &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
CStatusMessage CViewBase<ModelClass, ContainerType, ObjectType>::ps_loadJson()
|
||||
{
|
||||
const QString fileName = QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Load data file"), getDefaultFilename(true),
|
||||
tr("swift (*.json *.txt)"));
|
||||
if (fileName.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityDebug, "Load canceled", true); }
|
||||
QString json(CFileUtils::readFileToString(fileName));
|
||||
if (json.isEmpty())
|
||||
CStatusMessage m;
|
||||
do
|
||||
{
|
||||
return CStatusMessage(this, CStatusMessage::SeverityWarning, "Reading " + fileName + " yields no data", true);
|
||||
const QString fileName = QFileDialog::getOpenFileName(nullptr,
|
||||
tr("Load data file"), getDefaultFilename(true),
|
||||
tr("swift (*.json *.txt)"));
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
m = CStatusMessage(this, CStatusMessage::SeverityDebug, "Load canceled", true);
|
||||
break;
|
||||
}
|
||||
|
||||
QString json(CFileUtils::readFileToString(fileName));
|
||||
if (json.isEmpty())
|
||||
{
|
||||
m = CStatusMessage(this, CStatusMessage::SeverityWarning, "Reading " + fileName + " yields no data", true);
|
||||
break;
|
||||
}
|
||||
ContainerType container;
|
||||
container.convertFromJson(json);
|
||||
m = this->modifyLoadedJsonData(container);
|
||||
if (m.isFailure()) { break; } // modification error
|
||||
m = this->validateLoadedJsonData(container);
|
||||
if (m.isFailure()) { break; } // validaton error
|
||||
this->updateContainerMaybeAsync(container);
|
||||
m = CStatusMessage(this, CStatusMessage::SeverityInfo, "Reading " + fileName + " completed", true);
|
||||
this->jsonLoadedAndModelUpdated(container);
|
||||
}
|
||||
ContainerType container;
|
||||
container.convertFromJson(json);
|
||||
const CStatusMessage s = this->validateLoadedData(container);
|
||||
if (s.getSeverity() == CStatusMessage::SeverityError) { return s; }
|
||||
this->updateContainerMaybeAsync(container);
|
||||
return CStatusMessage(this, CStatusMessage::SeverityInfo, "Reading " + fileName + " completed", true);
|
||||
while (false);
|
||||
|
||||
emit this->jsonLoadCompleted(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace BlackGui
|
||||
//! Number of elements changed
|
||||
void rowCountChanged(int count, bool withFilter);
|
||||
|
||||
//! Model bas been changed
|
||||
//! Model bas been changed (means data in view have been changed)
|
||||
void modelChanged();
|
||||
|
||||
//! Single object was changed in model
|
||||
@@ -236,6 +236,9 @@ namespace BlackGui
|
||||
//! Object has been double clicked
|
||||
void objectSelected(const BlackMisc::CVariant &object);
|
||||
|
||||
//! JSON data load from disk completed, the BlackMisc::CStatusMessage represents the success
|
||||
void jsonLoadCompleted(const BlackMisc::CStatusMessage &msg);
|
||||
|
||||
public slots:
|
||||
//! Resize to contents, strategy depends on container size
|
||||
virtual void resizeToContents();
|
||||
@@ -401,7 +404,7 @@ namespace BlackGui
|
||||
//! Base class for views
|
||||
template <class ModelClass, class ContainerType, class ObjectType> class CViewBase : public CViewBaseNonTemplate
|
||||
{
|
||||
// I cannot use Q_OBJECT here, because error: Template classes not supported by Q_OBJECT
|
||||
// I cannot use Q_OBJECT here, because of error: Template classes not supported by Q_OBJECT
|
||||
// Cannot declare slots as SLOT because I have no Q_OBJECT macro
|
||||
|
||||
public:
|
||||
@@ -528,10 +531,14 @@ namespace BlackGui
|
||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize) override;
|
||||
|
||||
//! Modify JSON data loaded in BlackGui::Views::CViewBaseNonTemplate::ps_loadJson
|
||||
virtual BlackMisc::CStatusMessage modifyLoadedData(ContainerType &data) const;
|
||||
virtual BlackMisc::CStatusMessage modifyLoadedJsonData(ContainerType &data) const;
|
||||
|
||||
//! Verify JSON data loaded in BlackGui::Views::CViewBaseNonTemplate::ps_loadJson
|
||||
virtual BlackMisc::CStatusMessage validateLoadedData(const ContainerType &data) const;
|
||||
virtual BlackMisc::CStatusMessage validateLoadedJsonData(const ContainerType &data) const;
|
||||
|
||||
//! In BlackGui::Views::CViewBaseNonTemplate::ps_loadJson the view has been updated because of loaded JSON data
|
||||
//! \remark I cannot use a signal with a template parameter, so this functions serves as callback
|
||||
virtual void jsonLoadedAndModelUpdated(const ContainerType &data);
|
||||
|
||||
// --------------------------------------------- SLOTS start here -----------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user