Merge branch 'remove-plugin-system'
This commit is contained in:
commit
7450e5bd4c
47 changed files with 443 additions and 1626 deletions
|
|
@ -1,7 +1,6 @@
|
|||
#include "CatalogInspector.h"
|
||||
#include "OpenDatabase.h"
|
||||
#include "UserConfiguration.h"
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
#include "widgets/CatalogFunctionsPage.h"
|
||||
#include "widgets/CatalogSequencesPage.h"
|
||||
#include "widgets/CatalogTablesPage.h"
|
||||
|
|
@ -12,8 +11,8 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <unordered_set>
|
||||
|
||||
CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, PluginModule *module, QWidget *parent)
|
||||
: PluginContentWidget(context_, module, parent)
|
||||
CatalogInspector::CatalogInspector(std::shared_ptr<OpenDatabase> open_database, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_tabWidget = new QTabWidget(this);
|
||||
m_tablesPage = new CatalogTablesPage(this);
|
||||
|
|
@ -27,8 +26,7 @@ CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, Plugin
|
|||
m_tabWidget->addTab(m_functionsPage, "");
|
||||
m_tabWidget->addTab(m_sequencesPage, "");
|
||||
|
||||
auto db = context_->getObject<OpenDatabase>();
|
||||
setCatalog(db->catalog());
|
||||
setCatalog(open_database->catalog());
|
||||
retranslateUi(false);
|
||||
}
|
||||
|
||||
|
|
@ -75,32 +73,5 @@ void CatalogInspector::setNamespaceFilter(NamespaceFilter filter)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
context()->setCaption(this, caption, hint);
|
||||
// context()->setCaption(this, caption, hint);
|
||||
}
|
||||
|
||||
void CatalogInspectorModule::init()
|
||||
{
|
||||
registerModuleAction("open",
|
||||
[this] (IPluginContentWidgetContext* context,
|
||||
const ModuleActionParameters ¶ms)
|
||||
{
|
||||
moduleAction_open(context, params);
|
||||
});
|
||||
}
|
||||
|
||||
void CatalogInspectorModule::moduleAction_open(
|
||||
IPluginContentWidgetContext* context,
|
||||
const ModuleActionParameters ¶ms
|
||||
)
|
||||
{
|
||||
auto ct = new CatalogInspector(context, this);
|
||||
context->addContentWidget(ct);
|
||||
auto nsf = params.at("namespace-filter").toString();
|
||||
NamespaceFilter filter = NamespaceFilter::User;
|
||||
if (nsf == "pg_catalog") filter = NamespaceFilter::PgCatalog;
|
||||
else if (nsf == "information_schema") filter = NamespaceFilter::InformationSchema;
|
||||
ct->setNamespaceFilter(filter);
|
||||
}
|
||||
|
||||
REGISTER_PLUGIN_MODULE_CAT(CatalogInspectorModule, "Catalog inspector tool",
|
||||
"pglab.catalog-inspector", "database")
|
||||
|
|
|
|||
|
|
@ -4,20 +4,18 @@
|
|||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include "NamespaceFilter.h"
|
||||
#include "plugin_support/PluginContentWidget.h"
|
||||
#include "plugin_support/PluginModule.h"
|
||||
|
||||
class CatalogFunctionsPage;
|
||||
class CatalogSequencesPage;
|
||||
class CatalogTablesPage;
|
||||
class OpenDatabase;
|
||||
class PgDatabaseCatalog;
|
||||
class QTabWidget;
|
||||
|
||||
class CatalogInspector : public PluginContentWidget {
|
||||
class CatalogInspector : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CatalogInspector(IPluginContentWidgetContext *context, PluginModule *module,
|
||||
QWidget *parent = nullptr);
|
||||
explicit CatalogInspector(std::shared_ptr<OpenDatabase> open_database, QWidget *parent = nullptr);
|
||||
~CatalogInspector();
|
||||
|
||||
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
|
||||
|
|
@ -34,17 +32,4 @@ private:
|
|||
private slots:
|
||||
};
|
||||
|
||||
class CatalogInspectorModule: public PluginModule {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using PluginModule::PluginModule;
|
||||
|
||||
void init();
|
||||
private slots:
|
||||
|
||||
private:
|
||||
void moduleAction_open(IPluginContentWidgetContext* context, const ModuleActionParameters ¶ms);
|
||||
};
|
||||
|
||||
|
||||
#endif // TABLESPAGE_H
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
#include "UserConfiguration.h"
|
||||
#include <QTextStream>
|
||||
|
||||
CodeGenerator::CodeGenerator(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent) :
|
||||
PluginContentWidget(context, module, parent),
|
||||
ui(new Ui::CodeGenerator)
|
||||
CodeGenerator::CodeGenerator(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CodeGenerator)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#define CODEGENERATOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "plugin_support/PluginContentWidget.h"
|
||||
#include "Pgsql_declare.h"
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -11,12 +10,10 @@ class CodeGenerator;
|
|||
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class CodeGenerator : public PluginContentWidget
|
||||
{
|
||||
class CodeGenerator : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CodeGenerator(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent = nullptr);
|
||||
CodeGenerator(QWidget *parent = nullptr);
|
||||
~CodeGenerator();
|
||||
|
||||
void Init(std::shared_ptr<PgDatabaseCatalog> catalog, QString query, std::shared_ptr<const Pgsql::Result> dbres);
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@
|
|||
#include <QMessageBox>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include "plugin_support/PluginRegister.h"
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
|
||||
|
||||
CrudTab::CrudTab(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent)
|
||||
: PluginContentWidget(context, module, parent)
|
||||
CrudTab::CrudTab(std::shared_ptr<OpenDatabase> open_database, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CrudTab)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_db = open_database;
|
||||
|
||||
SetTableViewDefault(ui->tableView);
|
||||
|
||||
auto delegate = new PgLabItemDelegate(ui->tableView);
|
||||
|
|
@ -48,7 +48,6 @@ CrudTab::~CrudTab()
|
|||
|
||||
void CrudTab::setConfig(Oid oid) //std::shared_ptr<OpenDatabase> db, const PgClass &table)
|
||||
{
|
||||
m_db = context()->getObject<OpenDatabase>(); // getDatabase();;
|
||||
m_table = *m_db->catalog()->classes()->getByKey(oid);
|
||||
m_crudModel->setConfig(m_db, *m_table);
|
||||
}
|
||||
|
|
@ -117,33 +116,33 @@ void CrudTab::initActions()
|
|||
}
|
||||
}
|
||||
|
||||
QList<QAction *> CrudTab::actions()
|
||||
{
|
||||
return { m_refreshAction };
|
||||
}
|
||||
//QList<QAction *> CrudTab::actions()
|
||||
//{
|
||||
// return { m_refreshAction };
|
||||
//}
|
||||
|
||||
|
||||
void CrudPageModule::init()
|
||||
{
|
||||
registerModuleAction("open",
|
||||
[this] (IPluginContentWidgetContext* context,
|
||||
const ModuleActionParameters ¶ms)
|
||||
{
|
||||
moduleAction_open(context, params);
|
||||
});
|
||||
}
|
||||
//void CrudPageModule::init()
|
||||
//{
|
||||
// registerModuleAction("open",
|
||||
// [this] (IPluginContentWidgetContext* context,
|
||||
// const ModuleActionParameters ¶ms)
|
||||
// {
|
||||
// moduleAction_open(context, params);
|
||||
// });
|
||||
//}
|
||||
|
||||
void CrudPageModule::moduleAction_open(
|
||||
IPluginContentWidgetContext* context,
|
||||
const ModuleActionParameters ¶ms
|
||||
)
|
||||
{
|
||||
// create new widget for specified table
|
||||
// hand widget to context for display
|
||||
CrudTab *ct = new CrudTab(context, this);
|
||||
context->addContentWidget(ct); // maybe CrudTab should do this
|
||||
ct->setConfig(params.at("oid").toUInt());
|
||||
//void CrudPageModule::moduleAction_open(
|
||||
// IPluginContentWidgetContext* context,
|
||||
// const ModuleActionParameters ¶ms
|
||||
// )
|
||||
//{
|
||||
// // create new widget for specified table
|
||||
// // hand widget to context for display
|
||||
// CrudTab *ct = new CrudTab(context, this);
|
||||
// context->addContentWidget(ct); // maybe CrudTab should do this
|
||||
// ct->setConfig(params.at("oid").toUInt());
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
REGISTER_PLUGIN_MODULE_CAT(CrudPageModule, "CRUD tool", "pglab.crudpage", "database")
|
||||
//REGISTER_PLUGIN_MODULE_CAT(CrudPageModule, "CRUD tool", "pglab.crudpage", "database")
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "catalog/PgClass.h"
|
||||
#include <QWidget>
|
||||
#include "plugin_support/PluginContentWidget.h"
|
||||
#include "plugin_support/PluginModule.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
|
|
@ -15,13 +13,10 @@ namespace Ui {
|
|||
class OpenDatabase;
|
||||
class CrudModel;
|
||||
|
||||
class CrudTab : public PluginContentWidget
|
||||
{
|
||||
class CrudTab : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CrudTab(IPluginContentWidgetContext *context, PluginModule *module,
|
||||
QWidget *parent = nullptr);
|
||||
explicit CrudTab(std::shared_ptr<OpenDatabase> open_database, QWidget *parent = nullptr);
|
||||
~CrudTab() override;
|
||||
|
||||
void setConfig(Oid oid);
|
||||
|
|
@ -38,25 +33,25 @@ private:
|
|||
|
||||
void initActions();
|
||||
|
||||
virtual QList<QAction *> actions() override;
|
||||
// virtual QList<QAction *> actions() override;
|
||||
|
||||
private slots:
|
||||
void on_actionRemove_rows_triggered();
|
||||
void headerCustomContextMenu(const QPoint &pos);
|
||||
};
|
||||
|
||||
class CrudPageModule: public PluginModule {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using PluginModule::PluginModule;
|
||||
//class CrudPageModule: public PluginModule {
|
||||
// Q_OBJECT
|
||||
//public:
|
||||
// using PluginModule::PluginModule;
|
||||
|
||||
void init();
|
||||
private slots:
|
||||
// void init();
|
||||
//private slots:
|
||||
|
||||
private:
|
||||
//private:
|
||||
|
||||
void moduleAction_open(IPluginContentWidgetContext* context, const ModuleActionParameters ¶ms);
|
||||
};
|
||||
// void moduleAction_open(IPluginContentWidgetContext* context, const ModuleActionParameters ¶ms);
|
||||
//};
|
||||
|
||||
|
||||
#endif // CRUDTAB_H
|
||||
|
|
|
|||
|
|
@ -1,35 +1,63 @@
|
|||
#include "DatabaseWindow.h"
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
#include "util.h"
|
||||
#include "OpenDatabase.h"
|
||||
#include "MasterController.h"
|
||||
#include "TaskExecutor.h"
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaMethod>
|
||||
#include <QStandardPaths>
|
||||
#include <QTableView>
|
||||
|
||||
// Pages that should become modules
|
||||
#include "EditTableWidget.h"
|
||||
#include "CatalogInspector.h"
|
||||
#include "CodeGenerator.h"
|
||||
#include "QueryTool.h"
|
||||
|
||||
namespace pg = Pgsql;
|
||||
|
||||
|
||||
DatabaseWindow::DatabaseWindow(MasterController *master, QWidget *parent)
|
||||
: LMainWindow(parent)
|
||||
|
||||
: QMainWindow(parent)
|
||||
, m_masterController(master)
|
||||
{
|
||||
connect(&loadWatcher, &QFutureWatcher<LoadCatalog::Result>::finished,
|
||||
this, &DatabaseWindow::catalogLoaded);
|
||||
|
||||
initModuleMenus();
|
||||
m_tabWidget = new QTabWidget(this);
|
||||
setCentralWidget(m_tabWidget);
|
||||
|
||||
createActions();
|
||||
initMenus();
|
||||
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
}
|
||||
|
||||
DatabaseWindow::~DatabaseWindow() = default;
|
||||
|
||||
void DatabaseWindow::addPage(QWidget* page, QString caption)
|
||||
{
|
||||
m_tabWidget->addTab(page, caption);
|
||||
m_tabWidget->setCurrentWidget(page);
|
||||
}
|
||||
|
||||
void DatabaseWindow::setTabCaptionForWidget(QWidget *widget, const QString &caption, const QString &hint)
|
||||
{
|
||||
auto index = m_tabWidget->indexOf(widget);
|
||||
m_tabWidget->setTabText(index, caption);
|
||||
m_tabWidget->setTabToolTip(index, hint);
|
||||
}
|
||||
|
||||
void DatabaseWindow::setTabIcon(QWidget *widget, const QString &iconname)
|
||||
{
|
||||
auto index = m_tabWidget->indexOf(widget);
|
||||
auto n = ":/icons/16x16/" + iconname;
|
||||
m_tabWidget->setTabIcon(index, QIcon(n));
|
||||
}
|
||||
|
||||
void DatabaseWindow::newCreateTablePage()
|
||||
{
|
||||
auto w = new EditTableWidget(m_database, this);
|
||||
|
|
@ -46,6 +74,13 @@ void DatabaseWindow::newCodeGenPage(QString query, std::shared_ptr<const Pgsql::
|
|||
//
|
||||
}
|
||||
|
||||
QueryTool *DatabaseWindow::GetActiveQueryTool()
|
||||
{
|
||||
auto widget = m_tabWidget->currentWidget();
|
||||
auto qt = dynamic_cast<QueryTool*>(widget);
|
||||
return qt;
|
||||
}
|
||||
|
||||
void DatabaseWindow::setConfig(const ConnectionConfig &config)
|
||||
{
|
||||
m_config = config;
|
||||
|
|
@ -65,22 +100,173 @@ void DatabaseWindow::setConfig(const ConnectionConfig &config)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DatabaseWindow::createActions()
|
||||
{
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/about.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionAbout = new QAction(icon, tr("About"), this);
|
||||
action->setObjectName("actionAbout");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_delete.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionClose = new QAction(icon, tr("Close"), this);
|
||||
action->setObjectName("actionClose");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_copy.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionCopy = new QAction(icon, tr("Copy"), this);
|
||||
action->setObjectName("actionCopy");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/token_shortland_character.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionCopyAsCString = new QAction(icon, tr("Copy as C string"), this);
|
||||
action->setObjectName("actionCopyAsCString");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_C));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/token_shortland_character.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionCopyAsRawCppString = new QAction(icon, tr("Copy as raw C++-string"), this);
|
||||
action->setObjectName("actionCopyAsRawCppString");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_C));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/table_save.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionExportData = new QAction(icon, tr("Export data"), this);
|
||||
action->setObjectName("actionExportData");
|
||||
}
|
||||
{
|
||||
auto action = actionGenerateCode = new QAction(tr("Generate code"), this);
|
||||
action->setObjectName("actionGenerateCode");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_add.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionInspectInformationSchema = new QAction(icon, tr("Inspect information_schema"), this);
|
||||
action->setObjectName("actionInspectInformationSchema");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_add.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionInspectPgCatalog = new QAction(icon, tr("Inspect pg_catalog"), this);
|
||||
action->setObjectName("actionInspectPgCatalog");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_add.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionInspectUserSchemas = new QAction(icon, tr("Inspect user schemas"), this);
|
||||
action->setObjectName("actionInspectUserSchemas");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/new_query_tab.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionNewSql = new QAction(icon, tr("New Query"), this);
|
||||
action->setObjectName("actionNewSql");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/folder.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionOpenSql = new QAction(icon, tr("Open Query"), this);
|
||||
action->setObjectName("actionOpenSql");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/script_save.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
auto action = actionSaveSql = new QAction(icon, tr("Save query"), this);
|
||||
action->setObjectName("actionSaveSql");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
|
||||
}
|
||||
{
|
||||
auto action = actionSaveSqlAs = new QAction(tr("Save query as"), this);
|
||||
action->setObjectName("actionSaveSqlAs");
|
||||
}
|
||||
{
|
||||
auto action = actionSaveCopyOfSqlAs = new QAction(tr("Save copy of query as"), this);
|
||||
action->setObjectName("actionSaveCopyOfSqlAs");
|
||||
}
|
||||
{
|
||||
auto action = actionShowConnectionManager = new QAction(tr("Show connection manager"), this);
|
||||
action->setObjectName("actionShowConnectionManager");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DatabaseWindow::initMenus()
|
||||
{
|
||||
auto mb = new QMenuBar(this);
|
||||
menuFile = mb->addMenu(tr("File"));
|
||||
menuFile->addActions({
|
||||
actionNewSql,
|
||||
actionOpenSql,
|
||||
seperator(),
|
||||
actionSaveSql,
|
||||
actionSaveSqlAs,
|
||||
actionSaveCopyOfSqlAs,
|
||||
seperator(),
|
||||
actionExportData,
|
||||
seperator(),
|
||||
actionClose
|
||||
});
|
||||
|
||||
menuEdit = mb->addMenu(tr("Edit"));
|
||||
menuEdit->addActions({
|
||||
actionCopy,
|
||||
actionCopyAsCString,
|
||||
actionCopyAsRawCppString,
|
||||
actionGenerateCode
|
||||
});
|
||||
|
||||
menuWindow = mb->addMenu(tr("Window"));
|
||||
menuWindow->addActions({
|
||||
actionInspectUserSchemas,
|
||||
actionInspectPgCatalog,
|
||||
actionInspectInformationSchema,
|
||||
seperator(),
|
||||
actionShowConnectionManager
|
||||
});
|
||||
|
||||
|
||||
menuHelp = mb->addMenu(tr("Help"));
|
||||
menuHelp->addActions({
|
||||
seperator(),
|
||||
actionAbout
|
||||
});
|
||||
|
||||
setMenuBar(mb);
|
||||
}
|
||||
|
||||
QAction *DatabaseWindow::seperator()
|
||||
{
|
||||
auto ac = new QAction(this);
|
||||
ac->setSeparator(true);
|
||||
return ac;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DatabaseWindow::catalogLoaded()
|
||||
{
|
||||
try {
|
||||
m_database = loadWatcher.future().result();
|
||||
auto ctx = context();
|
||||
ctx->registerObject(m_database);
|
||||
|
||||
for (auto f : { "user", "pg_catalog", "information_schema" })
|
||||
ctx->moduleAction("pglab.catalog-inspector", "open", {
|
||||
{ "namespace-filter", f }
|
||||
});
|
||||
for (auto f : { "user", "pg_catalog", "information_schema" }) {
|
||||
// TODO open inspector windows
|
||||
}
|
||||
|
||||
|
||||
newCreateTablePage();
|
||||
} catch (const OpenDatabaseException &ex) {
|
||||
QMessageBox::critical(this, "Error reading database", ex.text());
|
||||
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
|
@ -104,15 +290,8 @@ void DatabaseWindow::on_actionAbout_triggered()
|
|||
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionShow_connection_manager_triggered()
|
||||
{
|
||||
m_masterController->showConnectionManager();
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionCopy_triggered()
|
||||
{
|
||||
// What should be copied?
|
||||
|
||||
QWidget *w = QApplication::focusWidget();
|
||||
QTableView *tv = dynamic_cast<QTableView*>(w);
|
||||
if (tv) {
|
||||
|
|
@ -128,4 +307,113 @@ void DatabaseWindow::on_actionCopy_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionCopyAsCString_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->copyQueryAsCString();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionCopyAsRawCppString_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->copyQueryAsRawCppString();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionExportData_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->exportData();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionGenerateCode_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->generateCode();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionClose_triggered()
|
||||
{
|
||||
m_tabWidget->tabCloseRequested(m_tabWidget->currentIndex());
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionInspectInformationSchema_triggered()
|
||||
{
|
||||
auto ct = new CatalogInspector(m_database, this);
|
||||
addPage(ct, "information_schema");
|
||||
ct->setNamespaceFilter(NamespaceFilter::InformationSchema);
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionInspectPgCatalog_triggered()
|
||||
{
|
||||
auto ct = new CatalogInspector(m_database, this);
|
||||
addPage(ct, "pg_catalog");
|
||||
ct->setNamespaceFilter(NamespaceFilter::PgCatalog);
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionInspectUserSchemas_triggered()
|
||||
{
|
||||
auto ct = new CatalogInspector(m_database, this);
|
||||
addPage(ct, "Schema");
|
||||
ct->setNamespaceFilter(NamespaceFilter::User);
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionNewSql_triggered()
|
||||
{
|
||||
auto *ct = new QueryTool(m_database, this);
|
||||
addPage(ct, "query");
|
||||
ct->newdoc();
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionOpenSql_triggered()
|
||||
{
|
||||
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
|
||||
QString file_name = QFileDialog::getOpenFileName(this,
|
||||
tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)"));
|
||||
if ( ! file_name.isEmpty()) {
|
||||
auto *ct = new QueryTool(m_database, this);
|
||||
if (ct->load(file_name)) {
|
||||
addPage(ct, "");
|
||||
}
|
||||
else {
|
||||
delete ct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionSaveSql_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->save();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionSaveSqlAs_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->saveAs();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionSaveCopyOfSqlAs_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
if (query_tool) {
|
||||
query_tool->saveCopyAs();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionShowConnectionManager_triggered()
|
||||
{
|
||||
m_masterController->showConnectionManager();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "plugin_support/LMainWindow.h"
|
||||
#include "ConnectionConfig.h"
|
||||
#include "OpenDatabase.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "ControllableTask.h"
|
||||
#include <QFutureWatcher>
|
||||
#include <QMainWindow>
|
||||
#include <memory>
|
||||
|
||||
namespace Pgsql {
|
||||
|
|
@ -16,15 +16,19 @@ namespace Pgsql {
|
|||
class MasterController;
|
||||
class QCloseEvent;
|
||||
class OpenDatabase;
|
||||
class QueryTool;
|
||||
class PgClass;
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QTabWidget;
|
||||
class QToolBar;
|
||||
|
||||
|
||||
/** This is the class for windows that handle tasks for a specific database/catalog
|
||||
*
|
||||
*/
|
||||
class DatabaseWindow : public LMainWindow {
|
||||
class DatabaseWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DatabaseWindow(MasterController *master, QWidget *parent);
|
||||
|
|
@ -34,15 +38,51 @@ public:
|
|||
|
||||
std::shared_ptr<OpenDatabase> getDatabase() { return m_database; }
|
||||
|
||||
void setTabCaptionForWidget(QWidget *widget, const QString &caption, const QString &hint);
|
||||
void setTabIcon(QWidget *widget, const QString &iconname);
|
||||
|
||||
/// Called when a newly created page is added to the QTabWidget
|
||||
void addPage(QWidget* page, QString caption);
|
||||
|
||||
void newCodeGenPage(QString query, std::shared_ptr<const Pgsql::Result> dbres);
|
||||
|
||||
QueryTool *GetActiveQueryTool();
|
||||
private:
|
||||
QTabWidget *m_tabWidget = nullptr;
|
||||
QToolBar *m_mainToolBar = nullptr;
|
||||
|
||||
ConnectionConfig m_config;
|
||||
std::shared_ptr<OpenDatabase> m_database;
|
||||
|
||||
MasterController *m_masterController;
|
||||
|
||||
// Standard menu's
|
||||
QMenu *m_fileMenu = nullptr;
|
||||
|
||||
// Standard actions
|
||||
QAction *actionAbout = nullptr;
|
||||
QAction *actionClose = nullptr;
|
||||
QAction *actionCopy = nullptr;
|
||||
QAction *actionCopyAsCString = nullptr;
|
||||
QAction *actionCopyAsRawCppString = nullptr;
|
||||
QAction *actionExportData = nullptr;
|
||||
QAction *actionGenerateCode = nullptr;
|
||||
QAction *actionInspectInformationSchema = nullptr; ///< Create or switch to pgcatalog tab
|
||||
QAction *actionInspectPgCatalog = nullptr; ///< Create or switch to pgcatalog tab
|
||||
QAction *actionInspectUserSchemas = nullptr; ///< Create or switch to pgcatalog tab
|
||||
QAction *actionNewSql = nullptr;
|
||||
QAction *actionOpenSql = nullptr;
|
||||
QAction *actionSaveSql = nullptr;
|
||||
QAction *actionSaveSqlAs = nullptr;
|
||||
QAction *actionSaveCopyOfSqlAs = nullptr;
|
||||
QAction *actionShowConnectionManager = nullptr;
|
||||
|
||||
QMenu *menuEdit = nullptr;
|
||||
QMenu *menuFile = nullptr;
|
||||
QMenu *menuHelp = nullptr;
|
||||
QMenu *menuWindow = nullptr;
|
||||
|
||||
|
||||
class LoadCatalog: public ControllableTask<OpenDatabase::OpenDatabaseSPtr> {
|
||||
public:
|
||||
LoadCatalog(ConnectionConfig config)
|
||||
|
|
@ -62,13 +102,31 @@ private:
|
|||
|
||||
void newCreateTablePage();
|
||||
|
||||
private slots:
|
||||
void createActions();
|
||||
void initMenus();
|
||||
|
||||
QAction* seperator();
|
||||
private slots:
|
||||
void catalogLoaded();
|
||||
// void tabWidget_tabCloseRequested(int index);
|
||||
// void tabWidget_currentChanged(int index);
|
||||
|
||||
void on_actionAbout_triggered();
|
||||
void on_actionShow_connection_manager_triggered();
|
||||
void on_actionClose_triggered();
|
||||
void on_actionCopy_triggered();
|
||||
void on_actionCopyAsCString_triggered();
|
||||
void on_actionCopyAsRawCppString_triggered();
|
||||
void on_actionExportData_triggered();
|
||||
void on_actionGenerateCode_triggered();
|
||||
void on_actionInspectInformationSchema_triggered();
|
||||
void on_actionInspectPgCatalog_triggered();
|
||||
void on_actionInspectUserSchemas_triggered();
|
||||
void on_actionNewSql_triggered();
|
||||
void on_actionOpenSql_triggered();
|
||||
void on_actionSaveSql_triggered();
|
||||
void on_actionSaveSqlAs_triggered();
|
||||
void on_actionSaveCopyOfSqlAs_triggered();
|
||||
void on_actionShowConnectionManager_triggered();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ int NotificationModel::columnCount(const QModelIndex &) const
|
|||
|
||||
QVariant NotificationModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant NotificationModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void NotificationService::addError(const QString &msg, const QString &detail)
|
|||
|
||||
void NotificationService::add(NotificationSeverity severity, const QString &msg, const QString &detail)
|
||||
{
|
||||
m_notifications.push_back({ severity, msg, detail });
|
||||
// m_notifications.push_back({ severity, msg, detail });
|
||||
}
|
||||
|
||||
int NotificationService::count() const
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ enum NotificationSeverity {
|
|||
Critical ///< Don't think you should ever need this in a correct program....
|
||||
};
|
||||
|
||||
class Notification: public QObject {
|
||||
Q_OBJECT
|
||||
class Notification {
|
||||
public:
|
||||
Notification() = default;
|
||||
Notification(int64_t id, NotificationSeverity severity, const QString &msg, const QString &detail = {});
|
||||
|
||||
int64_t id() const { return m_id; }
|
||||
|
|
@ -25,14 +25,15 @@ public:
|
|||
QString detailMessage() const { return m_detailMessage; }
|
||||
|
||||
private:
|
||||
int64_t m_id;
|
||||
NotificationSeverity m_severity;
|
||||
int64_t m_id = 0;
|
||||
NotificationSeverity m_severity = NotificationSeverity::Informational;
|
||||
QString m_shortMessage;
|
||||
QString m_detailMessage;
|
||||
|
||||
};
|
||||
|
||||
class NotificationService {
|
||||
class NotificationService: public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static std::shared_ptr<NotificationService> instance();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,19 +19,17 @@
|
|||
#include "util.h"
|
||||
#include "GlobalIoService.h"
|
||||
#include "UserConfiguration.h"
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
|
||||
|
||||
QueryTool::QueryTool(IPluginContentWidgetContext *context_, PluginModule *module, QWidget *parent)
|
||||
: PluginContentWidget(context_, module, parent)
|
||||
QueryTool::QueryTool(std::shared_ptr<OpenDatabase> open_database, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::QueryTab)
|
||||
, m_dbConnection(*getGlobalAsioIoService())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
auto db = context()->getObject<OpenDatabase>();
|
||||
m_config = db->config();
|
||||
m_catalog = db->catalog();
|
||||
m_config = open_database->config();
|
||||
m_catalog = open_database->catalog();
|
||||
|
||||
connect(&m_dbConnection, &ASyncDBConnection::onStateChanged, this, &QueryTool::connectionStateChanged);
|
||||
connect(&m_dbConnection, &ASyncDBConnection::onNotice, this, &QueryTool::receiveNotice);
|
||||
|
|
@ -39,11 +37,7 @@ QueryTool::QueryTool(IPluginContentWidgetContext *context_, PluginModule *module
|
|||
ui->queryEdit->setFont(UserConfiguration::instance()->codeFont());
|
||||
|
||||
highlighter = new SqlSyntaxHighlighter(ui->queryEdit->document());
|
||||
auto open_database = context()->getObject<OpenDatabase>();
|
||||
if (open_database) {
|
||||
auto cat = open_database->catalog();
|
||||
highlighter->setTypes(*cat->types());
|
||||
}
|
||||
highlighter->setTypes(*m_catalog->types());
|
||||
|
||||
initActions();
|
||||
|
||||
|
|
@ -232,7 +226,7 @@ void QueryTool::setFileName(const QString &filename)
|
|||
m_fileName = filename;
|
||||
QFileInfo fileInfo(filename);
|
||||
QString fn(fileInfo.fileName());
|
||||
context()->setCaption(this, fn, m_fileName);
|
||||
// context()->setCaption(this, fn, m_fileName);
|
||||
}
|
||||
|
||||
bool QueryTool::continueWithoutSavingWarning()
|
||||
|
|
@ -307,7 +301,7 @@ void QueryTool::connectionStateChanged(ASyncDBConnection::State state)
|
|||
case ASyncDBConnection::State::Terminating:
|
||||
break;
|
||||
}
|
||||
context()->setIcon(this, iconname);
|
||||
// context()->setIcon(this, iconname);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -396,7 +390,7 @@ void QueryTool::explain_ready(ExplainRoot::SPtr explain)
|
|||
ui->explainTreeView->setColumnWidth(6, 600);
|
||||
ui->tabWidget->setCurrentWidget(ui->explainTab);
|
||||
|
||||
context()->showStatusMessage(tr("Explain ready."));
|
||||
// context()->showStatusMessage(tr("Explain ready."));
|
||||
}
|
||||
else {
|
||||
addLog("Explain no result");
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include "tuplesresultwidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include "plugin_support/PluginContentWidget.h"
|
||||
#include <memory>
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -31,10 +30,10 @@ class OpenDatabase;
|
|||
class QueryParamListController;
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class QueryTool : public PluginContentWidget {
|
||||
class QueryTool : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QueryTool(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent = nullptr);
|
||||
QueryTool(std::shared_ptr<OpenDatabase> open_database, QWidget *parent = nullptr);
|
||||
~QueryTool() override;
|
||||
|
||||
void newdoc();
|
||||
|
|
@ -42,7 +41,7 @@ public:
|
|||
|
||||
void explain(bool analyze);
|
||||
|
||||
bool canClose() override;
|
||||
bool canClose();
|
||||
|
||||
void generateCode();
|
||||
void exportDataToFilename(const QString &filename);
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
#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());
|
||||
{
|
||||
StaticAction ma("New SQL", [this] (IPluginContentWidgetContext* context)
|
||||
{ staticAction_new(context); });
|
||||
ma.setMenuLocation(MenuPath("File/New"));
|
||||
ma.setToolbarLocation(ToolbarLocation("main", "new"));
|
||||
ma.setIcon(QIcon(":/icons/new_query_tab.png"));
|
||||
ma.setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
|
||||
registerStaticAction(ma);
|
||||
}
|
||||
{
|
||||
StaticAction ma("Open SQL", [this] (IPluginContentWidgetContext* context)
|
||||
{ staticAction_open(context); });
|
||||
ma.setMenuLocation(MenuPath("File/Open"));
|
||||
ma.setToolbarLocation(ToolbarLocation("main", "open"));
|
||||
ma.setIcon(QIcon(":/icons/folder.png"));
|
||||
registerStaticAction(ma);
|
||||
}
|
||||
|
||||
{
|
||||
auto ca = makeContextAction<QueryTool>(tr("Save SQL"), &QueryTool::save);
|
||||
ca->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
|
||||
ca->setMenuLocation(MenuPath("File/Save"));
|
||||
ca->setToolbarLocation(ToolbarLocation("main", "save"));
|
||||
// how we tell the system we want this to become a menu button with this as it's default action
|
||||
registerContextAction(ca);
|
||||
}
|
||||
{
|
||||
auto ca = makeContextAction<QueryTool>(tr("Save SQL as"), &QueryTool::saveAs);
|
||||
ca->setMenuLocation(MenuPath("File/Save"));
|
||||
ca->setToolbarLocation(ToolbarLocation("main", "save"));
|
||||
// how we tell the system we want this to become a secondary action for the previous button?
|
||||
registerContextAction(ca);
|
||||
}
|
||||
{
|
||||
auto ca = makeContextAction<QueryTool>(tr("Save copy of SQL as"), &QueryTool::saveCopyAs);
|
||||
ca->setMenuLocation(MenuPath("File/Save"));
|
||||
ca->setToolbarLocation(ToolbarLocation("main", "save"));
|
||||
// how we tell the system we want this to become a secondary action for the previous button?
|
||||
registerContextAction(ca);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QueryToolModule::staticAction_new(IPluginContentWidgetContext* context)
|
||||
{
|
||||
auto *ct = new QueryTool(context, this);
|
||||
|
||||
// Should we let constructor of PluginContentWidget do this?
|
||||
// Saves a line but what if we don't want it.
|
||||
context->addContentWidget(ct);
|
||||
|
||||
// should content widget now to which module it belongs?
|
||||
// That way the context would not need to keep track of this.
|
||||
|
||||
ct->newdoc();
|
||||
}
|
||||
|
||||
void QueryToolModule::staticAction_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, this);
|
||||
context->addContentWidget(ct);
|
||||
if (!ct->load(file_name)) {
|
||||
// TODO load has failed remove widget or never add it?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_PLUGIN_MODULE_CAT(QueryToolModule, "Query tool", "pglab.querytool", "database")
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#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 staticAction_new(IPluginContentWidgetContext* context);
|
||||
void staticAction_open(IPluginContentWidgetContext* context);
|
||||
private slots:
|
||||
};
|
||||
|
||||
|
||||
#endif // QUERYTOOLMODULE_H
|
||||
|
|
@ -5,7 +5,6 @@
|
|||
#endif
|
||||
#include <memory>
|
||||
#include "GlobalIoService.h"
|
||||
#include "plugin_support/PluginRegister.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -30,8 +29,6 @@ int main(int argc, char *argv[])
|
|||
QCoreApplication::setOrganizationDomain("eelkeklein.nl");
|
||||
QCoreApplication::setApplicationName("pglab");
|
||||
|
||||
PluginRegister::getInstance()->initModules();
|
||||
|
||||
std::thread asio_service_thread;
|
||||
int result = -1;
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@ SOURCES += main.cpp\
|
|||
ConnectionManagerWindow.cpp \
|
||||
ConnectionListModel.cpp \
|
||||
BackupRestore.cpp \
|
||||
plugin_support/LMenu.cpp \
|
||||
plugin_support/LMenuBar.cpp \
|
||||
plugin_support/LMenuItem.cpp \
|
||||
plugin_support/LMenuSection.cpp \
|
||||
stopwatch.cpp \
|
||||
TuplesResultWidget.cpp \
|
||||
BackupDialog.cpp \
|
||||
|
|
@ -79,19 +75,8 @@ PropertyProxyModel.cpp \
|
|||
SequenceModel.cpp \
|
||||
DatabaseWindow.cpp \
|
||||
PgLabTableView.cpp \
|
||||
plugin_support/PluginModule.cpp \
|
||||
plugin_support/MenuPath.cpp \
|
||||
plugin_support/MenuLocation.cpp \
|
||||
plugin_support/ToolbarLocation.cpp \
|
||||
plugin_support/PluginRegister.cpp \
|
||||
plugin_support/PluginContentWidget.cpp \
|
||||
plugin_support/PluginContentWidgetContextBase.cpp \
|
||||
plugin_support/LMainWindow.cpp \
|
||||
QueryTool.cpp \
|
||||
QueryToolModule.cpp \
|
||||
CatalogInspector.cpp \
|
||||
plugin_support/StaticAction.cpp \
|
||||
plugin_support/LMainMenu.cpp \
|
||||
widgets/CatalogIndexPage.cpp \
|
||||
widgets/CatalogPageBase.cpp \
|
||||
widgets/CatalogConstraintPage.cpp \
|
||||
|
|
@ -108,10 +93,6 @@ HEADERS += \
|
|||
CreateDatabaseDialog.h \
|
||||
ConnectionManagerWindow.h \
|
||||
ConnectionListModel.h \
|
||||
plugin_support/LMenu.h \
|
||||
plugin_support/LMenuBar.h \
|
||||
plugin_support/LMenuItem.h \
|
||||
plugin_support/LMenuSection.h \
|
||||
stopwatch.h \
|
||||
TuplesResultWidget.h \
|
||||
BackupDialog.h \
|
||||
|
|
@ -159,21 +140,8 @@ CustomDataRole.h \
|
|||
SequenceModel.h \
|
||||
DatabaseWindow.h \
|
||||
PgLabTableView.h \
|
||||
plugin_support/PluginModule.h \
|
||||
plugin_support/MenuPath.h \
|
||||
plugin_support/MenuLocation.h \
|
||||
plugin_support/ToolbarLocation.h \
|
||||
plugin_support/PluginRegister.h \
|
||||
plugin_support/PluginContentWidget.h \
|
||||
plugin_support/ModuleActionParameters.h \
|
||||
plugin_support/IPluginContentWidgetContext.h \
|
||||
plugin_support/PluginContentWidgetContextBase.h \
|
||||
plugin_support/LMainWindow.h \
|
||||
QueryTool.h \
|
||||
QueryToolModule.h \
|
||||
CatalogInspector.h \
|
||||
plugin_support/StaticAction.h \
|
||||
plugin_support/LMainMenu.h \
|
||||
widgets/CatalogIndexPage.h \
|
||||
widgets/CatalogPageBase.h \
|
||||
widgets/CatalogConstraintPage.h \
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
#ifndef IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
#define IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
|
||||
#include <QString>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#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.
|
||||
*
|
||||
* It provides interface for operating on the context without needing to many details.
|
||||
* Actual default implementation is in PluginContentWidgetContextBase.
|
||||
*
|
||||
* objectRegistry implementation is from Igor Tandetnik answer to the following question
|
||||
* https://stackoverflow.com/questions/35413745/using-shared-ptr-with-a-generic-registry-or-shared-object-storage-or-not
|
||||
*/
|
||||
class IPluginContentWidgetContext {
|
||||
public:
|
||||
|
||||
virtual ~IPluginContentWidgetContext() = default;
|
||||
/** Tells the context what to use as a caption for this content widget.
|
||||
*
|
||||
* Depending on the context the caption might not be visible or used as the caption
|
||||
* of a window or tab.
|
||||
*/
|
||||
virtual void setCaption(PluginContentWidget *content, const QString &caption, const QString &hint = {}) = 0;
|
||||
/** Tells the context what icon to use.
|
||||
*
|
||||
* In general the icon is used in a similar place as the caption.
|
||||
* \param iconname Assumed to be the name of an iconresource. The system will look for different
|
||||
* sizes under :/icons/<size>/iconname
|
||||
*/
|
||||
virtual void setIcon(PluginContentWidget *content, const QString &iconname) = 0;
|
||||
|
||||
virtual void showStatusMessage(const QString &msg) = 0;
|
||||
|
||||
virtual void moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
) = 0;
|
||||
|
||||
virtual void addContentWidget(PluginContentWidget *widget) = 0;
|
||||
virtual void removeContentWidget(PluginContentWidget *widget) = 0;
|
||||
|
||||
/** Return a widget you can use as a parent
|
||||
*/
|
||||
virtual QWidget* container() = 0;
|
||||
|
||||
template<typename T, class...Args>
|
||||
bool addObjects(Args&&...args);
|
||||
template<typename T>
|
||||
bool registerObject(std::shared_ptr<T> object);
|
||||
template<typename T>
|
||||
std::shared_ptr<T> getObject() const;
|
||||
|
||||
private:
|
||||
std::map<std::type_index, std::shared_ptr<void> > m_objectRegistry;
|
||||
|
||||
};
|
||||
|
||||
template<typename T, class...Args>
|
||||
bool IPluginContentWidgetContext::addObjects(Args&&...args)
|
||||
{
|
||||
std::type_index key(typeid(T));
|
||||
if (!m_objectRegistry.count(key)) {
|
||||
auto p = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
m_objectRegistry[key] = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool IPluginContentWidgetContext::registerObject(std::shared_ptr<T> object)
|
||||
{
|
||||
return m_objectRegistry.emplace(std::type_index(typeid(T)), object).second;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<T> IPluginContentWidgetContext::getObject() const
|
||||
{
|
||||
auto it = m_objectRegistry.find(typeid(T));
|
||||
if (it == m_objectRegistry.end()) {
|
||||
return {};
|
||||
}
|
||||
return std::static_pointer_cast<T>(it->second);
|
||||
}
|
||||
|
||||
|
||||
#endif // IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "LMainMenu.h"
|
||||
|
||||
LMainMenu::LMainMenu()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#ifndef LMAINMENU_H
|
||||
#define LMAINMENU_H
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
|
||||
class QAction;
|
||||
|
||||
class LMenuGroupItem {
|
||||
public:
|
||||
LMenuGroupItem(QAction *action, int position)
|
||||
: m_menuAction(action)
|
||||
, m_position(position)
|
||||
{}
|
||||
|
||||
int position() const { return m_position; }
|
||||
|
||||
private:
|
||||
QAction *m_menuAction;
|
||||
int m_position;
|
||||
};
|
||||
|
||||
// Menu's are divided into logical groups,
|
||||
// these groups form only a single level they are NOT submenu's
|
||||
class LMenuGroup {
|
||||
public:
|
||||
|
||||
explicit LMenuGroup(QString group_id);
|
||||
QString groupId() const;
|
||||
|
||||
private:
|
||||
QString m_groupId;
|
||||
};
|
||||
|
||||
class LMenu {
|
||||
public:
|
||||
QString menuId() const;
|
||||
|
||||
void addGroup(const LMenuGroup &group)
|
||||
{
|
||||
m_groups.push_back(group);
|
||||
}
|
||||
private:
|
||||
using Groups = std::vector<LMenuGroup>;
|
||||
|
||||
QString m_caption;
|
||||
Groups m_groups;
|
||||
};
|
||||
|
||||
|
||||
class LMainMenu: public LMenu {
|
||||
public:
|
||||
LMainMenu();
|
||||
};
|
||||
|
||||
#endif // LMAINMENU_H
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
#include "LMainWindow.h"
|
||||
#include "PluginContentWidget.h"
|
||||
#include "PluginContentWidgetContextBase.h"
|
||||
#include "PluginModule.h"
|
||||
#include "PluginRegister.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMenuBar>
|
||||
#include <QStatusBar>
|
||||
#include <QToolBar>
|
||||
|
||||
namespace LMainWindow_details {
|
||||
|
||||
class LMainWindowContentContext: public PluginContentWidgetContextBase {
|
||||
public:
|
||||
explicit LMainWindowContentContext(LMainWindow *window)
|
||||
: m_window(window)
|
||||
{}
|
||||
|
||||
void setCaption(PluginContentWidget *content, const QString &caption, const QString &hint = {}) override
|
||||
{
|
||||
m_window->setTabCaptionForWidget(content, caption, hint);
|
||||
}
|
||||
|
||||
void setIcon(PluginContentWidget *content, const QString &iconname) override
|
||||
{
|
||||
m_window->setTabIcon(content, iconname);
|
||||
}
|
||||
|
||||
void showStatusMessage(const QString &msg) override
|
||||
{
|
||||
m_window->statusBar()->showMessage(msg);
|
||||
}
|
||||
|
||||
void addContentWidget(PluginContentWidget *widget) override
|
||||
{
|
||||
PluginContentWidgetContextBase::addContentWidget(widget);
|
||||
m_window->addPage(widget, "");
|
||||
}
|
||||
|
||||
QWidget* container() override
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
private:
|
||||
LMainWindow *m_window;
|
||||
};
|
||||
|
||||
}
|
||||
using namespace LMainWindow_details;
|
||||
|
||||
|
||||
|
||||
LMainWindow::LMainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
m_context = new LMainWindowContentContext(this);
|
||||
|
||||
m_tabWidget = new QTabWidget(this);
|
||||
m_tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
|
||||
m_tabWidget->setDocumentMode(true);
|
||||
|
||||
setCentralWidget(m_tabWidget);
|
||||
|
||||
// menu
|
||||
auto menuBar = new QMenuBar(this);
|
||||
setMenuBar(menuBar);
|
||||
|
||||
// tooolbar
|
||||
m_mainToolBar = new QToolBar(this);
|
||||
addToolBar(Qt::TopToolBarArea, m_mainToolBar);
|
||||
|
||||
// statusbar
|
||||
auto statusBar = new QStatusBar(this);
|
||||
setStatusBar(statusBar);
|
||||
|
||||
m_fileMenu = new QMenu(tr("File"), this);
|
||||
|
||||
createActions();
|
||||
m_mainToolBar->addAction(m_closeAction);
|
||||
|
||||
connect(m_tabWidget, &QTabWidget::tabCloseRequested, this, &LMainWindow::tabWidget_tabCloseRequested);
|
||||
connect(m_tabWidget, &QTabWidget::currentChanged, this, &LMainWindow::tabWidget_currentChanged);
|
||||
}
|
||||
|
||||
LMainWindow::~LMainWindow()
|
||||
{
|
||||
delete m_context;
|
||||
}
|
||||
|
||||
void LMainWindow::initModuleMenus()
|
||||
{
|
||||
menuBar()->addMenu(m_fileMenu);
|
||||
addModuleMenuActions();
|
||||
}
|
||||
|
||||
void LMainWindow::addModuleMenuActions()
|
||||
{
|
||||
auto reg = PluginRegister::getInstance();
|
||||
auto mods = reg->modules();
|
||||
for (auto && mod : mods) {
|
||||
auto items = mod.second->staticActions();
|
||||
for (auto && item : items) {
|
||||
addMenuAction(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LMainWindow::createActions()
|
||||
{
|
||||
{
|
||||
auto action = m_closeAction = new QAction(this);
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/page_white_delete.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
action->setIcon(icon);
|
||||
connect(m_closeAction, &QAction::triggered, this, &LMainWindow::actionClose_triggered);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LMainWindow::addMenuAction(const StaticAction &ma)
|
||||
{
|
||||
qDebug() << "add action " << ma.text();
|
||||
//auto ac =
|
||||
m_fileMenu->addAction(ma.icon(), ma.text(),
|
||||
[ma, this] ()
|
||||
{
|
||||
ma.perform(m_context);
|
||||
},
|
||||
ma.shortcut());
|
||||
|
||||
|
||||
// auto ac = new QAction(this);
|
||||
// ac->
|
||||
}
|
||||
|
||||
void LMainWindow::actionClose_triggered()
|
||||
{
|
||||
m_tabWidget->tabCloseRequested(m_tabWidget->currentIndex());
|
||||
}
|
||||
|
||||
|
||||
void LMainWindow::addPage(PluginContentWidget* page, QString caption)
|
||||
{
|
||||
m_tabWidget->addTab(page, caption);
|
||||
m_tabWidget->setCurrentWidget(page);
|
||||
}
|
||||
|
||||
void LMainWindow::setTabCaptionForWidget(QWidget *widget, const QString &caption, const QString &hint)
|
||||
{
|
||||
auto index = m_tabWidget->indexOf(widget);
|
||||
m_tabWidget->setTabText(index, caption);
|
||||
m_tabWidget->setTabToolTip(index, hint);
|
||||
}
|
||||
|
||||
void LMainWindow::setTabIcon(QWidget *widget, const QString &iconname)
|
||||
{
|
||||
auto index = m_tabWidget->indexOf(widget);
|
||||
auto n = ":/icons/16x16/" + iconname;
|
||||
m_tabWidget->setTabIcon(index, QIcon(n));
|
||||
}
|
||||
|
||||
IPluginContentWidgetContext* LMainWindow::context()
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void LMainWindow::tabWidget_tabCloseRequested(int index)
|
||||
{
|
||||
QWidget *widget = m_tabWidget->widget(index);
|
||||
PluginContentWidget *plg_page = dynamic_cast<PluginContentWidget*>(widget);
|
||||
if (plg_page) {
|
||||
if (plg_page->canClose()) {
|
||||
m_tabWidget->removeTab(index);
|
||||
m_context->removeContentWidget(plg_page);
|
||||
delete plg_page;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// old behaviour shouldn't be needed any more when all pages have been migrated
|
||||
// to PlgPage
|
||||
m_tabWidget->removeTab(index);
|
||||
delete widget;
|
||||
}
|
||||
}
|
||||
|
||||
void LMainWindow::tabWidget_currentChanged(int index)
|
||||
{
|
||||
// remove buttons of old page
|
||||
if (m_previousPage) {
|
||||
removeModuleWidgetActionsForPage(m_previousPage);
|
||||
}
|
||||
|
||||
// add buttons of new page
|
||||
PluginContentWidget * page = nullptr;
|
||||
if (index >= 0) {
|
||||
QWidget *widget = m_tabWidget->widget(index);
|
||||
page = dynamic_cast<PluginContentWidget*>(widget);
|
||||
if (page) {
|
||||
addModuleWidgetActionsForPage(page);
|
||||
}
|
||||
}
|
||||
m_previousPage = page;
|
||||
}
|
||||
|
||||
void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||
{
|
||||
m_context->addWidgetActionsToToolbar(page, m_mainToolBar);
|
||||
m_context->addContextActionsToMenu(page, menuBar());
|
||||
}
|
||||
|
||||
void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||
{
|
||||
m_context->removeContextActionsFromMenu(page, menuBar());
|
||||
m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar);
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef LMAINWINDOW_H
|
||||
#define LMAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
class IPluginContentWidgetContext;
|
||||
class StaticAction;
|
||||
class PluginContentWidget;
|
||||
|
||||
namespace LMainWindow_details {
|
||||
class LMainWindowContentContext;
|
||||
}
|
||||
|
||||
class LMainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
LMainWindow(QWidget *parent = nullptr);
|
||||
~LMainWindow();
|
||||
|
||||
void initModuleMenus();
|
||||
void setTabCaptionForWidget(QWidget *widget, const QString &caption, const QString &hint);
|
||||
void setTabIcon(QWidget *widget, const QString &iconname);
|
||||
|
||||
/// Called when a newly created page is added to the QTabWidget
|
||||
void addPage(PluginContentWidget* page, QString caption);
|
||||
|
||||
IPluginContentWidgetContext* context();
|
||||
protected:
|
||||
QTabWidget *m_tabWidget = nullptr;
|
||||
QToolBar *m_mainToolBar = nullptr;
|
||||
|
||||
// Standard menu's
|
||||
QMenu *m_fileMenu = nullptr;
|
||||
|
||||
// Standard actions
|
||||
QAction *m_closeAction = nullptr;
|
||||
|
||||
|
||||
void addModuleMenuActions();
|
||||
|
||||
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
|
||||
|
||||
void createActions();
|
||||
void addMenuAction(const StaticAction &ma);
|
||||
|
||||
private slots:
|
||||
void actionClose_triggered();
|
||||
void tabWidget_tabCloseRequested(int index);
|
||||
void tabWidget_currentChanged(int index);
|
||||
};
|
||||
|
||||
|
||||
#endif // LMAINWINDOW_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "LMenu.h"
|
||||
|
||||
LMenu::LMenu()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef LMENU_H
|
||||
#define LMENU_H
|
||||
|
||||
/** Represents a menu wraps QMenu to give it more dynamic functionality
|
||||
*
|
||||
*/
|
||||
class LMenu
|
||||
{
|
||||
public:
|
||||
LMenu();
|
||||
};
|
||||
|
||||
#endif // LMENU_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "LMenuBar.h"
|
||||
|
||||
LMenuBar::LMenuBar()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef LMENUBAR_H
|
||||
#define LMENUBAR_H
|
||||
|
||||
/** Represents the main menubar. Linked to a QMenuBar
|
||||
*/
|
||||
class LMenuBar {
|
||||
public:
|
||||
LMenuBar();
|
||||
};
|
||||
|
||||
#endif // LMENUBAR_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "LMenuItem.h"
|
||||
|
||||
LMenuItem::LMenuItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef LMENUITEM_H
|
||||
#define LMENUITEM_H
|
||||
|
||||
|
||||
class LMenuItem {
|
||||
public:
|
||||
LMenuItem();
|
||||
};
|
||||
|
||||
#endif // LMENUITEM_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "LMenuSection.h"
|
||||
|
||||
LMenuSection::LMenuSection()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef LMENUSECTION_H
|
||||
#define LMENUSECTION_H
|
||||
|
||||
/** Logical grouping within a menu
|
||||
*/
|
||||
class LMenuSection {
|
||||
public:
|
||||
LMenuSection();
|
||||
};
|
||||
|
||||
#endif // LMENUSECTION_H
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#include "MenuLocation.h"
|
||||
|
||||
MenuLocation::MenuLocation() = default;
|
||||
|
||||
MenuLocation::MenuLocation(MenuPath path, int position)
|
||||
: m_path(std::move(path))
|
||||
, m_position(position)
|
||||
{}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef MENULOCATION_H
|
||||
#define MENULOCATION_H
|
||||
|
||||
#include "plugin_support/MenuPath.h"
|
||||
#include <QString>
|
||||
|
||||
///
|
||||
class MenuLocation {
|
||||
public:
|
||||
|
||||
MenuLocation();
|
||||
MenuLocation(MenuPath path, int position = -1);
|
||||
|
||||
bool isEmpty() const;
|
||||
private:
|
||||
MenuPath m_path;
|
||||
int m_position = -1;
|
||||
};
|
||||
|
||||
#endif // MENULOCATION_H
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#include "MenuPath.h"
|
||||
|
||||
MenuPath::MenuPath() = default;
|
||||
|
||||
//MenuPath::MenuPath(QString menu_path)
|
||||
// : m_menuPath(std::move(menu_path))
|
||||
//{
|
||||
//}
|
||||
|
||||
MenuPath::MenuPath(QString menu_path)
|
||||
{
|
||||
auto parts = menu_path.splitRef('/');
|
||||
for (auto&& elem : parts) {
|
||||
m_elems.emplace_back(elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef MENUPATH_H
|
||||
#define MENUPATH_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/// For a menu path we use a string very similar to a file path. Width however the addition of semicolons
|
||||
/// for specifying groups. So the following path
|
||||
///
|
||||
/// /File:Save
|
||||
///
|
||||
/// Specifies the File menu and the group Save within that menu while
|
||||
///
|
||||
/// /File/Export
|
||||
///
|
||||
/// Would specify the export sub menu of the file menu
|
||||
///
|
||||
class MenuPath {
|
||||
public:
|
||||
MenuPath();
|
||||
MenuPath(QString menu_path);
|
||||
|
||||
|
||||
private:
|
||||
class Elem {
|
||||
public:
|
||||
QStringRef menu;
|
||||
QStringRef group;
|
||||
|
||||
explicit Elem(QStringRef s)
|
||||
{
|
||||
auto p = s.split(':');
|
||||
menu = p[0];
|
||||
if (p.size() > 1) {
|
||||
group = p[1];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Elem> m_elems;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // MENUPATH_H
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef MODULEACTIONPARAMETERS_H
|
||||
#define MODULEACTIONPARAMETERS_H
|
||||
|
||||
#include <map>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
using ModuleActionParameters = std::map<QString, QVariant>;
|
||||
|
||||
#endif // MODULEACTIONPARAMETERS_H
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#include "PluginContentWidget.h"
|
||||
|
||||
PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context,
|
||||
PluginModule *module, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_context(context)
|
||||
, m_pluginModule(module)
|
||||
{}
|
||||
|
||||
bool PluginContentWidget::canClose()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<QAction *> PluginContentWidget::actions()
|
||||
{ return QList<QAction*>(); }
|
||||
|
||||
PluginModule *PluginContentWidget::pluginModule()
|
||||
{ return m_pluginModule; }
|
||||
|
||||
IPluginContentWidgetContext *PluginContentWidget::context()
|
||||
{ return m_context; }
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef PGLPAGE_H
|
||||
#define PGLPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
|
||||
class IPluginContentWidgetContext;
|
||||
class PluginModule;
|
||||
|
||||
/// Provides a pluggable system for toolbar buttons and menu actions
|
||||
///
|
||||
/// We will need several kind of actions
|
||||
/// - create actions, these will create a new document or load from file , always available in menu
|
||||
/// - save actions available when on tab
|
||||
/// - edit actions
|
||||
/// - custom menu?
|
||||
///
|
||||
/// Can we use same groupings for toolbars and menu's
|
||||
/// How about additional toolbars?
|
||||
///
|
||||
class PluginContentWidget: public QWidget{
|
||||
public:
|
||||
PluginContentWidget(IPluginContentWidgetContext *context, PluginModule *module, QWidget* parent = nullptr);
|
||||
/// Returns the toolbar buttons for this page
|
||||
virtual bool canClose();
|
||||
|
||||
virtual QList<QAction *> actions();
|
||||
|
||||
PluginModule *pluginModule();
|
||||
IPluginContentWidgetContext *context();
|
||||
protected:
|
||||
|
||||
private:
|
||||
IPluginContentWidgetContext *m_context = nullptr;
|
||||
PluginModule *m_pluginModule = nullptr;
|
||||
};
|
||||
|
||||
#endif // PGLPAGE_H
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
#include "PluginContentWidgetContextBase.h"
|
||||
#include "PluginContentWidget.h"
|
||||
#include "PluginModule.h"
|
||||
#include "PluginRegister.h"
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QMenuBar>
|
||||
#include <QToolBar>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
LWidgetData::LWidgetData(PluginModule *module, PluginContentWidget *widget)
|
||||
: m_module(module)
|
||||
, m_widget(widget)
|
||||
{}
|
||||
|
||||
void LWidgetData::init()
|
||||
{
|
||||
}
|
||||
|
||||
void LWidgetData::addToMenu(QMenuBar *menubar)
|
||||
{
|
||||
auto&& menu = menubar->actions().first()->menu();
|
||||
|
||||
auto ti = std::type_index(typeid(*m_widget));
|
||||
auto&& actions = m_module->actionsForContext(ti);
|
||||
m_menuActions.reserve(actions.size());
|
||||
for (auto&& actiondef : actions) {
|
||||
auto ac = actiondef->createAction(m_widget);
|
||||
menu->addAction(ac);
|
||||
m_menuActions.push_back(ac);
|
||||
}
|
||||
}
|
||||
|
||||
void LWidgetData::removeFromMenu(QMenuBar *menubar)
|
||||
{
|
||||
for (auto&& action : m_menuActions) {
|
||||
delete action;
|
||||
}
|
||||
m_menuActions.clear();
|
||||
}
|
||||
|
||||
|
||||
PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default;
|
||||
|
||||
void PluginContentWidgetContextBase::moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
)
|
||||
{
|
||||
auto reg = PluginRegister::getInstance();
|
||||
auto mod = reg->findModule(module_identifier);
|
||||
if (mod) {
|
||||
auto action = mod->findModuleAction(module_action);
|
||||
if (action) {
|
||||
qDebug() << QString("module %1 action %2 called ").arg(module_identifier, module_action);
|
||||
(*action)(this, action_params);
|
||||
}
|
||||
else
|
||||
qWarning() << QString("module %1 has no action %2").arg(module_identifier, module_action);
|
||||
}
|
||||
else
|
||||
qWarning() << QString("module not found %1").arg(module_identifier);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::addContentWidget(PluginContentWidget *widget)
|
||||
{
|
||||
auto res = m_widgetLst.emplace(widget, LWidgetData{widget->pluginModule(), widget});
|
||||
if (!res.second)
|
||||
throw std::runtime_error("Unexpected conflicting key on insertiong PluginContentWidgetContextBase::addContentWidget");
|
||||
|
||||
res.first->second.init();
|
||||
}
|
||||
|
||||
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 && actions = widget->actions();
|
||||
toolbar->addActions(actions);
|
||||
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar)
|
||||
{
|
||||
auto && actions = widget->actions();
|
||||
for (auto && ac : actions)
|
||||
toolbar->removeAction(ac);
|
||||
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::addContextActionsToMenu(PluginContentWidget *widget, QMenuBar *menubar)
|
||||
{
|
||||
auto res = m_widgetLst.find(widget);
|
||||
if (res == m_widgetLst.end())
|
||||
return;
|
||||
res->second.addToMenu(menubar);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::removeContextActionsFromMenu(PluginContentWidget *widget, QMenuBar *menubar)
|
||||
{
|
||||
auto res = m_widgetLst.find(widget);
|
||||
if (res == m_widgetLst.end())
|
||||
return;
|
||||
res->second.removeFromMenu(menubar);
|
||||
}
|
||||
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#ifndef PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
#define PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
#include <QList>
|
||||
#include <typeindex>
|
||||
|
||||
class LContextAction;
|
||||
class QToolBar;
|
||||
class QAction;
|
||||
class QMenuBar;
|
||||
|
||||
/// Maintains the list of actions added to a toolbar for a specific widget
|
||||
/// it facilitates the removal of all those actions.
|
||||
class WidgetToolbarActionList {
|
||||
public:
|
||||
QToolBar *m_toolBar;
|
||||
std::vector<QAction*> m_actions;
|
||||
void removeAll()
|
||||
{
|
||||
// for (auto && a : m_actions)
|
||||
// m_toolBar->removeAction(a);
|
||||
}
|
||||
};
|
||||
|
||||
class WidgetToolbarManager {
|
||||
public:
|
||||
void addAction(QAction *action, QString section);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LWidgetData {
|
||||
public:
|
||||
LWidgetData(PluginModule *module, PluginContentWidget *widget);
|
||||
PluginModule* module() { return m_module; }
|
||||
PluginContentWidget *widget() { return m_widget; }
|
||||
void init();
|
||||
|
||||
void addToMenu(QMenuBar* menubar);
|
||||
void removeFromMenu(QMenuBar* menubar);
|
||||
private:
|
||||
PluginModule *m_module;
|
||||
PluginContentWidget *m_widget;
|
||||
WidgetToolbarManager m_toolbarManager;
|
||||
|
||||
std::vector<QAction*> m_menuActions; ///< List of actions we put in the menu
|
||||
};
|
||||
|
||||
/// Provides base implementation of IPluginContentWidgetContext
|
||||
class PluginContentWidgetContextBase : public IPluginContentWidgetContext
|
||||
{
|
||||
public:
|
||||
PluginContentWidgetContextBase();
|
||||
|
||||
void moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
) override;
|
||||
|
||||
void addContentWidget(PluginContentWidget *widget) override;
|
||||
void removeContentWidget(PluginContentWidget *widget) override;
|
||||
|
||||
void addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||
void removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||
|
||||
void addContextActionsToMenu(PluginContentWidget *widget, QMenuBar *menubar);
|
||||
void removeContextActionsFromMenu(PluginContentWidget *widget, QMenuBar *menubar);
|
||||
private:
|
||||
|
||||
using WidgetLst = std::map<PluginContentWidget*, LWidgetData>;
|
||||
|
||||
WidgetLst m_widgetLst; /// Keeps track of which widget belongs to which module
|
||||
};
|
||||
|
||||
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
#include "plugin_support/PluginModule.h"
|
||||
#include "PluginContentWidget.h"
|
||||
#include <QDebug>
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
|
||||
PluginModule::PluginModule(QString name, QString ident)
|
||||
: m_name(std::move(name))
|
||||
, m_ident(std::move(ident))
|
||||
{
|
||||
}
|
||||
|
||||
void PluginModule::setDisplayCategory(QString category)
|
||||
{
|
||||
m_displayCategory = std::move(category);
|
||||
}
|
||||
|
||||
void PluginModule::registerStaticAction(StaticAction action)
|
||||
{
|
||||
m_menuActions.emplace_back(std::move(action));
|
||||
}
|
||||
|
||||
const PluginModule::StaticActionList& PluginModule::staticActions() const
|
||||
{
|
||||
return m_menuActions;
|
||||
}
|
||||
|
||||
void PluginModule::registerModuleAction(QString module_action, ModuleAction action)
|
||||
{
|
||||
m_moduleActions.emplace(
|
||||
std::move(module_action),
|
||||
std::move(action)
|
||||
);
|
||||
}
|
||||
|
||||
const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString &module_action) const
|
||||
{
|
||||
auto res = m_moduleActions.find(module_action);
|
||||
if (res == m_moduleActions.end())
|
||||
return nullptr;
|
||||
return &res->second;
|
||||
}
|
||||
|
||||
void PluginModule::registerContextAction(std::shared_ptr<ContextBaseAction> action)
|
||||
{
|
||||
auto find_result_iter = m_contextMap.find(action->contextTypeIndex());
|
||||
if (find_result_iter != m_contextMap.end())
|
||||
find_result_iter->second.push_back(action);
|
||||
else
|
||||
m_contextMap.emplace(action->contextTypeIndex(), ContextActionContainer({ action }));
|
||||
}
|
||||
|
||||
const PluginModule::ContextActionContainer &PluginModule::actionsForContext(std::type_index ti)
|
||||
{
|
||||
static const ContextActionContainer empty_result;
|
||||
|
||||
auto find_result_iter = m_contextMap.find(ti);
|
||||
if (find_result_iter != m_contextMap.end())
|
||||
return find_result_iter->second;
|
||||
|
||||
return empty_result;
|
||||
}
|
||||
|
||||
const PluginModule::ContextActionContainer& PluginModule::actionsForContext(PluginContentWidget *widget)
|
||||
{
|
||||
return actionsForContext(std::type_index(typeid(*widget)));
|
||||
}
|
||||
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#ifndef PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
#define PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
|
||||
#include "ModuleActionParameters.h"
|
||||
#include "StaticAction.h"
|
||||
#include "PluginRegister.h"
|
||||
#include <QObject>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <typeindex>
|
||||
|
||||
class QAction;
|
||||
class IPluginContentWidgetContext;
|
||||
class PluginContentWidget;
|
||||
|
||||
/** Defines available actions for the application framework.
|
||||
*
|
||||
* There are static and context actions.
|
||||
* There can be multiple contexts which are seperated by there typeid/type_index.
|
||||
*/
|
||||
class PluginModule: public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using StaticActionList = std::vector<StaticAction>;
|
||||
using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>;
|
||||
using ModuleActionMap = std::map<QString, ModuleAction>;
|
||||
|
||||
using ContextActionContainer = std::vector<std::shared_ptr<ContextBaseAction>>;
|
||||
|
||||
PluginModule(QString name, QString ident);
|
||||
|
||||
virtual void init() {}
|
||||
|
||||
const QString& name() const { return m_name; }
|
||||
const QString& identifier() const { return m_ident; }
|
||||
const QString& displayCategory() const { return m_displayCategory; }
|
||||
|
||||
void setDisplayCategory(QString category);
|
||||
|
||||
/// registers an action that should always be accessible from the menu
|
||||
void registerStaticAction(StaticAction action);
|
||||
const StaticActionList& staticActions() const;
|
||||
|
||||
/// "API" action that other modules can trigger by name without being linked to
|
||||
/// this module. Allows for loose coupling.
|
||||
void registerModuleAction(QString module_action, ModuleAction action);
|
||||
|
||||
/// 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 registerContextAction(std::shared_ptr<ContextBaseAction> action);
|
||||
|
||||
std::set<std::type_index> contextTypeIndexes();
|
||||
const ContextActionContainer& actionsForContext(std::type_index ti);
|
||||
const ContextActionContainer& actionsForContext(PluginContentWidget *widget);
|
||||
|
||||
private:
|
||||
using ContextMap = std::unordered_map<std::type_index, ContextActionContainer>;
|
||||
|
||||
/// Name shown to end users
|
||||
QString m_name;
|
||||
/// Unique identifier
|
||||
QString m_ident;
|
||||
QString m_displayCategory;
|
||||
|
||||
StaticActionList m_menuActions;
|
||||
ModuleActionMap m_moduleActions;
|
||||
ContextMap m_contextMap;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<PluginModule> createPluginModule(QString name, QString ident, QString category={})
|
||||
{
|
||||
auto module = std::make_shared<T>(std::move(name), std::move(ident));
|
||||
module->setDisplayCategory(category);
|
||||
|
||||
PluginRegister::getInstance()->registerModule(module);
|
||||
return std::move(module);
|
||||
}
|
||||
|
||||
#define REGISTER_PLUGIN_MODULE(module, name, ident) \
|
||||
namespace {\
|
||||
std::weak_ptr<PluginModule> register_variable = createPluginModule<module>\
|
||||
(name, ident);}
|
||||
|
||||
#define REGISTER_PLUGIN_MODULE_CAT(module, name, ident, category) \
|
||||
namespace {\
|
||||
std::weak_ptr<PluginModule> register_variable = createPluginModule<module>\
|
||||
(name, ident, category);}
|
||||
|
||||
|
||||
#endif // PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#include "PluginRegister.h"
|
||||
#include "plugin_support/PluginModule.h"
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
PluginRegister* PluginRegister::s_pluginRegister;
|
||||
|
||||
PluginRegister* PluginRegister::getInstance()
|
||||
{
|
||||
static std::mutex m;
|
||||
// check if set without locking first (in most cases it will be set and it will never be unset) so locking the mutex everytime
|
||||
// is a waist of time.
|
||||
if (!s_pluginRegister) {
|
||||
// not set then lock
|
||||
std::lock_guard<std::mutex> guard(m);
|
||||
// recheck in case someone else just set it
|
||||
if (!s_pluginRegister) {
|
||||
s_pluginRegister = new PluginRegister;
|
||||
}
|
||||
}
|
||||
return s_pluginRegister;
|
||||
}
|
||||
|
||||
PluginRegister::PluginRegister() = default;
|
||||
|
||||
void PluginRegister::initModules()
|
||||
{
|
||||
for (auto && mod : m_moduleMap) {
|
||||
mod.second->init();
|
||||
}
|
||||
}
|
||||
|
||||
void PluginRegister::registerModule(PluginModuleSPtr module)
|
||||
{
|
||||
qDebug() << "registerModule " << module->identifier();
|
||||
m_moduleMap.emplace(module->identifier(), module);
|
||||
}
|
||||
|
||||
const PluginModule* PluginRegister::findModule(const QString &module_ident) const
|
||||
{
|
||||
auto res = m_moduleMap.find(module_ident);
|
||||
if (res == m_moduleMap.end())
|
||||
return nullptr;
|
||||
return res->second.get();
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef PLUGINREGISTER_H
|
||||
#define PLUGINREGISTER_H
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <QString>
|
||||
|
||||
class QAction;
|
||||
class PluginModule;
|
||||
|
||||
class PluginRegister {
|
||||
public:
|
||||
using PluginModuleSPtr = std::shared_ptr<PluginModule>;
|
||||
using ModuleMap = std::map<QString, PluginModuleSPtr>;
|
||||
|
||||
static PluginRegister* getInstance();
|
||||
|
||||
PluginRegister();
|
||||
void registerModule(PluginModuleSPtr module);
|
||||
|
||||
void initModules();
|
||||
const ModuleMap& modules() const{ return m_moduleMap; }
|
||||
|
||||
const PluginModule* findModule(const QString &module_ident) const;
|
||||
private:
|
||||
|
||||
ModuleMap m_moduleMap;
|
||||
|
||||
static PluginRegister* s_pluginRegister;
|
||||
};
|
||||
|
||||
|
||||
#endif // PLUGINREGISTER_H
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
#include "StaticAction.h"
|
||||
|
||||
BaseAction::BaseAction(const QString &text)
|
||||
: m_text(text)
|
||||
{}
|
||||
|
||||
const QIcon& BaseAction::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
const MenuLocation& BaseAction::menuLocation() const
|
||||
{
|
||||
return m_menuLocation;
|
||||
}
|
||||
|
||||
void BaseAction::setIcon(QIcon icon)
|
||||
{
|
||||
m_icon = std::move(icon);
|
||||
}
|
||||
|
||||
void BaseAction::setMenuLocation(MenuLocation menu_location)
|
||||
{
|
||||
m_menuLocation = std::move(menu_location);
|
||||
}
|
||||
|
||||
void BaseAction::setToolbarLocation(ToolbarLocation toolbar_location)
|
||||
{
|
||||
m_toolbarLocation = toolbar_location;
|
||||
}
|
||||
|
||||
void BaseAction::setShortcut(QKeySequence shortcut)
|
||||
{
|
||||
m_shortcut = std::move(shortcut);
|
||||
}
|
||||
|
||||
void BaseAction::setText(QString text)
|
||||
{
|
||||
m_text = std::move(text);
|
||||
}
|
||||
|
||||
void BaseAction::setToolTip(QString tooltip)
|
||||
{
|
||||
m_toolTip = std::move(tooltip);
|
||||
}
|
||||
|
||||
const QKeySequence& BaseAction::shortcut() const
|
||||
{
|
||||
return m_shortcut;
|
||||
}
|
||||
|
||||
const QString& BaseAction::text() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
const QString& BaseAction::toolTip() const
|
||||
{
|
||||
return m_toolTip;
|
||||
}
|
||||
|
||||
StaticAction::StaticAction(QString text, Func func)
|
||||
: BaseAction(std::move(text))
|
||||
, m_func(std::move(func))
|
||||
{}
|
||||
|
||||
void StaticAction::perform(IPluginContentWidgetContext *context) const
|
||||
{
|
||||
if (m_func)
|
||||
m_func(context);
|
||||
}
|
||||
|
||||
|
||||
ContextBaseAction::~ContextBaseAction()
|
||||
{}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
#ifndef MENUACTION_H
|
||||
#define MENUACTION_H
|
||||
|
||||
#include "MenuLocation.h"
|
||||
#include "ToolbarLocation.h"
|
||||
#include "plugin_support/PluginContentWidget.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QIcon>
|
||||
#include <QKeySequence>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
#include <typeindex>
|
||||
|
||||
class IPluginContentWidgetContext;
|
||||
|
||||
class BaseAction {
|
||||
public:
|
||||
explicit BaseAction(const QString &text);
|
||||
|
||||
const QIcon& icon() const;
|
||||
const MenuLocation& menuLocation() const;
|
||||
void setIcon(QIcon icon);
|
||||
void setMenuLocation(MenuLocation menu_location);
|
||||
void setToolbarLocation(ToolbarLocation toolbar_location);
|
||||
void setShortcut(QKeySequence shortcut);
|
||||
void setText(QString text);
|
||||
void setToolTip(QString tooltip);
|
||||
const QKeySequence& shortcut() const;
|
||||
const QString& text() const;
|
||||
const QString& toolTip() const;
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
QString m_toolTip;
|
||||
QIcon m_icon;
|
||||
QKeySequence m_shortcut;
|
||||
MenuLocation m_menuLocation;
|
||||
ToolbarLocation m_toolbarLocation;
|
||||
|
||||
};
|
||||
/** An action for in a menu or toolbar that does not pertain to a specific
|
||||
* widget. It often will create a widget for instance a New or Open action.
|
||||
* It does need a context.
|
||||
*
|
||||
*/
|
||||
class StaticAction: public BaseAction {
|
||||
public:
|
||||
using Func = std::function<void(IPluginContentWidgetContext *context)>;
|
||||
|
||||
StaticAction(QString text, Func func);
|
||||
|
||||
|
||||
void perform(IPluginContentWidgetContext *context) const;
|
||||
private:
|
||||
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
|
||||
class ContextBaseAction: public BaseAction {
|
||||
public:
|
||||
using BaseAction::BaseAction;
|
||||
virtual ~ContextBaseAction();
|
||||
|
||||
virtual std::type_index contextTypeIndex() const = 0;
|
||||
|
||||
virtual QAction* createAction(PluginContentWidget *widget)
|
||||
{
|
||||
auto action = new QAction(widget);
|
||||
action->setText(text());
|
||||
setupConnectionForAction(action, widget);
|
||||
return action;
|
||||
}
|
||||
|
||||
virtual void setupConnectionForAction(QAction *action, PluginContentWidget *context) = 0;
|
||||
};
|
||||
|
||||
class QAction;
|
||||
|
||||
/** Defines an action that can be performed within a certain context.
|
||||
* For instance the save action for a query can only be called when a query is loaded.
|
||||
*
|
||||
* Note Func should be something that QAction::triggered can connect to. If not you
|
||||
* could get quite a vague error.
|
||||
*/
|
||||
template <typename Context, typename Func>
|
||||
class ContextAction: public ContextBaseAction {
|
||||
public:
|
||||
//using Func = void (Context::*)(bool);
|
||||
|
||||
ContextAction(QString text, Func func)
|
||||
: ContextBaseAction(text)
|
||||
, m_func(func)
|
||||
{}
|
||||
|
||||
std::type_index contextTypeIndex() const override
|
||||
{
|
||||
return std::type_index(typeid(Context));
|
||||
}
|
||||
|
||||
// Mostly a helper for the code that creates the QAction
|
||||
// without the helper that would need template code to.
|
||||
virtual void setupConnectionForAction(QAction *action, PluginContentWidget *context) override
|
||||
{
|
||||
QObject::connect(action, &QAction::triggered, dynamic_cast<Context*>(context), m_func);
|
||||
}
|
||||
|
||||
private:
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
template <typename Context, typename Func>
|
||||
auto makeContextAction(QString text, Func func)
|
||||
{
|
||||
return std::make_shared<ContextAction<Context, Func>>(text, func);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // MENUACTION_H
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#include "ToolbarLocation.h"
|
||||
|
||||
ToolbarLocation::ToolbarLocation() = default;
|
||||
|
||||
ToolbarLocation::ToolbarLocation(QString toolbar, QString group, int position)
|
||||
: m_toolbar(std::move(toolbar))
|
||||
, m_group(std::move(group))
|
||||
, m_position(position)
|
||||
{}
|
||||
|
||||
bool ToolbarLocation::isEmpty() const
|
||||
{
|
||||
return m_toolbar.isEmpty();
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef TOOLBARLOCATION_H
|
||||
#define TOOLBARLOCATION_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ToolbarLocation {
|
||||
public:
|
||||
ToolbarLocation();
|
||||
ToolbarLocation(QString toolbar, QString group, int position = -1);
|
||||
|
||||
bool isEmpty() const;
|
||||
private:
|
||||
QString m_toolbar;
|
||||
QString m_group;
|
||||
int m_position = -1;
|
||||
};
|
||||
|
||||
|
||||
#endif // TOOLBARLOCATION_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue