From f4f2474a818714a901b07230b68fc06e716fa2e9 Mon Sep 17 00:00:00 2001 From: eelke Date: Sat, 5 Jan 2019 19:58:23 +0100 Subject: [PATCH] Moved definition of widget instance actions to the module so other parts of the system can no about them. The plugin system will create the Action objects and bind them to the specified slots of the specific widget instances. --- pglab/CodeGenerator.cpp | 3 - pglab/CrudTab.cpp | 23 +-- pglab/CrudTab.h | 4 +- pglab/{QueryTab.cpp => QueryTool.cpp} | 169 +++++------------- pglab/{QueryTab.h => QueryTool.h} | 27 +-- pglab/QueryToolModule.cpp | 85 +++++++++ pglab/QueryToolModule.h | 18 ++ pglab/pglab.pro | 12 +- .../IPluginContentWidgetContext.h | 6 +- pglab/plugin_support/LMainWindow.cpp | 26 ++- pglab/plugin_support/LMainWindow.h | 4 +- pglab/plugin_support/LWidgetAction.cpp | 56 ++++++ pglab/plugin_support/LWidgetAction.h | 42 +++++ pglab/plugin_support/MenuAction.cpp | 8 +- pglab/plugin_support/MenuAction.h | 7 +- pglab/plugin_support/PluginContentWidget.cpp | 9 +- pglab/plugin_support/PluginContentWidget.h | 2 +- .../PluginContentWidgetContextBase.cpp | 78 +++++++- .../PluginContentWidgetContextBase.h | 31 ++++ pglab/plugin_support/PluginModule.cpp | 1 + pglab/plugin_support/PluginModule.h | 11 +- 21 files changed, 418 insertions(+), 204 deletions(-) rename pglab/{QueryTab.cpp => QueryTool.cpp} (77%) rename pglab/{QueryTab.h => QueryTool.h} (81%) create mode 100644 pglab/QueryToolModule.cpp create mode 100644 pglab/QueryToolModule.h create mode 100644 pglab/plugin_support/LWidgetAction.cpp create mode 100644 pglab/plugin_support/LWidgetAction.h diff --git a/pglab/CodeGenerator.cpp b/pglab/CodeGenerator.cpp index 0d74aa6..3c2841e 100644 --- a/pglab/CodeGenerator.cpp +++ b/pglab/CodeGenerator.cpp @@ -27,11 +27,8 @@ void CodeGenerator::Init(std::shared_ptr catalog, QString que m_query = std::move(query); m_dbres = std::move(dbres); generateCode(); - - } - void CodeGenerator::on_updateCodeButton_clicked() { generateCode(); diff --git a/pglab/CrudTab.cpp b/pglab/CrudTab.cpp index d1b46a0..b0b0cf0 100644 --- a/pglab/CrudTab.cpp +++ b/pglab/CrudTab.cpp @@ -93,19 +93,6 @@ void CrudTab::on_actionRemove_rows_triggered() } } -std::vector CrudTab::getToolbarActions() -{ - if (actions.empty()) { - QAction *action = new QAction(QIcon(":/icons/script_go.png"), tr("Refresh"), this); - action->setShortcut(QKeySequence(Qt::Key_F5)); - connect(action, &QAction::triggered, this, &CrudTab::refresh); - actions.push_back(action); - - actions.push_back(ui->actionRemove_rows); - } - return actions; -} - void CrudTab::headerCustomContextMenu(const QPoint &pos) { auto menu = new QMenu(this); @@ -128,6 +115,14 @@ void CrudPageModule::init() { moduleAction_open(context, params); }); + + { + LWidgetAction wa("Refresh", SLOT(refresh())); + wa.setMenuLocation(MenuPath("Window/1")); + wa.setIcon(QIcon(":/icons/script_go.png")); + wa.setShortcut(QKeySequence(Qt::Key_F5)); + registerWidgetAction(wa); + } } void CrudPageModule::moduleAction_open( @@ -138,7 +133,7 @@ void CrudPageModule::moduleAction_open( // create new widget for specified table // hand widget to context for display CrudTab *ct = new CrudTab(context, nullptr); - context->addContentWidget(ct); // maybe CrudTab should do this + context->addContentWidget(this, ct); // maybe CrudTab should do this ct->setConfig(params.at("oid").toUInt()); } diff --git a/pglab/CrudTab.h b/pglab/CrudTab.h index 76628ee..d20e4af 100644 --- a/pglab/CrudTab.h +++ b/pglab/CrudTab.h @@ -24,10 +24,8 @@ public: ~CrudTab() override; void setConfig(Oid oid); - +public slots: void refresh(); - - virtual std::vector getToolbarActions() override; private: Ui::CrudTab *ui; diff --git a/pglab/QueryTab.cpp b/pglab/QueryTool.cpp similarity index 77% rename from pglab/QueryTab.cpp rename to pglab/QueryTool.cpp index 5eaea0a..b03dfdb 100644 --- a/pglab/QueryTab.cpp +++ b/pglab/QueryTool.cpp @@ -1,12 +1,10 @@ - -#include "QueryTab.h" +#include "QueryTool.h" #include "ui_QueryTab.h" #include "SqlSyntaxHighlighter.h" #include #include #include #include -#include #include #include #include @@ -22,9 +20,9 @@ #include "GlobalIoService.h" #include "UserConfiguration.h" #include "plugin_support/IPluginContentWidgetContext.h" -#include "plugin_support/PluginRegister.h" -QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent) + +QueryTool::QueryTool(IPluginContentWidgetContext *context_, QWidget *parent) : PluginContentWidget(context_, parent) , ui(new Ui::QueryTab) , m_dbConnection(*getGlobalAsioIoService()) @@ -35,8 +33,8 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent) m_config = db->config(); m_catalog = db->catalog(); - connect(&m_dbConnection, &ASyncDBConnection::onStateChanged, this, &QueryTab::connectionStateChanged); - connect(&m_dbConnection, &ASyncDBConnection::onNotice, this, &QueryTab::receiveNotice); + connect(&m_dbConnection, &ASyncDBConnection::onStateChanged, this, &QueryTool::connectionStateChanged); + connect(&m_dbConnection, &ASyncDBConnection::onNotice, this, &QueryTool::receiveNotice); ui->queryEdit->setFont(UserConfiguration::instance()->codeFont()); @@ -47,7 +45,7 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent) highlighter->setTypes(*cat->types()); } - connect(ui->queryEdit, &QPlainTextEdit::textChanged, this, &QueryTab::queryTextChanged); + connect(ui->queryEdit, &QPlainTextEdit::textChanged, this, &QueryTool::queryTextChanged); m_queryParamListController = new QueryParamListController(ui->paramTableView, open_database, this); connect(ui->addButton, &QPushButton::clicked, m_queryParamListController, @@ -58,12 +56,12 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent) startConnect(); } -QueryTab::~QueryTab() +QueryTool::~QueryTool() { delete ui; } -bool QueryTab::canClose() +bool QueryTool::canClose() { bool can_close; if (m_queryTextChanged) { @@ -75,7 +73,7 @@ bool QueryTab::canClose() return can_close; } -void QueryTab::newdoc() +void QueryTool::newdoc() { ui->queryEdit->clear(); setFileName(tr("new")); @@ -83,7 +81,7 @@ void QueryTab::newdoc() m_new = true; } -bool QueryTab::load(const QString &filename) +bool QueryTool::load(const QString &filename) { bool result = false; QFile file(filename); @@ -109,7 +107,7 @@ bool QueryTab::load(const QString &filename) return result; } -bool QueryTab::save() +bool QueryTool::save() { bool result; if (m_fileName.isEmpty() || m_new) { @@ -121,7 +119,7 @@ bool QueryTab::save() return result; } -bool QueryTab::saveAs() +bool QueryTool::saveAs() { bool result = false; QString filename = promptUserForSaveSqlFilename(); @@ -135,7 +133,7 @@ bool QueryTab::saveAs() return result; } -void QueryTab::saveCopyAs() +void QueryTool::saveCopyAs() { QString filename = promptUserForSaveSqlFilename(); if (!filename.isEmpty()) { @@ -143,7 +141,7 @@ void QueryTab::saveCopyAs() } } -void QueryTab::execute() +void QueryTool::execute() { if (m_dbConnection.state() == ASyncDBConnection::State::Connected) { addLog("Query clicked"); @@ -175,7 +173,17 @@ void QueryTab::execute() } } -void QueryTab::explain(bool analyze) +void QueryTool::explain() +{ + explain(false); +} + +void QueryTool::analyze() +{ + explain(true); +} + +void QueryTool::explain(bool analyze) { ui->explainTreeView->setModel(nullptr); explainModel.reset(); @@ -221,13 +229,13 @@ void QueryTab::explain(bool analyze) m_dbConnection.send(cmd, m_queryParamListController->params(), cb); } -void QueryTab::cancel() +void QueryTool::cancel() { m_dbConnection.cancel(); } -void QueryTab::setFileName(const QString &filename) +void QueryTool::setFileName(const QString &filename) { m_fileName = filename; QFileInfo fileInfo(filename); @@ -235,7 +243,7 @@ void QueryTab::setFileName(const QString &filename) context()->setCaption(this, fn, m_fileName); } -bool QueryTab::continueWithoutSavingWarning() +bool QueryTool::continueWithoutSavingWarning() { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); @@ -254,7 +262,7 @@ bool QueryTab::continueWithoutSavingWarning() return ret != QMessageBox::Cancel; } -bool QueryTab::saveSqlTo(const QString &filename) +bool QueryTool::saveSqlTo(const QString &filename) { bool result = false; QFileInfo fileinfo(filename); @@ -277,19 +285,19 @@ bool QueryTab::saveSqlTo(const QString &filename) } -QString QueryTab::promptUserForSaveSqlFilename() +QString QueryTool::promptUserForSaveSqlFilename() { QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory); return QFileDialog::getSaveFileName(this, tr("Save query"), home_dir, tr("SQL file (*.sql)")); } -void QueryTab::queryTextChanged() +void QueryTool::queryTextChanged() { m_queryTextChanged = true; } -void QueryTab::connectionStateChanged(ASyncDBConnection::State state) +void QueryTool::connectionStateChanged(ASyncDBConnection::State state) { QString iconname; switch (state) { @@ -311,14 +319,14 @@ void QueryTab::connectionStateChanged(ASyncDBConnection::State state) } -void QueryTab::addLog(QString s) +void QueryTool::addLog(QString s) { QTextCursor text_cursor = QTextCursor(ui->edtLog->document()); text_cursor.movePosition(QTextCursor::End); text_cursor.insertText(s + "\r\n"); } -void QueryTab::receiveNotice(Pgsql::ErrorDetails notice) +void QueryTool::receiveNotice(Pgsql::ErrorDetails notice) { ui->messagesEdit->append(QString::fromStdString(notice.errorMessage)); @@ -365,12 +373,12 @@ void QueryTab::receiveNotice(Pgsql::ErrorDetails notice) // statementPosition } -void QueryTab::startConnect() +void QueryTool::startConnect() { m_dbConnection.setupConnection(m_config); } -void QueryTab::explain_ready(ExplainRoot::SPtr explain) +void QueryTool::explain_ready(ExplainRoot::SPtr explain) { m_stopwatch.stop(); if (explain) { @@ -405,7 +413,7 @@ void QueryTab::explain_ready(ExplainRoot::SPtr explain) } } -QString QueryTab::getCommand() const +QString QueryTool::getCommand() const { QString command; QTextCursor cursor = ui->queryEdit->textCursor(); @@ -418,7 +426,7 @@ QString QueryTab::getCommand() const return command; } -std::string QueryTab::getCommandUtf8() const +std::string QueryTool::getCommandUtf8() const { return getCommand().toUtf8().data(); } @@ -444,7 +452,7 @@ std::string QueryTab::getCommandUtf8() const //} -void QueryTab::query_ready(std::shared_ptr dbres, qint64 elapsedms) +void QueryTool::query_ready(std::shared_ptr dbres, qint64 elapsedms) { if (dbres) { addLog("query_ready with result"); @@ -520,7 +528,7 @@ void QueryTab::query_ready(std::shared_ptr dbres, qint64 elapsedm } } -void QueryTab::markError(const Pgsql::ErrorDetails &details) +void QueryTool::markError(const Pgsql::ErrorDetails &details) { if (details.statementPosition > 0) { QTextCursor cursor = ui->queryEdit->textCursor(); @@ -561,14 +569,14 @@ void QueryTab::markError(const Pgsql::ErrorDetails &details) } } -void QueryTab::clearResult() +void QueryTool::clearResult() { for (auto e : resultList) delete e; resultList.clear(); } -void QueryTab::copyQueryAsCString() +void QueryTool::copyQueryAsCString() { // QString command; // QTextCursor cursor = ui->queryEdit->textCursor(); @@ -586,7 +594,7 @@ void QueryTab::copyQueryAsCString() #include #include -void QueryTab::copyQueryAsRawCppString() +void QueryTool::copyQueryAsRawCppString() { QString command = getCommand(); //auto sql = getAllOrSelectedSql(); @@ -594,7 +602,7 @@ void QueryTab::copyQueryAsRawCppString() QApplication::clipboard()->setText(cs); } -void QueryTab::generateCode() +void QueryTool::generateCode() { QString command = getCommand(); @@ -607,7 +615,7 @@ void QueryTab::generateCode() } } -void QueryTab::exportData(const QString &file_name) +void QueryTool::exportData(const QString &file_name) { auto widget = ui->tabWidget->currentWidget(); auto fi = std::find(resultList.begin(), resultList.end(), widget); @@ -617,92 +625,7 @@ void QueryTab::exportData(const QString &file_name) } } -void QueryTab::focusEditor() +void QueryTool::focusEditor() { ui->queryEdit->setFocus(); } - - -std::vector QueryTab::getToolbarActions() -{ - if (actions.empty()) { - QAction *action; - // Save - action = new QAction(QIcon(":/icons/script_save.png"), tr("Save SQL"), this); - action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S)); - connect(action, &QAction::triggered, this, &QueryTab::save); - actions.push_back(action); - // Save as (menu only) - action = new QAction(QIcon(":/icons/script_save.png"), tr("Save SQL as"), this); - connect(action, &QAction::triggered, this, &QueryTab::saveAs); - actions.push_back(action); - // Save copy as - // Copy - // Copy as C-string - // Copy as raw cpp string - // Execute SQL - action = new QAction(QIcon(":/icons/script_go.png"), tr("Execute"), this); - action->setShortcut(QKeySequence(Qt::Key_F5)); - //connect(action, &QAction::triggered, this, &QueryTab::execute); - std::string slot_name = SLOT(execute()); - connect(action, SIGNAL(triggered()), this, slot_name.c_str()); - actions.push_back(action); - // Explain - action = new QAction(QIcon(":/icons/lightbulb_off.png"), tr("Explain"), this); - action->setShortcut(QKeySequence(Qt::Key_F7)); - connect(action, &QAction::triggered, this, [this] () { explain(false); }); - actions.push_back(action); - // Explain Anaylze - action = new QAction(QIcon(":/icons/lightbulb.png"), tr("Analyze"), this); - action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F7)); - connect(action, &QAction::triggered, this, [this] () { explain(true); }); - actions.push_back(action); - // Cancel - action = new QAction(QIcon(":/icons/script_delete.png"), tr("Cancel"), this); - action->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Pause)); - connect(action, &QAction::triggered, this, &QueryTab::cancel); - actions.push_back(action); - } - return actions; -} - - -void QueryToolModule::init() -{ - { - MenuAction ma("New SQL", [this] (IPluginContentWidgetContext* context) - { menuAction_new(context); }); - ma.setMenuLocation(MenuPath("File/New")); - ma.setIcon(QIcon(":/icons/new_query_tab.png")); - ma.setShortCut(QKeySequence(Qt::CTRL + Qt::Key_N)); - registerMenuAction(ma); - } - { - MenuAction ma("Open SQL", [this] (IPluginContentWidgetContext* context) - { menuAction_open(context); }); - ma.setMenuLocation(MenuPath("File/Open")); - ma.setIcon(QIcon(":/icons/folder.png")); - registerMenuAction(ma); - } -} - -void QueryToolModule::menuAction_new(IPluginContentWidgetContext* context) -{ - auto *ct = new QueryTab(context, nullptr); - context->addContentWidget(ct); - ct->newdoc(); -} - -void QueryToolModule::menuAction_open(IPluginContentWidgetContext* context) -{ - QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory); - QString file_name = QFileDialog::getOpenFileName(context->container(), - tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)")); - if ( ! file_name.isEmpty()) { - auto *ct = new QueryTab(context, nullptr); - context->addContentWidget(ct); - ct->load(file_name); - } -} - -REGISTER_PLUGIN_MODULE(QueryToolModule, "Query tool", "pglab.querytool") diff --git a/pglab/QueryTab.h b/pglab/QueryTool.h similarity index 81% rename from pglab/QueryTab.h rename to pglab/QueryTool.h index 65dca0c..8a30cb8 100644 --- a/pglab/QueryTab.h +++ b/pglab/QueryTool.h @@ -9,7 +9,6 @@ #include #include "plugin_support/PluginContentWidget.h" -#include "plugin_support/PluginModule.h" #include namespace Ui { @@ -32,20 +31,17 @@ class OpenDatabase; class QueryParamListController; class PgDatabaseCatalog; -class QueryTab : public PluginContentWidget { +class QueryTool : public PluginContentWidget { Q_OBJECT public: - QueryTab(IPluginContentWidgetContext *context, QWidget *parent = nullptr); - ~QueryTab() override; + QueryTool(IPluginContentWidgetContext *context, QWidget *parent = nullptr); + ~QueryTool() override; void newdoc(); bool load(const QString &filename); - bool save(); - bool saveAs(); void saveCopyAs(); void explain(bool analyze); - void cancel(); bool canClose() override; @@ -59,9 +55,13 @@ public: bool isNew() const { return m_new; } void focusEditor(); - virtual std::vector getToolbarActions() override; public slots: void execute(); + bool save(); + bool saveAs(); + void explain(); + void analyze(); + void cancel(); private: using ResultTabContainer = std::vector; @@ -70,7 +70,6 @@ private: SqlSyntaxHighlighter* highlighter; ConnectionConfig m_config; StopWatch m_stopwatch; - std::vector actions; QueryParamListController *m_queryParamListController = nullptr; @@ -113,15 +112,5 @@ private slots: void startConnect(); }; -class QueryToolModule: public PluginModule { - Q_OBJECT -public: - using PluginModule::PluginModule; - - void init() override; - void menuAction_new(IPluginContentWidgetContext* context); - void menuAction_open(IPluginContentWidgetContext* context); -private slots: -}; #endif // QUERYTAB_H diff --git a/pglab/QueryToolModule.cpp b/pglab/QueryToolModule.cpp new file mode 100644 index 0000000..6be8ec9 --- /dev/null +++ b/pglab/QueryToolModule.cpp @@ -0,0 +1,85 @@ +#include "QueryToolModule.h" +#include "QueryTool.h" +#include "plugin_support/IPluginContentWidgetContext.h" +#include "plugin_support/PluginRegister.h" + +#include +#include + +void QueryToolModule::init() +{ + std::string slot_name = SLOT(QueryTool::execute()); + { + MenuAction ma("New SQL", [this] (IPluginContentWidgetContext* context) + { menuAction_new(context); }); + ma.setMenuLocation(MenuPath("File/New")); + ma.setIcon(QIcon(":/icons/new_query_tab.png")); + ma.setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N)); + registerMenuAction(ma); + } + { + MenuAction ma("Open SQL", [this] (IPluginContentWidgetContext* context) + { menuAction_open(context); }); + ma.setMenuLocation(MenuPath("File/Open")); + ma.setIcon(QIcon(":/icons/folder.png")); + registerMenuAction(ma); + } + { + LWidgetAction wa("Save SQL", SLOT(save())); + wa.setMenuLocation(MenuPath("File/Save")); + wa.setIcon(QIcon(":/icons/script_save.png")); + wa.setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S)); + registerWidgetAction(wa); + } + { + LWidgetAction wa("Save SQL as", SLOT(saveAs())); + wa.setMenuLocation(MenuPath("File/Save")); + wa.setIcon(QIcon(":/icons/script_save.png")); + registerWidgetAction(wa); + } + { + LWidgetAction wa("Execute", SLOT(execute())); + wa.setMenuLocation(MenuPath("Query/1")); + wa.setIcon(QIcon(":/icons/script_go.png")); + registerWidgetAction(wa); + } + { + LWidgetAction wa("Explain", SLOT(explain())); + wa.setMenuLocation(MenuPath("Query/2")); + wa.setIcon(QIcon(":/icons/lightbulb_off.png")); + registerWidgetAction(wa); + } + { + LWidgetAction wa("Analyze", SLOT(analyze())); + wa.setMenuLocation(MenuPath("Query/1")); + wa.setIcon(QIcon(":/icons/lightbulb.png")); + registerWidgetAction(wa); + } + { + LWidgetAction wa("Cancel", SLOT(cancel())); + wa.setMenuLocation(MenuPath("Query/1")); + wa.setIcon(QIcon(":/icons/script_delete.png")); + registerWidgetAction(wa); + } +} + +void QueryToolModule::menuAction_new(IPluginContentWidgetContext* context) +{ + auto *ct = new QueryTool(context, nullptr); + context->addContentWidget(this, ct); + ct->newdoc(); +} + +void QueryToolModule::menuAction_open(IPluginContentWidgetContext* context) +{ + QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory); + QString file_name = QFileDialog::getOpenFileName(context->container(), + tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)")); + if ( ! file_name.isEmpty()) { + auto *ct = new QueryTool(context, nullptr); + context->addContentWidget(this, ct); + ct->load(file_name); + } +} + +REGISTER_PLUGIN_MODULE(QueryToolModule, "Query tool", "pglab.querytool") diff --git a/pglab/QueryToolModule.h b/pglab/QueryToolModule.h new file mode 100644 index 0000000..bc77101 --- /dev/null +++ b/pglab/QueryToolModule.h @@ -0,0 +1,18 @@ +#ifndef QUERYTOOLMODULE_H +#define QUERYTOOLMODULE_H + +#include "plugin_support/PluginModule.h" + +class QueryToolModule: public PluginModule { + Q_OBJECT +public: + using PluginModule::PluginModule; + + void init() override; + void menuAction_new(IPluginContentWidgetContext* context); + void menuAction_open(IPluginContentWidgetContext* context); +private slots: +}; + + +#endif // QUERYTOOLMODULE_H diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 39ae9bd..02a678d 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -32,7 +32,6 @@ SOURCES += main.cpp\ ConnectionManagerWindow.cpp \ ConnectionListModel.cpp \ BackupRestore.cpp \ - QueryTab.cpp \ stopwatch.cpp \ TuplesResultWidget.cpp \ BackupDialog.cpp \ @@ -89,7 +88,10 @@ PropertyProxyModel.cpp \ plugin_support/PluginContentWidget.cpp \ plugin_support/PluginContentWidgetContextBase.cpp \ plugin_support/MenuAction.cpp \ - plugin_support/LMainWindow.cpp + plugin_support/LMainWindow.cpp \ + plugin_support/LWidgetAction.cpp \ + QueryTool.cpp \ + QueryToolModule.cpp HEADERS += \ QueryResultModel.h \ @@ -97,7 +99,6 @@ HEADERS += \ CreateDatabaseDialog.h \ ConnectionManagerWindow.h \ ConnectionListModel.h \ - QueryTab.h \ stopwatch.h \ TuplesResultWidget.h \ BackupDialog.h \ @@ -158,7 +159,10 @@ CustomDataRole.h \ plugin_support/IPluginContentWidgetContext.h \ plugin_support/PluginContentWidgetContextBase.h \ plugin_support/MenuAction.h \ - plugin_support/LMainWindow.h + plugin_support/LMainWindow.h \ + plugin_support/LWidgetAction.h \ + QueryTool.h \ + QueryToolModule.h FORMS += \ ConnectionManagerWindow.ui \ diff --git a/pglab/plugin_support/IPluginContentWidgetContext.h b/pglab/plugin_support/IPluginContentWidgetContext.h index 1bef7cb..c976ce9 100644 --- a/pglab/plugin_support/IPluginContentWidgetContext.h +++ b/pglab/plugin_support/IPluginContentWidgetContext.h @@ -8,8 +8,10 @@ #include "plugin_support/ModuleActionParameters.h" class OpenDatabase; +class PluginModule; class PluginContentWidget; + /** This class serves to isolate the plugin from the actual construct in which it is * used. * @@ -45,7 +47,8 @@ public: const ModuleActionParameters &action_params ) = 0; - virtual void addContentWidget(PluginContentWidget *widget) = 0; + virtual void addContentWidget(PluginModule *module, PluginContentWidget *widget) = 0; + virtual void removeContentWidget(PluginContentWidget *widget) = 0; /** Return a widget you can use as a parent */ @@ -57,6 +60,7 @@ public: bool registerObject(std::shared_ptr object); template std::shared_ptr getObject() const; + private: std::map > m_objectRegistry; diff --git a/pglab/plugin_support/LMainWindow.cpp b/pglab/plugin_support/LMainWindow.cpp index 7d4a6ad..f782878 100644 --- a/pglab/plugin_support/LMainWindow.cpp +++ b/pglab/plugin_support/LMainWindow.cpp @@ -32,8 +32,9 @@ namespace LMainWindow_details { m_window->statusBar()->showMessage(msg); } - void addContentWidget(PluginContentWidget *widget) override + void addContentWidget(PluginModule *module, PluginContentWidget *widget) override { + PluginContentWidgetContextBase::addContentWidget(module, widget); m_window->addPage(widget, ""); } @@ -126,7 +127,7 @@ void LMainWindow::addMenuAction(const MenuAction &ma) { ma.perform(m_context); }, - ma.shortCut()); + ma.shortcut()); // auto ac = new QAction(this); @@ -171,6 +172,7 @@ void LMainWindow::tabWidget_tabCloseRequested(int index) if (plg_page) { if (plg_page->canClose()) { m_tabWidget->removeTab(index); + m_context->removeContentWidget(plg_page); delete plg_page; } } @@ -186,7 +188,7 @@ void LMainWindow::tabWidget_currentChanged(int index) { // remove buttons of old page if (m_previousPage) { - removeToolBarButtonsForPage(m_previousPage); + removeModuleWidgetActionsForPage(m_previousPage); } // add buttons of new page @@ -195,26 +197,18 @@ void LMainWindow::tabWidget_currentChanged(int index) QWidget *widget = m_tabWidget->widget(index); page = dynamic_cast(widget); if (page) { - addToolBarButtonsForPage(page); + addModuleWidgetActionsForPage(page); } } m_previousPage = page; } -void LMainWindow::addToolBarButtonsForPage(PluginContentWidget *page) +void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page) { - std::vector actions = page->getToolbarActions(); - QList list; - for (auto act : actions) { - list.append(act); - } - m_mainToolBar->addActions(list); + m_context->addWidgetActionsToToolbar(page, m_mainToolBar); } -void LMainWindow::removeToolBarButtonsForPage(PluginContentWidget *page) +void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page) { - std::vector actions = page->getToolbarActions(); - for (auto act : actions) { - m_mainToolBar->removeAction(act); - } + m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar); } diff --git a/pglab/plugin_support/LMainWindow.h b/pglab/plugin_support/LMainWindow.h index c7fac6d..0e30c71 100644 --- a/pglab/plugin_support/LMainWindow.h +++ b/pglab/plugin_support/LMainWindow.h @@ -39,8 +39,8 @@ protected: void addModuleMenuActions(); - void addToolBarButtonsForPage(PluginContentWidget *page); - void removeToolBarButtonsForPage(PluginContentWidget *page); + void addModuleWidgetActionsForPage(PluginContentWidget *page); + void removeModuleWidgetActionsForPage(PluginContentWidget *page); private: LMainWindow_details::LMainWindowContentContext *m_context; PluginContentWidget *m_previousPage = nullptr; ///< tracks which pages buttons were previously being displayed diff --git a/pglab/plugin_support/LWidgetAction.cpp b/pglab/plugin_support/LWidgetAction.cpp new file mode 100644 index 0000000..6196143 --- /dev/null +++ b/pglab/plugin_support/LWidgetAction.cpp @@ -0,0 +1,56 @@ +#include "LWidgetAction.h" + +LWidgetAction::LWidgetAction(QString text, const char * slotname) + : m_text(std::move(text)) + , m_slotname(slotname) +{} + +const QIcon& LWidgetAction::icon() const +{ + return m_icon; +} + +const MenuLocation& LWidgetAction::menuLocation() const +{ + return m_menuLocation; +} + +void LWidgetAction::setIcon(QIcon icon) +{ + m_icon = std::move(icon); +} + +void LWidgetAction::setMenuLocation(MenuLocation menu_location) +{ + m_menuLocation = std::move(menu_location); +} + +void LWidgetAction::setShortcut(QKeySequence shortcut) +{ + m_shortCut = std::move(shortcut); +} + +void LWidgetAction::setText(QString text) +{ + m_text = std::move(text); +} + +void LWidgetAction::setToolTip(QString tooltip) +{ + m_toolTip = std::move(tooltip); +} + +const QKeySequence& LWidgetAction::shortcut() const +{ + return m_shortCut; +} + +const QString& LWidgetAction::text() const +{ + return m_text; +} + +const QString& LWidgetAction::toolTip() const +{ + return m_toolTip; +} diff --git a/pglab/plugin_support/LWidgetAction.h b/pglab/plugin_support/LWidgetAction.h new file mode 100644 index 0000000..263c21a --- /dev/null +++ b/pglab/plugin_support/LWidgetAction.h @@ -0,0 +1,42 @@ +#ifndef LWIDGETACTION_H +#define LWIDGETACTION_H + +#include "MenuLocation.h" +#include +#include +#include + + +/** Action definition for a specific widget instance, it uses a slotname + * so the action can be defined before the widget instance is created. + * The plugin mechanism will take care of instantiating a connection to the named slot. + */ +class LWidgetAction { +public: + /// + /// \param slotname, use SLOT macro to pass name of the slot + LWidgetAction(QString text, const char * slotname); + + 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 char* slotName() const { return m_slotname; } + const QString& text() const; + const QString& toolTip() const; + +private: + QString m_text; + QString m_toolTip; + QIcon m_icon; + QKeySequence m_shortCut; + MenuLocation m_menuLocation; + + const char * m_slotname; +}; + +#endif // LWIDGETACTION_H diff --git a/pglab/plugin_support/MenuAction.cpp b/pglab/plugin_support/MenuAction.cpp index a53a0c7..205b898 100644 --- a/pglab/plugin_support/MenuAction.cpp +++ b/pglab/plugin_support/MenuAction.cpp @@ -25,9 +25,9 @@ void MenuAction::setMenuLocation(MenuLocation menu_location) m_menuLocation = std::move(menu_location); } -void MenuAction::setShortCut(QKeySequence shortcut) +void MenuAction::setShortcut(QKeySequence shortcut) { - m_shortCut = std::move(shortcut); + m_shortcut = std::move(shortcut); } void MenuAction::setText(QString text) @@ -40,9 +40,9 @@ void MenuAction::setToolTip(QString tooltip) m_toolTip = std::move(tooltip); } -const QKeySequence& MenuAction::shortCut() const +const QKeySequence& MenuAction::shortcut() const { - return m_shortCut; + return m_shortcut; } const QString& MenuAction::text() const diff --git a/pglab/plugin_support/MenuAction.h b/pglab/plugin_support/MenuAction.h index 21ff9ee..d987660 100644 --- a/pglab/plugin_support/MenuAction.h +++ b/pglab/plugin_support/MenuAction.h @@ -27,10 +27,10 @@ public: const MenuLocation& menuLocation() const; void setIcon(QIcon icon); void setMenuLocation(MenuLocation menu_location); - void setShortCut(QKeySequence shortcut); + void setShortcut(QKeySequence shortcut); void setText(QString text); void setToolTip(QString tooltip); - const QKeySequence& shortCut() const; + const QKeySequence& shortcut() const; const QString& text() const; const QString& toolTip() const; @@ -39,11 +39,10 @@ private: QString m_text; QString m_toolTip; QIcon m_icon; - QKeySequence m_shortCut; + QKeySequence m_shortcut; MenuLocation m_menuLocation; Func m_func; }; - #endif // MENUACTION_H diff --git a/pglab/plugin_support/PluginContentWidget.cpp b/pglab/plugin_support/PluginContentWidget.cpp index 303bc15..39ff62d 100644 --- a/pglab/plugin_support/PluginContentWidget.cpp +++ b/pglab/plugin_support/PluginContentWidget.cpp @@ -3,14 +3,7 @@ PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent) : QWidget(parent) , m_context(context) -{ - -} - -std::vector PluginContentWidget::getToolbarActions() -{ - return std::vector(); -} +{} bool PluginContentWidget::canClose() { diff --git a/pglab/plugin_support/PluginContentWidget.h b/pglab/plugin_support/PluginContentWidget.h index 9e8f1c5..663c181 100644 --- a/pglab/plugin_support/PluginContentWidget.h +++ b/pglab/plugin_support/PluginContentWidget.h @@ -5,6 +5,7 @@ #include class IPluginContentWidgetContext; +class PluginModule; /// Provides a pluggable system for toolbar buttons and menu actions /// @@ -21,7 +22,6 @@ class PluginContentWidget: public QWidget{ public: PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent = nullptr); /// Returns the toolbar buttons for this page - virtual std::vector getToolbarActions(); virtual bool canClose(); protected: diff --git a/pglab/plugin_support/PluginContentWidgetContextBase.cpp b/pglab/plugin_support/PluginContentWidgetContextBase.cpp index 10587ff..1d6703a 100644 --- a/pglab/plugin_support/PluginContentWidgetContextBase.cpp +++ b/pglab/plugin_support/PluginContentWidgetContextBase.cpp @@ -1,7 +1,43 @@ #include "PluginContentWidgetContextBase.h" -#include "PluginRegister.h" +#include "PluginContentWidget.h" #include "PluginModule.h" +#include "PluginRegister.h" +#include "LWidgetAction.h" +#include #include +#include +#include + + + +LWidgetData::LWidgetData(PluginModule *module) + : m_module(module) +{} + +void LWidgetData::init(PluginContentWidget *widget) +{ + auto&& widget_actions = m_module->widgetActions(); + m_widgetActions.reserve(widget_actions.size()); + for (auto&& wa : widget_actions) { + m_widgetActions.push_back(createAction(wa, widget)); + } +} + +QList LWidgetData::actions() +{ + return m_widgetActions; +} + +QAction *LWidgetData::createAction(const LWidgetAction &wa, PluginContentWidget *widget) +{ + auto ac = new QAction(wa.icon(), wa.text(), widget); + ac->setShortcut(wa.shortcut()); + ac->setToolTip(wa.toolTip()); + QObject::connect(ac, SIGNAL(triggered()), widget, wa.slotName()); + return ac; +} + + PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default; @@ -25,3 +61,43 @@ void PluginContentWidgetContextBase::moduleAction( else qWarning() << QString("module not found %1").arg(module_identifier); } + +void PluginContentWidgetContextBase::addContentWidget(PluginModule *module, PluginContentWidget *widget) +{ + auto res = m_widgetLst.emplace(widget, module); + if (!res.second) + throw std::runtime_error("Unexpected conflicting key on insertiong PluginContentWidgetContextBase::addContentWidget"); + + res.first->second.init(widget); +} + +void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *widget) +{ + auto res = m_widgetLst.find(widget); + if (res == m_widgetLst.end()) + return; + + m_widgetLst.erase(res); +} + +void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar) +{ + auto res = m_widgetLst.find(widget); + if (res == m_widgetLst.end()) + return; + + auto && actions = res->second.actions(); + toolbar->addActions(actions); +} + +void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar) +{ + auto res = m_widgetLst.find(widget); + if (res == m_widgetLst.end()) + return; + + auto && actions = res->second.actions(); + for (auto && ac : actions) + toolbar->removeAction(ac); + +} diff --git a/pglab/plugin_support/PluginContentWidgetContextBase.h b/pglab/plugin_support/PluginContentWidgetContextBase.h index d060ba3..55428c8 100644 --- a/pglab/plugin_support/PluginContentWidgetContextBase.h +++ b/pglab/plugin_support/PluginContentWidgetContextBase.h @@ -2,6 +2,26 @@ #define PLUGINCONTENTWIDGETCONTEXTBASE_H #include "plugin_support/IPluginContentWidgetContext.h" +#include + +class LWidgetAction; +class QToolBar; +class QAction; + +class LWidgetData { +public: + LWidgetData(PluginModule *module); + PluginModule* module() { return m_module; } + void init(PluginContentWidget *widget); + QList actions(); + +private: + PluginModule *m_module; + /// List of actions specifically created for this widget from the widgetAction list of the module. + QList m_widgetActions; + + QAction *createAction(const LWidgetAction &wa, PluginContentWidget *widget); +}; /// Provides base implementation of IPluginContentWidgetContext class PluginContentWidgetContextBase : public IPluginContentWidgetContext @@ -14,6 +34,17 @@ public: QString module_action, const ModuleActionParameters &action_params ) override; + + void addContentWidget(PluginModule *module, PluginContentWidget *widget) override; + void removeContentWidget(PluginContentWidget *widget) override; + + void addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar); + void removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar); +private: + + using WidgetLst = std::map; + + WidgetLst m_widgetLst; }; #endif // PLUGINCONTENTWIDGETCONTEXTBASE_H diff --git a/pglab/plugin_support/PluginModule.cpp b/pglab/plugin_support/PluginModule.cpp index 045604a..c5a3ac1 100644 --- a/pglab/plugin_support/PluginModule.cpp +++ b/pglab/plugin_support/PluginModule.cpp @@ -38,3 +38,4 @@ const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString & return nullptr; return &res->second; } + diff --git a/pglab/plugin_support/PluginModule.h b/pglab/plugin_support/PluginModule.h index b3ea1db..951347a 100644 --- a/pglab/plugin_support/PluginModule.h +++ b/pglab/plugin_support/PluginModule.h @@ -3,6 +3,7 @@ #include "ModuleActionParameters.h" #include "MenuAction.h" +#include "LWidgetAction.h" #include "PluginRegister.h" #include #include @@ -16,12 +17,13 @@ class PluginModule: public QObject { Q_OBJECT public: using MenuActionList = std::vector; + using LWidgetActionList = std::vector; using ModuleAction = std::function; using ModuleActionMap = std::map; PluginModule(QString name, QString ident); - virtual void init() {}; + virtual void init() {} const QString& name() const { return m_name; } const QString& identifier() const { return m_ident; } @@ -38,6 +40,12 @@ public: /// Searches for and returns a pointer to the requested module action. /// When the action is not found nullptr is returned. const ModuleAction* findModuleAction(const QString &module_action) const; + + void registerWidgetAction(const LWidgetAction &action) + { + m_widgetActions.push_back(action); + } + const LWidgetActionList& widgetActions() const { return m_widgetActions; } private: /// Name shown to end users QString m_name; @@ -47,6 +55,7 @@ private: MenuActionList m_menuActions; ModuleActionMap m_moduleActions; + LWidgetActionList m_widgetActions; };