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; };