diff --git a/src/blackgui/components/logcomponent.h b/src/blackgui/components/logcomponent.h index 9ab1ee619..865bba482 100644 --- a/src/blackgui/components/logcomponent.h +++ b/src/blackgui/components/logcomponent.h @@ -14,7 +14,7 @@ #include "blackgui/blackguiexport.h" #include "blackmisc/statusmessagelist.h" -#include "blackgui/menudelegate.h" +#include "blackgui/menus/menudelegate.h" #include #include #include @@ -76,7 +76,7 @@ namespace BlackGui QScopedPointer ui; //! Custom menu for the log component - class CLogMenu : public BlackGui::IMenuDelegate + class CLogMenu : public BlackGui::Menus::IMenuDelegate { public: //! Constructor diff --git a/src/blackgui/menudelegate.h b/src/blackgui/menudelegate.h deleted file mode 100644 index 206a9bf27..000000000 --- a/src/blackgui/menudelegate.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2015 - * swift project Community / Contributors - * - * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, - * including this file, may be copied, modified, propagated, or distributed except according to the terms - * contained in the LICENSE file. - */ - -#ifndef BLACKGUI_MENUDELEGATE_H -#define BLACKGUI_MENUDELEGATE_H - -#include -#include - -namespace BlackGui -{ - /*! - * Interface to implement a custom menu - */ - class IMenuDelegate : public QObject - { - Q_OBJECT - - public: - //! Display custom menu - virtual void customMenu(QMenu &menu) const = 0; - - //! Set nested delegate - void setNestedDelegate(IMenuDelegate *nestedDelegate) { m_nestedDelegate = nestedDelegate; } - - //! Nested delegate - IMenuDelegate *getNestedDelegate() const { return m_nestedDelegate; } - - //! Destructor - virtual ~IMenuDelegate() {} - - protected: - //! Constructor - IMenuDelegate(QWidget *parent = nullptr, bool separator = false) : - QObject(parent), m_separator(separator) {} - - //! Delegate down one level - void nestedCustomMenu(QMenu &menu) const - { - if (!m_nestedDelegate) { return; } - m_nestedDelegate->customMenu(menu); - } - - //! Add separator - void addSeparator(QMenu &menu) const - { - if (!m_separator || menu.isEmpty()) { return; } - menu.addSeparator(); - } - - IMenuDelegate *m_nestedDelegate = nullptr; //!< nested delegate if any - bool m_separator = false; //!< at end, terminate with separator - }; -} // ns - -#endif // guard diff --git a/src/blackgui/menus/aircraftmodelmenus.cpp b/src/blackgui/menus/aircraftmodelmenus.cpp new file mode 100644 index 000000000..2b6b0a6aa --- /dev/null +++ b/src/blackgui/menus/aircraftmodelmenus.cpp @@ -0,0 +1,133 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "aircraftmodelmenus.h" +#include "blackgui/guiapplication.h" +#include "blackmisc/icons.h" +#include "blackmisc/simulation/aircraftmodelloader.h" +#include + +using namespace BlackMisc; +using namespace BlackMisc::Simulation; +using namespace BlackGui; +using namespace BlackGui::Views; +using namespace BlackGui::Models; + +namespace BlackGui +{ + namespace Menus + { + CAircraftModelView *IAircraftModelViewMenu::modelView() const + { + CAircraftModelView *mv = qobject_cast(parent()); + Q_ASSERT_X(mv, Q_FUNC_INFO, "no view"); + return mv; + } + + const CAircraftModelList &IAircraftModelViewMenu::getAircraftModels() const + { + const CAircraftModelView *mv = modelView(); + Q_ASSERT_X(mv, Q_FUNC_INFO, "no view"); + return mv->container(); + } + + CAircraftModelList IAircraftModelViewMenu::getSelectedAircraftModels() const + { + const CAircraftModelView *mv = modelView(); + Q_ASSERT_X(mv, Q_FUNC_INFO, "no view"); + return mv->selectedObjects(); + } + + void CShowSimulatorFileMenu::customMenu(QMenu &menu) const + { + CAircraftModelView *mv = modelView(); + Q_ASSERT_X(mv, Q_FUNC_INFO, "no view"); + + if (mv->hasSelection()) + { + this->addSeparator(menu); + menu.addAction(CIcons::text16(), "Open simulator file", this, &CShowSimulatorFileMenu::ps_showSimulatorFile); + } + this->nestedCustomMenu(menu); + } + + void CShowSimulatorFileMenu::ps_showSimulatorFile() const + { + const CAircraftModelView *mv = modelView(); + if (!mv->hasSelection()) { return; } + const CAircraftModelList models(getSelectedAircraftModels().findWithFileName()); + if (models.isEmpty()) { return; } + int trails = 0; + + for (const CAircraftModel &model : models) + { + trails++; + if (QFile::exists(model.getFileName())) + { + const QString url("file:///" + model.getFileName()); + QDesktopServices::openUrl(QUrl(url)); + break; + } + if (trails > 10) { break; } + } + } + + void CMergeWithDbDataMenu::customMenu(QMenu &menu) const + { + const CAircraftModelView *mv = modelView(); + if (mv->isEmpty()) { return; } + if (!sGui->hasWebDataServices()) { return; } + + this->addSeparator(menu); + QMenu *mm = menu.addMenu(CIcons::databaseEdit16(), "Merge with DB data"); + mm->addAction("All", this, &CMergeWithDbDataMenu::ps_mergeData); + if (mv->hasSelection()) + { + mm->addAction("Selected only", this, &CMergeWithDbDataMenu::ps_mergeSelectedData); + } + this->nestedCustomMenu(menu); + } + + void CMergeWithDbDataMenu::ps_mergeData() + { + Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui"); + CAircraftModelView *mv = modelView(); + if (mv->isEmpty()) { return; } + if (!sGui->hasWebDataServices()) { return; } + + const CAircraftModelList dbModels(sGui->getWebDataServices()->getModels()); + CAircraftModelList models(this->getAircraftModels()); + IAircraftModelLoader::mergeWithDbData(models, dbModels, true); + mv->updateContainerMaybeAsync(models); + if (this->m_loader) + { + this->m_loader->replaceCacheWithModelData(models); + } + } + + void CMergeWithDbDataMenu::ps_mergeSelectedData() + { + Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui"); + CAircraftModelView *mv = modelView(); + if (mv->isEmpty()) { return; } + if (!sGui->hasWebDataServices()) { return; } + + CAircraftModelList models(this->getSelectedAircraftModels()); + if (models.isEmpty()) { return; } + const CAircraftModelList dbModels(sGui->getWebDataServices()->getModels()); + + IAircraftModelLoader::mergeWithDbData(models, dbModels, true); + mv->replaceOrAddModelsWithString(models); + if (this->m_loader) + { + this->m_loader->replaceCacheWithModelData(models); + } + } + } // ns +} // ns diff --git a/src/blackgui/menus/aircraftmodelmenus.h b/src/blackgui/menus/aircraftmodelmenus.h new file mode 100644 index 000000000..e0a8624dc --- /dev/null +++ b/src/blackgui/menus/aircraftmodelmenus.h @@ -0,0 +1,88 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#ifndef BLACKGUI_MENUS_AIRCRAFTMODELMENUS_H +#define BLACKGUI_MENUS_AIRCRAFTMODELMENUS_H + +#include "menudelegate.h" +#include "blackgui/views/aircraftmodelview.h" +#include "blackmisc/simulation/aircraftmodelloader.h" +#include +#include + +namespace BlackGui +{ + namespace Menus + { + //! Menu base for aircraft model view menus + class IAircraftModelViewMenu : public IMenuDelegate + { + public: + //! Constructor + IAircraftModelViewMenu(BlackGui::Views::CAircraftModelView *modelView, bool separator = true) : + IMenuDelegate(modelView, separator) + {} + + protected: + //! Model view + BlackGui::Views::CAircraftModelView *modelView() const; + + //! Get aircraft models + const BlackMisc::Simulation::CAircraftModelList &getAircraftModels() const; + + //! Selected aircraft models + BlackMisc::Simulation::CAircraftModelList getSelectedAircraftModels() const; + }; + + //! Open the simulator file (e.g. aircraft.cfg) in the standard text editor + class CShowSimulatorFileMenu : public IAircraftModelViewMenu + { + Q_OBJECT + + public: + //! Constructor + using IAircraftModelViewMenu::IAircraftModelViewMenu; + + //! \copydoc IMenuDelegate::customMenu + virtual void customMenu(QMenu &menu) const override; + + private slots: + //! Open simulator file + void ps_showSimulatorFile() const; + }; + + //! Merge with DB data + class CMergeWithDbDataMenu : public IAircraftModelViewMenu + { + Q_OBJECT + + public: + //! Constructor + using IAircraftModelViewMenu::IAircraftModelViewMenu; + + //! Constructor + CMergeWithDbDataMenu(BlackGui::Views::CAircraftModelView *modelView, + BlackMisc::Simulation::IAircraftModelLoader *modelLoader, bool separator = true) : + IAircraftModelViewMenu(modelView, separator), m_loader(modelLoader) + {} + + //! \copydoc IMenuDelegate::customMenu + virtual void customMenu(QMenu &menu) const override; + + private slots: + void ps_mergeData(); + void ps_mergeSelectedData(); + + private: + BlackMisc::Simulation::IAircraftModelLoader *m_loader = nullptr; //!< optional loader + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/menus/menudelegate.h b/src/blackgui/menus/menudelegate.h new file mode 100644 index 000000000..3359972d1 --- /dev/null +++ b/src/blackgui/menus/menudelegate.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#ifndef BLACKGUI_MENUS_MENUDELEGATE_H +#define BLACKGUI_MENUS_MENUDELEGATE_H + +#include +#include + +namespace BlackGui +{ + namespace Menus + { + /*! + * Interface to implement a custom menu + */ + class IMenuDelegate : public QObject + { + Q_OBJECT + + public: + //! Display custom menu + virtual void customMenu(QMenu &menu) const = 0; + + //! Set nested delegate + void setNestedDelegate(IMenuDelegate *nestedDelegate) { m_nestedDelegate = nestedDelegate; } + + //! Nested delegate + IMenuDelegate *getNestedDelegate() const { return m_nestedDelegate; } + + //! Destructor + virtual ~IMenuDelegate() {} + + protected: + //! Constructor + IMenuDelegate(QWidget *parent = nullptr, bool separator = false) : + QObject(parent), m_separator(separator) {} + + //! Delegate down one level + void nestedCustomMenu(QMenu &menu) const + { + if (!m_nestedDelegate) { return; } + m_nestedDelegate->customMenu(menu); + } + + //! Add separator + void addSeparator(QMenu &menu) const + { + if (!m_separator || menu.isEmpty()) { return; } + menu.addSeparator(); + } + + IMenuDelegate *m_nestedDelegate = nullptr; //!< nested delegate if any + bool m_separator = false; //!< at end, terminate with separator + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index 57f3812d2..7f94c9193 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -31,6 +31,7 @@ using namespace BlackMisc; using namespace BlackGui; +using namespace BlackGui::Menus; using namespace BlackGui::Models; using namespace BlackGui::Filters; @@ -151,7 +152,7 @@ namespace BlackGui return this->ps_saveJson(); } - void CViewBaseNonTemplate::setCustomMenu(IMenuDelegate *menu, bool nestPreviousMenu) + IMenuDelegate *CViewBaseNonTemplate::setCustomMenu(IMenuDelegate *menu, bool nestPreviousMenu) { if (menu && nestPreviousMenu) { @@ -169,6 +170,7 @@ namespace BlackGui // no nesting m_menu = menu; } + return menu; } void CViewBaseNonTemplate::customMenu(QMenu &menu) const diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index 3617fcb8e..62a7ae8d8 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -16,7 +16,7 @@ #include "blackgui/filters/filterdialog.h" #include "blackgui/filters/filterwidget.h" #include "blackgui/models/modelfilter.h" -#include "blackgui/menudelegate.h" +#include "blackgui/menus/menudelegate.h" #include "blackgui/loadindicator.h" #include "blackgui/dropbase.h" #include "blackgui/blackguiexport.h" @@ -165,7 +165,7 @@ namespace BlackGui void setFilterWidget(BlackGui::Filters::CFilterWidget *filterWidget); //! Set custom menu if applicable - void setCustomMenu(BlackGui::IMenuDelegate *menu, bool nestPreviousMenu = true); + BlackGui::Menus::IMenuDelegate *setCustomMenu(BlackGui::Menus::IMenuDelegate *menu, bool nestPreviousMenu = true); //! Enable loading indicator void enableLoadIndicator(bool enable); @@ -323,7 +323,7 @@ namespace BlackGui bool m_enableDeleteSelectedRows = false; //!< selected rows can be deleted QWidget *m_filterWidget = nullptr; //!< filter widget or dialog Menu m_menus = MenuDefault; //!< Default menu settings - BlackGui::IMenuDelegate *m_menu = nullptr; //!< custom menu if any + BlackGui::Menus::IMenuDelegate *m_menu = nullptr; //!< custom menu if any BlackGui::CLoadIndicator *m_loadIndicator = nullptr; //!< load indicator if neeeded protected slots: