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: