pgLab/pglab/plugin_support/StaticAction.h
eelke 601d071d0f 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.
2019-08-14 09:06:48 +02:00

122 lines
2.9 KiB
C++

#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