From dc8a052544ce9afd3a09d98da5c4d25da245de55 Mon Sep 17 00:00:00 2001 From: eelke Date: Tue, 1 Jan 2019 11:15:16 +0100 Subject: [PATCH] Basic concept of MenuAction is working Module can register action Window adds this action to its menu Clicking the menu item for the action has the expected result But menu structure still needs work (everything is now put into one dropdown menu) --- pglab/DatabaseWindow.cpp | 51 +++++++++++++++++++- pglab/DatabaseWindow.h | 26 +++++++++-- pglab/QueryTab.cpp | 14 ++++-- pglab/QueryTab.h | 4 +- pglab/main.cpp | 3 ++ pglab/pglab.pro | 6 ++- pglab/plugin_support/MenuAction.cpp | 62 +++++++++++++++++++++++-- pglab/plugin_support/MenuAction.h | 48 +++++++++++++++++-- pglab/plugin_support/PluginModule.cpp | 9 +++- pglab/plugin_support/PluginModule.h | 14 ++++-- pglab/plugin_support/PluginRegister.cpp | 7 +++ pglab/plugin_support/PluginRegister.h | 4 +- 12 files changed, 220 insertions(+), 28 deletions(-) diff --git a/pglab/DatabaseWindow.cpp b/pglab/DatabaseWindow.cpp index b073b7e..d48b0f5 100644 --- a/pglab/DatabaseWindow.cpp +++ b/pglab/DatabaseWindow.cpp @@ -65,17 +65,64 @@ namespace DatabaseWindow_details { using namespace DatabaseWindow_details; -DatabaseWindow::DatabaseWindow(MasterController *master, QWidget *parent) +LMainWindow::LMainWindow(QWidget *parent) : QMainWindow(parent) +{ + m_fileMenu = new QMenu("File T", this); + + +} + +void LMainWindow::initModuleMenus() +{ + menuBar()->addMenu(m_fileMenu); + addModuleMenuActions(); +} + +void LMainWindow::addModuleMenuActions() +{ + auto reg = PluginRegister::getInstance(); + auto mods = reg->modules(); + for (auto && mod : mods) { + auto items = mod.second->menuActions(); + for (auto && item : items) { + addMenuAction(item); + } + } +} + +void LMainWindow::addMenuAction(const MenuAction &ma) +{ + qDebug() << "add action " << ma.text(); + //auto ac = + m_fileMenu->addAction(ma.icon(), ma.text(), + [ma, this] () + { + ma.perform(m_context); + }, + ma.shortCut()); + + +// auto ac = new QAction(this); +// ac-> + + +} + +DatabaseWindow::DatabaseWindow(MasterController *master, QWidget *parent) + : LMainWindow(parent) , ui(new Ui::DatabaseWindow) - , m_context(new DatabaseWindowContentContext(this)) , m_masterController(master) { ui->setupUi(this); ui->tabWidget->setDocumentMode(true); + m_context = new DatabaseWindowContentContext(this); + connect(&loadWatcher, &QFutureWatcher::finished, this, &DatabaseWindow::catalogLoaded); + + initModuleMenus(); } DatabaseWindow::~DatabaseWindow() diff --git a/pglab/DatabaseWindow.h b/pglab/DatabaseWindow.h index 3c30a82..2bd8bd1 100644 --- a/pglab/DatabaseWindow.h +++ b/pglab/DatabaseWindow.h @@ -30,6 +30,7 @@ namespace Pgsql { class Connection; } +class MenuAction; class QueryTab; class MasterController; class QCloseEvent; @@ -41,13 +42,33 @@ namespace DatabaseWindow_details { class DatabaseWindowContentContext; } +class LMainWindow : public QMainWindow { + Q_OBJECT +public: + + LMainWindow(QWidget *parent = nullptr); + + void initModuleMenus(); +protected: + + DatabaseWindow_details::DatabaseWindowContentContext *m_context; + + void addModuleMenuActions(); + +private: + QMenu *m_fileMenu = nullptr; + + void addMenuAction(const MenuAction &ma); +}; + + /** This is the class for windows that handle tasks for a specific database/catalog * */ -class DatabaseWindow : public QMainWindow { +class DatabaseWindow : public LMainWindow { Q_OBJECT public: - explicit DatabaseWindow(MasterController *master, QWidget *parent); + DatabaseWindow(MasterController *master, QWidget *parent); ~DatabaseWindow(); void setConfig(const ConnectionConfig &config); @@ -64,7 +85,6 @@ public: private: Ui::DatabaseWindow *ui; - DatabaseWindow_details::DatabaseWindowContentContext *m_context; ConnectionConfig m_config; std::shared_ptr m_database; diff --git a/pglab/QueryTab.cpp b/pglab/QueryTab.cpp index a2db049..5331d4d 100644 --- a/pglab/QueryTab.cpp +++ b/pglab/QueryTab.cpp @@ -674,14 +674,18 @@ std::vector QueryTab::getToolbarActions() void QueryToolModule::init() { - auto action_new = new QAction(QIcon(":/icons/new_query_tab.png"), tr("New"), this); - connect(action_new, &QAction::triggered, this, &QueryToolModule::new_triggered); - - registerAction(action_new, MenuLocation({"File/New"}), ToolbarLocation("File", "")); + MenuAction ma_new("New", [this] (IPluginContentWidgetContext* context) + { menuAction_new(context); }); + ma_new.setMenuLocation(MenuPath("File/New")); + ma_new.setIcon(QIcon(":/icons/new_query_tab.png")); + registerMenuAction(ma_new); } -void QueryToolModule::new_triggered() +void QueryToolModule::menuAction_new(IPluginContentWidgetContext* context) { + auto *ct = new QueryTab(context, nullptr); + context->addContentWidget(ct); + ct->newdoc(); } REGISTER_PLUGIN_MODULE(QueryToolModule, "Query tool", "pglab.querytool") diff --git a/pglab/QueryTab.h b/pglab/QueryTab.h index 70bcee4..abcd7ef 100644 --- a/pglab/QueryTab.h +++ b/pglab/QueryTab.h @@ -117,9 +117,9 @@ class QueryToolModule: public PluginModule { public: using PluginModule::PluginModule; - void init(); + void init() override; + void menuAction_new(IPluginContentWidgetContext* context); private slots: - void new_triggered(); }; #endif // QUERYTAB_H diff --git a/pglab/main.cpp b/pglab/main.cpp index 38482a6..a78a29c 100644 --- a/pglab/main.cpp +++ b/pglab/main.cpp @@ -5,6 +5,7 @@ #endif #include #include "GlobalIoService.h" +#include "plugin_support/PluginRegister.h" int main(int argc, char *argv[]) { @@ -29,6 +30,8 @@ int main(int argc, char *argv[]) QCoreApplication::setOrganizationDomain("eelkeklein.nl"); QCoreApplication::setApplicationName("pglab"); + PluginRegister::getInstance()->initModules(); + std::thread asio_service_thread; int result = -1; { diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 652a3e8..dfffeff 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -87,7 +87,8 @@ PropertyProxyModel.cpp \ plugin_support/ToolbarLocation.cpp \ plugin_support/PluginRegister.cpp \ plugin_support/PluginContentWidget.cpp \ - plugin_support/PluginContentWidgetContextBase.cpp + plugin_support/PluginContentWidgetContextBase.cpp \ + plugin_support/MenuAction.cpp HEADERS += \ QueryResultModel.h \ @@ -154,7 +155,8 @@ CustomDataRole.h \ plugin_support/PluginContentWidget.h \ plugin_support/ModuleActionParameters.h \ plugin_support/IPluginContentWidgetContext.h \ - plugin_support/PluginContentWidgetContextBase.h + plugin_support/PluginContentWidgetContextBase.h \ + plugin_support/MenuAction.h FORMS += \ ConnectionManagerWindow.ui \ diff --git a/pglab/plugin_support/MenuAction.cpp b/pglab/plugin_support/MenuAction.cpp index 87199e2..a53a0c7 100644 --- a/pglab/plugin_support/MenuAction.cpp +++ b/pglab/plugin_support/MenuAction.cpp @@ -1,6 +1,62 @@ -#include "MenuAction.h" +#include "MenuAction.h" -MenuAction::MenuAction() +MenuAction::MenuAction(QString text, Func func) + : m_text(std::move(text)) + , m_func(std::move(func)) +{} + +const QIcon& MenuAction::icon() const { - + return m_icon; +} + +const MenuLocation& MenuAction::menuLocation() const +{ + return m_menuLocation; +} + +void MenuAction::setIcon(QIcon icon) +{ + m_icon = std::move(icon); +} + +void MenuAction::setMenuLocation(MenuLocation menu_location) +{ + m_menuLocation = std::move(menu_location); +} + +void MenuAction::setShortCut(QKeySequence shortcut) +{ + m_shortCut = std::move(shortcut); +} + +void MenuAction::setText(QString text) +{ + m_text = std::move(text); +} + +void MenuAction::setToolTip(QString tooltip) +{ + m_toolTip = std::move(tooltip); +} + +const QKeySequence& MenuAction::shortCut() const +{ + return m_shortCut; +} + +const QString& MenuAction::text() const +{ + return m_text; +} + +const QString& MenuAction::toolTip() const +{ + return m_toolTip; +} + +void MenuAction::perform(IPluginContentWidgetContext *context) const +{ + if (m_func) + m_func(context); } diff --git a/pglab/plugin_support/MenuAction.h b/pglab/plugin_support/MenuAction.h index 95409c5..21ff9ee 100644 --- a/pglab/plugin_support/MenuAction.h +++ b/pglab/plugin_support/MenuAction.h @@ -1,11 +1,49 @@ -#ifndef MENUACTION_H +#ifndef MENUACTION_H #define MENUACTION_H +#include "MenuLocation.h" +#include "ToolbarLocation.h" -class MenuAction -{ +#include +#include +#include +#include + +class QAction; +class IPluginContentWidgetContext; + +/** An action for in a menu or toolbar that does not pertain to a specific + * widget. It often will create a widget for instance a New or Open action. + * It does need a context. + * + */ +class MenuAction { public: - MenuAction(); + using Func = std::function; + + MenuAction(QString text, Func func); + + const QIcon& icon() const; + const MenuLocation& menuLocation() const; + void setIcon(QIcon icon); + void setMenuLocation(MenuLocation menu_location); + void setShortCut(QKeySequence shortcut); + void setText(QString text); + void setToolTip(QString tooltip); + const QKeySequence& shortCut() const; + const QString& text() const; + const QString& toolTip() const; + + void perform(IPluginContentWidgetContext *context) const; +private: + QString m_text; + QString m_toolTip; + QIcon m_icon; + QKeySequence m_shortCut; + MenuLocation m_menuLocation; + + Func m_func; }; -#endif // MENUACTION_H \ No newline at end of file + +#endif // MENUACTION_H diff --git a/pglab/plugin_support/PluginModule.cpp b/pglab/plugin_support/PluginModule.cpp index a9e9ec7..045604a 100644 --- a/pglab/plugin_support/PluginModule.cpp +++ b/pglab/plugin_support/PluginModule.cpp @@ -1,4 +1,5 @@ #include "plugin_support/PluginModule.h" +#include PluginModule::PluginModule(QString name, QString ident) : m_name(std::move(name)) @@ -11,9 +12,15 @@ void PluginModule::setDisplayCategory(QString category) m_displayCategory = std::move(category); } -void PluginModule::registerAction(QAction *action, MenuLocation menu_location, ToolbarLocation toolbar_location) +void PluginModule::registerMenuAction(MenuAction action) { + qDebug() << "registerMenuAction " << action.text(); + m_menuActions.emplace_back(std::move(action)); +} +const PluginModule::MenuActionList& PluginModule::menuActions() const +{ + return m_menuActions; } void PluginModule::registerModuleAction(QString module_action, ModuleAction action) diff --git a/pglab/plugin_support/PluginModule.h b/pglab/plugin_support/PluginModule.h index c5aa8a0..e069246 100644 --- a/pglab/plugin_support/PluginModule.h +++ b/pglab/plugin_support/PluginModule.h @@ -1,13 +1,13 @@ #ifndef PLUGIN_SUPPORTPLUGINMODULE_H #define PLUGIN_SUPPORTPLUGINMODULE_H -#include "MenuLocation.h" -#include "ToolbarLocation.h" #include "ModuleActionParameters.h" +#include "MenuAction.h" #include "PluginRegister.h" #include #include #include +#include class QAction; class IPluginContentWidgetContext; @@ -15,17 +15,23 @@ class IPluginContentWidgetContext; class PluginModule: public QObject { Q_OBJECT public: + using MenuActionList = std::vector; using ModuleAction = std::function; using ModuleActionMap = std::map; PluginModule(QString name, QString ident); + virtual void init() {}; + const QString& name() const { return m_name; } const QString& identifier() const { return m_ident; } const QString& displayCategory() const { return m_displayCategory; } void setDisplayCategory(QString category); - void registerAction(QAction *action, MenuLocation menu_location, ToolbarLocation toolbar_location); + + /// registers an action that should always be accessible from the menu + void registerMenuAction(MenuAction action); + const MenuActionList& menuActions() const; void registerModuleAction(QString module_action, ModuleAction action); @@ -39,6 +45,7 @@ private: QString m_ident; QString m_displayCategory; + MenuActionList m_menuActions; ModuleActionMap m_moduleActions; }; @@ -47,7 +54,6 @@ template std::shared_ptr createPluginModule(QString name, QString ident) { auto module = std::make_shared(std::move(name), std::move(ident)); - module->init(); PluginRegister::getInstance()->registerModule(module); return std::move(module); diff --git a/pglab/plugin_support/PluginRegister.cpp b/pglab/plugin_support/PluginRegister.cpp index 342a691..f80791c 100644 --- a/pglab/plugin_support/PluginRegister.cpp +++ b/pglab/plugin_support/PluginRegister.cpp @@ -23,6 +23,13 @@ PluginRegister* PluginRegister::getInstance() PluginRegister::PluginRegister() = default; +void PluginRegister::initModules() +{ + for (auto && mod : m_moduleMap) { + mod.second->init(); + } +} + void PluginRegister::registerModule(PluginModuleSPtr module) { m_moduleMap.emplace(module->identifier(), module); diff --git a/pglab/plugin_support/PluginRegister.h b/pglab/plugin_support/PluginRegister.h index 3bd43a7..cc8449a 100644 --- a/pglab/plugin_support/PluginRegister.h +++ b/pglab/plugin_support/PluginRegister.h @@ -18,7 +18,9 @@ public: PluginRegister(); void registerModule(PluginModuleSPtr module); - const ModuleMap& modules() const { return m_moduleMap; } + + void initModules(); + const ModuleMap& modules() const{ return m_moduleMap; } const PluginModule* findModule(const QString &module_ident) const; private: