1/* This file is part of the KDE project
2 * Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19#ifndef kgenericfactory_h
20#define kgenericfactory_h
21
22#include <klibloader.h>
23#include <kpluginfactory.h>
24#include <kpluginloader.h>
25#include <ktypelist.h>
26#include <kcomponentdata.h>
27#include <kgenericfactory.tcc>
28#include <kglobal.h>
29#include <klocale.h>
30#include <kdebug.h>
31
32#ifndef KDE_NO_DEPRECATED
33
34/* @internal */
35template <class T>
36class KGenericFactoryBase : public KPluginFactory
37{
38public:
39 explicit KGenericFactoryBase(const char *componentName, const char *catalogName)
40 : KPluginFactory(componentName, catalogName)
41 {
42 s_self = this;
43 s_createComponentDataCalled = false;
44 }
45
46 explicit KGenericFactoryBase( const KAboutData *data )
47 : KPluginFactory(data)
48 {
49 s_self = this;
50 s_createComponentDataCalled = false;
51 }
52
53 virtual ~KGenericFactoryBase()
54 {
55 s_self = 0;
56 }
57
58 static KComponentData componentData()
59 {
60 Q_ASSERT(s_self);
61 if (!s_createComponentDataCalled) {
62 s_createComponentDataCalled = true;
63
64 KComponentData *kcd = s_self->createComponentData();
65 Q_ASSERT(kcd);
66 s_self->setComponentData(*kcd);
67 delete kcd;
68 }
69 return static_cast<KPluginFactory *>(s_self)->componentData();
70 }
71
72protected:
73 virtual KComponentData *createComponentData()
74 {
75 return new KComponentData(componentData());
76 }
77
78private:
79 static bool s_createComponentDataCalled;
80 static KGenericFactoryBase<T> *s_self;
81};
82
83/* @internal */
84template <class T>
85KGenericFactoryBase<T> *KGenericFactoryBase<T>::s_self = 0;
86
87/* @internal */
88template <class T>
89bool KGenericFactoryBase<T>::s_createComponentDataCalled = false;
90
91/**
92 * This template provides a generic implementation of a KLibFactory ,
93 * for use with shared library components. It implements the pure virtual
94 * createObject method of KLibFactory and instantiates objects of the
95 * specified class (template argument) when the class name argument of
96 * createObject matches a class name in the given hierarchy.
97 *
98 * In case you are developing a KParts component, skip this file and
99 * go directly to KParts::GenericFactory .
100 *
101 * Note that the class specified as template argument needs to provide
102 * a certain constructor:
103 * <ul>
104 * <li>If the class is derived from QObject then it needs to have
105 * a constructor like:
106 * <code>MyClass( QObject *parent,
107 * const QStringList &args );</code>
108 * <li>If the class is derived from QWidget then it needs to have
109 * a constructor like:
110 * <code>MyWidget( QWidget *parent,
111 * const QStringList &args);</code>
112 * <li>If the class is derived from KParts::Part then it needs to have
113 * a constructor like:
114 * <code>MyPart( QWidget *parentWidget,
115 * QObject *parent,
116 * const QStringList &args );</code>
117 * </ul>
118 * The args QStringList passed to the constructor is the args string list
119 * that the caller passed to KLibFactory's create method.
120 *
121 * In addition upon instantiation this template provides a central
122 * KComponentData object for your component, accessible through the
123 * static componentData() method. The componentName and catalogName arguments
124 * of the KGenericFactory constructor are passed to the KComponentData object.
125 *
126 * The creation of the KComponentData object can be customized by inheriting
127 * from this template class and re-implementing the virtual createComponentData
128 * method. For example it could look like this:
129 * \code
130 * KComponentData *MyFactory::createComponentData()
131 * {
132 * return new KComponentData( myAboutData );
133 * }
134 * \endcode
135 *
136 * Example of usage of the whole template:
137 * \code
138 * class MyPlugin : public KParts::Plugin
139 * {
140 * Q_ OBJECT
141 * public:
142 * MyPlugin( QObject *parent, const QStringList &args );
143 * ...
144 * };
145 *
146 * K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<MyPlugin> )
147 * \endcode
148 *
149 * @deprecated use KPluginFactory
150 */
151template <class Product, class ParentType = QObject>
152class KDE_DEPRECATED KGenericFactory : public KGenericFactoryBase<Product>
153{
154public:
155 explicit KGenericFactory( const char *componentName = 0, const char *catalogName = 0 )
156 : KGenericFactoryBase<Product>(componentName, catalogName)
157 {}
158
159 explicit KGenericFactory( const KAboutData *data )
160 : KGenericFactoryBase<Product>(data)
161 {}
162
163protected:
164 virtual QObject *createObject( QObject *parent,
165 const char *className, const QStringList &args )
166 {
167 return KDEPrivate::ConcreteFactory<Product, ParentType>
168 ::create( 0, parent, className, args );
169 }
170};
171
172/**
173 * \class KGenericFactory kgenericfactory.h <KGenericFactory>
174 *
175 * This template provides a generic implementation of a KLibFactory ,
176 * for use with shared library components. It implements the pure virtual
177 * createObject method of KLibFactory and instantiates objects of the
178 * specified classes in the given typelist template argument when the class
179 * name argument of createObject matches a class names in the given hierarchy
180 * of classes.
181 *
182 * Note that each class in the specified in the typelist template argument
183 * needs to provide a certain constructor:
184 * <ul>
185 * <li>If the class is derived from QObject then it needs to have
186 * a constructor like:
187 * <code>MyClass( QObject *parent,
188 * const QStringList &args );</code>
189 * <li>If the class is derived from QWidget then it needs to have
190 * a constructor like:
191 * <code>MyWidget( QWidget *parent,
192 * const QStringList &args);</code>
193 * <li>If the class is derived from KParts::Part then it needs to have
194 * a constructor like:
195 * <code>MyPart( QWidget *parentWidget,
196 * QObject *parent,
197 * const QStringList &args );</code>
198 * </ul>
199 * The args QStringList passed to the constructor is the args string list
200 * that the caller passed to KLibFactory's create method.
201 *
202 * In addition upon instantiation this template provides a central
203 * KComponentData object for your component, accessible through the
204 * static componentData() method. The componentName and catalogName arguments
205 * of the KGenericFactory constructor are passed to the KComponentData object.
206 *
207 * The creation of the KComponentData object can be customized by inheriting
208 * from this template class and re-implementing the virtual createComponentData
209 * method. For example it could look like this:
210 * \code
211 * KComponentData *MyFactory::createComponentData()
212 * {
213 * return new KComponentData( myAboutData );
214 * }
215 * \endcode
216 *
217 * Example of usage of the whole template:
218 * \code
219 * class MyPlugin : public KParts::Plugin
220 * {
221 * Q_ OBJECT
222 * public:
223 * MyPlugin( QObject *parent,
224 * const QStringList &args );
225 * ...
226 * };
227 *
228 * class MyDialogComponent : public KDialog
229 * {
230 * Q_ OBJECT
231 * public:
232 * MyDialogComponent( QWidget *parentWidget,
233 * const QStringList &args );
234 * ...
235 * };
236 *
237 * typedef K_TYPELIST_2( MyPlugin, MyDialogComponent ) Products;
238 * K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<Products> )
239 * \endcode
240 */
241template <class Product, class ProductListTail>
242class KGenericFactory< KTypeList<Product, ProductListTail>, QObject >
243 : public KGenericFactoryBase<KTypeList<Product, ProductListTail> >
244{
245public:
246 explicit KGenericFactory( const char *componentName = 0, const char *catalogName = 0 )
247 : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName, catalogName)
248 {}
249
250 explicit KGenericFactory( const KAboutData *data )
251 : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(data)
252 {}
253
254
255protected:
256 virtual QObject *createObject( QObject *parent,
257 const char *className, const QStringList &args )
258 {
259 return KDEPrivate::MultiFactory< KTypeList< Product, ProductListTail > >
260 ::create( 0, parent, className, args );
261 }
262};
263
264/**
265 * \class KGenericFactory kgenericfactory.h <KGenericFactory>
266 *
267 * This template provides a generic implementation of a KLibFactory ,
268 * for use with shared library components. It implements the pure virtual
269 * createObject method of KLibFactory and instantiates objects of the
270 * specified classes in the given typelist template argument when the class
271 * name argument of createObject matches a class names in the given hierarchy
272 * of classes.
273 *
274 * Note that each class in the specified in the typelist template argument
275 * needs to provide a certain constructor:
276 * <ul>
277 * <li>If the class is derived from QObject then it needs to have
278 * a constructor like:
279 * <code>MyClass( QObject *parent,
280 * const QStringList &args );</code>
281 * <li>If the class is derived from QWidget then it needs to have
282 * a constructor like:
283 * <code>MyWidget( QWidget *parent,
284 * const QStringList &args);</code>
285 * <li>If the class is derived from KParts::Part then it needs to have
286 * a constructor like:
287 * <code>MyPart( QWidget *parentWidget,
288 * QObject *parent,
289 * const QStringList &args );</code>
290 * </ul>
291 * The args QStringList passed to the constructor is the args string list
292 * that the caller passed to KLibFactory's create method.
293 *
294 * In addition upon instantiation this template provides a central
295 * KComponentData object for your component, accessible through the
296 * static componentData() method. The componentName and catalogNames arguments
297 * of the KGenericFactory constructor are passed to the KComponentData object.
298 *
299 * The creation of the KComponentData object can be customized by inheriting
300 * from this template class and re-implementing the virtual createComponentData
301 * method. For example it could look like this:
302 * \code
303 * KComponentData *MyFactory::createComponentData()
304 * {
305 * return new KComponentData( myAboutData );
306 * }
307 * \endcode
308 *
309 * Example of usage of the whole template:
310 * \code
311 * class MyPlugin : public KParts::Plugin
312 * {
313 * Q_ OBJECT
314 * public:
315 * MyPlugin( QObject *parent,
316 * const QStringList &args );
317 * ...
318 * };
319 *
320 * class MyDialogComponent : public KDialog
321 * {
322 * Q_ OBJECT
323 * public:
324 * MyDialogComponent( QWidget *parentWidget,
325 * const QStringList &args );
326 * ...
327 * };
328 *
329 * typedef K_TYPELIST_2( MyPlugin, MyDialogComponent ) Products;
330 * K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<Products> )
331 * \endcode
332 */
333template <class Product, class ProductListTail,
334 class ParentType, class ParentTypeListTail>
335class KGenericFactory< KTypeList<Product, ProductListTail>,
336 KTypeList<ParentType, ParentTypeListTail> >
337 : public KGenericFactoryBase<KTypeList<Product, ProductListTail> >
338{
339public:
340 explicit KGenericFactory( const char *componentName = 0, const char *catalogName = 0 )
341 : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName, catalogName)
342 {}
343 explicit KGenericFactory( const KAboutData *data )
344 : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(data)
345 {}
346
347
348protected:
349 virtual QObject *createObject( QObject *parent,
350 const char *className, const QStringList &args )
351 {
352 return KDEPrivate::MultiFactory< KTypeList< Product, ProductListTail >,
353 KTypeList< ParentType, ParentTypeListTail > >
354 ::create( 0, 0, parent,
355 className, args );
356 }
357};
358
359#endif
360#endif
361
362
363