File indexing completed on 2025-02-16 13:02:47
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