Moved definition of widget instance actions to the module so other parts of the system can no about them.
The plugin system will create the Action objects and bind them to the specified slots of the specific widget instances.
This commit is contained in:
parent
d0c4dabe8b
commit
f4f2474a81
21 changed files with 418 additions and 204 deletions
|
|
@ -8,8 +8,10 @@
|
|||
#include "plugin_support/ModuleActionParameters.h"
|
||||
|
||||
class OpenDatabase;
|
||||
class PluginModule;
|
||||
class PluginContentWidget;
|
||||
|
||||
|
||||
/** This class serves to isolate the plugin from the actual construct in which it is
|
||||
* used.
|
||||
*
|
||||
|
|
@ -45,7 +47,8 @@ public:
|
|||
const ModuleActionParameters &action_params
|
||||
) = 0;
|
||||
|
||||
virtual void addContentWidget(PluginContentWidget *widget) = 0;
|
||||
virtual void addContentWidget(PluginModule *module, PluginContentWidget *widget) = 0;
|
||||
virtual void removeContentWidget(PluginContentWidget *widget) = 0;
|
||||
|
||||
/** Return a widget you can use as a parent
|
||||
*/
|
||||
|
|
@ -57,6 +60,7 @@ public:
|
|||
bool registerObject(std::shared_ptr<T> object);
|
||||
template<typename T>
|
||||
std::shared_ptr<T> getObject() const;
|
||||
|
||||
private:
|
||||
std::map<std::type_index, std::shared_ptr<void> > m_objectRegistry;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ namespace LMainWindow_details {
|
|||
m_window->statusBar()->showMessage(msg);
|
||||
}
|
||||
|
||||
void addContentWidget(PluginContentWidget *widget) override
|
||||
void addContentWidget(PluginModule *module, PluginContentWidget *widget) override
|
||||
{
|
||||
PluginContentWidgetContextBase::addContentWidget(module, widget);
|
||||
m_window->addPage(widget, "");
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ void LMainWindow::addMenuAction(const MenuAction &ma)
|
|||
{
|
||||
ma.perform(m_context);
|
||||
},
|
||||
ma.shortCut());
|
||||
ma.shortcut());
|
||||
|
||||
|
||||
// auto ac = new QAction(this);
|
||||
|
|
@ -171,6 +172,7 @@ void LMainWindow::tabWidget_tabCloseRequested(int index)
|
|||
if (plg_page) {
|
||||
if (plg_page->canClose()) {
|
||||
m_tabWidget->removeTab(index);
|
||||
m_context->removeContentWidget(plg_page);
|
||||
delete plg_page;
|
||||
}
|
||||
}
|
||||
|
|
@ -186,7 +188,7 @@ void LMainWindow::tabWidget_currentChanged(int index)
|
|||
{
|
||||
// remove buttons of old page
|
||||
if (m_previousPage) {
|
||||
removeToolBarButtonsForPage(m_previousPage);
|
||||
removeModuleWidgetActionsForPage(m_previousPage);
|
||||
}
|
||||
|
||||
// add buttons of new page
|
||||
|
|
@ -195,26 +197,18 @@ void LMainWindow::tabWidget_currentChanged(int index)
|
|||
QWidget *widget = m_tabWidget->widget(index);
|
||||
page = dynamic_cast<PluginContentWidget*>(widget);
|
||||
if (page) {
|
||||
addToolBarButtonsForPage(page);
|
||||
addModuleWidgetActionsForPage(page);
|
||||
}
|
||||
}
|
||||
m_previousPage = page;
|
||||
}
|
||||
|
||||
void LMainWindow::addToolBarButtonsForPage(PluginContentWidget *page)
|
||||
void LMainWindow::addModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||
{
|
||||
std::vector<QAction*> actions = page->getToolbarActions();
|
||||
QList<QAction*> list;
|
||||
for (auto act : actions) {
|
||||
list.append(act);
|
||||
}
|
||||
m_mainToolBar->addActions(list);
|
||||
m_context->addWidgetActionsToToolbar(page, m_mainToolBar);
|
||||
}
|
||||
|
||||
void LMainWindow::removeToolBarButtonsForPage(PluginContentWidget *page)
|
||||
void LMainWindow::removeModuleWidgetActionsForPage(PluginContentWidget *page)
|
||||
{
|
||||
std::vector<QAction*> actions = page->getToolbarActions();
|
||||
for (auto act : actions) {
|
||||
m_mainToolBar->removeAction(act);
|
||||
}
|
||||
m_context->removeWidgetActionsFromToolbar(page, m_mainToolBar);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ protected:
|
|||
|
||||
void addModuleMenuActions();
|
||||
|
||||
void addToolBarButtonsForPage(PluginContentWidget *page);
|
||||
void removeToolBarButtonsForPage(PluginContentWidget *page);
|
||||
void addModuleWidgetActionsForPage(PluginContentWidget *page);
|
||||
void removeModuleWidgetActionsForPage(PluginContentWidget *page);
|
||||
private:
|
||||
LMainWindow_details::LMainWindowContentContext *m_context;
|
||||
PluginContentWidget *m_previousPage = nullptr; ///< tracks which pages buttons were previously being displayed
|
||||
|
|
|
|||
56
pglab/plugin_support/LWidgetAction.cpp
Normal file
56
pglab/plugin_support/LWidgetAction.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "LWidgetAction.h"
|
||||
|
||||
LWidgetAction::LWidgetAction(QString text, const char * slotname)
|
||||
: m_text(std::move(text))
|
||||
, m_slotname(slotname)
|
||||
{}
|
||||
|
||||
const QIcon& LWidgetAction::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
const MenuLocation& LWidgetAction::menuLocation() const
|
||||
{
|
||||
return m_menuLocation;
|
||||
}
|
||||
|
||||
void LWidgetAction::setIcon(QIcon icon)
|
||||
{
|
||||
m_icon = std::move(icon);
|
||||
}
|
||||
|
||||
void LWidgetAction::setMenuLocation(MenuLocation menu_location)
|
||||
{
|
||||
m_menuLocation = std::move(menu_location);
|
||||
}
|
||||
|
||||
void LWidgetAction::setShortcut(QKeySequence shortcut)
|
||||
{
|
||||
m_shortCut = std::move(shortcut);
|
||||
}
|
||||
|
||||
void LWidgetAction::setText(QString text)
|
||||
{
|
||||
m_text = std::move(text);
|
||||
}
|
||||
|
||||
void LWidgetAction::setToolTip(QString tooltip)
|
||||
{
|
||||
m_toolTip = std::move(tooltip);
|
||||
}
|
||||
|
||||
const QKeySequence& LWidgetAction::shortcut() const
|
||||
{
|
||||
return m_shortCut;
|
||||
}
|
||||
|
||||
const QString& LWidgetAction::text() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
const QString& LWidgetAction::toolTip() const
|
||||
{
|
||||
return m_toolTip;
|
||||
}
|
||||
42
pglab/plugin_support/LWidgetAction.h
Normal file
42
pglab/plugin_support/LWidgetAction.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef LWIDGETACTION_H
|
||||
#define LWIDGETACTION_H
|
||||
|
||||
#include "MenuLocation.h"
|
||||
#include <QIcon>
|
||||
#include <QKeySequence>
|
||||
#include <QString>
|
||||
|
||||
|
||||
/** Action definition for a specific widget instance, it uses a slotname
|
||||
* so the action can be defined before the widget instance is created.
|
||||
* The plugin mechanism will take care of instantiating a connection to the named slot.
|
||||
*/
|
||||
class LWidgetAction {
|
||||
public:
|
||||
///
|
||||
/// \param slotname, use SLOT macro to pass name of the slot
|
||||
LWidgetAction(QString text, const char * slotname);
|
||||
|
||||
const QIcon& icon() const;
|
||||
const MenuLocation& menuLocation() const;
|
||||
void setIcon(QIcon icon);
|
||||
void setMenuLocation(MenuLocation menu_location);
|
||||
void setShortcut(QKeySequence shortcut);
|
||||
void setText(QString text);
|
||||
void setToolTip(QString tooltip);
|
||||
const QKeySequence& shortcut() const;
|
||||
const char* slotName() const { return m_slotname; }
|
||||
const QString& text() const;
|
||||
const QString& toolTip() const;
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
QString m_toolTip;
|
||||
QIcon m_icon;
|
||||
QKeySequence m_shortCut;
|
||||
MenuLocation m_menuLocation;
|
||||
|
||||
const char * m_slotname;
|
||||
};
|
||||
|
||||
#endif // LWIDGETACTION_H
|
||||
|
|
@ -25,9 +25,9 @@ void MenuAction::setMenuLocation(MenuLocation menu_location)
|
|||
m_menuLocation = std::move(menu_location);
|
||||
}
|
||||
|
||||
void MenuAction::setShortCut(QKeySequence shortcut)
|
||||
void MenuAction::setShortcut(QKeySequence shortcut)
|
||||
{
|
||||
m_shortCut = std::move(shortcut);
|
||||
m_shortcut = std::move(shortcut);
|
||||
}
|
||||
|
||||
void MenuAction::setText(QString text)
|
||||
|
|
@ -40,9 +40,9 @@ void MenuAction::setToolTip(QString tooltip)
|
|||
m_toolTip = std::move(tooltip);
|
||||
}
|
||||
|
||||
const QKeySequence& MenuAction::shortCut() const
|
||||
const QKeySequence& MenuAction::shortcut() const
|
||||
{
|
||||
return m_shortCut;
|
||||
return m_shortcut;
|
||||
}
|
||||
|
||||
const QString& MenuAction::text() const
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ public:
|
|||
const MenuLocation& menuLocation() const;
|
||||
void setIcon(QIcon icon);
|
||||
void setMenuLocation(MenuLocation menu_location);
|
||||
void setShortCut(QKeySequence shortcut);
|
||||
void setShortcut(QKeySequence shortcut);
|
||||
void setText(QString text);
|
||||
void setToolTip(QString tooltip);
|
||||
const QKeySequence& shortCut() const;
|
||||
const QKeySequence& shortcut() const;
|
||||
const QString& text() const;
|
||||
const QString& toolTip() const;
|
||||
|
||||
|
|
@ -39,11 +39,10 @@ private:
|
|||
QString m_text;
|
||||
QString m_toolTip;
|
||||
QIcon m_icon;
|
||||
QKeySequence m_shortCut;
|
||||
QKeySequence m_shortcut;
|
||||
MenuLocation m_menuLocation;
|
||||
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
|
||||
#endif // MENUACTION_H
|
||||
|
|
|
|||
|
|
@ -3,14 +3,7 @@
|
|||
PluginContentWidget::PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_context(context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<QAction*> PluginContentWidget::getToolbarActions()
|
||||
{
|
||||
return std::vector<QAction*>();
|
||||
}
|
||||
{}
|
||||
|
||||
bool PluginContentWidget::canClose()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <vector>
|
||||
|
||||
class IPluginContentWidgetContext;
|
||||
class PluginModule;
|
||||
|
||||
/// Provides a pluggable system for toolbar buttons and menu actions
|
||||
///
|
||||
|
|
@ -21,7 +22,6 @@ class PluginContentWidget: public QWidget{
|
|||
public:
|
||||
PluginContentWidget(IPluginContentWidgetContext *context, QWidget* parent = nullptr);
|
||||
/// Returns the toolbar buttons for this page
|
||||
virtual std::vector<QAction*> getToolbarActions();
|
||||
virtual bool canClose();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,43 @@
|
|||
#include "PluginContentWidgetContextBase.h"
|
||||
#include "PluginRegister.h"
|
||||
#include "PluginContentWidget.h"
|
||||
#include "PluginModule.h"
|
||||
#include "PluginRegister.h"
|
||||
#include "LWidgetAction.h"
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QToolBar>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
LWidgetData::LWidgetData(PluginModule *module)
|
||||
: m_module(module)
|
||||
{}
|
||||
|
||||
void LWidgetData::init(PluginContentWidget *widget)
|
||||
{
|
||||
auto&& widget_actions = m_module->widgetActions();
|
||||
m_widgetActions.reserve(widget_actions.size());
|
||||
for (auto&& wa : widget_actions) {
|
||||
m_widgetActions.push_back(createAction(wa, widget));
|
||||
}
|
||||
}
|
||||
|
||||
QList<QAction *> LWidgetData::actions()
|
||||
{
|
||||
return m_widgetActions;
|
||||
}
|
||||
|
||||
QAction *LWidgetData::createAction(const LWidgetAction &wa, PluginContentWidget *widget)
|
||||
{
|
||||
auto ac = new QAction(wa.icon(), wa.text(), widget);
|
||||
ac->setShortcut(wa.shortcut());
|
||||
ac->setToolTip(wa.toolTip());
|
||||
QObject::connect(ac, SIGNAL(triggered()), widget, wa.slotName());
|
||||
return ac;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default;
|
||||
|
||||
|
|
@ -25,3 +61,43 @@ void PluginContentWidgetContextBase::moduleAction(
|
|||
else
|
||||
qWarning() << QString("module not found %1").arg(module_identifier);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::addContentWidget(PluginModule *module, PluginContentWidget *widget)
|
||||
{
|
||||
auto res = m_widgetLst.emplace(widget, module);
|
||||
if (!res.second)
|
||||
throw std::runtime_error("Unexpected conflicting key on insertiong PluginContentWidgetContextBase::addContentWidget");
|
||||
|
||||
res.first->second.init(widget);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *widget)
|
||||
{
|
||||
auto res = m_widgetLst.find(widget);
|
||||
if (res == m_widgetLst.end())
|
||||
return;
|
||||
|
||||
m_widgetLst.erase(res);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar)
|
||||
{
|
||||
auto res = m_widgetLst.find(widget);
|
||||
if (res == m_widgetLst.end())
|
||||
return;
|
||||
|
||||
auto && actions = res->second.actions();
|
||||
toolbar->addActions(actions);
|
||||
}
|
||||
|
||||
void PluginContentWidgetContextBase::removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar)
|
||||
{
|
||||
auto res = m_widgetLst.find(widget);
|
||||
if (res == m_widgetLst.end())
|
||||
return;
|
||||
|
||||
auto && actions = res->second.actions();
|
||||
for (auto && ac : actions)
|
||||
toolbar->removeAction(ac);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,26 @@
|
|||
#define PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
#include <QList>
|
||||
|
||||
class LWidgetAction;
|
||||
class QToolBar;
|
||||
class QAction;
|
||||
|
||||
class LWidgetData {
|
||||
public:
|
||||
LWidgetData(PluginModule *module);
|
||||
PluginModule* module() { return m_module; }
|
||||
void init(PluginContentWidget *widget);
|
||||
QList<QAction *> actions();
|
||||
|
||||
private:
|
||||
PluginModule *m_module;
|
||||
/// List of actions specifically created for this widget from the widgetAction list of the module.
|
||||
QList<QAction *> m_widgetActions;
|
||||
|
||||
QAction *createAction(const LWidgetAction &wa, PluginContentWidget *widget);
|
||||
};
|
||||
|
||||
/// Provides base implementation of IPluginContentWidgetContext
|
||||
class PluginContentWidgetContextBase : public IPluginContentWidgetContext
|
||||
|
|
@ -14,6 +34,17 @@ public:
|
|||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
) override;
|
||||
|
||||
void addContentWidget(PluginModule *module, PluginContentWidget *widget) override;
|
||||
void removeContentWidget(PluginContentWidget *widget) override;
|
||||
|
||||
void addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||
void removeWidgetActionsFromToolbar(PluginContentWidget *widget, QToolBar *toolbar);
|
||||
private:
|
||||
|
||||
using WidgetLst = std::map<PluginContentWidget*, LWidgetData>;
|
||||
|
||||
WidgetLst m_widgetLst;
|
||||
};
|
||||
|
||||
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
|
|
|||
|
|
@ -38,3 +38,4 @@ const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString &
|
|||
return nullptr;
|
||||
return &res->second;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "ModuleActionParameters.h"
|
||||
#include "MenuAction.h"
|
||||
#include "LWidgetAction.h"
|
||||
#include "PluginRegister.h"
|
||||
#include <QObject>
|
||||
#include <functional>
|
||||
|
|
@ -16,12 +17,13 @@ class PluginModule: public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
using MenuActionList = std::vector<MenuAction>;
|
||||
using LWidgetActionList = std::vector<LWidgetAction>;
|
||||
using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>;
|
||||
using ModuleActionMap = std::map<QString, ModuleAction>;
|
||||
|
||||
PluginModule(QString name, QString ident);
|
||||
|
||||
virtual void init() {};
|
||||
virtual void init() {}
|
||||
|
||||
const QString& name() const { return m_name; }
|
||||
const QString& identifier() const { return m_ident; }
|
||||
|
|
@ -38,6 +40,12 @@ public:
|
|||
/// Searches for and returns a pointer to the requested module action.
|
||||
/// When the action is not found nullptr is returned.
|
||||
const ModuleAction* findModuleAction(const QString &module_action) const;
|
||||
|
||||
void registerWidgetAction(const LWidgetAction &action)
|
||||
{
|
||||
m_widgetActions.push_back(action);
|
||||
}
|
||||
const LWidgetActionList& widgetActions() const { return m_widgetActions; }
|
||||
private:
|
||||
/// Name shown to end users
|
||||
QString m_name;
|
||||
|
|
@ -47,6 +55,7 @@ private:
|
|||
|
||||
MenuActionList m_menuActions;
|
||||
ModuleActionMap m_moduleActions;
|
||||
LWidgetActionList m_widgetActions;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue