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 | |
34 | class KPluginFactoryPrivate; |
35 | namespace KParts { class Part; } |
36 | |
37 | #define K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \ |
38 | class 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) \ |
50 | K_GLOBAL_STATIC(KComponentData, name##factorycomponentdata) \ |
51 | name::name(const char *componentName, const char *catalogName, QObject *parent) \ |
52 | : baseFactory(componentName, catalogName, parent) { init(); } \ |
53 | name::name(const KAboutData &aboutData, QObject *parent) \ |
54 | : baseFactory(aboutData, parent) { init(); } \ |
55 | void name::init() \ |
56 | { \ |
57 | if (name##factorycomponentdata->isValid()) \ |
58 | setComponentData(*name##factorycomponentdata); \ |
59 | else \ |
60 | *name##factorycomponentdata = KPluginFactory::componentData(); \ |
61 | pluginRegistrations \ |
62 | } \ |
63 | name::~name() {} \ |
64 | KComponentData 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 | */ |
232 | class KDECORE_EXPORT KPluginFactory : public QObject |
233 | { |
234 | Q_OBJECT |
235 | Q_DECLARE_PRIVATE(KPluginFactory) |
236 | public: |
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 | |
359 | Q_SIGNALS: |
360 | void objectCreated(QObject *object); |
361 | |
362 | protected: |
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 | |
498 | private: |
499 | void registerPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction); |
500 | }; |
501 | |
502 | typedef KPluginFactory KLibFactory; |
503 | |
504 | template<typename T> |
505 | inline 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 | |
516 | template<typename T> |
517 | inline 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 | |
528 | template<typename T> |
529 | inline 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.