fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kparts / genericfactory.h
blob08c681c5e5624676bfb56c2a2e7d1f1b4d491298
1 /* This file is part of the KDE project
2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
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.
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
12 GNU Library General Public License for more details.
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 the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
19 #ifndef KPARTS_GENERICFACTORY_H
20 #define KPARTS_GENERICFACTORY_H
22 #include <kparts/factory.h>
23 #include <kparts/part.h>
24 #include <kgenericfactory.h>
25 #include <kaboutdata.h>
26 #include <kdebug.h>
28 namespace KParts
31 /**
32 * @internal
34 template <class T>
35 class GenericFactoryBase : public KParts::Factory
37 public:
38 GenericFactoryBase()
40 if ( s_self )
41 kWarning() << "KParts::GenericFactory instantiated more than once!";
42 s_self = this;
44 virtual ~GenericFactoryBase()
46 delete s_aboutData;
47 delete s_componentData;
48 s_aboutData = 0;
49 s_componentData = 0;
50 s_self = 0;
53 static const KComponentData &componentData();
54 static KAboutData *aboutData();
55 virtual KComponentData partComponentData()
57 return componentData();
61 protected:
62 virtual KComponentData *createComponentData()
64 return new KComponentData(aboutData());
68 private:
69 static GenericFactoryBase<T> *s_self;
70 static KComponentData *s_componentData;
71 static KAboutData *s_aboutData;
74 /**
75 * A template for a KParts::Factory implementation. It implements the pure virtual
76 * createPartObject method by instantiating the template argument when requested
77 * through the className field. In addition it is a container for a part's KComponentData
78 * object, by providing a static KComponentData componentData() method.
80 * The template argument has to inherit from KParts::Part and has to implement two methods:
81 * 1) There needs to be a public constructor with the following signature:
82 * MyPart( QWidget *parentWidget, QObject *parent, const QStringList& args )
84 * 2) It needs to provide one static method to create a KAboutData object per
85 * request, holding information about the component's name, its authors, license, etc.
86 * The signature of that static method has to be
87 * KAboutData *createAboutData()
89 * The template will take care of memory management of the KComponentData and the KAboutData object,
90 * meaning ownership of what createAboutData returns is passed to the caller (this template) .
92 * For advanced use you can also inherit from the template and re-implement additionally the
93 * virtual KComponentData createComponentData() method, for example in case you want to extend the
94 * paths of your instance's KStandardDirs object.
96 * If a KParts::ReadOnlyPart is requested through this factory and the template argument
97 * implements a KParts::ReadWritePart then setReadWrite( false ) will automatically be
98 * called in createPartObject.
100 * Use the factory through the K_EXPORT_COMPONENT_FACTORY macro, like that:
101 * \code
102 * typedef KParts::GenericFactory&lt;YourKPart&gt; YourKPartFactory;
103 * K_EXPORT_COMPONENT_FACTORY( yourlibrary, YourKPartFactory )
104 * \endcode
105 * yourlibrary is the library name that you compiled your KPart into.
107 template <class T>
108 class GenericFactory : public GenericFactoryBase<T>
110 public:
111 GenericFactory() { }
113 virtual KParts::Part *createPartObject( QWidget *parentWidget,
114 QObject *parent,
115 const char *className,
116 const QStringList &args )
118 T *part = KDEPrivate::ConcreteFactory<T>::create( parentWidget,
119 parent,
120 className,
121 args );
123 if ( part && !qstrcmp( className, "KParts::ReadOnlyPart" ) )
125 KParts::ReadWritePart *rwp = dynamic_cast<KParts::ReadWritePart *>( part );
126 if ( rwp )
127 rwp->setReadWrite( false );
129 return part;
133 template <class T1, class T2>
134 class GenericFactory< KTypeList<T1, T2> > : public GenericFactoryBase<T1>
136 public:
137 GenericFactory() { }
139 virtual KParts::Part *createPartObject( QWidget *parentWidget,
140 QObject *parent,
141 const char *className,
142 const QStringList &args )
144 QObject *object = KDEPrivate::MultiFactory< KTypeList<T1, T2> >::create( parentWidget,
145 parent,
146 className,
147 args );
149 // (this cast is guaranteed to work...)
150 KParts::Part *part = dynamic_cast<KParts::Part *>( object );
152 if ( part && !qstrcmp( className, "KParts::ReadOnlyPart" ) )
154 KParts::ReadWritePart *rwp = dynamic_cast<KParts::ReadWritePart *>( part );
155 if ( rwp )
156 rwp->setReadWrite( false );
158 return part;
163 * @internal
165 template <class T>
166 GenericFactoryBase<T> *GenericFactoryBase<T>::s_self = 0;
169 * @internal
171 template <class T>
172 KComponentData *GenericFactoryBase<T>::s_componentData = 0;
175 * @internal
177 template <class T>
178 KAboutData *GenericFactoryBase<T>::s_aboutData = 0;
181 * @internal
183 template <class T>
184 const KComponentData &GenericFactoryBase<T>::componentData()
186 if ( !s_componentData )
188 if ( s_self )
189 s_componentData = s_self->createComponentData();
190 else
191 s_componentData = new KComponentData(aboutData());
193 return *s_componentData;
197 * @internal
199 template <class T>
200 KAboutData *GenericFactoryBase<T>::aboutData()
202 if ( !s_aboutData )
203 s_aboutData = T::createAboutData();
204 return s_aboutData;
209 #endif
212 * vim: et sw=4