refs #535, mapping component

* handle drop
* renamed save -> publish
* fixed cache handling as disucssed in slack / refs #558
* vPilot tab no longer OS / FS restricted
This commit is contained in:
Klaus Basan
2015-12-17 20:30:26 +01:00
parent 7dbfd85047
commit 16a6544017
3 changed files with 167 additions and 46 deletions

View File

@@ -10,9 +10,9 @@
#include "dbmappingcomponent.h" #include "dbmappingcomponent.h"
#include "ui_dbmappingcomponent.h" #include "ui_dbmappingcomponent.h"
#include "blackgui/guiutility.h" #include "blackgui/guiutility.h"
#include "blackgui/shortcut.h"
#include "blackmisc/simulation/fscommon/aircraftcfgparser.h" #include "blackmisc/simulation/fscommon/aircraftcfgparser.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/project.h"
#include <QShortcut> #include <QShortcut>
using namespace BlackCore; using namespace BlackCore;
@@ -35,14 +35,23 @@ namespace BlackGui
{ {
ui->setupUi(this); ui->setupUi(this);
this->ui->comp_StashAircraft->setMappingComponent(this); this->ui->comp_StashAircraft->setMappingComponent(this);
this->ui->tvp_AircraftModelsForVPilot->setAircraftModelMode(CAircraftModelListModel::VPilotRuleModel);
this->ui->tvp_OwnAircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnSimulatorModelMapping);
connect(ui->editor_Model, &CModelMappingForm::requestSave, this, &CDbMappingComponent::saveSingleModelToDb); this->ui->tvp_AircraftModelsForVPilot->setAircraftModelMode(CAircraftModelListModel::VPilotRuleModel);
this->ui->tvp_AircraftModelsForVPilot->setAllowStash(true);
this->ui->tvp_OwnAircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnSimulatorModelMapping);
this->ui->tvp_OwnAircraftModels->setAllowStash(true);
// connects
connect(ui->editor_Model, &CModelMappingForm::requestPublish, this, &CDbMappingComponent::ps_publishSingleModelToDb);
connect(ui->editor_Model, &CModelMappingForm::requestStash, this, &CDbMappingComponent::ps_stashCurrentModel);
connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected); connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected);
connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onOwnModelsCountChanged); connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onOwnModelsCountChanged);
connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::requestStash, this, &CDbMappingComponent::stashSelectedModels);
connect(ui->comp_StashAircraft->getView(), &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onStashCountChanged); connect(ui->comp_StashAircraft->getView(), &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onStashCountChanged);
connect(ui->comp_StashAircraft, &CDbStashComponent::stashedModelChanged, this, &CDbMappingComponent::ps_onStashedModelsChanged); connect(ui->comp_StashAircraft->getView(), &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected);
connect(ui->comp_StashAircraft->getView(), &CAircraftModelView::requestHandlingOfStashDrop, this, &CDbMappingComponent::ps_handleStashDropRequest);
connect(ui->comp_StashAircraft, &CDbStashComponent::stashedModelsChanged, this, &CDbMappingComponent::ps_onStashedModelsChanged);
ui->tvp_OwnAircraftModels->setDisplayAutomatically(true); ui->tvp_OwnAircraftModels->setDisplayAutomatically(true);
ui->tvp_OwnAircraftModels->setCustomMenu(new CMappingSimulatorModelMenu(this)); ui->tvp_OwnAircraftModels->setCustomMenu(new CMappingSimulatorModelMenu(this));
@@ -57,6 +66,7 @@ namespace BlackGui
this->ui->tw_ModelsToBeMapped->setTabIcon(TabStash, CIcons::appDbStash16()); this->ui->tw_ModelsToBeMapped->setTabIcon(TabStash, CIcons::appDbStash16());
this->ui->tw_ModelsToBeMapped->setTabIcon(TabOwnModels, CIcons::appModels16()); this->ui->tw_ModelsToBeMapped->setTabIcon(TabOwnModels, CIcons::appModels16());
// vPilot
this->initVPilotLoading(); this->initVPilotLoading();
} }
@@ -67,17 +77,18 @@ namespace BlackGui
void CDbMappingComponent::initVPilotLoading() void CDbMappingComponent::initVPilotLoading()
{ {
bool canUseVPilot = CProject::isRunningOnWindowsNtPlatform() && CProject::isCompiledWithMsFlightSimulatorSupport(); bool canUseVPilot = true; // further restriction could go here
bool withVPilotRights = canUseVPilot && this->m_user.get().isMappingAdmin(); bool withVPilotRights = canUseVPilot && this->m_user.get().isMappingAdmin();
this->m_withVPilot = withVPilotRights; this->m_withVPilot = withVPilotRights;
static const QString tabName(this->ui->tw_ModelsToBeMapped->tabText(TabVPliot)); static const QString tabName(this->ui->tw_ModelsToBeMapped->tabText(TabVPliot));
if (this->m_vPilot1stInit && canUseVPilot) if (this->m_vPilot1stInit && canUseVPilot)
{ {
ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CStashMenu(this, true)); this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CStashMenu(this, true));
connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected); connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected);
connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onVPilotCountChanged); connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onVPilotCountChanged);
connect(&m_vPilotReader, &CVPilotRulesReader::readFinished, this, &CDbMappingComponent::ps_onLoadVPilotDataFinished); connect(&m_vPilotReader, &CVPilotRulesReader::readFinished, this, &CDbMappingComponent::ps_onLoadVPilotDataFinished);
connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::requestStash, this, &CDbMappingComponent::stashSelectedModels);
this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CMappingVPilotMenu(this, true)); this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CMappingVPilotMenu(this, true));
this->ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true); this->ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true);
const CAircraftModelList cachedModels(m_cachedVPilotModels.get()); const CAircraftModelList cachedModels(m_cachedVPilotModels.get());
@@ -122,6 +133,29 @@ namespace BlackGui
} }
} }
CAircraftModel CDbMappingComponent::getModelFromView(const QModelIndex &index) const
{
if (!index.isValid()) { return CAircraftModel(); }
QObject *sender = QObject::sender();
if (sender == this->ui->tvp_AircraftModelsForVPilot)
{
return this->ui->tvp_AircraftModelsForVPilot->at(index);
}
else if (sender == this->ui->tvp_OwnAircraftModels)
{
return this->ui->tvp_OwnAircraftModels->at(index);
}
else if (sender == this->ui->comp_StashAircraft || sender == this->ui->comp_StashAircraft->getView())
{
return this->ui->comp_StashAircraft->getView()->at(index);
}
// no sender, use current tab
const CAircraftModelView *v = this->currentModelView();
if (!v) { return CAircraftModel(); }
return v->at(index);
}
void CDbMappingComponent::setProvider(BlackMisc::Network::IWebDataServicesProvider *provider) void CDbMappingComponent::setProvider(BlackMisc::Network::IWebDataServicesProvider *provider)
{ {
CWebDataServicesAware::setProvider(provider); CWebDataServicesAware::setProvider(provider);
@@ -139,24 +173,40 @@ namespace BlackGui
if (this->m_modelLoader) { this->m_modelLoader->gracefulShutdown(); } if (this->m_modelLoader) { this->m_modelLoader->gracefulShutdown(); }
} }
bool CDbMappingComponent::hasModelsForStash() const bool CDbMappingComponent::hasModelsToStash() const
{ {
TabIndex tab = currentTabIndex(); TabIndex tab = currentTabIndex();
switch (tab) switch (tab)
{ {
case TabOwnModels: case TabOwnModels:
return ui->tvp_OwnAircraftModels->hasSelection(); return ui->tvp_OwnAircraftModels->hasModelsToStash();
case TabVPliot: case TabVPliot:
return ui->tvp_AircraftModelsForVPilot->hasSelection(); return ui->tvp_AircraftModelsForVPilot->hasModelsToStash();
default: default:
break; break;
} }
return false; return false;
} }
CAircraftModelList CDbMappingComponent::getModelsForStash() const const CAircraftModelView *CDbMappingComponent::currentModelView() const
{ {
if (!hasModelsForStash()) { return CAircraftModelList(); } TabIndex tab = currentTabIndex();
switch (tab)
{
case TabOwnModels:
return ui->tvp_OwnAircraftModels;
case TabVPliot:
return ui->tvp_AircraftModelsForVPilot;
case TabStash:
return ui->comp_StashAircraft->getView();
default:
return nullptr;
}
}
CAircraftModelList CDbMappingComponent::getModelsToStash() const
{
if (!hasModelsToStash()) { return CAircraftModelList(); }
TabIndex tab = currentTabIndex(); TabIndex tab = currentTabIndex();
switch (tab) switch (tab)
{ {
@@ -170,12 +220,27 @@ namespace BlackGui
return CAircraftModelList(); return CAircraftModelList();
} }
const CAircraftModelList &CDbMappingComponent::getStashedModels() const
{
return ui->comp_StashAircraft->getStashedModels();
}
QStringList CDbMappingComponent::getStashedModelStrings() const
{
return ui->comp_StashAircraft->getStashedModelStrings();
}
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
{
return currentTabIndex() == TabStash;
}
CStatusMessageList CDbMappingComponent::validate(bool withNestedForms) const CStatusMessageList CDbMappingComponent::validate(bool withNestedForms) const
{ {
CStatusMessageList msgs(this->ui->editor_Model->validate(!withNestedForms)); CStatusMessageList msgs(this->ui->editor_Model->validate(!withNestedForms));
@@ -188,7 +253,7 @@ namespace BlackGui
return msgs; return msgs;
} }
void CDbMappingComponent::saveSingleModelToDb() void CDbMappingComponent::ps_publishSingleModelToDb()
{ {
CStatusMessageList msgs(validate(true)); CStatusMessageList msgs(validate(true));
if (msgs.hasErrorMessages()) if (msgs.hasErrorMessages())
@@ -198,14 +263,33 @@ namespace BlackGui
return; return;
} }
CAircraftModel model(getAircraftModel()); const CAircraftModel model(getAircraftModel());
msgs = this->asyncWriteModelToDb(model); msgs = this->asyncWriteModel(model);
if (!msgs.isEmpty()) if (!msgs.isEmpty())
{ {
CLogMessage(this).preformatted(msgs); CLogMessage(this).preformatted(msgs);
} }
} }
void CDbMappingComponent::ps_handleStashDropRequest(const CAirlineIcaoCode &code) const
{
CLivery stdLivery(this->getStdLiveryForAirlineCode(code));
if (!stdLivery.hasValidDbKey()) { return; }
this->ui->comp_StashAircraft->applyToSelected(stdLivery);
}
void CDbMappingComponent::ps_stashCurrentModel()
{
const CAircraftModel model(getAircraftModel());
if (!model.hasModelString())
{
CStatusMessage msg = CStatusMessage(CStatusMessage::SeverityError, "no model string, ignored");
this->showMessage(msg);
return;
}
this->ui->comp_StashAircraft->stashModel(model);
}
void CDbMappingComponent::resizeForSelect() void CDbMappingComponent::resizeForSelect()
{ {
int h = this->height(); int h = this->height();
@@ -279,6 +363,14 @@ namespace BlackGui
this->ui->tvp_OwnAircraftModels->hideLoadIndicator(); this->ui->tvp_OwnAircraftModels->hideLoadIndicator();
} }
void CDbMappingComponent::ps_onVPilotCacheChanged()
{
if (this->ui->tvp_AircraftModelsForVPilot->displayAutomatically())
{
this->ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(this->m_cachedVPilotModels.get());
}
}
void CDbMappingComponent::ps_onStashedModelsChanged() void CDbMappingComponent::ps_onStashedModelsChanged()
{ {
bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightGivenModelStrings(); bool hlvp = this->ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightGivenModelStrings();
@@ -351,10 +443,10 @@ namespace BlackGui
void CDbMappingComponent::stashSelectedModels() void CDbMappingComponent::stashSelectedModels()
{ {
if (!this->hasModelsForStash()) { return; } if (!this->hasModelsToStash()) { return; }
CStatusMessageList msgs = CStatusMessageList msgs =
this->ui->comp_StashAircraft->stashModels( this->ui->comp_StashAircraft->stashModels(
this->getModelsForStash() this->getModelsToStash()
); );
if (msgs.hasWarningOrErrorMessages()) if (msgs.hasWarningOrErrorMessages())
{ {
@@ -364,20 +456,8 @@ namespace BlackGui
void CDbMappingComponent::ps_onModelRowSelected(const QModelIndex &index) void CDbMappingComponent::ps_onModelRowSelected(const QModelIndex &index)
{ {
QObject *sender = QObject::sender(); CAircraftModel model(this->getModelFromView(index));
CAircraftModel model; if (!model.hasModelString()) { return; }
if (sender == this->ui->tvp_AircraftModelsForVPilot)
{
model = this->ui->tvp_AircraftModelsForVPilot->at(index);
}
else if (sender == this->ui->tvp_OwnAircraftModels)
{
model = this->ui->tvp_OwnAircraftModels->at(index);
}
else
{
return;
}
this->ui->editor_Model->setValue(model); this->ui->editor_Model->setValue(model);
const CLivery livery(this->smartLiverySelector(model.getLivery())); const CLivery livery(this->smartLiverySelector(model.getLivery()));
@@ -507,11 +587,9 @@ namespace BlackGui
{ {
CDbMappingComponent *mapComp = qobject_cast<CDbMappingComponent *>(this->parent()); CDbMappingComponent *mapComp = qobject_cast<CDbMappingComponent *>(this->parent());
Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access mapping component"); Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access mapping component");
if (mapComp->hasModelsForStash()) if (mapComp->hasModelsToStash())
{ {
QAction *a = menu.addAction(CIcons::appMappings16(), "Stash", mapComp, SLOT(stashSelectedModels()), Qt::ALT + Qt::Key_S); menu.addAction(CIcons::appMappings16(), "Stash", mapComp, SLOT(stashSelectedModels()), CShortcut::keyStash());
a->setShortcut(Qt::ALT + Qt::Key_S);
} }
this->nestedCustomMenu(menu); this->nestedCustomMenu(menu);
} }

View File

@@ -19,6 +19,7 @@
#include "blackgui/menudelegate.h" #include "blackgui/menudelegate.h"
#include "blackgui/enableforviewbasedindicator.h" #include "blackgui/enableforviewbasedindicator.h"
#include "blackgui/components/enablefordockwidgetinfoarea.h" #include "blackgui/components/enablefordockwidgetinfoarea.h"
#include "blackgui/views/aircraftmodelview.h"
#include "blackmisc/simulation/aircraftmodelloader.h" #include "blackmisc/simulation/aircraftmodelloader.h"
#include "blackmisc/simulation/fscommon/vpilotrulesreader.h" #include "blackmisc/simulation/fscommon/vpilotrulesreader.h"
#include "blackmisc/network/webdataservicesprovider.h" #include "blackmisc/network/webdataservicesprovider.h"
@@ -69,15 +70,24 @@ namespace BlackGui
//! With vPilot rules //! With vPilot rules
bool withVPilot() const { return m_withVPilot; } bool withVPilot() const { return m_withVPilot; }
//! And models which can be stashed //! Any models which can be stashed
bool hasModelsForStash() const; bool hasModelsToStash() const;
//! The model to be stashed //! The models to be stashed
BlackMisc::Simulation::CAircraftModelList getModelsForStash() const; BlackMisc::Simulation::CAircraftModelList getModelsToStash() const;
//! Stashed models
const BlackMisc::Simulation::CAircraftModelList &getStashedModels() const;
//! Stashed models trings
QStringList getStashedModelStrings() const;
//! Current tab index //! Current tab index
TabIndex currentTabIndex() const; TabIndex currentTabIndex() const;
//! Is stashed view
bool isStashedView() const;
//! Unvalidated consolidated aircraft model from the subparts (icao, distributor) //! Unvalidated consolidated aircraft model from the subparts (icao, distributor)
//! \note not guaranteed to be valid, just snapshot of as it state //! \note not guaranteed to be valid, just snapshot of as it state
BlackMisc::Simulation::CAircraftModel getAircraftModel() const; BlackMisc::Simulation::CAircraftModel getAircraftModel() const;
@@ -96,9 +106,6 @@ namespace BlackGui
//! Validate, empty list means OK //! Validate, empty list means OK
BlackMisc::CStatusMessageList validate(bool withNestedForms) const; BlackMisc::CStatusMessageList validate(bool withNestedForms) const;
//! Save
void saveSingleModelToDb();
//! Resize so that selection is easy (larger table view) //! Resize so that selection is easy (larger table view)
void resizeForSelect(); void resizeForSelect();
@@ -115,9 +122,18 @@ namespace BlackGui
//! Data for vPilot have been loaded //! Data for vPilot have been loaded
void ps_onLoadVPilotDataFinished(bool success); void ps_onLoadVPilotDataFinished(bool success);
//! vPilot cached changed
void ps_onVPilotCacheChanged();
//! Stashed models changed //! Stashed models changed
void ps_onStashedModelsChanged(); void ps_onStashedModelsChanged();
//! Publish
void ps_publishSingleModelToDb();
//! Stash drop request
void ps_handleStashDropRequest(const BlackMisc::Aviation::CAirlineIcaoCode &code) const;
//! Row count for vPilot data changed //! Row count for vPilot data changed
void ps_onVPilotCountChanged(int count, bool withFilter); void ps_onVPilotCountChanged(int count, bool withFilter);
@@ -142,10 +158,13 @@ namespace BlackGui
//! User object changed //! User object changed
void ps_userChanged(); void ps_userChanged();
//! Stash current model
void ps_stashCurrentModel();
private: private:
QScopedPointer<Ui::CDbMappingComponent> ui; QScopedPointer<Ui::CDbMappingComponent> ui;
BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules BlackMisc::Simulation::FsCommon::CVPilotRulesReader m_vPilotReader; //!< read vPilot rules
BlackCore::CData<BlackCore::Data::VPilotAircraftModels> m_cachedVPilotModels { this }; //!< cache for latest vPilot rules BlackCore::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
BlackCore::CData<BlackCore::Data::OwnSimulatorAircraftModels> m_cachedOwnModels { this }; //!< cache for latest models BlackCore::CData<BlackCore::Data::OwnSimulatorAircraftModels> m_cachedOwnModels { this }; //!< cache for latest models
BlackCore::CData<BlackCore::Data::AuthenticatedUser> m_user {this, &CDbMappingComponent::ps_userChanged}; BlackCore::CData<BlackCore::Data::AuthenticatedUser> m_user {this, &CDbMappingComponent::ps_userChanged};
@@ -158,6 +177,12 @@ namespace BlackGui
//! Init model loader //! Init model loader
bool initModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simInfo); bool initModelLoader(const BlackMisc::Simulation::CSimulatorInfo &simInfo);
//! Model for given index from sender/current view
BlackMisc::Simulation::CAircraftModel getModelFromView(const QModelIndex &index) const;
//! Current model view
const BlackGui::Views::CAircraftModelView *currentModelView() const;
// -------------------- component specific menus -------------------------- // -------------------- component specific menus --------------------------
//! The menu for loading and handling own models for mapping //! The menu for loading and handling own models for mapping
@@ -188,6 +213,7 @@ namespace BlackGui
virtual void customMenu(QMenu &menu) const override; virtual void customMenu(QMenu &menu) const override;
private: private:
//! Mapping component
CDbMappingComponent *mappingComponent() const; CDbMappingComponent *mappingComponent() const;
}; };
@@ -204,6 +230,8 @@ namespace BlackGui
//! \copydoc IMenuDelegate::customMenu //! \copydoc IMenuDelegate::customMenu
virtual void customMenu(QMenu &menu) const override; virtual void customMenu(QMenu &menu) const override;
private:
//! Mapping component
CDbMappingComponent *mappingComponent() const; CDbMappingComponent *mappingComponent() const;
}; };
}; };

View File

@@ -2,6 +2,14 @@
<ui version="4.0"> <ui version="4.0">
<class>CDbMappingComponent</class> <class>CDbMappingComponent</class>
<widget class="BlackGui::COverlayMessagesFrame" name="CDbMappingComponent"> <widget class="BlackGui::COverlayMessagesFrame" name="CDbMappingComponent">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>618</height>
</rect>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Frame</string> <string>Frame</string>
</property> </property>
@@ -214,6 +222,14 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="qw_EditorsScrollArea"> <widget class="QWidget" name="qw_EditorsScrollArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>244</width>
<height>425</height>
</rect>
</property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
@@ -281,7 +297,6 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<zorder>fr_EditorsRight</zorder>
</widget> </widget>
</item> </item>
</layout> </layout>