Proof of concept for having the context actions statically defined in the module.
Needs work for correctly placing the items in menu and on toolbar. Old system still needs to be removed left in place to keep app useable.
This commit is contained in:
parent
7f09d5fe07
commit
601d071d0f
21 changed files with 303 additions and 70 deletions
|
|
@ -12,8 +12,8 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, QWidget *parent)
|
CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, PluginModule *module, QWidget *parent)
|
||||||
: PluginContentWidget(context_, parent)
|
: PluginContentWidget(context_, module, parent)
|
||||||
{
|
{
|
||||||
m_tabWidget = new QTabWidget(this);
|
m_tabWidget = new QTabWidget(this);
|
||||||
m_tablesPage = new CatalogTablesPage(this);
|
m_tablesPage = new CatalogTablesPage(this);
|
||||||
|
|
@ -93,8 +93,8 @@ void CatalogInspectorModule::moduleAction_open(
|
||||||
const ModuleActionParameters ¶ms
|
const ModuleActionParameters ¶ms
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto ct = new CatalogInspector(context, nullptr);
|
auto ct = new CatalogInspector(context, this);
|
||||||
context->addContentWidget(this, ct);
|
context->addContentWidget(ct);
|
||||||
auto nsf = params.at("namespace-filter").toString();
|
auto nsf = params.at("namespace-filter").toString();
|
||||||
NamespaceFilter filter = NamespaceFilter::User;
|
NamespaceFilter filter = NamespaceFilter::User;
|
||||||
if (nsf == "pg_catalog") filter = NamespaceFilter::PgCatalog;
|
if (nsf == "pg_catalog") filter = NamespaceFilter::PgCatalog;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ class QTabWidget;
|
||||||
class CatalogInspector : public PluginContentWidget {
|
class CatalogInspector : public PluginContentWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CatalogInspector(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
|
explicit CatalogInspector(IPluginContentWidgetContext *context, PluginModule *module,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
~CatalogInspector();
|
~CatalogInspector();
|
||||||
|
|
||||||
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
|
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include "UserConfiguration.h"
|
#include "UserConfiguration.h"
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
CodeGenerator::CodeGenerator(IPluginContentWidgetContext *context, QWidget *parent) :
|
CodeGenerator::CodeGenerator(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent) :
|
||||||
PluginContentWidget(context, parent),
|
PluginContentWidget(context, module, parent),
|
||||||
ui(new Ui::CodeGenerator)
|
ui(new Ui::CodeGenerator)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class CodeGenerator : public PluginContentWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CodeGenerator(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
|
CodeGenerator(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent = nullptr);
|
||||||
~CodeGenerator();
|
~CodeGenerator();
|
||||||
|
|
||||||
void Init(std::shared_ptr<PgDatabaseCatalog> catalog, QString query, std::shared_ptr<const Pgsql::Result> dbres);
|
void Init(std::shared_ptr<PgDatabaseCatalog> catalog, QString query, std::shared_ptr<const Pgsql::Result> dbres);
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||||
|
|
||||||
|
|
||||||
CrudTab::CrudTab(IPluginContentWidgetContext *context, QWidget *parent)
|
CrudTab::CrudTab(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent)
|
||||||
: PluginContentWidget(context, parent)
|
: PluginContentWidget(context, module, parent)
|
||||||
, ui(new Ui::CrudTab)
|
, ui(new Ui::CrudTab)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
@ -140,8 +140,8 @@ 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, this);
|
||||||
context->addContentWidget(this, ct); // maybe CrudTab should do this
|
context->addContentWidget(ct); // maybe CrudTab should do this
|
||||||
ct->setConfig(params.at("oid").toUInt());
|
ct->setConfig(params.at("oid").toUInt());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ class CrudTab : public PluginContentWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CrudTab(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
|
explicit CrudTab(IPluginContentWidgetContext *context, PluginModule *module,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
~CrudTab() override;
|
~CrudTab() override;
|
||||||
|
|
||||||
void setConfig(Oid oid);
|
void setConfig(Oid oid);
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,12 @@ void DatabaseWindow::newCreateTablePage()
|
||||||
|
|
||||||
void DatabaseWindow::newCodeGenPage(QString query, std::shared_ptr<const Pgsql::Result> dbres)
|
void DatabaseWindow::newCodeGenPage(QString query, std::shared_ptr<const Pgsql::Result> dbres)
|
||||||
{
|
{
|
||||||
auto cgtab = new CodeGenerator(context(), this);
|
// TODO should this call be this direct or should it go through module system
|
||||||
cgtab->Init(m_database->catalog(), query, dbres);
|
// yes it should otherwise context cannot properly setup toolbar and menu!!!
|
||||||
addPage(cgtab, "Codegen");
|
// auto cgtab = new CodeGenerator(context(), pluginModule(), this);
|
||||||
|
// cgtab->Init(m_database->catalog(), query, dbres);
|
||||||
|
// addPage(cgtab, "Codegen");
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWindow::setConfig(const ConnectionConfig &config)
|
void DatabaseWindow::setConfig(const ConnectionConfig &config)
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,9 @@ void PgLabItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
||||||
else {
|
else {
|
||||||
auto str = value.toString();
|
auto str = value.toString();
|
||||||
auto s = str.leftRef(100);
|
auto s = str.leftRef(100);
|
||||||
auto f = s.indexOf('\n');
|
// auto f = s.indexOf('\n');
|
||||||
option->text = ((f > 0) ? s.left(f) : s).toString();
|
// option->text = ((f > 0) ? s.left(f) : s).toString();
|
||||||
|
option->text = s.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@
|
||||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||||
|
|
||||||
|
|
||||||
QueryTool::QueryTool(IPluginContentWidgetContext *context_, QWidget *parent)
|
QueryTool::QueryTool(IPluginContentWidgetContext *context_, PluginModule *module, QWidget *parent)
|
||||||
: PluginContentWidget(context_, parent)
|
: PluginContentWidget(context_, module, parent)
|
||||||
, ui(new Ui::QueryTab)
|
, ui(new Ui::QueryTab)
|
||||||
, m_dbConnection(*getGlobalAsioIoService())
|
, m_dbConnection(*getGlobalAsioIoService())
|
||||||
{
|
{
|
||||||
|
|
@ -632,8 +632,6 @@ void QueryTool::exportData()
|
||||||
|
|
||||||
void QueryTool::initActions()
|
void QueryTool::initActions()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto ac = new QAction(QIcon(":/icons/script_save.png"), tr("Save SQL"), this);
|
auto ac = new QAction(QIcon(":/icons/script_save.png"), tr("Save SQL"), this);
|
||||||
ac->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
|
ac->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class PgDatabaseCatalog;
|
||||||
class QueryTool : public PluginContentWidget {
|
class QueryTool : public PluginContentWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QueryTool(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
|
QueryTool(IPluginContentWidgetContext *context, PluginModule *module, QWidget *parent = nullptr);
|
||||||
~QueryTool() override;
|
~QueryTool() override;
|
||||||
|
|
||||||
void newdoc();
|
void newdoc();
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,43 @@ void QueryToolModule::init()
|
||||||
ma.setIcon(QIcon(":/icons/folder.png"));
|
ma.setIcon(QIcon(":/icons/folder.png"));
|
||||||
registerStaticAction(ma);
|
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)
|
void QueryToolModule::staticAction_new(IPluginContentWidgetContext* context)
|
||||||
{
|
{
|
||||||
auto *ct = new QueryTool(context, nullptr);
|
auto *ct = new QueryTool(context, this);
|
||||||
context->addContentWidget(this, ct);
|
|
||||||
|
// 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();
|
ct->newdoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,9 +72,11 @@ void QueryToolModule::staticAction_open(IPluginContentWidgetContext* context)
|
||||||
QString file_name = QFileDialog::getOpenFileName(context->container(),
|
QString file_name = QFileDialog::getOpenFileName(context->container(),
|
||||||
tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)"));
|
tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)"));
|
||||||
if ( ! file_name.isEmpty()) {
|
if ( ! file_name.isEmpty()) {
|
||||||
auto *ct = new QueryTool(context, nullptr);
|
auto *ct = new QueryTool(context, this);
|
||||||
context->addContentWidget(this, ct);
|
context->addContentWidget(ct);
|
||||||
ct->load(file_name);
|
if (!ct->load(file_name)) {
|
||||||
|
// TODO load has failed remove widget or never add it?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public:
|
||||||
const ModuleActionParameters &action_params
|
const ModuleActionParameters &action_params
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
virtual void addContentWidget(PluginModule *module, PluginContentWidget *widget) = 0;
|
virtual void addContentWidget(PluginContentWidget *widget) = 0;
|
||||||
virtual void removeContentWidget(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
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,9 @@ namespace LMainWindow_details {
|
||||||
m_window->statusBar()->showMessage(msg);
|
m_window->statusBar()->showMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addContentWidget(PluginModule *module, PluginContentWidget *widget) override
|
void addContentWidget(PluginContentWidget *widget) override
|
||||||
{
|
{
|
||||||
PluginContentWidgetContextBase::addContentWidget(module, widget);
|
PluginContentWidgetContextBase::addContentWidget(widget);
|
||||||
m_window->addPage(widget, "");
|
m_window->addPage(widget, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,9 +207,11 @@ void LMainWindow::tabWidget_currentChanged(int index)
|
||||||
void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page)
|
void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||||
{
|
{
|
||||||
m_context->addWidgetActionsToToolbar(page, m_mainToolBar);
|
m_context->addWidgetActionsToToolbar(page, m_mainToolBar);
|
||||||
|
m_context->addContextActionsToMenu(page, menuBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page)
|
void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||||
{
|
{
|
||||||
|
m_context->removeContextActionsFromMenu(page, menuBar());
|
||||||
m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar);
|
m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,22 @@
|
||||||
#include "PluginContentWidget.h"
|
#include "PluginContentWidget.h"
|
||||||
|
|
||||||
PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent)
|
PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context,
|
||||||
|
PluginModule *module, QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_context(context)
|
, m_context(context)
|
||||||
|
, m_pluginModule(module)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool PluginContentWidget::canClose()
|
bool PluginContentWidget::canClose()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QAction *> PluginContentWidget::actions()
|
||||||
|
{ return QList<QAction*>(); }
|
||||||
|
|
||||||
|
PluginModule *PluginContentWidget::pluginModule()
|
||||||
|
{ return m_pluginModule; }
|
||||||
|
|
||||||
|
IPluginContentWidgetContext *PluginContentWidget::context()
|
||||||
|
{ return m_context; }
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,19 @@ class PluginModule;
|
||||||
///
|
///
|
||||||
class PluginContentWidget: public QWidget{
|
class PluginContentWidget: public QWidget{
|
||||||
public:
|
public:
|
||||||
PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent = nullptr);
|
PluginContentWidget(IPluginContentWidgetContext *context, PluginModule *module, QWidget* parent = nullptr);
|
||||||
/// Returns the toolbar buttons for this page
|
/// Returns the toolbar buttons for this page
|
||||||
virtual bool canClose();
|
virtual bool canClose();
|
||||||
|
|
||||||
virtual QList<QAction *> actions() { return QList<QAction*>(); }
|
virtual QList<QAction *> actions();
|
||||||
|
|
||||||
|
PluginModule *pluginModule();
|
||||||
|
IPluginContentWidgetContext *context();
|
||||||
protected:
|
protected:
|
||||||
IPluginContentWidgetContext *context() { return m_context; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPluginContentWidgetContext *m_context;
|
IPluginContentWidgetContext *m_context = nullptr;
|
||||||
|
PluginModule *m_pluginModule = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PGLPAGE_H
|
#endif // PGLPAGE_H
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,43 @@
|
||||||
#include "PluginRegister.h"
|
#include "PluginRegister.h"
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QMenuBar>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LWidgetData::LWidgetData(PluginModule *module)
|
LWidgetData::LWidgetData(PluginModule *module, PluginContentWidget *widget)
|
||||||
: m_module(module)
|
: m_module(module)
|
||||||
|
, m_widget(widget)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void LWidgetData::init(PluginContentWidget *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;
|
PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default;
|
||||||
|
|
||||||
|
|
@ -41,13 +65,13 @@ void PluginContentWidgetContextBase::moduleAction(
|
||||||
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)
|
void PluginContentWidgetContextBase::addContentWidget(PluginContentWidget *widget)
|
||||||
{
|
{
|
||||||
auto res = m_widgetLst.emplace(widget, module);
|
auto res = m_widgetLst.emplace(widget, LWidgetData{widget->pluginModule(), widget});
|
||||||
if (!res.second)
|
if (!res.second)
|
||||||
throw std::runtime_error("Unexpected conflicting key on insertiong PluginContentWidgetContextBase::addContentWidget");
|
throw std::runtime_error("Unexpected conflicting key on insertiong PluginContentWidgetContextBase::addContentWidget");
|
||||||
|
|
||||||
res.first->second.init(widget);
|
res.first->second.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *widget)
|
void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *widget)
|
||||||
|
|
@ -64,6 +88,7 @@ void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidg
|
||||||
{
|
{
|
||||||
auto && actions = widget->actions();
|
auto && actions = widget->actions();
|
||||||
toolbar->addActions(actions);
|
toolbar->addActions(actions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar)
|
void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar)
|
||||||
|
|
@ -73,3 +98,20 @@ void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginConten
|
||||||
toolbar->removeAction(ac);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
class LContextAction;
|
class LContextAction;
|
||||||
class QToolBar;
|
class QToolBar;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
class QMenuBar;
|
||||||
|
|
||||||
/// Maintains the list of actions added to a toolbar for a specific widget
|
/// Maintains the list of actions added to a toolbar for a specific widget
|
||||||
/// it facilitates the removal of all those actions.
|
/// it facilitates the removal of all those actions.
|
||||||
|
|
@ -32,13 +34,19 @@ private:
|
||||||
|
|
||||||
class LWidgetData {
|
class LWidgetData {
|
||||||
public:
|
public:
|
||||||
LWidgetData(PluginModule *module);
|
LWidgetData(PluginModule *module, PluginContentWidget *widget);
|
||||||
PluginModule* module() { return m_module; }
|
PluginModule* module() { return m_module; }
|
||||||
void init(PluginContentWidget *widget);
|
PluginContentWidget *widget() { return m_widget; }
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void addToMenu(QMenuBar* menubar);
|
||||||
|
void removeFromMenu(QMenuBar* menubar);
|
||||||
private:
|
private:
|
||||||
PluginModule *m_module;
|
PluginModule *m_module;
|
||||||
|
PluginContentWidget *m_widget;
|
||||||
WidgetToolbarManager m_toolbarManager;
|
WidgetToolbarManager m_toolbarManager;
|
||||||
|
|
||||||
|
std::vector<QAction*> m_menuActions; ///< List of actions we put in the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Provides base implementation of IPluginContentWidgetContext
|
/// Provides base implementation of IPluginContentWidgetContext
|
||||||
|
|
@ -53,16 +61,19 @@ public:
|
||||||
const ModuleActionParameters &action_params
|
const ModuleActionParameters &action_params
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
void addContentWidget(PluginModule *module, PluginContentWidget *widget) override;
|
void addContentWidget(PluginContentWidget *widget) override;
|
||||||
void removeContentWidget(PluginContentWidget *widget) override;
|
void removeContentWidget(PluginContentWidget *widget) override;
|
||||||
|
|
||||||
void addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
void addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||||
void removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
void removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||||
|
|
||||||
|
void addContextActionsToMenu(PluginContentWidget *widget, QMenuBar *menubar);
|
||||||
|
void removeContextActionsFromMenu(PluginContentWidget *widget, QMenuBar *menubar);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
using WidgetLst = std::map<PluginContentWidget*, LWidgetData>;
|
using WidgetLst = std::map<PluginContentWidget*, LWidgetData>;
|
||||||
|
|
||||||
WidgetLst m_widgetLst;
|
WidgetLst m_widgetLst; /// Keeps track of which widget belongs to which module
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H
|
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#include "plugin_support/PluginModule.h"
|
#include "plugin_support/PluginModule.h"
|
||||||
|
#include "PluginContentWidget.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
PluginModule::PluginModule(QString name, QString ident)
|
PluginModule::PluginModule(QString name, QString ident)
|
||||||
: m_name(std::move(name))
|
: m_name(std::move(name))
|
||||||
|
|
@ -14,7 +17,6 @@ void PluginModule::setDisplayCategory(QString category)
|
||||||
|
|
||||||
void PluginModule::registerStaticAction(StaticAction action)
|
void PluginModule::registerStaticAction(StaticAction action)
|
||||||
{
|
{
|
||||||
qDebug() << "registerMenuAction " << action.text();
|
|
||||||
m_menuActions.emplace_back(std::move(action));
|
m_menuActions.emplace_back(std::move(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,3 +41,28 @@ const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString &
|
||||||
return &res->second;
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,20 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
class IPluginContentWidgetContext;
|
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 {
|
class PluginModule: public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
@ -19,6 +28,8 @@ public:
|
||||||
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>;
|
||||||
|
|
||||||
|
using ContextActionContainer = std::vector<std::shared_ptr<ContextBaseAction>>;
|
||||||
|
|
||||||
PluginModule(QString name, QString ident);
|
PluginModule(QString name, QString ident);
|
||||||
|
|
||||||
virtual void init() {}
|
virtual void init() {}
|
||||||
|
|
@ -41,7 +52,15 @@ public:
|
||||||
/// 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 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:
|
private:
|
||||||
|
using ContextMap = std::unordered_map<std::type_index, ContextActionContainer>;
|
||||||
|
|
||||||
/// Name shown to end users
|
/// Name shown to end users
|
||||||
QString m_name;
|
QString m_name;
|
||||||
/// Unique identifier
|
/// Unique identifier
|
||||||
|
|
@ -50,6 +69,7 @@ private:
|
||||||
|
|
||||||
StaticActionList m_menuActions;
|
StaticActionList m_menuActions;
|
||||||
ModuleActionMap m_moduleActions;
|
ModuleActionMap m_moduleActions;
|
||||||
|
ContextMap m_contextMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,75 @@
|
||||||
#include "StaticAction.h"
|
#include "StaticAction.h"
|
||||||
|
|
||||||
StaticAction::StaticAction(QString text, Func func)
|
BaseAction::BaseAction(const QString &text)
|
||||||
: m_text(std::move(text))
|
: m_text(text)
|
||||||
, m_func(std::move(func))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const QIcon& StaticAction::icon() const
|
const QIcon& BaseAction::icon() const
|
||||||
{
|
{
|
||||||
return m_icon;
|
return m_icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuLocation& StaticAction::menuLocation() const
|
const MenuLocation& BaseAction::menuLocation() const
|
||||||
{
|
{
|
||||||
return m_menuLocation;
|
return m_menuLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setIcon(QIcon icon)
|
void BaseAction::setIcon(QIcon icon)
|
||||||
{
|
{
|
||||||
m_icon = std::move(icon);
|
m_icon = std::move(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setMenuLocation(MenuLocation menu_location)
|
void BaseAction::setMenuLocation(MenuLocation menu_location)
|
||||||
{
|
{
|
||||||
m_menuLocation = std::move(menu_location);
|
m_menuLocation = std::move(menu_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setToolbarLocation(ToolbarLocation toolbar_location)
|
void BaseAction::setToolbarLocation(ToolbarLocation toolbar_location)
|
||||||
{
|
{
|
||||||
m_toolbarLocation = toolbar_location;
|
m_toolbarLocation = toolbar_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setShortcut(QKeySequence shortcut)
|
void BaseAction::setShortcut(QKeySequence shortcut)
|
||||||
{
|
{
|
||||||
m_shortcut = std::move(shortcut);
|
m_shortcut = std::move(shortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setText(QString text)
|
void BaseAction::setText(QString text)
|
||||||
{
|
{
|
||||||
m_text = std::move(text);
|
m_text = std::move(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticAction::setToolTip(QString tooltip)
|
void BaseAction::setToolTip(QString tooltip)
|
||||||
{
|
{
|
||||||
m_toolTip = std::move(tooltip);
|
m_toolTip = std::move(tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QKeySequence& StaticAction::shortcut() const
|
const QKeySequence& BaseAction::shortcut() const
|
||||||
{
|
{
|
||||||
return m_shortcut;
|
return m_shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& StaticAction::text() const
|
const QString& BaseAction::text() const
|
||||||
{
|
{
|
||||||
return m_text;
|
return m_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& StaticAction::toolTip() const
|
const QString& BaseAction::toolTip() const
|
||||||
{
|
{
|
||||||
return m_toolTip;
|
return m_toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StaticAction::StaticAction(QString text, Func func)
|
||||||
|
: BaseAction(std::move(text))
|
||||||
|
, m_func(std::move(func))
|
||||||
|
{}
|
||||||
|
|
||||||
void StaticAction::perform(IPluginContentWidgetContext *context) const
|
void StaticAction::perform(IPluginContentWidgetContext *context) const
|
||||||
{
|
{
|
||||||
if (m_func)
|
if (m_func)
|
||||||
m_func(context);
|
m_func(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ContextBaseAction::~ContextBaseAction()
|
||||||
|
{}
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,20 @@
|
||||||
|
|
||||||
#include "MenuLocation.h"
|
#include "MenuLocation.h"
|
||||||
#include "ToolbarLocation.h"
|
#include "ToolbarLocation.h"
|
||||||
|
#include "plugin_support/PluginContentWidget.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
class IPluginContentWidgetContext;
|
class IPluginContentWidgetContext;
|
||||||
|
|
||||||
/** An action for in a menu or toolbar that does not pertain to a specific
|
class BaseAction {
|
||||||
* widget. It often will create a widget for instance a New or Open action.
|
|
||||||
* It does need a context.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class StaticAction {
|
|
||||||
public:
|
public:
|
||||||
using Func = std::function<void(IPluginContentWidgetContext *context)>;
|
explicit BaseAction(const QString &text);
|
||||||
|
|
||||||
StaticAction(QString text, Func func);
|
|
||||||
|
|
||||||
const QIcon& icon() const;
|
const QIcon& icon() const;
|
||||||
const MenuLocation& menuLocation() const;
|
const MenuLocation& menuLocation() const;
|
||||||
|
|
@ -34,7 +30,6 @@ public:
|
||||||
const QString& text() const;
|
const QString& text() const;
|
||||||
const QString& toolTip() const;
|
const QString& toolTip() const;
|
||||||
|
|
||||||
void perform(IPluginContentWidgetContext *context) const;
|
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
QString m_text;
|
||||||
QString m_toolTip;
|
QString m_toolTip;
|
||||||
|
|
@ -43,7 +38,85 @@ private:
|
||||||
MenuLocation m_menuLocation;
|
MenuLocation m_menuLocation;
|
||||||
ToolbarLocation m_toolbarLocation;
|
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;
|
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
|
#endif // MENUACTION_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue