Krita Source Code Documentation
Loading...
Searching...
No Matches
KoPluginLoader Class Reference

#include <KoPluginLoader.h>

+ Inheritance diagram for KoPluginLoader:

Classes

struct  PluginsConfig
 

Public Member Functions

 KoPluginLoader ()
 DO NOT USE! Use instance() instead.
 
void load (const QString &serviceType, const PluginsConfig &config=PluginsConfig(), QObject *owner=0, bool cache=true)
 
KPluginFactory * loadSinglePlugin (const QString &id, const QString &serviceType)
 
KPluginFactory * loadSinglePlugin (const std::pair< QString, QString > &predicates, const QString &serviceType)
 
KPluginFactory * loadSinglePlugin (const std::vector< std::pair< QString, QString > > &predicates, const QString &serviceType)
 
 ~KoPluginLoader () override
 

Static Public Member Functions

static KoPluginLoaderinstance ()
 

Public Attributes

QStringList loadedServiceTypes
 

Private Member Functions

 KoPluginLoader (const KoPluginLoader &)
 
KoPluginLoader operator= (const KoPluginLoader &)
 
- Private Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Private Attributes

Private *const d
 
- Private Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Detailed Description

The pluginloader singleton is responsible for loading the plugins that it's asked to load. It keeps track of which servicetypes it has seen and doesn't reload them. The plugins need to inherit a QObject with a default constructor. Inside the default constructor you can create whatever object you want and add it to whatever registry you prefer. After having been constructed, your plugin will be deleted, so do all you need in the constructor. Things like adding a factory to a registry make sense there. Example header file;

#include <QObject>
class MyPlugin : public QObject {
Q_OBJECT
public:
MyPlugin(QObject *parent, const QVariantList & );
~MyPlugin() {}
};

Example cpp file;

#include "MyPlugin.h"
#include <kpluginfactory.h>
K_PLUGIN_FACTORY_WITH_JSON(MyPluginFactory, "myplugin.json", registerPlugin<MyPlugin>();)
MyPlugin::MyPlugin( QObject *parent, const QVariantList& ) : QObject(parent) {
// do stuff like creating a factory and adding it to the
// registry instance.
}
#include <MyPlugin.moc>
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL

Definition at line 60 of file KoPluginLoader.cpp.

Constructor & Destructor Documentation

◆ ~KoPluginLoader()

KoPluginLoader::~KoPluginLoader ( )
override

Definition at line 71 of file KoPluginLoader.cpp.

72{
73 delete d;
74}
Private *const d

References d.

◆ KoPluginLoader() [1/2]

KoPluginLoader::KoPluginLoader ( )

DO NOT USE! Use instance() instead.

Definition at line 66 of file KoPluginLoader.cpp.

67 : d(new Private())
68{
69}

◆ KoPluginLoader() [2/2]

KoPluginLoader::KoPluginLoader ( const KoPluginLoader & )
private

Member Function Documentation

◆ instance()

KoPluginLoader * KoPluginLoader::instance ( )
static

Return an instance of the KoPluginLoader Creates an instance if that has never happened before and returns the singleton instance.

Definition at line 78 of file KoPluginLoader.cpp.

79{
80 return pluginLoaderInstance();
81}

◆ load()

void KoPluginLoader::load ( const QString & serviceType,
const PluginsConfig & config = PluginsConfig(),
QObject * owner = 0,
bool cache = true )

Load all plugins that conform to the versiontype, for instance: KoPluginLoader::instance()->load("Krita/Flake"); This method allows you to optionally limit the plugins that are loaded by version, but also using a user configurable set of config options. If you pass a PluginsConfig struct only those plugins are loaded that are specified in the application config file. New plugins found since last start will be automatically loaded.

Parameters
serviceTypeThe string used to identify the plugins.
configwhen passing a valid config only the wanted plugins are actually loaded #param owner if 0, the plugin will be deleted after instantiation, if not, the given qobject will own the plugin in its qobject hierarchy
cacheif true, the plugin will only be loaded once
Returns
a list of services (by library name) that were not know in the config

First, remove all the duplicated plugins and keep only the ones with the highest version number

Erasing an element in QList in Qt5 may invalidate the existing iterator, so we should derive the new position from the iterator returned by erase() method

Then remove all the blacklisted plugins if necessary

Now "load" all the plugins. If "owner" object is not provided, we just create the plugin object and immediately destroy it. Usually the constructor of this plugin will just populate some registry, so the object is not necessary anymore.

Definition at line 83 of file KoPluginLoader.cpp.

