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.
This commit is contained in:
eelke 2019-01-05 19:58:23 +01:00
parent d0c4dabe8b
commit f4f2474a81
21 changed files with 418 additions and 204 deletions

View file

@ -27,11 +27,8 @@ void CodeGenerator::Init(std::shared_ptr<PgDatabaseCatalog> catalog, QString que
m_query = std::move(query); m_query = std::move(query);
m_dbres = std::move(dbres); m_dbres = std::move(dbres);
generateCode(); generateCode();
} }
void CodeGenerator::on_updateCodeButton_clicked() void CodeGenerator::on_updateCodeButton_clicked()
{ {
generateCode(); generateCode();

View file

@ -93,19 +93,6 @@ void CrudTab::on_actionRemove_rows_triggered()
} }
} }
std::vector<QAction*> 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) void CrudTab::headerCustomContextMenu(const QPoint &pos)
{ {
auto menu = new QMenu(this); auto menu = new QMenu(this);
@ -128,6 +115,14 @@ void CrudPageModule::init()
{ {
moduleAction_open(context, params); 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( void CrudPageModule::moduleAction_open(
@ -138,7 +133,7 @@ void CrudPageModule::moduleAction_open(
// create new widget for specified table // create new widget for specified table
// hand widget to context for display // hand widget to context for display
CrudTab *ct = new CrudTab(context, nullptr); 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()); ct->setConfig(params.at("oid").toUInt());
} }

View file

@ -24,10 +24,8 @@ public:
~CrudTab() override; ~CrudTab() override;
void setConfig(Oid oid); void setConfig(Oid oid);
public slots:
void refresh(); void refresh();
virtual std::vector<QAction*> getToolbarActions() override;
private: private:
Ui::CrudTab *ui; Ui::CrudTab *ui;

View file

@ -1,12 +1,10 @@
 #include "QueryTool.h"
#include "QueryTab.h"
#include "ui_QueryTab.h" #include "ui_QueryTab.h"
#include "SqlSyntaxHighlighter.h" #include "SqlSyntaxHighlighter.h"
#include <QStandardPaths> #include <QStandardPaths>
#include <QPushButton> #include <QPushButton>
#include <QAction> #include <QAction>
#include <QFileDialog> #include <QFileDialog>
#include <QStatusBar>
#include <QMessageBox> #include <QMessageBox>
#include <QTabWidget> #include <QTabWidget>
#include <QTextCodec> #include <QTextCodec>
@ -22,9 +20,9 @@
#include "GlobalIoService.h" #include "GlobalIoService.h"
#include "UserConfiguration.h" #include "UserConfiguration.h"
#include "plugin_support/IPluginContentWidgetContext.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) : PluginContentWidget(context_, parent)
, ui(new Ui::QueryTab) , ui(new Ui::QueryTab)
, m_dbConnection(*getGlobalAsioIoService()) , m_dbConnection(*getGlobalAsioIoService())
@ -35,8 +33,8 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent)
m_config = db->config(); m_config = db->config();
m_catalog = db->catalog(); m_catalog = db->catalog();
connect(&m_dbConnection, &ASyncDBConnection::onStateChanged, this, &QueryTab::connectionStateChanged); connect(&m_dbConnection, &ASyncDBConnection::onStateChanged, this, &QueryTool::connectionStateChanged);
connect(&m_dbConnection, &ASyncDBConnection::onNotice, this, &QueryTab::receiveNotice); connect(&m_dbConnection, &ASyncDBConnection::onNotice, this, &QueryTool::receiveNotice);
ui->queryEdit->setFont(UserConfiguration::instance()->codeFont()); ui->queryEdit->setFont(UserConfiguration::instance()->codeFont());
@ -47,7 +45,7 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent)
highlighter->setTypes(*cat->types()); 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); m_queryParamListController = new QueryParamListController(ui->paramTableView, open_database, this);
connect(ui->addButton, &QPushButton::clicked, m_queryParamListController, connect(ui->addButton, &QPushButton::clicked, m_queryParamListController,
@ -58,12 +56,12 @@ QueryTab::QueryTab(IPluginContentWidgetContext *context_, QWidget *parent)
startConnect(); startConnect();
} }
QueryTab::~QueryTab() QueryTool::~QueryTool()
{ {
delete ui; delete ui;
} }
bool QueryTab::canClose() bool QueryTool::canClose()
{ {
bool can_close; bool can_close;
if (m_queryTextChanged) { if (m_queryTextChanged) {
@ -75,7 +73,7 @@ bool QueryTab::canClose()
return can_close; return can_close;
} }
void QueryTab::newdoc() void QueryTool::newdoc()
{ {
ui->queryEdit->clear(); ui->queryEdit->clear();
setFileName(tr("new")); setFileName(tr("new"));
@ -83,7 +81,7 @@ void QueryTab::newdoc()
m_new = true; m_new = true;
} }
bool QueryTab::load(const QString &filename) bool QueryTool::load(const QString &filename)
{ {
bool result = false; bool result = false;
QFile file(filename); QFile file(filename);
@ -109,7 +107,7 @@ bool QueryTab::load(const QString &filename)
return result; return result;
} }
bool QueryTab::save() bool QueryTool::save()
{ {
bool result; bool result;
if (m_fileName.isEmpty() || m_new) { if (m_fileName.isEmpty() || m_new) {
@ -121,7 +119,7 @@ bool QueryTab::save()
return result; return result;
} }
bool QueryTab::saveAs() bool QueryTool::saveAs()
{ {
bool result = false; bool result = false;
QString filename = promptUserForSaveSqlFilename(); QString filename = promptUserForSaveSqlFilename();
@ -135,7 +133,7 @@ bool QueryTab::saveAs()
return result; return result;
} }
void QueryTab::saveCopyAs() void QueryTool::saveCopyAs()
{ {
QString filename = promptUserForSaveSqlFilename(); QString filename = promptUserForSaveSqlFilename();
if (!filename.isEmpty()) { if (!filename.isEmpty()) {
@ -143,7 +141,7 @@ void QueryTab::saveCopyAs()
} }
} }
void QueryTab::execute() void QueryTool::execute()
{ {
if (m_dbConnection.state() == ASyncDBConnection::State::Connected) { if (m_dbConnection.state() == ASyncDBConnection::State::Connected) {
addLog("Query clicked"); 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); ui->explainTreeView->setModel(nullptr);
explainModel.reset(); explainModel.reset();
@ -221,13 +229,13 @@ void QueryTab::explain(bool analyze)
m_dbConnection.send(cmd, m_queryParamListController->params(), cb); m_dbConnection.send(cmd, m_queryParamListController->params(), cb);
} }
void QueryTab::cancel() void QueryTool::cancel()
{ {
m_dbConnection.cancel(); m_dbConnection.cancel();
} }
void QueryTab::setFileName(const QString &filename) void QueryTool::setFileName(const QString &filename)
{ {
m_fileName = filename; m_fileName = filename;
QFileInfo fileInfo(filename); QFileInfo fileInfo(filename);
@ -235,7 +243,7 @@ void QueryTab::setFileName(const QString &filename)
context()->setCaption(this, fn, m_fileName); context()->setCaption(this, fn, m_fileName);
} }
bool QueryTab::continueWithoutSavingWarning() bool QueryTool::continueWithoutSavingWarning()
{ {
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning); msgBox.setIcon(QMessageBox::Warning);
@ -254,7 +262,7 @@ bool QueryTab::continueWithoutSavingWarning()
return ret != QMessageBox::Cancel; return ret != QMessageBox::Cancel;
} }
bool QueryTab::saveSqlTo(const QString &filename) bool QueryTool::saveSqlTo(const QString &filename)
{ {
bool result = false; bool result = false;
QFileInfo fileinfo(filename); 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); QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
return QFileDialog::getSaveFileName(this, tr("Save query"), home_dir, tr("SQL file (*.sql)")); return QFileDialog::getSaveFileName(this, tr("Save query"), home_dir, tr("SQL file (*.sql)"));
} }
void QueryTab::queryTextChanged() void QueryTool::queryTextChanged()
{ {
m_queryTextChanged = true; m_queryTextChanged = true;
} }
void QueryTab::connectionStateChanged(ASyncDBConnection::State state) void QueryTool::connectionStateChanged(ASyncDBConnection::State state)
{ {
QString iconname; QString iconname;
switch (state) { 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()); QTextCursor text_cursor = QTextCursor(ui->edtLog->document());
text_cursor.movePosition(QTextCursor::End); text_cursor.movePosition(QTextCursor::End);
text_cursor.insertText(s + "\r\n"); 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)); ui->messagesEdit->append(QString::fromStdString(notice.errorMessage));
@ -365,12 +373,12 @@ void QueryTab::receiveNotice(Pgsql::ErrorDetails notice)
// statementPosition // statementPosition
} }
void QueryTab::startConnect() void QueryTool::startConnect()
{ {
m_dbConnection.setupConnection(m_config); m_dbConnection.setupConnection(m_config);
} }
void QueryTab::explain_ready(ExplainRoot::SPtr explain) void QueryTool::explain_ready(ExplainRoot::SPtr explain)
{ {
m_stopwatch.stop(); m_stopwatch.stop();
if (explain) { if (explain) {
@ -405,7 +413,7 @@ void QueryTab::explain_ready(ExplainRoot::SPtr explain)
} }
} }
QString QueryTab::getCommand() const QString QueryTool::getCommand() const
{ {
QString command; QString command;
QTextCursor cursor = ui->queryEdit->textCursor(); QTextCursor cursor = ui->queryEdit->textCursor();
@ -418,7 +426,7 @@ QString QueryTab::getCommand() const
return command; return command;
} }
std::string QueryTab::getCommandUtf8() const std::string QueryTool::getCommandUtf8() const
{ {
return getCommand().toUtf8().data(); return getCommand().toUtf8().data();
} }
@ -444,7 +452,7 @@ std::string QueryTab::getCommandUtf8() const
//} //}
void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedms) void QueryTool::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedms)
{ {
if (dbres) { if (dbres) {
addLog("query_ready with result"); addLog("query_ready with result");
@ -520,7 +528,7 @@ void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedm
} }
} }
void QueryTab::markError(const Pgsql::ErrorDetails &details) void QueryTool::markError(const Pgsql::ErrorDetails &details)
{ {
if (details.statementPosition > 0) { if (details.statementPosition > 0) {
QTextCursor cursor = ui->queryEdit->textCursor(); 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) for (auto e : resultList)
delete e; delete e;
resultList.clear(); resultList.clear();
} }
void QueryTab::copyQueryAsCString() void QueryTool::copyQueryAsCString()
{ {
// QString command; // QString command;
// QTextCursor cursor = ui->queryEdit->textCursor(); // QTextCursor cursor = ui->queryEdit->textCursor();
@ -586,7 +594,7 @@ void QueryTab::copyQueryAsCString()
#include <codebuilder/CodeBuilder.h> #include <codebuilder/CodeBuilder.h>
#include <codebuilder/DefaultConfigs.h> #include <codebuilder/DefaultConfigs.h>
void QueryTab::copyQueryAsRawCppString() void QueryTool::copyQueryAsRawCppString()
{ {
QString command = getCommand(); QString command = getCommand();
//auto sql = getAllOrSelectedSql(); //auto sql = getAllOrSelectedSql();
@ -594,7 +602,7 @@ void QueryTab::copyQueryAsRawCppString()
QApplication::clipboard()->setText(cs); QApplication::clipboard()->setText(cs);
} }
void QueryTab::generateCode() void QueryTool::generateCode()
{ {
QString command = getCommand(); 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 widget = ui->tabWidget->currentWidget();
auto fi = std::find(resultList.begin(), resultList.end(), widget); 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(); ui->queryEdit->setFocus();
} }
std::vector<QAction*> 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")

View file

@ -9,7 +9,6 @@
#include <QWidget> #include <QWidget>
#include "plugin_support/PluginContentWidget.h" #include "plugin_support/PluginContentWidget.h"
#include "plugin_support/PluginModule.h"
#include <memory> #include <memory>
namespace Ui { namespace Ui {
@ -32,20 +31,17 @@ class OpenDatabase;
class QueryParamListController; class QueryParamListController;
class PgDatabaseCatalog; class PgDatabaseCatalog;
class QueryTab : public PluginContentWidget { class QueryTool : public PluginContentWidget {
Q_OBJECT Q_OBJECT
public: public:
QueryTab(IPluginContentWidgetContext *context, QWidget *parent = nullptr); QueryTool(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
~QueryTab() override; ~QueryTool() override;
void newdoc(); void newdoc();
bool load(const QString &filename); bool load(const QString &filename);
bool save();
bool saveAs();
void saveCopyAs(); void saveCopyAs();
void explain(bool analyze); void explain(bool analyze);
void cancel();
bool canClose() override; bool canClose() override;
@ -59,9 +55,13 @@ public:
bool isNew() const { return m_new; } bool isNew() const { return m_new; }
void focusEditor(); void focusEditor();
virtual std::vector<QAction*> getToolbarActions() override;
public slots: public slots:
void execute(); void execute();
bool save();
bool saveAs();
void explain();
void analyze();
void cancel();
private: private:
using ResultTabContainer = std::vector<TuplesResultWidget*>; using ResultTabContainer = std::vector<TuplesResultWidget*>;
@ -70,7 +70,6 @@ private:
SqlSyntaxHighlighter* highlighter; SqlSyntaxHighlighter* highlighter;
ConnectionConfig m_config; ConnectionConfig m_config;
StopWatch m_stopwatch; StopWatch m_stopwatch;
std::vector<QAction*> actions;
QueryParamListController *m_queryParamListController = nullptr; QueryParamListController *m_queryParamListController = nullptr;
@ -113,15 +112,5 @@ private slots:
void startConnect(); 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 #endif // QUERYTAB_H

85
pglab/QueryToolModule.cpp Normal file
View file

@ -0,0 +1,85 @@
#include "QueryToolModule.h"
#include "QueryTool.h"
#include "plugin_support/IPluginContentWidgetContext.h"
#include "plugin_support/PluginRegister.h"
#include <QStandardPaths>
#include <QFileDialog>
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")

18
pglab/QueryToolModule.h Normal file
View file

@ -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

View file

@ -32,7 +32,6 @@ SOURCES += main.cpp\
ConnectionManagerWindow.cpp \ ConnectionManagerWindow.cpp \
ConnectionListModel.cpp \ ConnectionListModel.cpp \
BackupRestore.cpp \ BackupRestore.cpp \
QueryTab.cpp \
stopwatch.cpp \ stopwatch.cpp \
TuplesResultWidget.cpp \ TuplesResultWidget.cpp \
BackupDialog.cpp \ BackupDialog.cpp \
@ -89,7 +88,10 @@ PropertyProxyModel.cpp \
plugin_support/PluginContentWidget.cpp \ plugin_support/PluginContentWidget.cpp \
plugin_support/PluginContentWidgetContextBase.cpp \ plugin_support/PluginContentWidgetContextBase.cpp \
plugin_support/MenuAction.cpp \ plugin_support/MenuAction.cpp \
plugin_support/LMainWindow.cpp plugin_support/LMainWindow.cpp \
plugin_support/LWidgetAction.cpp \
QueryTool.cpp \
QueryToolModule.cpp
HEADERS += \ HEADERS += \
QueryResultModel.h \ QueryResultModel.h \
@ -97,7 +99,6 @@ HEADERS += \
CreateDatabaseDialog.h \ CreateDatabaseDialog.h \
ConnectionManagerWindow.h \ ConnectionManagerWindow.h \
ConnectionListModel.h \ ConnectionListModel.h \
QueryTab.h \
stopwatch.h \ stopwatch.h \
TuplesResultWidget.h \ TuplesResultWidget.h \
BackupDialog.h \ BackupDialog.h \
@ -158,7 +159,10 @@ CustomDataRole.h \
plugin_support/IPluginContentWidgetContext.h \ plugin_support/IPluginContentWidgetContext.h \
plugin_support/PluginContentWidgetContextBase.h \ plugin_support/PluginContentWidgetContextBase.h \
plugin_support/MenuAction.h \ plugin_support/MenuAction.h \
plugin_support/LMainWindow.h plugin_support/LMainWindow.h \
plugin_support/LWidgetAction.h \
QueryTool.h \
QueryToolModule.h
FORMS += \ FORMS += \
ConnectionManagerWindow.ui \ ConnectionManagerWindow.ui \

View file

@ -8,8 +8,10 @@
#include "plugin_support/ModuleActionParameters.h" #include "plugin_support/ModuleActionParameters.h"
class OpenDatabase; class OpenDatabase;
class PluginModule;
class PluginContentWidget; class PluginContentWidget;
/** This class serves to isolate the plugin from the actual construct in which it is /** This class serves to isolate the plugin from the actual construct in which it is
* used. * used.
* *
@ -45,7 +47,8 @@ public:
const ModuleActionParameters &action_params const ModuleActionParameters &action_params
) = 0; ) = 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 /** Return a widget you can use as a parent
*/ */
@ -57,6 +60,7 @@ public:
bool registerObject(std::shared_ptr<T> object); bool registerObject(std::shared_ptr<T> object);
template<typename T> template<typename T>
std::shared_ptr<T> getObject() const; std::shared_ptr<T> getObject() const;
private: private:
std::map<std::type_index, std::shared_ptr<void> > m_objectRegistry; std::map<std::type_index, std::shared_ptr<void> > m_objectRegistry;

View file

@ -32,8 +32,9 @@ namespace LMainWindow_details {
m_window->statusBar()->showMessage(msg); 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, ""); m_window->addPage(widget, "");
} }
@ -126,7 +127,7 @@ void LMainWindow::addMenuAction(const MenuAction &ma)
{ {
ma.perform(m_context); ma.perform(m_context);
}, },
ma.shortCut()); ma.shortcut());
// auto ac = new QAction(this); // auto ac = new QAction(this);
@ -171,6 +172,7 @@ void LMainWindow::tabWidget_tabCloseRequested(int index)
if (plg_page) { if (plg_page) {
if (plg_page->canClose()) { if (plg_page->canClose()) {
m_tabWidget->removeTab(index); m_tabWidget->removeTab(index);
m_context->removeContentWidget(plg_page);
delete plg_page; delete plg_page;
} }
} }
@ -186,7 +188,7 @@ void LMainWindow::tabWidget_currentChanged(int index)
{ {
// remove buttons of old page // remove buttons of old page
if (m_previousPage) { if (m_previousPage) {
removeToolBarButtonsForPage(m_previousPage); removeModuleWidgetActionsForPage(m_previousPage);
} }
// add buttons of new page // add buttons of new page
@ -195,26 +197,18 @@ void LMainWindow::tabWidget_currentChanged(int index)
QWidget *widget = m_tabWidget->widget(index); QWidget *widget = m_tabWidget->widget(index);
page = dynamic_cast<PluginContentWidget*>(widget); page = dynamic_cast<PluginContentWidget*>(widget);
if (page) { if (page) {
addToolBarButtonsForPage(page); addModuleWidgetActionsForPage(page);
} }
} }
m_previousPage = page; m_previousPage = page;
} }
void LMainWindow::addToolBarButtonsForPage(PluginContentWidget *page) void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page)
{ {
std::vector<QAction*> actions = page->getToolbarActions(); m_context->addWidgetActionsToToolbar(page, m_mainToolBar);
QList<QAction*> list;
for (auto act : actions) {
list.append(act);
}
m_mainToolBar->addActions(list);
} }
void LMainWindow::removeToolBarButtonsForPage(PluginContentWidget *page) void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page)
{ {
std::vector<QAction*> actions = page->getToolbarActions(); m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar);
for (auto act : actions) {
m_mainToolBar->removeAction(act);
}
} }

View file

@ -39,8 +39,8 @@ protected:
void addModuleMenuActions(); void addModuleMenuActions();
void addToolBarButtonsForPage(PluginContentWidget *page); void addModuleWidgetActionsForPage(PluginContentWidget *page);
void removeToolBarButtonsForPage(PluginContentWidget *page); void removeModuleWidgetActionsForPage(PluginContentWidget *page);
private: private:
LMainWindow_details::LMainWindowContentContext *m_context; LMainWindow_details::LMainWindowContentContext *m_context;
PluginContentWidget *m_previousPage = nullptr; ///< tracks which pages buttons were previously being displayed PluginContentWidget *m_previousPage = nullptr; ///< tracks which pages buttons were previously being displayed

View file

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

View file

@ -0,0 +1,42 @@
#ifndef LWIDGETACTION_H
#define LWIDGETACTION_H
#include "MenuLocation.h"
#include <QIcon>
#include <QKeySequence>
#include <QString>
/** 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

View file

@ -25,9 +25,9 @@ void MenuAction::setMenuLocation(MenuLocation menu_location)
m_menuLocation = std::move(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) void MenuAction::setText(QString text)
@ -40,9 +40,9 @@ void MenuAction::setToolTip(QString tooltip)
m_toolTip = std::move(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 const QString& MenuAction::text() const

View file

@ -27,10 +27,10 @@ public:
const MenuLocation& menuLocation() const; const MenuLocation& menuLocation() const;
void setIcon(QIcon icon); void setIcon(QIcon icon);
void setMenuLocation(MenuLocation menu_location); void setMenuLocation(MenuLocation menu_location);
void setShortCut(QKeySequence shortcut); void setShortcut(QKeySequence shortcut);
void setText(QString text); void setText(QString text);
void setToolTip(QString tooltip); void setToolTip(QString tooltip);
const QKeySequence& shortCut() const; const QKeySequence& shortcut() const;
const QString& text() const; const QString& text() const;
const QString& toolTip() const; const QString& toolTip() const;
@ -39,11 +39,10 @@ private:
QString m_text; QString m_text;
QString m_toolTip; QString m_toolTip;
QIcon m_icon; QIcon m_icon;
QKeySequence m_shortCut; QKeySequence m_shortcut;
MenuLocation m_menuLocation; MenuLocation m_menuLocation;
Func m_func; Func m_func;
}; };
#endif // MENUACTION_H #endif // MENUACTION_H

View file

@ -3,14 +3,7 @@
PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent) PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent)
: QWidget(parent) : QWidget(parent)
, m_context(context) , m_context(context)
{ {}
}
std::vector<QAction*> PluginContentWidget::getToolbarActions()
{
return std::vector<QAction*>();
}
bool PluginContentWidget::canClose() bool PluginContentWidget::canClose()
{ {

View file

@ -5,6 +5,7 @@
#include <vector> #include <vector>
class IPluginContentWidgetContext; class IPluginContentWidgetContext;
class PluginModule;
/// Provides a pluggable system for toolbar buttons and menu actions /// Provides a pluggable system for toolbar buttons and menu actions
/// ///
@ -21,7 +22,6 @@ class PluginContentWidget: public QWidget{
public: public:
PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent = nullptr); PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent = nullptr);
/// Returns the toolbar buttons for this page /// Returns the toolbar buttons for this page
virtual std::vector<QAction*> getToolbarActions();
virtual bool canClose(); virtual bool canClose();
protected: protected:

View file

@ -1,7 +1,43 @@
#include "PluginContentWidgetContextBase.h" #include "PluginContentWidgetContextBase.h"
#include "PluginRegister.h" #include "PluginContentWidget.h"
#include "PluginModule.h" #include "PluginModule.h"
#include "PluginRegister.h"
#include "LWidgetAction.h"
#include <QAction>
#include <QDebug> #include <QDebug>
#include <QToolBar>
#include <vector>
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<QAction *> 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; PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default;
@ -25,3 +61,43 @@ void PluginContentWidgetContextBase::moduleAction(
else else
qWarning() << QString("module not found %1").arg(module_identifier); 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);
}

View file

@ -2,6 +2,26 @@
#define PLUGINCONTENTWIDGETCONTEXTBASE_H #define PLUGINCONTENTWIDGETCONTEXTBASE_H
#include "plugin_support/IPluginContentWidgetContext.h" #include "plugin_support/IPluginContentWidgetContext.h"
#include <QList>
class LWidgetAction;
class QToolBar;
class QAction;
class LWidgetData {
public:
LWidgetData(PluginModule *module);
PluginModule* module() { return m_module; }
void init(PluginContentWidget *widget);
QList<QAction *> actions();
private:
PluginModule *m_module;
/// List of actions specifically created for this widget from the widgetAction list of the module.
QList<QAction *> m_widgetActions;
QAction *createAction(const LWidgetAction &wa, PluginContentWidget *widget);
};
/// Provides base implementation of IPluginContentWidgetContext /// Provides base implementation of IPluginContentWidgetContext
class PluginContentWidgetContextBase : public IPluginContentWidgetContext class PluginContentWidgetContextBase : public IPluginContentWidgetContext
@ -14,6 +34,17 @@ public:
QString module_action, QString module_action,
const ModuleActionParameters &action_params const ModuleActionParameters &action_params
) override; ) 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<PluginContentWidget*, LWidgetData>;
WidgetLst m_widgetLst;
}; };
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H #endif // PLUGINCONTENTWIDGETCONTEXTBASE_H

View file

@ -38,3 +38,4 @@ const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString &
return nullptr; return nullptr;
return &res->second; return &res->second;
} }

View file

@ -3,6 +3,7 @@
#include "ModuleActionParameters.h" #include "ModuleActionParameters.h"
#include "MenuAction.h" #include "MenuAction.h"
#include "LWidgetAction.h"
#include "PluginRegister.h" #include "PluginRegister.h"
#include <QObject> #include <QObject>
#include <functional> #include <functional>
@ -16,12 +17,13 @@ class PluginModule: public QObject {
Q_OBJECT Q_OBJECT
public: public:
using MenuActionList = std::vector<MenuAction>; using MenuActionList = std::vector<MenuAction>;
using LWidgetActionList = std::vector<LWidgetAction>;
using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>; using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>;
using ModuleActionMap = std::map<QString, ModuleAction>; using ModuleActionMap = std::map<QString, ModuleAction>;
PluginModule(QString name, QString ident); PluginModule(QString name, QString ident);
virtual void init() {}; virtual void init() {}
const QString& name() const { return m_name; } const QString& name() const { return m_name; }
const QString& identifier() const { return m_ident; } const QString& identifier() const { return m_ident; }
@ -38,6 +40,12 @@ public:
/// Searches for and returns a pointer to the requested module action. /// Searches for and returns a pointer to the requested module action.
/// When the action is not found nullptr is returned. /// When the action is not found nullptr is returned.
const ModuleAction* findModuleAction(const QString &module_action) const; 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: private:
/// Name shown to end users /// Name shown to end users
QString m_name; QString m_name;
@ -47,6 +55,7 @@ private:
MenuActionList m_menuActions; MenuActionList m_menuActions;
ModuleActionMap m_moduleActions; ModuleActionMap m_moduleActions;
LWidgetActionList m_widgetActions;
}; };