refs #571, consolidate with own models or DB models when stashed (goal: better defaults)

* improved missing parts updates
* sync. with own and DB models
This commit is contained in:
Klaus Basan
2016-01-12 01:21:26 +01:00
parent 9f646f215c
commit 6625b83c5e
9 changed files with 130 additions and 35 deletions

View File

@@ -177,7 +177,7 @@ namespace BlackGui
if (this->m_modelLoader) { this->m_modelLoader->gracefulShutdown(); } if (this->m_modelLoader) { this->m_modelLoader->gracefulShutdown(); }
} }
bool CDbMappingComponent::hasModelsToStash() const bool CDbMappingComponent::hasSelectedModelsToStash() const
{ {
TabIndex tab = currentTabIndex(); TabIndex tab = currentTabIndex();
switch (tab) switch (tab)
@@ -208,9 +208,9 @@ namespace BlackGui
} }
} }
CAircraftModelList CDbMappingComponent::getModelsToStash() const CAircraftModelList CDbMappingComponent::getSelectedModelsToStash() const
{ {
if (!hasModelsToStash()) { return CAircraftModelList(); } if (!hasSelectedModelsToStash()) { return CAircraftModelList(); }
TabIndex tab = currentTabIndex(); TabIndex tab = currentTabIndex();
switch (tab) switch (tab)
{ {
@@ -234,13 +234,18 @@ namespace BlackGui
return ui->comp_StashAircraft->getStashedModelStrings(); return ui->comp_StashAircraft->getStashedModelStrings();
} }
CAircraftModel CDbMappingComponent::getOwnModelForModelString(const QString &modelString)
{
return m_cachedOwnModels.get().findFirstByModelString(modelString);
}
CDbMappingComponent::TabIndex CDbMappingComponent::currentTabIndex() const CDbMappingComponent::TabIndex CDbMappingComponent::currentTabIndex() const
{ {
int t = ui->tw_ModelsToBeMapped->currentIndex(); int t = ui->tw_ModelsToBeMapped->currentIndex();
return static_cast<TabIndex>(t); return static_cast<TabIndex>(t);
} }
bool CDbMappingComponent::isStashedView() const bool CDbMappingComponent::isStashedTab() const
{ {
return currentTabIndex() == TabStash; return currentTabIndex() == TabStash;
} }
@@ -266,7 +271,7 @@ namespace BlackGui
void CDbMappingComponent::ps_stashCurrentModel() void CDbMappingComponent::ps_stashCurrentModel()
{ {
const CAircraftModel model(getAircraftModel()); const CAircraftModel model(getEditorAircraftModel());
CStatusMessageList msgs(this->validateCurrentModel(true)); CStatusMessageList msgs(this->validateCurrentModel(true));
if (!msgs.hasErrorMessages()) if (!msgs.hasErrorMessages())
{ {
@@ -439,10 +444,10 @@ namespace BlackGui
void CDbMappingComponent::stashSelectedModels() void CDbMappingComponent::stashSelectedModels()
{ {
if (!this->hasModelsToStash()) { return; } if (!this->hasSelectedModelsToStash()) { return; }
CStatusMessageList msgs = CStatusMessageList msgs =
this->ui->comp_StashAircraft->stashModels( this->ui->comp_StashAircraft->stashModels(
this->getModelsToStash() this->getSelectedModelsToStash()
); );
if (msgs.hasWarningOrErrorMessages()) if (msgs.hasWarningOrErrorMessages())
{ {
@@ -515,7 +520,7 @@ namespace BlackGui
this->ui->tvp_OwnAircraftModels->hideLoadIndicator(); this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
} }
CAircraftModel CDbMappingComponent::getAircraftModel() const CAircraftModel CDbMappingComponent::getEditorAircraftModel() const
{ {
CAircraftModel model(ui->editor_Model->getValue()); CAircraftModel model(ui->editor_Model->getValue());
model.setDistributor(ui->editor_Distributor->getValue()); model.setDistributor(ui->editor_Distributor->getValue());

View File

@@ -72,26 +72,29 @@ namespace BlackGui
bool withVPilot() const { return m_withVPilot; } bool withVPilot() const { return m_withVPilot; }
//! Any models which can be stashed //! Any models which can be stashed
bool hasModelsToStash() const; bool hasSelectedModelsToStash() const;
//! The models to be stashed from currently activated tab (table view) //! Models to be stashed from currently activated tab (table view)
BlackMisc::Simulation::CAircraftModelList getModelsToStash() const; BlackMisc::Simulation::CAircraftModelList getSelectedModelsToStash() const;
//! Stashed models //! Stashed models
const BlackMisc::Simulation::CAircraftModelList &getStashedModels() const; const BlackMisc::Simulation::CAircraftModelList &getStashedModels() const;
//! Stashed models trings //! Stashed model strings
QStringList getStashedModelStrings() const; QStringList getStashedModelStrings() const;
//! Own (installed) model for given model string
BlackMisc::Simulation::CAircraftModel getOwnModelForModelString(const QString &modelString);
//! Current tab index //! Current tab index
TabIndex currentTabIndex() const; TabIndex currentTabIndex() const;
//! Is stashed view //! Is stashed view
bool isStashedView() const; bool isStashedTab() const;
//! Unvalidated consolidated aircraft model from the subparts (icao, distributor) //! Unvalidated consolidated aircraft model from the editor subparts (icao, distributor)
//! \note not guaranteed to be valid, just snapshot of as it state //! \note not guaranteed to be valid, just a snapshot of its current editor state
BlackMisc::Simulation::CAircraftModel getAircraftModel() const; BlackMisc::Simulation::CAircraftModel getEditorAircraftModel() const;
public slots: public slots:
//! Stash model //! Stash model
@@ -177,7 +180,7 @@ namespace BlackGui
BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules
BlackMisc::CData<BlackCore::Data::VPilotAircraftModels> m_cachedVPilotModels { this, &CDbMappingComponent::ps_onVPilotCacheChanged }; //!< cache for latest vPilot rules BlackMisc::CData<BlackCore::Data::VPilotAircraftModels> m_cachedVPilotModels { this, &CDbMappingComponent::ps_onVPilotCacheChanged }; //!< cache for latest vPilot rules
std::unique_ptr<BlackMisc::Simulation::IAircraftModelLoader> m_modelLoader; //!< read own aircraft models std::unique_ptr<BlackMisc::Simulation::IAircraftModelLoader> m_modelLoader; //!< read own aircraft models
BlackMisc::CData<BlackCore::Data::OwnSimulatorAircraftModels> m_cachedOwnModels { this }; //!< cache for latest models BlackMisc::CData<BlackCore::Data::OwnSimulatorAircraftModels> m_cachedOwnModels { this }; //!< cache for own installed models
BlackMisc::CData<BlackCore::Data::AuthenticatedUser> m_user {this, &CDbMappingComponent::ps_userChanged}; BlackMisc::CData<BlackCore::Data::AuthenticatedUser> m_user {this, &CDbMappingComponent::ps_userChanged};
bool m_vPilot1stInit = true; bool m_vPilot1stInit = true;
bool m_withVPilot = false; bool m_withVPilot = false;

View File

@@ -12,6 +12,7 @@
#include "ui_dbstashcomponent.h" #include "ui_dbstashcomponent.h"
#include "blackgui/views/aircraftmodelview.h" #include "blackgui/views/aircraftmodelview.h"
#include "blackmisc/icons.h" #include "blackmisc/icons.h"
#include "blackmisc/simulation/aircraftmodel.h"
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
@@ -82,16 +83,30 @@ namespace BlackGui
CStatusMessage CDbStashComponent::stashModel(const CAircraftModel &model, bool replace) CStatusMessage CDbStashComponent::stashModel(const CAircraftModel &model, bool replace)
{ {
CStatusMessage m(validateStashModel(model, replace)); CAircraftModel pushModel(model);
// merge with own models if any
if (pushModel.getModelType() != CAircraftModel::TypeOwnSimulatorModel)
{
pushModel = this->consolidateWithOwnModels(pushModel);
}
// merge with DB data if any
if (!pushModel.hasValidDbKey())
{
pushModel = this->consolidateWithDbData(pushModel);
}
CStatusMessage m(validateStashModel(pushModel, replace));
if (!m.isWarningOrAbove()) if (!m.isWarningOrAbove())
{ {
if (replace) if (replace)
{ {
this->ui->tvp_StashAircraftModels->replaceOrAdd(&CAircraftModel::getModelString, model.getModelString(), model); this->ui->tvp_StashAircraftModels->replaceOrAdd(&CAircraftModel::getModelString, pushModel.getModelString(), pushModel);
} }
else else
{ {
this->ui->tvp_StashAircraftModels->insert(model); this->ui->tvp_StashAircraftModels->insert(pushModel);
} }
} }
return m; return m;
@@ -313,6 +328,28 @@ namespace BlackGui
return models; return models;
} }
CAircraftModel CDbStashComponent::consolidateWithDbData(const CAircraftModel &model)
{
if (!model.hasModelString()) { return model; }
CAircraftModel dbModel(this->getModelForModelString(model.getModelString()));
if (!dbModel.hasValidDbKey()) { return model; }
// use DB model as base, update everything else
dbModel.updateMissingParts(model);
return dbModel;
}
CAircraftModel CDbStashComponent::consolidateWithOwnModels(const CAircraftModel &model)
{
if (!model.hasModelString()) { return model; }
if (model.getModelType() == CAircraftModel::TypeOwnSimulatorModel) { return model; }
CAircraftModel ownModel(this->getMappingComponent()->getOwnModelForModelString(model.getModelString()));
if (!ownModel.hasModelString()) { return model; }
ownModel.updateMissingParts(model);
return ownModel;
}
void CDbStashComponent::ps_copyOverPartsToSelected() void CDbStashComponent::ps_copyOverPartsToSelected()
{ {
QObject *sender = QObject::sender(); QObject *sender = QObject::sender();
@@ -320,7 +357,7 @@ namespace BlackGui
if (!this->getMappingComponent()) { return; } if (!this->getMappingComponent()) { return; }
if (!this->ui->tvp_StashAircraftModels->hasSelection()) { return; } if (!this->ui->tvp_StashAircraftModels->hasSelection()) { return; }
CAircraftModel model(this->getMappingComponent()->getAircraftModel()); CAircraftModel model(this->getMappingComponent()->getEditorAircraftModel());
if (sender == this->ui->pb_AircraftIcao) if (sender == this->ui->pb_AircraftIcao)
{ {
this->applyToSelected(model.getAircraftIcaoCode()); this->applyToSelected(model.getAircraftIcaoCode());

View File

@@ -152,6 +152,12 @@ namespace BlackGui
//! Get the selected only models or all models depending on checkbox //! Get the selected only models or all models depending on checkbox
BlackMisc::Simulation::CAircraftModelList getSelectedOrAllModels() const; BlackMisc::Simulation::CAircraftModelList getSelectedOrAllModels() const;
//! Consolidate with any DB data (if available).
BlackMisc::Simulation::CAircraftModel consolidateWithDbData(const BlackMisc::Simulation::CAircraftModel &model);
//! Consolidate with own models (if available).
BlackMisc::Simulation::CAircraftModel consolidateWithOwnModels(const BlackMisc::Simulation::CAircraftModel &model);
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -225,6 +225,16 @@ namespace BlackMisc
void CAirlineIcaoCode::updateMissingParts(const CAirlineIcaoCode &otherIcaoCode) void CAirlineIcaoCode::updateMissingParts(const CAirlineIcaoCode &otherIcaoCode)
{ {
if (!this->hasValidDbKey() && otherIcaoCode.hasValidDbKey())
{
// we have no DB data, but the other one has
// so we change roles. We take the DB object as base, and update our parts
CAirlineIcaoCode copy(otherIcaoCode);
copy.updateMissingParts(*this);
*this = copy;
return;
}
if (!this->hasValidDesignator()) { this->setDesignator(otherIcaoCode.getDesignator()); } if (!this->hasValidDesignator()) { this->setDesignator(otherIcaoCode.getDesignator()); }
if (!this->hasValidCountry()) { this->setCountry(otherIcaoCode.getCountry()); } if (!this->hasValidCountry()) { this->setCountry(otherIcaoCode.getCountry()); }
if (!this->hasName()) { this->setName(otherIcaoCode.getName()); } if (!this->hasName()) { this->setName(otherIcaoCode.getName()); }

View File

@@ -143,7 +143,8 @@ namespace BlackMisc
} }
QString combinedCode(json.value(prefix + "combinedcode").toString()); QString combinedCode(json.value(prefix + "combinedcode").toString());
if (combinedCode.isEmpty()) { if (combinedCode.isEmpty())
{
CLivery liveryStub; // only consists of id, maybe id and timestamp CLivery liveryStub; // only consists of id, maybe id and timestamp
liveryStub.setKeyAndTimestampFromDatabaseJson(json, prefix); liveryStub.setKeyAndTimestampFromDatabaseJson(json, prefix);
return liveryStub; return liveryStub;
@@ -235,6 +236,8 @@ namespace BlackMisc
int CLivery::comparePropertyByIndex(const CLivery &compareValue, const CPropertyIndex &index) const int CLivery::comparePropertyByIndex(const CLivery &compareValue, const CPropertyIndex &index) const
{ {
if (index.isMyself()) { return this->getCombinedCode().compare(compareValue.getCombinedCode()); }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);}
ColumnIndex i = index.frontCasted<ColumnIndex>(); ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i) switch (i)
{ {
@@ -259,6 +262,16 @@ namespace BlackMisc
void CLivery::updateMissingParts(const CLivery &otherLivery) void CLivery::updateMissingParts(const CLivery &otherLivery)
{ {
if (!this->hasValidDbKey() && otherLivery.hasValidDbKey())
{
// we have no DB data, but the other one has
// so we change roles. We take the DB object as base, and update our parts
CLivery copy(otherLivery);
copy.updateMissingParts(*this);
*this = copy;
return;
}
if (!this->m_colorFuselage.isValid()) { this->setColorFuselage(otherLivery.getColorFuselage()); } if (!this->m_colorFuselage.isValid()) { this->setColorFuselage(otherLivery.getColorFuselage()); }
if (!this->m_colorTail.isValid()) { this->setColorTail(otherLivery.getColorTail()); } if (!this->m_colorTail.isValid()) { this->setColorTail(otherLivery.getColorTail()); }
if (this->m_combinedCode.isEmpty()) { this->setCombinedCode(otherLivery.getCombinedCode());} if (this->m_combinedCode.isEmpty()) { this->setCombinedCode(otherLivery.getCombinedCode());}

View File

@@ -259,25 +259,35 @@ namespace BlackMisc
return this->m_livery.hasValidAirlineDesignator(); return this->m_livery.hasValidAirlineDesignator();
} }
void CAircraftModel::updateMissingParts(const CAircraftModel &model) void CAircraftModel::updateMissingParts(const CAircraftModel &otherModel)
{ {
if (this->m_modelString.isEmpty()) { this->setModelString(model.getModelString()); } if (!this->hasValidDbKey() && otherModel.hasValidDbKey())
if (this->m_description.isEmpty()) { this->setDescription(model.getDescription()); } {
if (this->m_fileName.isEmpty()) { this->setFileName(model.getFileName()); } // we have no DB data, but the other one has
if (this->m_callsign.isEmpty()) { this->setCallsign(model.getCallsign()); } // so we change roles. We take the DB object as base, and update our parts
if (this->m_modelType == TypeUnknown) { this->m_modelType = model.getModelType(); } CAircraftModel copy(otherModel);
copy.updateMissingParts(*this);
*this = copy;
return;
}
if (this->m_modelString.isEmpty()) { this->setModelString(otherModel.getModelString()); }
if (this->m_description.isEmpty()) { this->setDescription(otherModel.getDescription()); }
if (this->m_fileName.isEmpty()) { this->setFileName(otherModel.getFileName()); }
if (this->m_callsign.isEmpty()) { this->setCallsign(otherModel.getCallsign()); }
if (this->m_modelType == TypeUnknown) { this->m_modelType = otherModel.getModelType(); }
if (this->m_simulator.isUnspecified()) if (this->m_simulator.isUnspecified())
{ {
this->setSimulatorInfo(model.getSimulatorInfo()); this->setSimulatorInfo(otherModel.getSimulatorInfo());
} }
else else
{ {
this->m_simulator.add(model.getSimulatorInfo()); this->m_simulator.add(otherModel.getSimulatorInfo());
} }
this->m_livery.updateMissingParts(model.getLivery()); this->m_livery.updateMissingParts(otherModel.getLivery());
this->m_aircraftIcao.updateMissingParts(model.getAircraftIcaoCode()); this->m_aircraftIcao.updateMissingParts(otherModel.getAircraftIcaoCode());
this->m_distributor.updateMissingParts(model.getDistributor()); this->m_distributor.updateMissingParts(otherModel.getDistributor());
} }
bool CAircraftModel::hasQueriedModelString() const bool CAircraftModel::hasQueriedModelString() const

View File

@@ -210,7 +210,7 @@ namespace BlackMisc
void setFileName(const QString &fileName) { m_fileName = fileName; } void setFileName(const QString &fileName) { m_fileName = fileName; }
//! Update missing parts from another model //! Update missing parts from another model
void updateMissingParts(const CAircraftModel &model); void updateMissingParts(const CAircraftModel &otherModel);
//! Queried model string? //! Queried model string?
bool hasQueriedModelString() const; bool hasQueriedModelString() const;

View File

@@ -115,6 +115,16 @@ namespace BlackMisc
void CDistributor::updateMissingParts(const CDistributor &otherDistributor) void CDistributor::updateMissingParts(const CDistributor &otherDistributor)
{ {
if (!this->hasValidDbKey() && otherDistributor.hasValidDbKey())
{
// we have no DB data, but the other one has
// so we change roles. We take the DB object as base, and update our parts
CDistributor copy(otherDistributor);
copy.updateMissingParts(*this);
*this = copy;
return;
}
if (!this->hasAlias1()) { this->setAlias1(otherDistributor.getAlias1()); } if (!this->hasAlias1()) { this->setAlias1(otherDistributor.getAlias1()); }
if (!this->hasAlias2()) { this->setAlias1(otherDistributor.getAlias2()); } if (!this->hasAlias2()) { this->setAlias1(otherDistributor.getAlias2()); }
if (!this->hasDescription()) { this->setDescription(otherDistributor.getDescription()); } if (!this->hasDescription()) { this->setDescription(otherDistributor.getDescription()); }
@@ -129,7 +139,8 @@ namespace BlackMisc
} }
QString description(json.value(prefix + "description").toString()); QString description(json.value(prefix + "description").toString());
if (description.isEmpty()) { if (description.isEmpty())
{
// stub, only key, maybe also timestamps // stub, only key, maybe also timestamps
CDistributor distributorStub; CDistributor distributorStub;
distributorStub.setKeyAndTimestampFromDatabaseJson(json, prefix); distributorStub.setKeyAndTimestampFromDatabaseJson(json, prefix);