diff --git a/src/blackgui/components/dbmappingcomponent.cpp b/src/blackgui/components/dbmappingcomponent.cpp index 17d1f0a5a..472075013 100644 --- a/src/blackgui/components/dbmappingcomponent.cpp +++ b/src/blackgui/components/dbmappingcomponent.cpp @@ -48,7 +48,8 @@ namespace BlackGui this->ui->tvp_AircraftModelsForVPilot->addFilterDialog(); // own models - ui->comp_OwnAircraftModels->view()->setCustomMenu(new CModelStashTools(this, false)); + ui->comp_OwnAircraftModels->view()->setCustomMenu(new COwnModelSetMenu(this, true)); + ui->comp_OwnAircraftModels->view()->setCustomMenu(new CModelStashToolsMenu(this, false)); // connects connect(ui->editor_Model, &CModelMappingForm::requestStash, this, &CDbMappingComponent::ps_stashCurrentModel); @@ -101,7 +102,7 @@ namespace BlackGui connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::requestUpdate, this, &CDbMappingComponent::ps_requestVPilotDataUpdate); this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CMappingVPilotMenu(this, true)); - this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CModelStashTools(this, false)); + this->ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CModelStashToolsMenu(this, false)); this->ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true); this->ui->tvp_AircraftModelsForVPilot->addFilterDialog(); const CAircraftModelList vPilotModels(m_cachedVPilotModels.get()); @@ -228,7 +229,7 @@ namespace BlackGui return static_cast(t); } - bool CDbMappingComponent::isStashedTab() const + bool CDbMappingComponent::isStashTab() const { return currentTabIndex() == TabStash; } @@ -490,6 +491,15 @@ namespace BlackGui this->ui->tw_ModelsToBeMapped->setTabText(i, o); } + void CDbMappingComponent::ps_addToOwnModelSet() + { + if (this->currentTabIndex() != CDbMappingComponent::TabOwnModels) { return; } + if (!currentModelView()->hasSelection()) { return; } + const CAircraftModelList models(this->currentModelView()->selectedObjects()); + const CStatusMessage m = this->addToOwnModelSet(models, this->getOwnModelsSimulator()); + CLogMessage::preformatted(m); + } + void CDbMappingComponent::ps_onStashCountChanged(int count, bool withFilter) { Q_UNUSED(count); @@ -618,6 +628,11 @@ namespace BlackGui return this->ui->comp_StashAircraft->stashModels(models); } + CStatusMessage CDbMappingComponent::addToOwnModelSet(const CAircraftModelList &models, const CSimulatorInfo &simulator) + { + return this->ui->comp_OwnModelSet->addToModelSet(models, simulator); + } + CAircraftModel CDbMappingComponent::consolidateModel(const CAircraftModel &model) const { return this->ui->comp_StashAircraft->consolidateModel(model); @@ -647,7 +662,11 @@ namespace BlackGui return qobject_cast(this->parent()); } - void CDbMappingComponent::CModelStashTools::customMenu(QMenu &menu) const + CDbMappingComponent::CModelStashToolsMenu::CModelStashToolsMenu(CDbMappingComponent *mappingComponent, bool separator) : + BlackGui::Menus::IMenuDelegate(mappingComponent, separator) + {} + + void CDbMappingComponent::CModelStashToolsMenu::customMenu(QMenu &menu) const { CDbMappingComponent *mapComp = mappingComponent(); Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component"); @@ -656,34 +675,62 @@ namespace BlackGui { if (!mapComp->currentModelView()->isEmpty() && mapComp->currentModelView()->getMenu().testFlag(CViewBaseNonTemplate::MenuCanStashModels)) { - this->addSeparator(menu); + QMenu *stashMenu = new QMenu("Stash tools", &menu); int dbModels = sGui->getWebDataServices()->getModelsCount(); if (dbModels > 0) { - // we have keys and data where we could delete them from view + // we have keys and data by which we could delete them from view const QString msgDelete("Delete " + QString::number(dbModels) + " DB model(s) from " + mapComp->currentTabText()); - menu.addAction(CIcons::delete16(), msgDelete, mapComp, &CDbMappingComponent::ps_removeDbModelsFromView); + stashMenu->addAction(CIcons::delete16(), msgDelete, mapComp, &CDbMappingComponent::ps_removeDbModelsFromView); } - // we have keys and data where we could delete them from const QString msgAutoStash("Auto stashing"); - menu.addAction(CIcons::appDbStash16(), msgAutoStash, mapComp, &CDbMappingComponent::ps_displayAutoStashingDialog); + stashMenu->addAction(CIcons::appDbStash16(), msgAutoStash, mapComp, &CDbMappingComponent::ps_displayAutoStashingDialog); if (mapComp->m_autoStashDialog && mapComp->m_autoStashDialog->isCompleted()) { - menu.addAction(CIcons::appDbStash16(), "Last auto stash run", mapComp->m_autoStashDialog.data(), &CDbAutoStashingComponent::showLastResults); + stashMenu->addAction(CIcons::appDbStash16(), "Last auto stash run", mapComp->m_autoStashDialog.data(), &CDbAutoStashingComponent::showLastResults); } // auto filter in DB views - QAction *a = menu.addAction(CIcons::filter16(), "Auto filtering in DB views (on/off)", mapComp, &CDbMappingComponent::ps_toggleAutoFiltering); + QAction *a = stashMenu->addAction(CIcons::filter16(), "Auto filtering in DB views (on/off)", mapComp, &CDbMappingComponent::ps_toggleAutoFiltering); a->setCheckable(true); a->setChecked(mapComp->m_autoFilterInDbViews); + + // add menu + if (stashMenu->isEmpty()) + { + menu.deleteLater(); + } + else + { + this->addSeparator(menu); + menu.addMenu(stashMenu); + stashMenu->setIcon(CIcons::appDbStash16()); + } } } this->nestedCustomMenu(menu); } - CDbMappingComponent *CDbMappingComponent::CModelStashTools::mappingComponent() const + CDbMappingComponent *CDbMappingComponent::CModelStashToolsMenu::mappingComponent() const + { + return qobject_cast(this->parent()); + } + + void CDbMappingComponent::COwnModelSetMenu::customMenu(QMenu &menu) const + { + CDbMappingComponent *mapComp = mappingComponent(); + Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component"); + if (mapComp->currentTabIndex() == CDbMappingComponent::TabOwnModels && mapComp->currentModelView()->hasSelection()) + { + this->addSeparator(menu); + menu.addAction(CIcons::appAircraft16(), "Add to own model set", mapComp, &CDbMappingComponent::ps_addToOwnModelSet); + } + this->nestedCustomMenu(menu); + } + + CDbMappingComponent *CDbMappingComponent::COwnModelSetMenu::mappingComponent() const { return qobject_cast(this->parent()); } diff --git a/src/blackgui/components/dbmappingcomponent.h b/src/blackgui/components/dbmappingcomponent.h index f2b3b642a..fd765d7c7 100644 --- a/src/blackgui/components/dbmappingcomponent.h +++ b/src/blackgui/components/dbmappingcomponent.h @@ -52,11 +52,11 @@ namespace BlackGui //! Must match real tab index enum TabIndex { - NoValidTab = -1, - TabStash = 0, - TabOwnModels = 1, - TabOwnModelSet = 2, - TabVPilot = 3 + NoValidTab = -1, + TabStash = 0, + TabOwnModels = 1, + TabOwnModelSet = 2, + TabVPilot = 3 }; //! Constructor @@ -71,34 +71,36 @@ namespace BlackGui //! With vPilot rules bool withVPilot() const { return m_withVPilot; } - //! Any models which can be stashed + //! Any models which can be stashed? bool hasSelectedModelsToStash() const; //! Models to be stashed from currently activated tab (table view) BlackMisc::Simulation::CAircraftModelList getSelectedModelsToStash() const; - //! Stashed models - const BlackMisc::Simulation::CAircraftModelList &getStashedModels() const; - - //! Stashed model strings - QStringList getStashedModelStrings() const; - //! Current tab index TabIndex currentTabIndex() const; + //! Is stashed view + bool isStashTab() const; + //! Current model view BlackGui::Views::CAircraftModelView *currentModelView() const; - //! Is stashed view - bool isStashedTab() const; - //! Unvalidated consolidated aircraft model from the editor subparts (icao, distributor) //! \note not guaranteed to be valid, just a snapshot of its current editor state BlackMisc::Simulation::CAircraftModel getEditorAircraftModel() const; + //! \name Models from BlackGui::Components::CDbStashComponent + //! @{ + //! Stashed models + const BlackMisc::Simulation::CAircraftModelList &getStashedModels() const; + + //! Stashed model strings + QStringList getStashedModelStrings() const; + //! @} + //! \name Own models from BlackGui::Components::CDbOwnModelsComponent //! @{ - //! Own models BlackMisc::Simulation::CAircraftModelList getOwnModels() const; @@ -119,6 +121,9 @@ namespace BlackGui //! \copydoc CDbStashComponent::stashModels BlackMisc::CStatusMessageList stashModels(const BlackMisc::Simulation::CAircraftModelList &models); + //! \copydoc CDbOwnModelSetComponent::addToModelSet + BlackMisc::CStatusMessage addToOwnModelSet(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CSimulatorInfo &simulator); + //! \copydoc CDbStashComponent::consolidateModel BlackMisc::Simulation::CAircraftModel consolidateModel(const BlackMisc::Simulation::CAircraftModel &model) const; @@ -214,6 +219,9 @@ namespace BlackGui //! Own models have been changed void ps_onOwnModelsCountChanged(int count, bool withFilter); + //! Add to own model set + void ps_addToOwnModelSet(); + private: QScopedPointer ui; QScopedPointer m_autoStashDialog; //!< dialog auto stashing @@ -259,11 +267,26 @@ namespace BlackGui //! -# for auto stashing //! -# toggle auto filtering //! \note This is a specific menu for that very component - class CModelStashTools : public BlackGui::Menus::IMenuDelegate + class CModelStashToolsMenu : public BlackGui::Menus::IMenuDelegate { public: //! Constructor - CModelStashTools(CDbMappingComponent *mappingComponent, bool separator = true) : + CModelStashToolsMenu(CDbMappingComponent *mappingComponent, bool separator = true); + + //! \copydoc IMenuDelegate::customMenu + virtual void customMenu(QMenu &menu) const override; + + private: + //! Mapping component + CDbMappingComponent *mappingComponent() const; + }; + + //! Menu for own model sets + class COwnModelSetMenu : public BlackGui::Menus::IMenuDelegate + { + public: + //! Constructor + COwnModelSetMenu(CDbMappingComponent *mappingComponent, bool separator = true) : BlackGui::Menus::IMenuDelegate(mappingComponent, separator) {} diff --git a/src/blackgui/components/dbownmodelsetcomponent.cpp b/src/blackgui/components/dbownmodelsetcomponent.cpp index 6ed384202..977ab60b2 100644 --- a/src/blackgui/components/dbownmodelsetcomponent.cpp +++ b/src/blackgui/components/dbownmodelsetcomponent.cpp @@ -58,17 +58,59 @@ namespace BlackGui void CDbOwnModelSetComponent::setModelSet(const CAircraftModelList &models, const CSimulatorInfo &simulator) { Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator"); - if (models.isEmpty()) { return; } + this->setSimulator(simulator); + if (models.isEmpty()) + { + this->ui->tvp_OwnModelSet->clear(); + return; + } + + // unempty set, consolidate CAircraftModelList cleanModelList(models.matchesSimulator(simulator)); // remove those not matching the simulator const int diff = models.size() - cleanModelList.size(); if (diff > 0) { CLogMessage(this).warning("Removed models from set because not matching " + simulator.toQString(true)); } - if (cleanModelList.isEmpty()) { return; } + this->ui->tvp_OwnModelSet->updateContainerMaybeAsync(cleanModelList); + } - this->setSimulator(simulator); - this->ui->tvp_OwnModelSet->updateContainerMaybeAsync(models); + const CAircraftModelList &CDbOwnModelSetComponent::getModelSet() const + { + return ui->tvp_OwnModelSet->container(); + } + + CStatusMessage CDbOwnModelSetComponent::addToModelSet(const CAircraftModel &model, const CSimulatorInfo &simulator) + { + return this->addToModelSet(CAircraftModelList({model}), simulator); + } + + CStatusMessage CDbOwnModelSetComponent::addToModelSet(const CAircraftModelList &models, const CSimulatorInfo &simulator) + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator"); + if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityInfo, "No data", true); } + if (!this->getModelSetSimulator().isSingleSimulator()) + { + // no sim yet, we set it + this->setSimulator(simulator); + } + if (simulator != this->getModelSetSimulator()) + { + // only currently selected sim allowed + return CStatusMessage(this, CStatusMessage::SeverityError, + "Cannot add data for " + simulator.toQString(true) + " to " + this->getModelSetSimulator().toQString(true), true); + } + CAircraftModelList updateModels(this->getModelSet()); + int d = updateModels.replaceOrAddModelsWithString(models, Qt::CaseInsensitive); + if (d > 0) + { + this->ui->tvp_OwnModelSet->updateContainerMaybeAsync(updateModels); + return CStatusMessage(this, CStatusMessage::SeverityInfo, "Modified " + QString::number(d) + " entries in model set " + this->getModelSetSimulator().toQString(true), true); + } + else + { + return CStatusMessage(this, CStatusMessage::SeverityInfo, "No data modified in model set", true); + } } void CDbOwnModelSetComponent::setMappingComponent(CDbMappingComponent *component) @@ -219,6 +261,36 @@ namespace BlackGui ownModelSetComp->ps_changeSimulator(CSimulatorInfo(CSimulatorInfo::XPLANE)); }); } + + QMenu *emptySetMenu = load->addMenu("New empty set"); + if (sims.fsx()) + { + emptySetMenu->addAction(CIcons::appModels16(), "FSX models", ownModelSetComp, [ownModelSetComp]() + { + ownModelSetComp->setModelSet(CAircraftModelList(), CSimulatorInfo(CSimulatorInfo::FSX)); + }); + } + if (sims.p3d()) + { + emptySetMenu->addAction(CIcons::appModels16(), "P3D models", ownModelSetComp, [ownModelSetComp]() + { + ownModelSetComp->setModelSet(CAircraftModelList(), CSimulatorInfo(CSimulatorInfo::P3D)); + }); + } + if (sims.fs9()) + { + emptySetMenu->addAction(CIcons::appModels16(), "FS9 models", ownModelSetComp, [ownModelSetComp]() + { + ownModelSetComp->setModelSet(CAircraftModelList(), CSimulatorInfo(CSimulatorInfo::FS9)); + }); + } + if (sims.xplane()) + { + emptySetMenu->addAction(CIcons::appModels16(), "XP models", ownModelSetComp, [ownModelSetComp]() + { + ownModelSetComp->setModelSet(CAircraftModelList(), CSimulatorInfo(CSimulatorInfo::XPLANE)); + }); + } } this->nestedCustomMenu(menu); } diff --git a/src/blackgui/components/dbownmodelsetcomponent.h b/src/blackgui/components/dbownmodelsetcomponent.h index ed9e5d832..ba991a0ed 100644 --- a/src/blackgui/components/dbownmodelsetcomponent.h +++ b/src/blackgui/components/dbownmodelsetcomponent.h @@ -48,14 +48,24 @@ namespace BlackGui //! Corresponding view Views::CAircraftModelView *view() const; - //! Set the model set - void setModelSet(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CSimulatorInfo &simulator); + //! Add to model set + BlackMisc::CStatusMessage addToModelSet(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CSimulatorInfo &simulator); + + //! Add to model set + BlackMisc::CStatusMessage addToModelSet(const BlackMisc::Simulation::CAircraftModel &model, const BlackMisc::Simulation::CSimulatorInfo &simulator); + + //! Current model set for simulator CDbOwnModelSetComponent::getModelSetSimulator + const BlackMisc::Simulation::CAircraftModelList &getModelSet() const; + + //! Model set is for simulator + const BlackMisc::Simulation::CSimulatorInfo &getModelSetSimulator() const { return m_simulator; } //! \copydoc CDbMappingComponentAware::setMappingComponent virtual void setMappingComponent(CDbMappingComponent *component) override; - //! Model set is for simulator - const BlackMisc::Simulation::CSimulatorInfo &getModelSetSimulator() const { return m_simulator; } + public slots: + //! Set the model set + void setModelSet(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CSimulatorInfo &simulator); private slots: //! Tab has been changed