Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* This file is part of the KDE project
2 Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
3 Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19
20*/
21
22#ifndef KDECORE_KPLUGINFACTORY_H
23#define KDECORE_KPLUGINFACTORY_H
24
25#include "kdecore_export.h"
26
27#include <QtCore/QObject>
28#include <QtCore/QVariant>
29#include <QtCore/QStringList>
30#include <kcomponentdata.h>
31#include <kexportplugin.h>
32#include <kglobal.h>
33
34class KPluginFactoryPrivate;
35namespace KParts { class Part; }
36
37#define K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \
38class name : public baseFactory \
39{ \
40 public: \
41 explicit name(const char * = 0, const char * = 0, QObject * = 0); \
42 explicit name(const KAboutData &, QObject * = 0); \
43 ~name(); \
44 static KComponentData componentData(); \
45 private: \
46 void init(); \
47};
48
49#define K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \
50K_GLOBAL_STATIC(KComponentData, name##factorycomponentdata) \
51name::name(const char *componentName, const char *catalogName, QObject *parent) \
52 : baseFactory(componentName, catalogName, parent) { init(); } \
53name::name(const KAboutData &aboutData, QObject *parent) \
54 : baseFactory(aboutData, parent) { init(); } \
55void name::init() \
56{ \
57 if (name##factorycomponentdata->isValid()) \
58 setComponentData(*name##factorycomponentdata); \
59 else \
60 *name##factorycomponentdata = KPluginFactory::componentData(); \
61 pluginRegistrations \
62} \
63name::~name() {} \
64KComponentData name::componentData() \
65{ \
66 return *name##factorycomponentdata; \
67}
68
69#define K_PLUGIN_FACTORY_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \
70 K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \
71 K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations)
72
73/**
74 * \relates KPluginFactory
75 * Defines a KPluginFactory subclass with two constructors and a static componentData function.
76 *
77 * The first constructor takes the arguments (const char *componentName, const char *catalogName,
78 * QObject *parent).
79 * The second constructor takes (const KAboutData *aboutData, QObject *parent).
80 *
81 * The static componentData method returns the same KComponentData object as the
82 * KPluginFactory::componentData function returns. As you normally don't have a pointer to the
83 * factory object in the plugin code the static componentData function is a convenient way to access
84 * the KComponentData.
85 *
86 * \param name The name of the KPluginFactory derived class. This is the name you'll need for
87 * K_EXPORT_PLUGIN
88 *
89 * \param pluginRegistrations This is code inserted into the constructors the class. You'll want to
90 * call registerPlugin from there.
91 *
92 * Example:
93 * \code
94 * #include <KPluginFactory>
95 * #include <KPluginLoader>
96 * #include <plugininterface.h>
97 *
98 * class MyPlugin;
99 *
100 * K_PLUGIN_FACTORY(MyPluginFactory,
101 * registerPlugin<MyPlugin>();
102 * )
103 * K_EXPORT_PLUGIN(MyPluginFactory("componentName", "catalogName"))
104 *
105 * // or:
106 * static KAboutData createAboutData()
107 * {
108 * KAboutData aboutData("myplugin", "myplugin", ki18n("MyPlugin"), "0.1",
109 * ki18n("a description of the plugin"), KAboutData::License_LGPL,
110 * ki18n("Copyright (C) 2007 Your Name"));
111 * aboutData.addAuthor(ki18n("Your Name"), ...);
112 * return aboutData;
113 * }
114 * K_EXPORT_PLUGIN(MyPluginFactory(createAboutData()))
115 *
116 * class MyPlugin : public PluginInterface
117 * {
118 * ...
119 * KComponentData kcd = MyPluginFactory::componentData();
120 * ...
121 * };
122 * \endcode
123 *
124 * \see K_PLUGIN_FACTORY_DECLARATION
125 * \see K_PLUGIN_FACTORY_DEFINITION
126 */
127#define K_PLUGIN_FACTORY(name, pluginRegistrations) K_PLUGIN_FACTORY_WITH_BASEFACTORY(name, KPluginFactory, pluginRegistrations)
128
129/**
130 * \relates KPluginFactory
131 * K_PLUGIN_FACTORY_DECLARATION declares the KPluginFactory subclass. This macro can be used in a
132 * header file.
133 *
134 * \param name The name of the KPluginFactory derived class. This is the name you'll need for
135 * K_EXPORT_PLUGIN
136 *
137 * \see K_PLUGIN_FACTORY
138 * \see K_PLUGIN_FACTORY_DEFINITION
139 */
140#define K_PLUGIN_FACTORY_DECLARATION(name) K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, KPluginFactory)
141
142/**
143 * \relates KPluginFactory
144 * K_PLUGIN_FACTORY_DEFINITION defines the KPluginFactory subclass. This macro can <b>not</b> be used in a
145 * header file.
146 *
147 * \param name The name of the KPluginFactory derived class. This is the name you'll need for
148 * K_EXPORT_PLUGIN
149 *
150 * \param pluginRegistrations This is code inserted into the constructors the class. You'll want to
151 * call registerPlugin from there.
152 *
153 * \see K_PLUGIN_FACTORY
154 * \see K_PLUGIN_FACTORY_DECLARATION
155 */
156#define K_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, KPluginFactory, pluginRegistrations)
157
158/**
159 * \class KPluginFactory kpluginfactory.h <KPluginFactory>
160 *
161 * If you develop a library that is to be loaded dynamically at runtime, then
162 * you should return a pointer to a KPluginFactory.
163 *
164 * For most cases it is enough to use the K_PLUGIN_FACTORY macro to create the factory.
165 *
166 * Example:
167 * \code
168 * #include <KPluginFactory>
169 * #include <KPluginLoader>
170 * #include <plugininterface.h>
171 *
172 * class MyPlugin;
173 *
174 * K_PLUGIN_FACTORY(MyPluginFactory,
175 * registerPlugin<MyPlugin>();
176 * )
177 * K_EXPORT_PLUGIN(MyPluginFactory("componentName"))
178 *
179 * class MyPlugin : public PluginInterface
180 * {
181 * ...
182 * KComponentData kcd = MyPluginFactory::componentData();
183 * ...
184 * };
185 * \endcode
186 *
187 * K_PLUGIN_FACTORY is a convenient macro that expands to a class derived from KPluginFactory
188 * providing two constructors and a static componentData() function. The second argument to
189 * K_PLUGIN_FACTORY is code that is called from the constructors. There you can use registerPlugin
190 * to register as many plugins for the factory as you want to.
191 *
192 * If you want to write a custom KPluginFactory not using the standard macro(s) you can reimplement
193 * the create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword)
194 * function.
195 *
196 * Example:
197 * \code
198 * class SomeScriptLanguageFactory : public KPluginFactory
199 * {
200 * Q_OBJECT
201 * public:
202 * SomeScriptLanguageFactory()
203 * : KPluginFactory("SomeScriptLanguageComponent")
204 * {}
205 *
206 * protected:
207 * virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword)
208 * {
209 * const QString identifier = QLatin1String(iface) + QLatin1Char('_') + keyword;
210 * // load scripting language module from the information in identifier
211 * // and return it:
212 * return object;
213 * }
214 * };
215 * \endcode
216 *
217 * If you want to load a library use KPluginLoader.
218 * The application that wants to instantiate plugin classes can do the following:
219 * \code
220 * KPluginFactory *factory = KPluginLoader("libraryname").factory();
221 * if (factory) {
222 * PluginInterface *p1 = factory->create<PluginInterface>(parent);
223 * OtherInterface *p2 = factory->create<OtherInterface>(parent);
224 * NextInterface *p3 = factory->create<NextInterface>("keyword1", parent);
225 * NextInterface *p3 = factory->create<NextInterface>("keyword2", parent);
226 * }
227 * \endcode
228 *
229 * \author Matthias Kretz <kretz@kde.org>
230 * \author Bernhard Loos <nhuh.put@web.de>
231 */
232class KDECORE_EXPORT KPluginFactory : public QObject
233{
234 Q_OBJECT
235 Q_DECLARE_PRIVATE(KPluginFactory)
236public:
237 /**
238 * This constructor creates a factory for a plugin with the given \p componentName and
239 * \p catalogName. Those values are used to initialize a KComponentData object for the plugin.
240 * You can later access it with componentData(). If \p componentName is 0, an invalid KComponentData
241 * object will be created.
242 *
243 * \param componentName the component name of the plugin
244 * \param catalogName the translation catalog to use
245 * \param parent a parent object
246 */
247 explicit KPluginFactory(const char *componentName = 0, const char *catalogName = 0, QObject *parent = 0);
248
249 /**
250 * This constructor creates a factory for a plugin with the given KAboutData object. This object is
251 * used to initialize a KComponentData object for the plugin. You can later access it with
252 * componentData().
253 * KPluginFactory takes ownership of the \p aboutData object, so don't delete it yourself!
254 *
255 * \param aboutData the KAboutData for the plugin
256 * \param parent a parent object
257 */
258 explicit KPluginFactory(const KAboutData &aboutData, QObject *parent = 0);
259 /**
260 * @deprecated
261 */
262#ifndef KDE_NO_DEPRECATED
263 KDE_CONSTRUCTOR_DEPRECATED explicit KPluginFactory(const KAboutData *aboutData, QObject *parent = 0);
264#endif
265
266 /**
267 * @deprecated
268 */
269#ifndef KDE_NO_DEPRECATED
270 explicit KDE_CONSTRUCTOR_DEPRECATED KPluginFactory(QObject *parent);
271#endif
272
273 /**
274 * This destroys the PluginFactory. It will remove the translation catalog for the plugin,
275 * if it was initialized.
276 */
277 virtual ~KPluginFactory();
278
279 /**
280 * You can use this method to get the component data of the plugin. It is filled with the
281 * information given to the constructor of KPluginFactory.
282 * The K_PLUGIN_FACTORY macros provide a static version of this method, this can be used from
283 * any place within the plugin.
284 *
285 * Only use this method if you specified a componentData name or instance to the factory
286 * constructor or to setComponentData.
287 * Otherwise you get an invalid KComponentData, which will crash if used.
288 *
289 * \returns The KComponentData for the plugin
290 */
291 KComponentData componentData() const;
292
293 /**
294 * Use this method to create an object. It will try to create an object which inherits
295 * \p T. If it has multiple choices, you will get a fatal error (kFatal()), so be careful
296 * to request a unique interface or use keywords.
297 *
298 * \tparam T The interface for which an object should be created. The object will inherit \p T.
299 * \param parent The parent of the object. If \p parent is a widget type, it will also passed
300 * to the parentWidget argument of the CreateInstanceFunction for the object.
301 * \param args Additional arguments which will be passed to the object.
302 * \returns A pointer to the created object is returned, or 0 if an error occurred.
303 */
304 template<typename T>
305 T *create(QObject *parent = 0, const QVariantList &args = QVariantList());
306
307 /**
308 * Use this method to create an object. It will try to create an object which inherits
309 * \p T and was registered with \p keyword.
310 *
311 * \tparam T The interface for which an object should be created. The object will inherit \p T.
312 * \param keyword The keyword of the object.
313 * \param parent The parent of the object. If \p parent is a widget type, it will also passed
314 * to the parentWidget argument of the CreateInstanceFunction for the object.
315 * \param args Additional arguments which will be passed to the object.
316 * \returns A pointer to the created object is returned, or 0 if an error occurred.
317 */
318 template<typename T>
319 T *create(const QString &keyword, QObject *parent = 0, const QVariantList &args = QVariantList());
320
321 /**
322 * Use this method to create an object. It will try to create an object which inherits
323 * \p T and was registered with \p keyword.
324 * This overload has an additional \p parentWidget argument, which is used by some plugins (e.g. Parts).
325
326 * \tparam T The interface for which an object should be created. The object will inherit \p T.
327 * \param parentWidget An additional parent widget.
328 * \param parent The parent of the object. If \p parent is a widget type, it will also passed
329 * to the parentWidget argument of the CreateInstanceFunction for the object.
330 * \param keyword The keyword of the object.
331 * \param args Additional arguments which will be passed to the object.
332 * \returns A pointer to the created object is returned, or 0 if an error occurred.
333 */
334 template<typename T>
335 T *create(QWidget *parentWidget, QObject *parent, const QString &keyword = QString(), const QVariantList &args = QVariantList());
336
337 /**
338 * @deprecated
339 */
340#ifndef KDE_NO_DEPRECATED
341 template<typename T>
342 KDE_DEPRECATED
343 T *create(QObject *parent, const QStringList &args)
344 {
345 return create<T>(parent, stringListToVariantList(args));
346 }
347#endif
348
349 /**
350 * @deprecated
351 */
352#ifndef KDE_NO_DEPRECATED
353 KDE_DEPRECATED QObject *create(QObject *parent = 0, const char *classname = "QObject", const QStringList &args = QStringList())
354 {
355 return create(classname, 0, parent, stringListToVariantList(args), QString());
356 }
357#endif
358
359Q_SIGNALS:
360 void objectCreated(QObject *object);
361
362protected:
363 /**
364 * Function pointer type to a function that instantiates a plugin.
365 */
366 typedef QObject *(*CreateInstanceFunction)(QWidget *, QObject *, const QVariantList &);
367
368 explicit KPluginFactory(KPluginFactoryPrivate &dd, QObject *parent = 0);
369
370 /**
371 * Registers a plugin with the factory. Call this function from the constructor of the
372 * KPluginFactory subclass to make the create function able to instantiate the plugin when asked
373 * for an interface the plugin implements.
374 *
375 * You can register as many plugin classes as you want as long as either the plugin interface or
376 * the \p keyword makes it unique. E.g. it is possible to register a KCModule and a
377 * KParts::Part without having to specify keywords since their interfaces differ.
378 *
379 * \tparam T the name of the plugin class
380 *
381 * \param keyword An optional keyword as unique identifier for the plugin. This allows you to
382 * put more than one plugin with the same interface into the same library using the same
383 * factory. X-KDE-PluginKeyword is a convenient way to specify the keyword in a desktop file.
384 *
385 * \param instanceFunction A function pointer to a function that creates an instance of the
386 * plugin. The default function that will be used depends on the type of interface. If the
387 * interface inherits from
388 * \li \c KParts::Part the function will call
389 * \code
390 * new T(QWidget *parentWidget, QObject *parent, const QVariantList &args)
391 * \endcode
392 * \li \c QWidget the function will call
393 * \code
394 * new T(QWidget *parent, const QVariantList &args)
395 * \endcode
396 * \li else the function will call
397 * \code
398 * new T(QObject *parent, const QVariantList &args)
399 * \endcode
400 */
401 template<class T>
402 void registerPlugin(const QString &keyword = QString(), CreateInstanceFunction instanceFunction
403 = InheritanceChecker<T>().createInstanceFunction(reinterpret_cast<T *>(0)))
404 {
405 registerPlugin(keyword, &T::staticMetaObject, instanceFunction);
406 }
407
408 /**
409 * \internal
410 * Converts a QStringList to a QVariantList
411 */
412 QVariantList stringListToVariantList(const QStringList &list);
413
414 /**
415 * \internal
416 * Converts a QVariantList of strings to a QStringList
417 */
418 QStringList variantListToStringList(const QVariantList &list);
419
420 virtual void setupTranslations();
421
422 KPluginFactoryPrivate *const d_ptr;
423
424 /**
425 * @deprecated
426 */
427#ifndef KDE_NO_DEPRECATED
428 virtual KDE_DEPRECATED QObject *createObject(QObject *parent, const char *className, const QStringList &args);
429#endif
430
431 /**
432 * @deprecated
433 */
434#ifndef KDE_NO_DEPRECATED
435 virtual KDE_DEPRECATED KParts::Part *createPartObject(QWidget *parentWidget, QObject *parent, const char *classname, const QStringList &args);
436#endif
437
438
439 /**
440 * This method sets the component data of the plugin. You can access the component data object
441 * later with componentData().
442 * Normally you don't have to call this, because the factory constructs a component data object
443 * from the information given to the constructor.
444 * The object is destroyed, when the module containing the plugin is unloaded. Normally this happens
445 * only on application shutdown.
446 *
447 * \param componentData the new KComponentData object
448 */
449
450 void setComponentData(const KComponentData &componentData);
451
452 /**
453 * This function is called when the factory asked to create an Object.
454 *
455 * You may reimplement it to provide a very flexible factory. This is especially useful to
456 * provide generic factories for plugins implemeted using a scripting language.
457 *
458 * \param iface The staticMetaObject::className() string identifying the plugin interface that
459 * was requested. E.g. for KCModule plugins this string will be "KCModule".
460 * \param parentWidget Only used if the requested plugin is a KPart.
461 * \param parent The parent object for the plugin object.
462 * \param args A plugin specific list of arbitrary arguments.
463 * \param keyword A string that uniquely identifies the plugin. If a KService is used this
464 * keyword is read from the X-KDE-PluginKeyword entry in the .desktop file.
465 */
466 virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword);
467
468 template<class impl, class ParentType>
469 static QObject *createInstance(QWidget *parentWidget, QObject *parent, const QVariantList &args)
470 {
471 Q_UNUSED(parentWidget);
472 ParentType *p = 0;
473 if (parent) {
474 p = qobject_cast<ParentType *>(parent);
475 Q_ASSERT(p);
476 }
477 return new impl(p, args);
478 }
479
480 template<class impl>
481 static QObject *createPartInstance(QWidget *parentWidget, QObject *parent, const QVariantList &args)
482 {
483 return new impl(parentWidget, parent, args);
484 }
485
486 /**
487 * This is used to detect the arguments need for the constructor of plugin classes.
488 * You can inherit it, if you want to add new classes and still keep support for the old ones.
489 */
490 template<class impl>
491 struct InheritanceChecker
492 {
493 CreateInstanceFunction createInstanceFunction(KParts::Part *) { return &createPartInstance<impl>; }
494 CreateInstanceFunction createInstanceFunction(QWidget *) { return &createInstance<impl, QWidget>; }
495 CreateInstanceFunction createInstanceFunction(...) { return &createInstance<impl, QObject>; }
496 };
497
498private:
499 void registerPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction);
500};
501
502typedef KPluginFactory KLibFactory;
503
504template<typename T>
505inline T *KPluginFactory::create(QObject *parent, const QVariantList &args)
506{
507 QObject *o = create(T::staticMetaObject.className(), parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent): 0, parent, args, QString());
508
509 T *t = qobject_cast<T *>(o);
510 if (!t) {
511 delete o;
512 }
513 return t;
514}
515
516template<typename T>
517inline T *KPluginFactory::create(const QString &keyword, QObject *parent, const QVariantList &args)
518{
519 QObject *o = create(T::staticMetaObject.className(), parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent): 0, parent, args, keyword);
520
521 T *t = qobject_cast<T *>(o);
522 if (!t) {
523 delete o;
524 }
525 return t;
526}
527
528template<typename T>
529inline T *KPluginFactory::create(QWidget *parentWidget, QObject *parent, const QString &keyword, const QVariantList &args)
530{
531 QObject *o = create(T::staticMetaObject.className(), parentWidget, parent, args, keyword);
532
533 T *t = qobject_cast<T *>(o);
534 if (!t) {
535 delete o;
536 }
537 return t;
538}
539
540#endif // KDECORE_KPLUGINFACTORY_H
541

Warning: That file was not part of the compilation database. It may have many parsing errors.