File indexing completed on 2024-04-14 14:20:31

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
0012    GNU 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 the
0016    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 #ifndef KPARTS_GENERICFACTORY_H
0020 #define KPARTS_GENERICFACTORY_H
0021 
0022 #include <kparts/factory.h>
0023 #include <kparts/part.h>
0024 #include <kgenericfactory.h>
0025 #include <kaboutdata.h>
0026 #include <kdebug.h>
0027 
0028 namespace KParts
0029 {
0030 
0031 /**
0032  * @internal
0033  */
0034 template <class T>
0035 class GenericFactoryBase : public KParts::Factory
0036 {
0037 public:
0038     GenericFactoryBase()
0039     {
0040         if (s_self) {
0041             kWarning() << "KParts::GenericFactory instantiated more than once!";
0042         }
0043         s_self = this;
0044     }
0045     ~GenericFactoryBase() override
0046     {
0047         delete s_aboutData;
0048         delete s_componentData;
0049         s_aboutData = nullptr;
0050         s_componentData = nullptr;
0051         s_self = 0;
0052     }
0053 
0054     static const KComponentData &componentData();
0055     static K4AboutData *aboutData();
0056     KComponentData partComponentData() override
0057     {
0058         return componentData();
0059     }
0060 
0061 protected:
0062     virtual KComponentData *createComponentData()
0063     {
0064         return new KComponentData(aboutData());
0065     }
0066 
0067 private:
0068     static GenericFactoryBase<T> *s_self;
0069     static KComponentData *s_componentData;
0070     static K4AboutData *s_aboutData;
0071 };
0072 
0073 /**
0074  * A template for a KParts::Factory implementation. It implements the pure virtual
0075  * createPartObject method by instantiating the template argument when requested
0076  * through the className field. In addition it is a container for a part's KComponentData
0077  * object, by providing a static KComponentData componentData() method.
0078  *
0079  * The template argument has to inherit from KParts::Part and has to implement two methods:
0080  *  1) There needs to be a public constructor with the following signature:
0081  *         MyPart( QWidget *parentWidget, QObject *parent, const QStringList& args )
0082  *
0083  *  2) It needs to provide one static method to create a K4AboutData object per
0084  *     request, holding information about the component's name, its authors, license, etc.
0085  *     The signature of that static method has to be
0086  *         K4AboutData *createAboutData()
0087  *
0088  * The template will take care of memory management of the KComponentData and the K4AboutData object,
0089  * meaning ownership of what createAboutData returns is passed to the caller (this template) .
0090  *
0091  * For advanced use you can also inherit from the template and re-implement additionally the
0092  * virtual KComponentData createComponentData() method, for example in case you want to extend the
0093  * paths of your instance's KStandardDirs object.
0094  *
0095  * If a KParts::ReadOnlyPart is requested through this factory and the template argument
0096  * implements a KParts::ReadWritePart then setReadWrite( false ) will automatically be
0097  * called in createPartObject.
0098  *
0099  * Use the factory through the K_EXPORT_COMPONENT_FACTORY macro, like that:
0100  * \code
0101  * typedef KParts::GenericFactory&lt;YourKPart&gt; YourKPartFactory;
0102  * K_EXPORT_COMPONENT_FACTORY( yourlibrary, YourKPartFactory )
0103  * \endcode
0104  * yourlibrary is the library name that you compiled your KPart into.
0105  */
0106 template <class T>
0107 class KDELIBS4SUPPORT_DEPRECATED GenericFactory : public GenericFactoryBase<T>
0108 {
0109 public:
0110     GenericFactory() { }
0111 
0112     virtual KParts::Part *createPartObject(QWidget *parentWidget,
0113                                            QObject *parent,
0114                                            const char *className,
0115                                            const QStringList &args)
0116     {
0117         T *part = KDEPrivate::ConcreteFactory<T>::create(parentWidget,
0118                   parent,
0119                   className,
0120                   args);
0121 
0122         if (part && !qstrcmp(className, "KParts::ReadOnlyPart")) {
0123             KParts::ReadWritePart *rwp = dynamic_cast<KParts::ReadWritePart *>(part);
0124             if (rwp) {
0125                 rwp->setReadWrite(false);
0126             }
0127         }
0128         return part;
0129     }
0130 };
0131 
0132 template <class T1, class T2>
0133 class GenericFactory< KTypeList<T1, T2> > : public GenericFactoryBase<T1>
0134 {
0135 public:
0136     GenericFactory() { }
0137 
0138     virtual KParts::Part *createPartObject(QWidget *parentWidget,
0139                                            QObject *parent,
0140                                            const char *className,
0141                                            const QStringList &args)
0142     {
0143         QObject *object = KDEPrivate::MultiFactory< KTypeList<T1, T2> >::create(parentWidget,
0144                           parent,
0145                           className,
0146                           args);
0147 
0148         // (this cast is guaranteed to work...)
0149         KParts::Part *part = dynamic_cast<KParts::Part *>(object);
0150 
0151         if (part && !qstrcmp(className, "KParts::ReadOnlyPart")) {
0152             KParts::ReadWritePart *rwp = dynamic_cast<KParts::ReadWritePart *>(part);
0153             if (rwp) {
0154                 rwp->setReadWrite(false);
0155             }
0156         }
0157         return part;
0158     }
0159 };
0160 
0161 /**
0162  * @internal
0163  */
0164 template <class T>
0165 GenericFactoryBase<T> *GenericFactoryBase<T>::s_self = 0;
0166 
0167 /**
0168  * @internal
0169  */
0170 template <class T>
0171 KComponentData *GenericFactoryBase<T>::s_componentData = nullptr;
0172 
0173 /**
0174  * @internal
0175  */
0176 template <class T>
0177 K4AboutData *GenericFactoryBase<T>::s_aboutData = nullptr;
0178 
0179 /**
0180  * @internal
0181  */
0182 template <class T>
0183 const KComponentData &GenericFactoryBase<T>::componentData()
0184 {
0185     if (!s_componentData) {
0186         if (s_self) {
0187             s_componentData = s_self->createComponentData();
0188         } else {
0189             s_componentData = new KComponentData(aboutData());
0190         }
0191     }
0192     return *s_componentData;
0193 }
0194 
0195 /**
0196  * @internal
0197  */
0198 template <class T>
0199 K4AboutData *GenericFactoryBase<T>::aboutData()
0200 {
0201     if (!s_aboutData) {
0202         s_aboutData = T::createAboutData();
0203     }
0204     return s_aboutData;
0205 }
0206 
0207 }
0208 
0209 #endif
0210