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:
Klaus Basan
2016-03-28 00:56:22 +02:00
parent 5c1ce9763e
commit fe677a5594
6 changed files with 131 additions and 35 deletions

View File

@@ -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");

View File

@@ -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);

View File

@@ -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()

View File

@@ -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

View File

@@ -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>

View File

@@ -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 -----------------------------------------