KCoreAddons

kpluginfactory.h
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-2023 Alexander Lohnau <alexander.lohnau@gmx.de>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#ifndef KPLUGINFACTORY_H
12#define KPLUGINFACTORY_H
13
14#include "kcoreaddons_export.h"
15#include "kpluginmetadata.h"
16
17#include <QObject>
18#include <QVariant>
19
20#include <memory>
21#include <type_traits>
22
23class QWidget;
24class KPluginFactoryPrivate;
25
26namespace KParts
27{
28class Part;
29}
30
31#define KPluginFactory_iid "org.kde.KPluginFactory"
32
33// Internal macro that generated the KPluginFactory subclass
34#define __K_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations, ...) \
35 class name : public KPluginFactory \
36 { \
37 Q_OBJECT \
38 Q_INTERFACES(KPluginFactory) \
39 Q_PLUGIN_METADATA(__VA_ARGS__) \
40 public: \
41 explicit name() \
42 { \
43 pluginRegistrations \
44 } \
45 ~name() { }; \
46 };
47
48/**
49 * @relates KPluginFactory
50 *
51 * Create a KPluginFactory subclass and export it as the root plugin object.
52 *
53 * @param name the name of the KPluginFactory derived class.
54 *
55 * @param pluginRegistrations code to be inserted into the constructor of the
56 * class. Usually a series of registerPlugin() calls.
57 *
58 * @note K_PLUGIN_FACTORY declares the subclass including a Q_OBJECT macro.
59 * So you need to make sure to have Qt's moc run also for the source file
60 * where you use the macro. E.g. in projects using CMake and it's automoc feature,
61 * as usual you need to have a line
62 * @code
63 * #include <myplugin.moc>
64 * @endcode
65 * in the same source file when that one has the name "myplugin.cpp".
66 *
67 * Example:
68 * @code
69 * #include <KPluginFactory>
70 * #include <plugininterface.h>
71 *
72 * class MyPlugin : public PluginInterface
73 * {
74 * public:
75 * MyPlugin(QObject *parent, const QVariantList &args)
76 * : PluginInterface(parent)
77 * {}
78 * };
79 *
80 * K_PLUGIN_FACTORY(MyPluginFactory, registerPlugin<MyPlugin>();)
81 *
82 * #include <myplugin.moc>
83 * @endcode
84 *
85 * If you want to compile a .json file into the plugin, use K_PLUGIN_FACTORY_WITH_JSON.
86 *
87 * @see K_PLUGIN_FACTORY_WITH_JSON
88 * @see K_PLUGIN_FACTORY_DECLARATION
89 * @see K_PLUGIN_FACTORY_DEFINITION
90 */
91#define K_PLUGIN_FACTORY(name, pluginRegistrations) __K_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations, IID KPluginFactory_iid)
92
93/**
94 * @relates KPluginFactory
95 *
96 * Create a KPluginFactory subclass and export it as the root plugin object with
97 * JSON metadata.
98 *
99 * This macro does the same as K_PLUGIN_FACTORY, but adds a JSON file as plugin
100 * metadata. See Q_PLUGIN_METADATA() for more information.
101 *
102 * @param name the name of the KPluginFactory derived class.
103 *
104 * @param pluginRegistrations code to be inserted into the constructor of the
105 * class. Usually a series of registerPlugin() calls.
106 *
107 * @param jsonFile name of the JSON file to be compiled into the plugin as metadata
108 *
109 * @note K_PLUGIN_FACTORY_WITH_JSON declares the subclass including a Q_OBJECT macro.
110 * So you need to make sure to have Qt's moc run also for the source file
111 * where you use the macro. E.g. in projects using CMake and its automoc feature,
112 * as usual you need to have a line
113 * @code
114 * #include <myplugin.moc>
115 * @endcode
116 * in the same source file when that one has the name "myplugin.cpp".
117 *
118 * Example:
119 * @code
120 * #include <KPluginFactory>
121 * #include <plugininterface.h>
122 *
123 * class MyPlugin : public PluginInterface
124 * {
125 * public:
126 * MyPlugin(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
127 * : PluginInterface(parent)
128 * {}
129 * };
130 *
131 * K_PLUGIN_FACTORY_WITH_JSON(MyPluginFactory,
132 * "metadata.json",
133 * registerPlugin<MyPlugin>();
134 * )
135 *
136 * #include <myplugin.moc>
137 * @endcode
138 *
139 * @see K_PLUGIN_FACTORY
140 * @see K_PLUGIN_FACTORY_DECLARATION
141 * @see K_PLUGIN_FACTORY_DEFINITION
142 *
143 * @since 5.0
144 */
145#define K_PLUGIN_FACTORY_WITH_JSON(name, jsonFile, pluginRegistrations) \
146 __K_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations, IID KPluginFactory_iid FILE jsonFile)
147
148/**
149 * @relates KPluginFactory
150 *
151 * Create a KPluginFactory subclass and export it as the root plugin object with
152 * JSON metadata.
153 *
154 * This macro does the same as K_PLUGIN_FACTORY_WITH_JSON, but you only have to pass the class name and the json file.
155 * The factory name and registerPlugin call are deduced from the class name.
156 *
157 * @code
158 * #include <myplugin.moc>
159 * @endcode
160 * in the same source file when that one has the name "myplugin.cpp".
161 *
162 * Example:
163 * @code
164 * #include <KPluginFactory>
165 * #include <plugininterface.h>
166 *
167 * class MyPlugin : public PluginInterface
168 * {
169 * public:
170 * MyPlugin(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
171 * : PluginInterface(parent)
172 * {}
173 * };
174 *
175 * K_PLUGIN_CLASS_WITH_JSON(MyPlugin, "metadata.json")
176 *
177 * #include <myplugin.moc>
178 * @endcode
179 *
180 * @see K_PLUGIN_FACTORY_WITH_JSON
181 *
182 * @since 5.44
183 */
184#ifdef KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME
185#define K_PLUGIN_CLASS_WITH_JSON(classname, jsonFile) \
186 K_PLUGIN_FACTORY_WITH_JSON(KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME, jsonFile, registerPlugin<classname>();)
187#else
188#define K_PLUGIN_CLASS_WITH_JSON(classname, jsonFile) K_PLUGIN_FACTORY_WITH_JSON(classname##Factory, jsonFile, registerPlugin<classname>();)
189#endif
190
191/**
192 * @relates KPluginFactory
193 *
194 * Creates a KPluginFactory subclass and exports it as the root plugin object.
195 * Unlike @ref K_PLUGIN_CLASS_WITH_JSON, this macro does not require json meta data.
196 *
197 * This macro does the same as K_PLUGIN_FACTORY, but you only have to pass the class name.
198 * The factory name and registerPlugin call are deduced from the class name.
199 * This is also useful if you want to use static plugins, see the kcoreaddons_add_plugin CMake method.
200 * @since 5.90
201 */
202#ifdef KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME
203#define K_PLUGIN_CLASS(classname) K_PLUGIN_FACTORY(KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME, registerPlugin<classname>();)
204#else
205#define K_PLUGIN_CLASS(classname) K_PLUGIN_FACTORY(classname##Factory, registerPlugin<classname>();)
206#endif
207
208/**
209 * @class KPluginFactory kpluginfactory.h <KPluginFactory>
210 *
211 * KPluginFactory provides a convenient way to provide factory-style plugins.
212 * Qt plugins provide a singleton object, but a common pattern is for plugins
213 * to generate as many objects of a particular type as the application requires.
214 * By using KPluginFactory, you can avoid implementing the factory pattern
215 * yourself.
216 *
217 * KPluginFactory also allows plugins to provide multiple different object
218 * types, indexed by keywords.
219 *
220 * The objects created by KPluginFactory must inherit QObject, and must have a
221 * standard constructor pattern:
222 * @li if the object is a KPart::Part, it must be of the form
223 * @code
224 * T(QWidget *parentWidget, QObject *parent, const QVariantList &args)
225 * @endcode
226 * or
227 * @code
228 * T(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
229 * @endcode
230 * @li if it is a QWidget, it must be of the form
231 * @code
232 * T(QWidget *parent, const QVariantList &args)
233 * @endcode
234 * or
235 * @code
236 * T(QWidget *parent, const KPluginMetaData &metaData, const QVariantList &args)
237 * @endcode
238 * @li otherwise it must be of the form
239 * @code
240 * T(QObject *parent, const QVariantList &args)
241 * @endcode
242 * or
243 * @code
244 * T(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
245 * @endcode
246 *
247 * You should typically use either K_PLUGIN_CLASS() or
248 * K_PLUGIN_CLASS_WITH_JSON() in your plugin code to generate a factory.
249 * The typical pattern is:
250 *
251 * @code
252 * #include <KPluginFactory>
253 * #include <plugininterface.h>
254 *
255 * class MyPlugin : public PluginInterface
256 * {
257 * public:
258 * MyPlugin(QObject *parent, const QVariantList &args)
259 * : PluginInterface(parent)
260 * {}
261 * };
262 *
263 * K_PLUGIN_CLASS(MyPlugin)
264 * #include <myplugin.moc>
265 * @endcode
266 *
267 * If you want to write a custom KPluginFactory not using the standard macro(s)
268 * you can reimplement the
269 * create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args)
270 * method.
271 *
272 * Example:
273 * @code
274 * class SomeScriptLanguageFactory : public KPluginFactory
275 * {
276 * Q_OBJECT
277 * public:
278 * SomeScriptLanguageFactory()
279 * {}
280 *
281 * protected:
282 * virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args)
283 * {
284 * // Create an identifier based on the iface and given pluginId
285 * const QString identifier = QLatin1String(iface) + QLatin1Char('_') + metaData().pluginId();
286 * // load scripting language module from the information in identifier and return it:
287 * return object;
288 * }
289 * };
290 * @endcode
291 *
292 * To load the KPluginFactory from an installed plugin you can use @ref loadFactory and for
293 * directly creating a plugin instance from it @ref instantiatePlugin
294 *
295 * @author Matthias Kretz <kretz@kde.org>
296 * @author Bernhard Loos <nhuh.put@web.de>
297 * @author Alexander Lohnau <alexander.lohnau@gmx.de>
298 */
299class KCOREADDONS_EXPORT KPluginFactory : public QObject
300{
301 Q_OBJECT
302
303public:
304 /**
305 * This constructor creates a factory for a plugin.
306 */
307 explicit KPluginFactory();
308
309 /**
310 * This destroys the PluginFactory.
311 */
312 ~KPluginFactory() override;
313
314 /// @since 5.86
316 NO_PLUGIN_ERROR = 0,
317 INVALID_PLUGIN,
318 INVALID_FACTORY,
319 INVALID_KPLUGINFACTORY_INSTANTIATION,
320 };
321 /**
322 * Holds the result of a plugin load operation, i.e. the loaded plugin on success or information about the error on failure
323 * @since 5.86
324 */
325 template<typename T>
326 class Result
327 {
328 public:
329 T *plugin = nullptr;
330 /// translated, user-visible error string
332 /// untranslated error text
334 ResultErrorReason errorReason = NO_PLUGIN_ERROR;
335 explicit operator bool() const
336 {
337 return plugin != nullptr;
338 }
339 };
340
341 /**
342 * Attempts to load the KPluginFactory from the given metadata.
343 * The errors will be logged using the `kf.coreaddons` debug category.
344 * @param data KPluginMetaData from which the plugin should be loaded
345 * @return Result object which contains the plugin instance and potentially error information
346 * @since 5.86
347 */
348 static Result<KPluginFactory> loadFactory(const KPluginMetaData &data);
349
350 /**
351 * Attempts to load the KPluginFactory and create a @p T instance from the given metadata
352 * KCoreAddons will log error messages automatically, meaning you only need to implement your
353 * own logging in case you want to give it more context info or have a custom category.
354 * @code
355 if (auto result = KPluginFactory::instantiatePlugin<MyClass>(metaData, parent, args)) {
356 // The plugin is valid and result.plugin contains the object
357 } else {
358 // We can access the error related properties, but result.plugin is a nullptr
359 qCWarning(MYCATEGORY) << result.errorString;
360 }
361 * @endcode
362 * If there is no extra error handling needed the plugin can be directly accessed and checked if it is a nullptr
363 * @code
364 if (auto plugin = KPluginFactory::instantiatePlugin<MyClass>(metaData, parent, args).plugin) {
365 }
366 * @endcode
367 * @param data KPluginMetaData from which the plugin should be loaded
368 * @param args arguments which get passed to the plugin's constructor
369 * @return Result object which contains the plugin instance and potentially error information
370 * @since 5.86
371 */
372 template<typename T>
373 static Result<T> instantiatePlugin(const KPluginMetaData &data, QObject *parent = nullptr, const QVariantList &args = {})
374 {
375 Result<T> result;
376 KPluginFactory::Result<KPluginFactory> factoryResult = loadFactory(data);
377 if (!factoryResult.plugin) {
378 result.errorString = factoryResult.errorString;
379 result.errorText = factoryResult.errorText;
380 result.errorReason = factoryResult.errorReason;
381 return result;
382 }
383 T *instance = factoryResult.plugin->create<T>(parent, args);
384 if (!instance) {
385 const QLatin1String className(T::staticMetaObject.className());
386 result.errorString = tr("KPluginFactory could not create a %1 instance from %2").arg(className, data.fileName());
387 result.errorText = QStringLiteral("KPluginFactory could not create a %1 instance from %2").arg(className, data.fileName());
388 result.errorReason = INVALID_KPLUGINFACTORY_INSTANTIATION;
389 logFailedInstantiationMessage(T::staticMetaObject.className(), data);
390 } else {
391 result.plugin = instance;
392 }
393 return result;
394 }
395
396 /**
397 * Use this method to create an object. It will try to create an object which inherits
398 * @p T. If it has multiple choices it's not defined which object will be returned, so be careful
399 * to request a unique interface or use keywords.
400 *
401 * @tparam T the interface for which an object should be created. The object will inherit @p T.
402 * @param parent the parent of the object. If @p parent is a widget type, it will also passed
403 * to the parentWidget argument of the CreateInstanceFunction for the object.
404 * @param args additional arguments which will be passed to the object.
405 * @returns pointer to the created object is returned, or @c nullptr if an error occurred.
406 */
407 template<typename T>
408 T *create(QObject *parent = nullptr, const QVariantList &args = {});
409
410 /**
411 * Use this method to create an object. It will try to create an object which inherits @p T
412 * This overload has an additional @p parentWidget argument, which is used by some plugins (e.g. Parts).
413
414 * @tparam T the interface for which an object should be created. The object will inherit @p T.
415 * @param parentWidget an additional parent widget.
416 * @param parent the parent of the object. If @p parent is a widget type, it will also passed
417 * to the parentWidget argument of the CreateInstanceFunction for the object.
418 * @param args additional arguments which will be passed to the object. Since 5.93 this has a default arg.
419 * @returns pointer to the created object is returned, or @c nullptr if an error occurred.
420 */
421 template<typename T>
422 T *create(QWidget *parentWidget, QObject *parent, const QVariantList &args = {});
423
424 /**
425 * @returns the metadata of the plugin
426 *
427 * @since 5.77
428 */
429 KPluginMetaData metaData() const;
430
431 /**
432 * Set the metadata about the plugin this factory generates.
433 *
434 * @param metaData the metadata about the plugin
435 *
436 * @since 5.77
437 */
438 void setMetaData(const KPluginMetaData &metaData);
439
440protected:
441 /**
442 * Function pointer type to a function that instantiates a plugin
443 * For plugins that don't support a KPluginMetaData parameter it is discarded
444 * @since 5.77
445 */
446 using CreateInstanceWithMetaDataFunction = QObject *(*)(QWidget *, QObject *, const KPluginMetaData &, const QVariantList &);
447
448 /**
449 * This is used to detect the arguments need for the constructor of metadata-taking plugin classes.
450 * You can inherit it, if you want to add new classes and still keep support for the old ones.
451 */
452 template<class impl>
454 /// property to control the availability of the registerPlugin overload taking default values
455 static constexpr bool enabled = std::is_constructible<impl, QWidget *, QObject *, KPluginMetaData, QVariantList>::value // KParts
456 || std::is_constructible<impl, QWidget *, QObject *, KPluginMetaData>::value
457 || std::is_constructible<impl, QWidget *, KPluginMetaData, QVariantList>::value // QWidgets
458 || std::is_constructible<impl, QWidget *, KPluginMetaData>::value
459 || std::is_constructible<impl, QObject *, KPluginMetaData, QVariantList>::value // Nomal QObjects
460 || std::is_constructible<impl, QObject *, KPluginMetaData>::value;
461
462 CreateInstanceWithMetaDataFunction createInstanceFunction(KParts::Part *)
463 {
464 return &createPartWithMetaDataInstance<impl>;
465 }
466 CreateInstanceWithMetaDataFunction createInstanceFunction(QWidget *)
467 {
468 return &createWithMetaDataInstance<impl, QWidget>;
469 }
470 CreateInstanceWithMetaDataFunction createInstanceFunction(...)
471 {
472 return &createWithMetaDataInstance<impl, QObject>;
473 }
474 };
475
476 /**
477 * This is used to detect the arguments need for the constructor of metadata-less plugin classes.
478 * You can inherit it, if you want to add new classes and still keep support for the old ones.
479 */
480 template<class impl>
482 /// property to control the availability of the registerPlugin overload taking default values
483 static constexpr bool _canConstruct = std::is_constructible<impl, QWidget *, QVariantList>::value // QWidget plugin
484 || std::is_constructible<impl, QWidget *>::value //
485 || std::is_constructible<impl, QObject *, QVariantList>::value // QObject plugins
486 || std::is_constructible<impl, QObject *>::value;
487 static constexpr bool enabled = _canConstruct && !InheritanceWithMetaDataChecker<impl>::enabled; // Avoid ambiguity in case of default arguments
488
489 CreateInstanceWithMetaDataFunction createInstanceFunction(QWidget *)
490 {
491 return &createInstance<impl, QWidget>;
492 }
493 CreateInstanceWithMetaDataFunction createInstanceFunction(...)
494 {
495 return &createInstance<impl, QObject>;
496 }
497 };
498
499 // Use std::enable_if_t once C++14 can be relied on
500 template<bool B, class T = void>
501 using enable_if_t = typename std::enable_if<B, T>::type;
502
503 /**
504 * Uses a default instance creation function depending on the type of interface. If the
505 * interface inherits from
506 * @li @c KParts::Part the function will call
507 * @code
508 * new T(QWidget *parentWidget, QObject *parent, const QVariantList &args)
509 * @endcode
510 * @li @c QWidget the function will call
511 * @code
512 * new T(QWidget *parent, const QVariantList &args)
513 * @endcode
514 * @li else the function will call
515 * @code
516 * new T(QObject *parent, const QVariantList &args)
517 * @endcode
518 *
519 * If those constructor methods are not callable this overload is not available.
520 */
521 template<class T, enable_if_t<InheritanceChecker<T>::enabled, int> = 0>
523 {
524 CreateInstanceWithMetaDataFunction instanceFunction = InheritanceChecker<T>().createInstanceFunction(static_cast<T *>(nullptr));
525 registerPlugin(&T::staticMetaObject, instanceFunction);
526 }
527
528 /**
529 * Uses a default instance creation function depending on the type of interface. If the
530 * interface inherits from
531 * @li @c KParts::Part the function will call
532 * @code
533 * new T(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
534 * @endcode
535 * @li @c QWidget the function will call
536 * @code
537 * new T(QWidget *parent, const KPluginMetaData &metaData, const QVariantList &args)
538 * @endcode
539 * @li else the function will call
540 * @code
541 * new T(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
542 * @endcode
543 *
544 * If those constructor methods are not callable this overload is not available.
545 */
546 template<class T, enable_if_t<InheritanceWithMetaDataChecker<T>::enabled, int> = 0>
548 {
549 CreateInstanceWithMetaDataFunction instanceFunction = InheritanceWithMetaDataChecker<T>().createInstanceFunction(static_cast<T *>(nullptr));
550 registerPlugin(&T::staticMetaObject, instanceFunction);
551 }
552
553 /**
554 * Registers a plugin with the factory. Call this function from the constructor of the
555 * KPluginFactory subclass to make the create function able to instantiate the plugin when asked
556 * for an interface the plugin implements.
557 *
558 * @param T the name of the plugin class
559 * @param instanceFunction A function pointer to a function that creates an instance of the plugin.
560 * @since 5.96
561 */
562 template<class T>
564 {
565 registerPlugin(&T::staticMetaObject, instanceFunction);
566 }
567
568 /**
569 * This function is called when the factory asked to create an Object.
570 *
571 * You may reimplement it to provide a very flexible factory. This is especially useful to
572 * provide generic factories for plugins implemented using a scripting language.
573 *
574 * @param iface the staticMetaObject::className() string identifying the plugin interface that
575 * was requested. E.g. for KCModule plugins this string will be "KCModule".
576 * @param parentWidget only used if the requested plugin is a KPart.
577 * @param parent the parent object for the plugin object.
578 * @param args a plugin specific list of arbitrary arguments.
579 */
580 virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args);
581
582 template<class impl, class ParentType>
583 static QObject *createInstance(QWidget * /*parentWidget*/, QObject *parent, const KPluginMetaData & /*metaData*/, const QVariantList &args)
584 {
585 ParentType *p = nullptr;
586 if (parent) {
587 p = qobject_cast<ParentType *>(parent);
588 Q_ASSERT(p);
589 }
590 if constexpr (std::is_constructible<impl, ParentType *, QVariantList>::value) {
591 return new impl(p, args);
592 } else {
593 return new impl(p);
594 }
595 }
596
597 template<class impl, class ParentType>
598 static QObject *createWithMetaDataInstance(QWidget * /*parentWidget*/, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
599 {
600 ParentType *p = nullptr;
601 if (parent) {
602 p = qobject_cast<ParentType *>(parent);
603 Q_ASSERT(p);
604 }
605 if constexpr (std::is_constructible<impl, ParentType *, KPluginMetaData, QVariantList>::value) {
606 return new impl(p, metaData, args);
607 } else {
608 return new impl(p, metaData);
609 }
610 }
611
612 template<class impl>
613 static QObject *createPartWithMetaDataInstance(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
614 {
615 if constexpr (std::is_constructible<impl, QWidget *, QObject *, KPluginMetaData, QVariantList>::value) {
616 return new impl(parentWidget, parent, metaData, args);
617 } else {
618 return new impl(parentWidget, parent, metaData);
619 }
620 }
621
622private:
623 friend KPluginFactoryPrivate;
624 std::unique_ptr<KPluginFactoryPrivate> const d;
625 void registerPlugin(const QMetaObject *metaObject, CreateInstanceWithMetaDataFunction instanceFunction);
626 // The logging categories are not part of the public API, consequently this needs to be a private function
627 static void logFailedInstantiationMessage(KPluginMetaData data);
628 static void logFailedInstantiationMessage(const char *className, KPluginMetaData data);
629};
630
631template<typename T>
632inline T *KPluginFactory::create(QObject *parent, const QVariantList &args)
633{
634 QObject *o = create(T::staticMetaObject.className(), parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent) : nullptr, parent, args);
635
636 T *t = qobject_cast<T *>(o);
637 if (!t) {
638 delete o;
639 }
640 return t;
641}
642
643template<typename T>
644inline T *KPluginFactory::create(QWidget *parentWidget, QObject *parent, const QVariantList &args)
645{
646 QObject *o = create(T::staticMetaObject.className(), parentWidget, parent, args);
647
648 T *t = qobject_cast<T *>(o);
649 if (!t) {
650 delete o;
651 }
652 return t;
653}
654
655Q_DECLARE_INTERFACE(KPluginFactory, KPluginFactory_iid)
656
657#endif // KPLUGINFACTORY_H
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.
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.
static Result< T > instantiatePlugin(const KPluginMetaData &data, QObject *parent=nullptr, const QVariantList &args={})
Attempts to load the KPluginFactory and create a T instance from the given metadata KCoreAddons will ...
void registerPlugin(CreateInstanceWithMetaDataFunction instanceFunction)
Registers a plugin with the factory.
~KPluginFactory() override
This destroys the PluginFactory.
QObject *(*)(QWidget *, QObject *, const KPluginMetaData &, const QVariantList &) CreateInstanceWithMetaDataFunction
Function pointer type to a function that instantiates a plugin For plugins that don't support a KPlug...
This class allows easily accessing some standardized values from the JSON metadata that can be embedd...
QAction * create(StandardAction id, const Receiver *recvr, Func slot, QObject *parent, std::optional< Qt::ConnectionType > connectionType=std::nullopt)
KCOREADDONS_EXPORT void setMetaData(const MetaDataMap &metaData, QMimeData *mimeData)
bool isWidgetType() const const
QObject * parent() const const
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
This is used to detect the arguments need for the constructor of metadata-less plugin classes.
This is used to detect the arguments need for the constructor of metadata-taking plugin classes.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:24 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.