84{
85 // Don't load the same plugins again
86 if (cache && d->loadedServiceTypes.contains(serviceType)) {
87 return;
88 }
89 d->loadedServiceTypes << serviceType;
90
91 QList<KoJsonTrader::Plugin> plugins = KoJsonTrader::instance()->query(serviceType, QString());
92
93 {
98 std::sort(plugins.begin(), plugins.end(), &sortByIdAndReversedVersion);
99 auto it = plugins.begin();
100 while ((it = std::adjacent_find(it, plugins.end(), &idCompareEqual)) != plugins.end()) {
101 warnPlugins << "Skipping duplicated plugin, id:" << idFromPlugin(*it)
102 << "version:" << versionFromPlugin(*it) << "filename:" << it->fileName();
108 it = std::prev(plugins.erase(std::next(it)));
109 }
110 }
111
112 if (config.isValid()) {
116 KConfigGroup configGroup(KSharedConfig::openConfig(), config.group);
117 QStringList blackList = configGroup.readEntry(config.blacklist, QStringList());
118
119 auto it = plugins.begin();
120 while (it != plugins.end()) {
121 if (blackList.contains(idFromPlugin(*it))) {
122 it = plugins.erase(it);
123 } else {
124 ++it;
125 }
126 }
127 }
128
135 for (KoJsonTrader::Plugin &plugin : plugins) {
136 const QString pluginName = idFromPlugin(plugin);
137 dbgPlugins << "loading" << pluginName;
138
139 QObject *object = 0;
140
141 KPluginFactory *factory = qobject_cast<KPluginFactory *>(plugin.instance());
142 if (factory) {
143 object = factory->create<QObject>(owner ? owner : this, QVariantList());
144 }
145
146 if (object) {
147 dbgPlugins << "\tLoaded plugin" << plugin.fileName() << "owner:" << owner;
148 if (!owner) {
149 delete object;
150 }
151 } else {
152 qWarning() << "\tLoading plugin" << plugin.fileName() << "failed, " << plugin.errorString();
153 }
154 }
155}
static KoJsonTrader * instance()
QList< Plugin > query(const QString &servicetype, const QString &mimetype)
#define warnPlugins
Definition kis_debug.h:93
#define dbgPlugins
Definition kis_debug.h:51

References KoPluginLoader::PluginsConfig::blacklist, d, dbgPlugins, KoJsonTrader::Plugin::errorString(), KoJsonTrader::Plugin::fileName(), KoPluginLoader::PluginsConfig::group, KoJsonTrader::instance(), KoJsonTrader::Plugin::instance(), KoPluginLoader::PluginsConfig::isValid(), KoJsonTrader::query(), and warnPlugins.

◆ loadSinglePlugin() [1/3]

KPluginFactory * KoPluginLoader::loadSinglePlugin ( const QString & id,
const QString & serviceType )

Definition at line 189 of file KoPluginLoader.cpp.

190{
191 return loadSinglePlugin({"Id", id}, serviceType);
192}
KPluginFactory * loadSinglePlugin(const std::vector< std::pair< QString, QString > > &predicates, const QString &serviceType)

References loadSinglePlugin().

◆ loadSinglePlugin() [2/3]

KPluginFactory * KoPluginLoader::loadSinglePlugin ( const std::pair< QString, QString > & predicates,
const QString & serviceType )

Definition at line 184 of file KoPluginLoader.cpp.

185{
186 return loadSinglePlugin(std::vector<std::pair<QString, QString>>{predicates}, serviceType);
187}

References loadSinglePlugin().

◆ loadSinglePlugin() [3/3]

KPluginFactory * KoPluginLoader::loadSinglePlugin ( const std::vector< std::pair< QString, QString > > & predicates,
const QString & serviceType )

Load a single plugin from the plugins directory

One can pass a set of predicates that should be satisfied for the plugin to be selected. The loader will compare metadata of the plugin against those predicates and choose only the one satisfying all of them.

If multiple plugins are found, then the one with highest version number is used. If two plugins with the same maximum version number exist, then a random one is selected.

Usage:

KPluginFactory *factory = KoPluginLoader::instance()->loadSinglePlugin(
std::make_pair("X-Krita-PlatformId", QGuiApplication::platformName()),
"Krita/PlatformPlugin");
if (factory) {
interface = factory->create<KisExtendedModifiersMapperPluginInterface>();
}
static KoPluginLoader * instance()

Definition at line 157 of file KoPluginLoader.cpp.

158{
159 QList<KoJsonTrader::Plugin> offers = KoJsonTrader::instance()->query(serviceType, QString());
160
161 offers.erase(std::remove_if(offers.begin(),
162 offers.end(),
163 [&](const KoJsonTrader::Plugin &plugin) {
164 QJsonObject json = plugin.metaData().value("MetaData").toObject();
165 Q_FOREACH(const auto &predicate, predicates) {
166 if (json.value(predicate.first).toString() != predicate.second) {
167 return true;
168 }
169 }
170 return false;
171 }),
172 offers.end());
173
174 auto it = std::max_element(offers.begin(), offers.end(), versionCompareLess);
175
176 if (it != offers.end()) {
177 KPluginFactory *factory = qobject_cast<KPluginFactory *>(it->instance());
178 return factory;
179 }
180
181 return nullptr;
182}

References KoJsonTrader::instance(), and KoJsonTrader::query().

◆ operator=()

KoPluginLoader KoPluginLoader::operator= ( const KoPluginLoader & )
private

Member Data Documentation

◆ d

Private* const KoPluginLoader::d
private

Definition at line 152 of file KoPluginLoader.h.

◆ loadedServiceTypes

QStringList KoPluginLoader::loadedServiceTypes

Definition at line 63 of file KoPluginLoader.cpp.


The documentation for this class was generated from the following files: