Work on plugin mechanism

Context actions have become normal actions in the pluginwidget so the widget knows abot them and
can easily do things like enable/disable.
This commit is contained in:
eelke 2019-02-08 10:10:11 +01:00
parent eca8841427
commit a704332342
24 changed files with 239 additions and 267 deletions

View file

@ -1,61 +0,0 @@
#include "LContextAction.h"
LContextAction::LContextAction(QString text, const char * slotname)
: m_text(std::move(text))
, m_slotname(slotname)
{}
const QIcon& LContextAction::icon() const
{
return m_icon;
}
const MenuLocation& LContextAction::menuLocation() const
{
return m_menuLocation;
}
void LContextAction::setIcon(QIcon icon)
{
m_icon = std::move(icon);
}
void LContextAction::setMenuLocation(MenuLocation menu_location)
{
m_menuLocation = std::move(menu_location);
}
void LContextAction::setToolbarLocation(ToolbarLocation toolbar_location)
{
m_toolbarLocation = toolbar_location;
}
void LContextAction::setShortcut(QKeySequence shortcut)
{
m_shortCut = std::move(shortcut);
}
void LContextAction::setText(QString text)
{
m_text = std::move(text);
}
void LContextAction::setToolTip(QString tooltip)
{
m_toolTip = std::move(tooltip);
}
const QKeySequence& LContextAction::shortcut() const
{
return m_shortCut;
}
const QString& LContextAction::text() const
{
return m_text;
}
const QString& LContextAction::toolTip() const
{
return m_toolTip;
}

View file

@ -1,47 +0,0 @@
#ifndef LWIDGETACTION_H
#define LWIDGETACTION_H
#include "MenuLocation.h"
#include "ToolbarLocation.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 LContextAction {
public:
///
/// \param slotname, use SLOT macro to pass name of the slot
LContextAction(QString text, const char * slotname);
const QIcon& icon() const;
const MenuLocation& menuLocation() const;
void setIcon(QIcon icon);
void setIcon(const char * icon) { setIcon(QIcon(icon)); }
void setMenuLocation(MenuLocation menu_location);
void setMenuLocation(const char * menu_location) { setMenuLocation(MenuPath(menu_location)); }
void setToolbarLocation(ToolbarLocation toolbar_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;
ToolbarLocation m_toolbarLocation;
const char * m_slotname;
};
#endif // LWIDGETACTION_H

View file

@ -0,0 +1,6 @@
#include "LMainMenu.h"
LMainMenu::LMainMenu()
{
}

View file

@ -0,0 +1,56 @@
#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

View file

@ -99,7 +99,7 @@ void LMainWindow::addModuleMenuActions()
auto reg = PluginRegister::getInstance();
auto mods = reg->modules();
for (auto && mod : mods) {
auto items = mod.second->menuActions();
auto items = mod.second->staticActions();
for (auto && item : items) {
addMenuAction(item);
}

View file

@ -2,9 +2,12 @@
#define MENULOCATION_H
#include "plugin_support/MenuPath.h"
#include <QString>
///
class MenuLocation {
public:
MenuLocation();
MenuLocation(MenuPath path, int position = -1);

View file

@ -2,9 +2,16 @@
MenuPath::MenuPath() = default;
//MenuPath::MenuPath(QString menu_path)
// : m_menuPath(std::move(menu_path))
//{
//}
MenuPath::MenuPath(QString menu_path)
: m_menuPath(std::move(menu_path))
{
auto parts = menu_path.splitRef('/');
for (auto&& elem : parts) {
m_elems.emplace_back(elem);
}
}

View file

@ -2,17 +2,46 @@
#define MENUPATH_H
#include <QString>
#include <boost/container/small_vector.hpp>
#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:
QString m_menuPath;
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

View file

@ -24,8 +24,11 @@ public:
/// Returns the toolbar buttons for this page
virtual bool canClose();
virtual QList<QAction *> actions() { return QList<QAction*>(); }
protected:
IPluginContentWidgetContext *context() { return m_context; }
private:
IPluginContentWidgetContext *m_context;
};

View file

@ -2,7 +2,6 @@
#include "PluginContentWidget.h"
#include "PluginModule.h"
#include "PluginRegister.h"
#include "LContextAction.h"
#include <QAction>
#include <QDebug>
#include <QToolBar>
@ -16,28 +15,8 @@ LWidgetData::LWidgetData(PluginModule *module)
void LWidgetData::init(PluginContentWidget *widget)
{
auto&& widget_actions = m_module->contextActions();
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 LContextAction &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;
@ -82,21 +61,13 @@ void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *wi
void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar)
{
auto res = m_widgetLst.find(widget);
if (res == m_widgetLst.end())
return;
auto && actions = res->second.actions();
auto && actions = widget->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();
auto && actions = widget->actions();
for (auto && ac : actions)
toolbar->removeAction(ac);

View file

@ -13,14 +13,9 @@ 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 LContextAction &wa, PluginContentWidget *widget);
};
/// Provides base implementation of IPluginContentWidgetContext

View file

@ -3,7 +3,6 @@
#include "ModuleActionParameters.h"
#include "StaticAction.h"
#include "LContextAction.h"
#include "PluginRegister.h"
#include <QObject>
#include <functional>
@ -17,7 +16,6 @@ class PluginModule: public QObject {
Q_OBJECT
public:
using StaticActionList = std::vector<StaticAction>;
using ContextActionList = std::vector<LContextAction>;
using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>;
using ModuleActionMap = std::map<QString, ModuleAction>;
@ -43,11 +41,6 @@ public:
/// When the action is not found nullptr is returned.
const ModuleAction* findModuleAction(const QString &module_action) const;
void registerContextAction(const LContextAction &action)
{
m_widgetActions.push_back(action);
}
const ContextActionList& contextActions() const { return m_widgetActions; }
private:
/// Name shown to end users
QString m_name;
@ -57,7 +50,6 @@ private:
StaticActionList m_menuActions;
ModuleActionMap m_moduleActions;
ContextActionList m_widgetActions;
};

View file

@ -9,7 +9,6 @@
#include <QString>
#include <functional>
class QAction;
class IPluginContentWidgetContext;
/** An action for in a menu or toolbar that does not pertain to a specific