File indexing completed on 2024-04-21 14:55:34

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 #ifndef kgenericfactory_h
0020 #define kgenericfactory_h
0021 
0022 #include <klibloader.h>
0023 #include <kpluginfactory.h>
0024 #include <kpluginloader.h>
0025 #include <ktypelist.h>
0026 #include <kcomponentdata.h>
0027 #include <kgenericfactory.tcc>
0028 #include <klocalizedstring.h>
0029 #include <kdebug.h>
0030 
0031 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
0032 
0033 /* @internal */
0034 template <class T>
0035 class KGenericFactoryBase : public KPluginFactory
0036 {
0037 public:
0038     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactoryBase(const char *componentName)
0039         : KPluginFactory()
0040     {
0041         s_self = this;
0042         s_createComponentDataCalled = false;
0043     }
0044 
0045     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactoryBase(const KAboutData *data)
0046         : KPluginFactory()
0047     {
0048         KAboutData::registerPluginData(*data);
0049         s_self = this;
0050         s_createComponentDataCalled = false;
0051     }
0052 
0053     ~KGenericFactoryBase() override
0054     {
0055         s_self = nullptr;
0056     }
0057 
0058 #if 0 // not available anymore. Port away from KGenericFactory!
0059     static KComponentData componentData()
0060     {
0061         Q_ASSERT(s_self);
0062         if (!s_createComponentDataCalled) {
0063             s_createComponentDataCalled = true;
0064 
0065             KComponentData *kcd = s_self->createComponentData();
0066             Q_ASSERT(kcd);
0067             s_self->setComponentData(*kcd);
0068             delete kcd;
0069         }
0070         return static_cast<KPluginFactory *>(s_self)->componentData();
0071     }
0072 
0073 protected:
0074     virtual KComponentData *createComponentData()
0075     {
0076         return new KComponentData(componentData());
0077     }
0078 #endif
0079 private:
0080     static bool s_createComponentDataCalled;
0081     static KGenericFactoryBase<T> *s_self;
0082 };
0083 
0084 /* @internal */
0085 template <class T>
0086 KGenericFactoryBase<T> *KGenericFactoryBase<T>::s_self = nullptr;
0087 
0088 /* @internal */
0089 template <class T>
0090 bool KGenericFactoryBase<T>::s_createComponentDataCalled = false;
0091 
0092 /**
0093  * This template provides a generic implementation of a KLibFactory ,
0094  * for use with shared library components. It implements the pure virtual
0095  * createObject method of KLibFactory and instantiates objects of the
0096  * specified class (template argument) when the class name argument of
0097  * createObject matches a class name in the given hierarchy.
0098  *
0099  * In case you are developing a KParts component, skip this file and
0100  * go directly to KParts::GenericFactory .
0101  *
0102  * Note that the class specified as template argument needs to provide
0103  * a certain constructor:
0104  * <ul>
0105  *     <li>If the class is derived from QObject then it needs to have
0106  *         a constructor like:
0107  *         <code>MyClass( QObject *parent,
0108  *                        const QStringList &args );</code>
0109  *     <li>If the class is derived from QWidget then it needs to have
0110  *         a constructor like:
0111  *         <code>MyWidget( QWidget *parent,
0112  *                         const QStringList &args);</code>
0113  *     <li>If the class is derived from KParts::Part then it needs to have
0114  *         a constructor like:
0115  *         <code>MyPart( QWidget *parentWidget,
0116  *                       QObject *parent,
0117  *                       const QStringList &args );</code>
0118  * </ul>
0119  * The args QStringList passed to the constructor is the args string list
0120  * that the caller passed to KLibFactory's create method.
0121  *
0122  * In addition upon instantiation this template provides a central
0123  * KComponentData object for your component, accessible through the
0124  * static componentData() method. The componentName argument
0125  * of the KGenericFactory constructor is passed to the KComponentData object.
0126  *
0127  * The creation of the KComponentData object can be customized by inheriting
0128  * from this template class and re-implementing the virtual createComponentData
0129  * method. For example it could look like this:
0130  * \code
0131  *     KComponentData *MyFactory::createComponentData()
0132  *     {
0133  *         return new KComponentData( myAboutData );
0134  *     }
0135  * \endcode
0136  *
0137  * Example of usage of the whole template:
0138  * \code
0139  *     class MyPlugin : public KParts::Plugin
0140  *     {
0141  *         Q_ OBJECT
0142  *     public:
0143  *         MyPlugin( QObject *parent, const QStringList &args );
0144  *         ...
0145  *     };
0146  *
0147  *     K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<MyPlugin> )
0148  * \endcode
0149  *
0150  * @deprecated use KPluginFactory
0151  */
0152 template <class Product, class ParentType = QObject>
0153 class KDELIBS4SUPPORT_DEPRECATED KGenericFactory : public KGenericFactoryBase<Product>
0154 {
0155 public:
0156     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const char *componentName = nullptr)
0157         : KGenericFactoryBase<Product>(componentName)
0158     {}
0159 
0160     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const KAboutData *data)
0161         : KGenericFactoryBase<Product>(data)
0162     {}
0163 
0164 protected:
0165     virtual QObject *createObject(QObject *parent,
0166                                   const char *className, const QStringList &args)
0167     {
0168         return KDEPrivate::ConcreteFactory<Product, ParentType>
0169                ::create(nullptr, parent, className, args);
0170     }
0171 };
0172 
0173 /**
0174  * \class KGenericFactory kgenericfactory.h <KGenericFactory>
0175  *
0176  * This template provides a generic implementation of a KLibFactory ,
0177  * for use with shared library components. It implements the pure virtual
0178  * createObject method of KLibFactory and instantiates objects of the
0179  * specified classes in the given typelist template argument when the class
0180  * name argument of createObject matches a class names in the given hierarchy
0181  * of classes.
0182  *
0183  * Note that each class in the specified in the typelist template argument
0184  * needs to provide a certain constructor:
0185  * <ul>
0186  *     <li>If the class is derived from QObject then it needs to have
0187  *         a constructor like:
0188  *         <code>MyClass( QObject *parent,
0189  *                        const QStringList &args );</code>
0190  *     <li>If the class is derived from QWidget then it needs to have
0191  *         a constructor like:
0192  *         <code>MyWidget( QWidget *parent,
0193  *                         const QStringList &args);</code>
0194  *     <li>If the class is derived from KParts::Part then it needs to have
0195  *         a constructor like:
0196  *         <code>MyPart( QWidget *parentWidget,
0197  *                       QObject *parent,
0198  *                       const QStringList &args );</code>
0199  * </ul>
0200  * The args QStringList passed to the constructor is the args string list
0201  * that the caller passed to KLibFactory's create method.
0202  *
0203  * In addition upon instantiation this template provides a central
0204  * KComponentData object for your component, accessible through the
0205  * static componentData() method. The componentName argument
0206  * of the KGenericFactory constructor is passed to the KComponentData object.
0207  *
0208  * The creation of the KComponentData object can be customized by inheriting
0209  * from this template class and re-implementing the virtual createComponentData
0210  * method. For example it could look like this:
0211  * \code
0212  *     KComponentData *MyFactory::createComponentData()
0213  *     {
0214  *         return new KComponentData( myAboutData );
0215  *     }
0216  * \endcode
0217  *
0218  * Example of usage of the whole template:
0219  * \code
0220  *     class MyPlugin : public KParts::Plugin
0221  *     {
0222  *         Q_ OBJECT
0223  *     public:
0224  *         MyPlugin( QObject *parent,
0225  *                   const QStringList &args );
0226  *         ...
0227  *     };
0228  *
0229  *     class MyDialogComponent : public KDialog
0230  *     {
0231  *         Q_ OBJECT
0232  *     public:
0233  *         MyDialogComponent( QWidget *parentWidget,
0234  *                            const QStringList &args );
0235  *         ...
0236  *     };
0237  *
0238  *     typedef K_TYPELIST_2( MyPlugin, MyDialogComponent ) Products;
0239  *     K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<Products> )
0240  * \endcode
0241  */
0242 template <class Product, class ProductListTail>
0243 class KGenericFactory< KTypeList<Product, ProductListTail>, QObject >
0244     : public KGenericFactoryBase<KTypeList<Product, ProductListTail> >
0245 {
0246 public:
0247     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const char *componentName  = nullptr)
0248         : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName)
0249     {}
0250 
0251     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const KAboutData *data)
0252         : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(data)
0253     {}
0254 
0255 protected:
0256     virtual QObject *createObject(QObject *parent,
0257                                   const char *className, const QStringList &args)
0258     {
0259         return KDEPrivate::MultiFactory< KTypeList< Product, ProductListTail > >
0260                ::create(nullptr, parent, className, args);
0261     }
0262 };
0263 
0264 /**
0265  * \class KGenericFactory kgenericfactory.h <KGenericFactory>
0266  *
0267  * This template provides a generic implementation of a KLibFactory ,
0268  * for use with shared library components. It implements the pure virtual
0269  * createObject method of KLibFactory and instantiates objects of the
0270  * specified classes in the given typelist template argument when the class
0271  * name argument of createObject matches a class names in the given hierarchy
0272  * of classes.
0273  *
0274  * Note that each class in the specified in the typelist template argument
0275  * needs to provide a certain constructor:
0276  * <ul>
0277  *     <li>If the class is derived from QObject then it needs to have
0278  *         a constructor like:
0279  *         <code>MyClass( QObject *parent,
0280  *                        const QStringList &args );</code>
0281  *     <li>If the class is derived from QWidget then it needs to have
0282  *         a constructor like:
0283  *         <code>MyWidget( QWidget *parent,
0284  *                         const QStringList &args);</code>
0285  *     <li>If the class is derived from KParts::Part then it needs to have
0286  *         a constructor like:
0287  *         <code>MyPart( QWidget *parentWidget,
0288  *                       QObject *parent,
0289  *                       const QStringList &args );</code>
0290  * </ul>
0291  * The args QStringList passed to the constructor is the args string list
0292  * that the caller passed to KLibFactory's create method.
0293  *
0294  * In addition upon instantiation this template provides a central
0295  * KComponentData object for your component, accessible through the
0296  * static componentData() method. The componentName argument
0297  * of the KGenericFactory constructor is passed to the KComponentData object.
0298  *
0299  * The creation of the KComponentData object can be customized by inheriting
0300  * from this template class and re-implementing the virtual createComponentData
0301  * method. For example it could look like this:
0302  * \code
0303  *     KComponentData *MyFactory::createComponentData()
0304  *     {
0305  *         return new KComponentData( myAboutData );
0306  *     }
0307  * \endcode
0308  *
0309  * Example of usage of the whole template:
0310  * \code
0311  *     class MyPlugin : public KParts::Plugin
0312  *     {
0313  *         Q_ OBJECT
0314  *     public:
0315  *         MyPlugin( QObject *parent,
0316  *                   const QStringList &args );
0317  *         ...
0318  *     };
0319  *
0320  *     class MyDialogComponent : public KDialog
0321  *     {
0322  *         Q_ OBJECT
0323  *     public:
0324  *         MyDialogComponent( QWidget *parentWidget,
0325  *                            const QStringList &args );
0326  *         ...
0327  *     };
0328  *
0329  *     typedef K_TYPELIST_2( MyPlugin, MyDialogComponent ) Products;
0330  *     K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<Products> )
0331  * \endcode
0332  */
0333 template <class Product, class ProductListTail,
0334           class ParentType, class ParentTypeListTail>
0335 class KGenericFactory< KTypeList<Product, ProductListTail>,
0336     KTypeList<ParentType, ParentTypeListTail> >
0337     : public KGenericFactoryBase<KTypeList<Product, ProductListTail> >
0338 {
0339 public:
0340     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const char *componentName  = nullptr)
0341         : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName)
0342     {}
0343     KDELIBS4SUPPORT_DEPRECATED explicit KGenericFactory(const KAboutData *data)
0344         : KGenericFactoryBase<KTypeList<Product, ProductListTail> >(data)
0345     {}
0346 
0347 protected:
0348     virtual QObject *createObject(QObject *parent,
0349                                   const char *className, const QStringList &args)
0350     {
0351         return KDEPrivate::MultiFactory< KTypeList< Product, ProductListTail >,
0352                KTypeList< ParentType, ParentTypeListTail > >
0353                ::create(nullptr, nullptr, parent,
0354                         className, args);
0355     }
0356 };
0357 
0358 #endif
0359 #endif
0360