KCoreAddons

kpluginfactory.cpp
1/*
2 This file is part of the KDE project
3
4 SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org>
5 SPDX-FileCopyrightText: 2007 Bernhard Loos <nhuh.put@web.de>
6 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "kpluginfactory.h"
12#include "kpluginfactory_p.h"
13
14#include "kcoreaddons_debug.h"
15#include <QPluginLoader>
16#include <algorithm>
17
19 : d(new KPluginFactoryPrivate)
20{
21}
22
24
26{
28 QObject *obj = nullptr;
29 if (data.isStaticPlugin()) {
30 obj = data.staticPlugin().instance();
31 } else {
32 if (data.fileName().isEmpty()) {
33 result.errorString = tr("Could not find plugin %1").arg(data.requestedFileName());
34 result.errorText = QStringLiteral("Could not find plugin %1").arg(data.requestedFileName());
35 result.errorReason = INVALID_PLUGIN;
36 qCWarning(KCOREADDONS_DEBUG) << result.errorText;
37 return result;
38 }
39 QPluginLoader loader(data.fileName());
40 obj = loader.instance();
41 if (!obj) {
42 result.errorString = tr("Could not load plugin from %1: %2").arg(data.fileName(), loader.errorString());
43 result.errorText = QStringLiteral("Could not load plugin from %1: %2").arg(data.fileName(), loader.errorString());
44 result.errorReason = INVALID_PLUGIN;
45 qCWarning(KCOREADDONS_DEBUG) << result.errorText;
46 return result;
47 }
48 }
49
50 KPluginFactory *factory = qobject_cast<KPluginFactory *>(obj);
51
52 if (factory == nullptr) {
53 result.errorString = tr("The library %1 does not offer a KPluginFactory.").arg(data.fileName());
54 result.errorReason = INVALID_FACTORY;
55 qCWarning(KCOREADDONS_DEBUG) << "Expected a KPluginFactory, got a" << obj->metaObject()->className();
56 delete obj;
57 return result;
58 }
59
60 factory->setMetaData(data);
61 result.plugin = factory;
62 return result;
63}
64
66{
67 return d->metaData;
68}
69
71{
72 d->metaData = metaData;
73}
74
75void KPluginFactory::registerPlugin(const QMetaObject *metaObject, CreateInstanceWithMetaDataFunction instanceFunction)
76{
77 Q_ASSERT(metaObject);
78 const QMetaObject *superClass = metaObject->superClass();
79 Q_ASSERT(superClass);
80
81 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) {
82 for (const QMetaObject *otherSuper = plugin.first->superClass(); otherSuper; otherSuper = otherSuper->superClass()) {
83 if (superClass == otherSuper) {
84 qCWarning(KCOREADDONS_DEBUG).nospace() << "Two plugins with the same interface (" << superClass->className()
85 << ") were registered in the KPluginFactory " << this->metaObject()->className() << ". "
86 << "This might be due to a missing Q_OBJECT macro in one of the registered classes";
87 }
88 }
89 }
90 // check hierarchy of newly newly registered plugin against all registered classes
91 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) {
92 superClass = plugin.first->superClass();
93 for (const QMetaObject *otherSuper = metaObject->superClass(); otherSuper; otherSuper = otherSuper->superClass()) {
94 if (superClass == otherSuper) {
95 qCWarning(KCOREADDONS_DEBUG).nospace() << "Two plugins with the same interface (" << superClass->className()
96 << ") were registered in the KPluginFactory " << this->metaObject()->className() << ". "
97 << "This might be due to a missing Q_OBJECT macro in one of the registered classes";
98 }
99 }
100 }
101 d->createInstanceWithMetaDataHash.push_back({metaObject, instanceFunction});
102}
103
104void KPluginFactory::logFailedInstantiationMessage(KPluginMetaData data)
105{
106 qCWarning(KCOREADDONS_DEBUG) << "KPluginFactory could not load the plugin" << data.fileName();
107}
108void KPluginFactory::logFailedInstantiationMessage(const char *className, KPluginMetaData data)
109{
110 qCWarning(KCOREADDONS_DEBUG) << "KPluginFactory could not create a" << className << "instance from" << data.fileName();
111}
112
113QObject *KPluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args)
114{
115 for (const KPluginFactoryPrivate::PluginWithMetadata &plugin : d->createInstanceWithMetaDataHash) {
116 for (const QMetaObject *current = plugin.first; current; current = current->superClass()) {
117 if (0 == qstrcmp(iface, current->className())) {
118 return plugin.second(parentWidget, parent, d->metaData, args);
119 }
120 }
121 }
122
123 return nullptr;
124}
125
126#include "moc_kpluginfactory.cpp"
Holds the result of a plugin load operation, i.e.
QString errorString
translated, user-visible error string
QString errorText
untranslated error text
KPluginFactory provides a convenient way to provide factory-style plugins.
static Result< KPluginFactory > loadFactory(const KPluginMetaData &data)
Attempts to load the KPluginFactory from the given metadata.
T * create(QObject *parent=nullptr, const QVariantList &args={})
Use this method to create an object.
void registerPlugin()
Uses a default instance creation function depending on the type of interface.
KPluginMetaData metaData() const
void setMetaData(const KPluginMetaData &metaData)
Set the metadata about the plugin this factory generates.
KPluginFactory()
This constructor creates a factory for a plugin.
~KPluginFactory() override
This destroys the PluginFactory.
This class allows easily accessing some standardized values from the JSON metadata that can be embedd...
bool isStaticPlugin() const
const char * className() const const
const QMetaObject * superClass() const const
virtual const QMetaObject * metaObject() const const
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString errorString() const const
QObject * instance()
QString arg(Args &&... args) const const
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Apr 27 2024 22:07:13 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.