Extended the plugin system to allow for dynamic runtime bindings between modules.
As a test implementation, this allows the TablesPage to open a CrudTab for a table/view without the need for TablesPage, CrudTab and DatabaseWindow to know anything about each other.
This commit is contained in:
parent
f996703937
commit
b0cd47ef46
17 changed files with 209 additions and 55 deletions
51
pglab/plugin_support/IPluginContentWidgetContext.h
Normal file
51
pglab/plugin_support/IPluginContentWidgetContext.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
#define IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
#include "plugin_support/ModuleActionParameters.h"
|
||||
|
||||
class OpenDatabase;
|
||||
class PluginContentWidget;
|
||||
|
||||
/** This class serves to isolate the plugin from the actual construct in which it is
|
||||
* used.
|
||||
*
|
||||
* It provides interface for operating on the context without needing to many details.
|
||||
* Actual default implementation is in PluginContentWidgetContextBase.
|
||||
*/
|
||||
class IPluginContentWidgetContext {
|
||||
public:
|
||||
|
||||
virtual ~IPluginContentWidgetContext() = default;
|
||||
/** Tells the context what to use as a caption for this content widget.
|
||||
*
|
||||
* Depending on the context the caption might not be visible or used as the caption
|
||||
* of a window or tab.
|
||||
*/
|
||||
virtual void setCaption(PluginContentWidget *content, const QString &caption, const QString &hint = {}) = 0;
|
||||
/** Tells the context what icon to use.
|
||||
*
|
||||
* In general the icon is used in a similar place as the caption.
|
||||
* \param iconname Assumed to be the name of an iconresource. The system will look for different
|
||||
* sizes under :/icons/<size>/iconname
|
||||
*/
|
||||
virtual void setIcon(PluginContentWidget *content, const QString &iconname) = 0;
|
||||
|
||||
/** Returns an OpenDatabase object the widget can use to access
|
||||
* the database.
|
||||
*/
|
||||
virtual std::shared_ptr<OpenDatabase> getDatabase() = 0;
|
||||
|
||||
virtual void showStatusMessage(const QString &msg) = 0;
|
||||
|
||||
virtual void moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
) = 0;
|
||||
|
||||
virtual void addContentWidget(PluginContentWidget *widget) = 0;
|
||||
};
|
||||
|
||||
#endif // IPLUGINCONTENTWIDGETCONTEXT_H
|
||||
10
pglab/plugin_support/ModuleActionParameters.h
Normal file
10
pglab/plugin_support/ModuleActionParameters.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef MODULEACTIONPARAMETERS_H
|
||||
#define MODULEACTIONPARAMETERS_H
|
||||
|
||||
#include <map>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
using ModuleActionParameters = std::map<QString, QVariant>;
|
||||
|
||||
#endif // MODULEACTIONPARAMETERS_H
|
||||
27
pglab/plugin_support/PluginContentWidgetContextBase.cpp
Normal file
27
pglab/plugin_support/PluginContentWidgetContextBase.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "PluginContentWidgetContextBase.h"
|
||||
#include "PluginRegister.h"
|
||||
#include "PluginModule.h"
|
||||
#include <QDebug>
|
||||
|
||||
PluginContentWidgetContextBase::PluginContentWidgetContextBase() = default;
|
||||
|
||||
void PluginContentWidgetContextBase::moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
)
|
||||
{
|
||||
auto reg = PluginRegister::getInstance();
|
||||
auto mod = reg->findModule(module_identifier);
|
||||
if (mod) {
|
||||
auto action = mod->findModuleAction(module_action);
|
||||
if (action) {
|
||||
qDebug() << QString("module %1 action %2 called ").arg(module_identifier, module_action);
|
||||
(*action)(this, action_params);
|
||||
}
|
||||
else
|
||||
qWarning() << QString("module %1 has no action %2").arg(module_identifier, module_action);
|
||||
}
|
||||
else
|
||||
qWarning() << QString("module not found %1").arg(module_identifier);
|
||||
}
|
||||
19
pglab/plugin_support/PluginContentWidgetContextBase.h
Normal file
19
pglab/plugin_support/PluginContentWidgetContextBase.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
#define PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
||||
#include "plugin_support/IPluginContentWidgetContext.h"
|
||||
|
||||
/// Provides base implementation of IPluginContentWidgetContext
|
||||
class PluginContentWidgetContextBase : public IPluginContentWidgetContext
|
||||
{
|
||||
public:
|
||||
PluginContentWidgetContextBase();
|
||||
|
||||
void moduleAction(
|
||||
const QString &module_identifier,
|
||||
QString module_action,
|
||||
const ModuleActionParameters &action_params
|
||||
) override;
|
||||
};
|
||||
|
||||
#endif // PLUGINCONTENTWIDGETCONTEXTBASE_H
|
||||
|
|
@ -16,4 +16,18 @@ void PluginModule::registerAction(QAction *action, MenuLocation menu_location, T
|
|||
|
||||
}
|
||||
|
||||
void PluginModule::registerModuleAction(QString module_action, ModuleAction action)
|
||||
{
|
||||
m_moduleActions.emplace(
|
||||
std::move(module_action),
|
||||
std::move(action)
|
||||
);
|
||||
}
|
||||
|
||||
const PluginModule::ModuleAction* PluginModule::findModuleAction(const QString &module_action) const
|
||||
{
|
||||
auto res = m_moduleActions.find(module_action);
|
||||
if (res == m_moduleActions.end())
|
||||
return nullptr;
|
||||
return &res->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
#ifndef PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
#define PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
|
||||
#include "plugin_support/MenuLocation.h"
|
||||
#include "plugin_support/ToolbarLocation.h"
|
||||
#include "MenuLocation.h"
|
||||
#include "ToolbarLocation.h"
|
||||
#include "ModuleActionParameters.h"
|
||||
#include "PluginRegister.h"
|
||||
#include <QObject>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
class QAction;
|
||||
|
||||
class IPluginContentWidgetContext;
|
||||
|
||||
class PluginModule: public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using ModuleAction = std::function<void(IPluginContentWidgetContext*, const ModuleActionParameters &)>;
|
||||
using ModuleActionMap = std::map<QString, ModuleAction>;
|
||||
|
||||
PluginModule(QString name, QString ident);
|
||||
|
||||
const QString& name() const { return m_name; }
|
||||
|
|
@ -19,13 +26,32 @@ public:
|
|||
|
||||
void setDisplayCategory(QString category);
|
||||
void registerAction(QAction *action, MenuLocation menu_location, ToolbarLocation toolbar_location);
|
||||
|
||||
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;
|
||||
private:
|
||||
/// Name shown to end users
|
||||
QString m_name;
|
||||
/// Unique identifier
|
||||
QString m_ident;
|
||||
QString m_displayCategory;
|
||||
|
||||
ModuleActionMap m_moduleActions;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<PluginModule> createPluginModule(QString name, QString ident)
|
||||
{
|
||||
auto module = std::make_shared<T>(std::move(name), std::move(ident));
|
||||
module->init();
|
||||
|
||||
PluginRegister::getInstance()->registerModule(module);
|
||||
return std::move(module);
|
||||
}
|
||||
|
||||
|
||||
#endif // PLUGIN_SUPPORTPLUGINMODULE_H
|
||||
|
|
|
|||
|
|
@ -25,5 +25,13 @@ PluginRegister::PluginRegister() = default;
|
|||
|
||||
void PluginRegister::registerModule(PluginModuleSPtr module)
|
||||
{
|
||||
qDebug() << "Register called for " << module->identifier();
|
||||
m_moduleMap.emplace(module->identifier(), module);
|
||||
}
|
||||
|
||||
const PluginModule* PluginRegister::findModule(const QString &module_ident) const
|
||||
{
|
||||
auto res = m_moduleMap.find(module_ident);
|
||||
if (res == m_moduleMap.end())
|
||||
return nullptr;
|
||||
return res->second.get();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ public:
|
|||
PluginRegister();
|
||||
void registerModule(PluginModuleSPtr module);
|
||||
const ModuleMap& modules() const { return m_moduleMap; }
|
||||
|
||||
const PluginModule* findModule(const QString &module_ident) const;
|
||||
private:
|
||||
|
||||
ModuleMap m_moduleMap;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue