pgLab/pglab/plugin_support/PluginModule.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

97 lines
3 KiB
C++

#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