[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: KPluginFactory/-Loader as KLibFactory replacement and KDE enhanced
From: Matthias Kretz <kretz () kde ! org>
Date: 2007-08-24 8:19:27
Message-ID: 200708241019.32498.kretz () kde ! org
[Download RAW message or body]
[Attachment #2 (multipart/mixed)]
Hi,
Bernhard, probably better known as PutHuhn, has been continuing the work I
started on KPluginFactory the last days. He also added KPluginLoader, which
is a subclass of QPluginLoader and therefore does the Qt library version
check when loading a plugin. In addition KPluginLoader does the same kind of
check for the kdelibs version. That way plugins compiled against a newer
version of Qt or kdelibs will refuse to load.
Most of the work on completing KPluginFactory was to make it compatible enough
to be a drop in replacement for KLibFactory, but I'm confident that it'll
work out quite well with what we got now.
Attached you'll find his patch. I'll comment in a separate mail.
--
________________________________________________________
Matthias Kretz (Germany) <><
http://Vir.homelinux.org/
MatthiasKretz@gmx.net, kretz@kde.org,
Matthias.Kretz@urz.uni-heidelberg.de
["kpluginfactoryloader.patch" (text/x-diff)]
Index: kernel/kcomponentdata.cpp
===================================================================
--- kernel/kcomponentdata.cpp (revision 704027)
+++ kernel/kcomponentdata.cpp (working copy)
@@ -78,7 +78,7 @@
}
}
-KComponentData::KComponentData(const KAboutData *aboutData)
+KComponentData::KComponentData(const KAboutData *aboutData, \
MainComponentRegistration registerAsMain) : d(new KComponentDataPrivate)
{
d->name = aboutData->appName();
@@ -88,7 +88,9 @@
Q_ASSERT(!d->name.isEmpty());
- KGlobal::newComponentData(*this);
+ if (registerAsMain == RegisterAsMainComponent) {
+ KGlobal::newComponentData(*this);
+ }
}
void KComponentData::_checkConfig() // called by KSharedConfigPtr
Index: kernel/kcomponentdata.h
===================================================================
--- kernel/kcomponentdata.h (revision 704027)
+++ kernel/kcomponentdata.h (working copy)
@@ -113,7 +113,7 @@
*
* @see KAboutData
*/
- explicit KComponentData(const KAboutData *aboutData);
+ explicit KComponentData(const KAboutData *aboutData, MainComponentRegistration = \
RegisterAsMainComponent);
/**
* Destructor.
Index: util/kgenericfactory.h
===================================================================
--- util/kgenericfactory.h (revision 704027)
+++ util/kgenericfactory.h (working copy)
@@ -19,14 +19,15 @@
#ifndef kgenericfactory_h
#define kgenericfactory_h
-#include <klibloader.h>
+#include <kpluginfactory.h>
+#include <kpluginloader.h>
#include <ktypelist.h>
#include <kcomponentdata.h>
#include <kgenericfactory.tcc>
#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
-
+#if 0
/* @internal */
template <class T>
class KGenericFactoryBase
@@ -75,7 +76,7 @@
virtual void setupTranslations( void )
{
if (componentData().isValid()) {
- KGlobal::locale()->insertCatalog(s_componentData->catalogName());
+ KGlobal::locale() s_componentData->catalogName());
}
}
@@ -118,7 +119,7 @@
}
return *s_componentData;
}
-
+#endif
/**
* This template provides a generic implementation of a KLibFactory ,
* for use with shared library components. It implements the pure virtual
@@ -178,15 +179,15 @@
* \endcode
*/
template <class Product, class ParentType = QObject>
-class KGenericFactory : public KLibFactory, public KGenericFactoryBase<Product>
+class KDE_DEPRECATED KGenericFactory : public KLibFactory
{
public:
explicit KGenericFactory( const char *componentName = 0, const char *catalogName \
= 0 )
- : KGenericFactoryBase<Product>( componentName, catalogName )
+ : KLibFactory(componentName, catalogName)
{}
explicit KGenericFactory( const KAboutData *data )
- : KGenericFactoryBase<Product>( data )
+ : KLibFactory(data)
{}
@@ -194,12 +195,11 @@
virtual QObject *createObject( QObject *parent,
const char *className, const QStringList &args )
{
- KGenericFactoryBase<Product>::initializeMessageCatalog();
return KDEPrivate::ConcreteFactory<Product, ParentType>
::create( 0, parent, className, args );
}
};
-
+#if 0
/**
* This template provides a generic implementation of a KLibFactory ,
* for use with shared library components. It implements the pure virtual
@@ -274,11 +274,11 @@
{
public:
explicit KGenericFactory( const char *componentName = 0, const char \
*catalogName = 0 )
- : KGenericFactoryBase< KTypeList<Product, ProductListTail> >( componentName, \
catalogName ) + : KLibFactory(componentName, catalogName), \
KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName, catalogName) \
{}
explicit KGenericFactory( const KAboutData *data )
- : KGenericFactoryBase< KTypeList<Product, ProductListTail> >( data )
+ : KLibFactory(data), KGenericFactoryBase<KTypeList<Product, ProductListTail> \
>(data) {}
@@ -368,10 +368,10 @@
{
public:
explicit KGenericFactory( const char *componentName = 0, const char \
*catalogName = 0 )
- : KGenericFactoryBase< KTypeList<Product, ProductListTail> >( componentName, \
catalogName ) + : KLibFactory(componentName, catalogName), \
KGenericFactoryBase<KTypeList<Product, ProductListTail> >(componentName, catalogName) \
{} explicit KGenericFactory( const KAboutData *data )
- : KGenericFactoryBase< KTypeList<Product, ProductListTail> >( data )
+ : KLibFactory(data), KGenericFactoryBase<KTypeList<Product, ProductListTail> \
>(data) {}
@@ -387,10 +387,11 @@
}
};
-
+#endif
/*
* vim: et sw=4
*/
#endif
+
Index: util/klibloader.cpp
===================================================================
--- util/klibloader.cpp (revision 704027)
+++ util/klibloader.cpp (working copy)
@@ -95,14 +95,22 @@
// -------------------------------------------------------------------------
+#if 0
KLibFactory::KLibFactory( QObject* _parent )
- : QObject( _parent ), d(0)
+ : QObject( _parent ), d_ptr(0)
{
}
+KLibFactory::KLibFactory(KLibFactoryPrivate &dd, QObject *parent)
+ : QObject(parent), d_ptr(&dd)
+{
+ d_ptr->q_ptr = this;
+}
+
KLibFactory::~KLibFactory()
{
// kDebug(150) << "Deleting KLibFactory " << this;
+ delete d_ptr;
}
QObject* KLibFactory::create( QObject* _parent, const char* classname, const \
QStringList &args ) @@ -112,8 +120,8 @@
emit objectCreated( obj );
return obj;
}
+#endif
-
// -----------------------------------------------
class KLibraryPrivate
@@ -123,13 +131,13 @@
KLibrary *q;
QString libname;
QString filename;
- QHash<QByteArray, KLibFactory*> factories;
+ QHash<QByteArray, KPluginFactory*> factories;
QLibrary* handle;
QList<QObject*> objs;
QTimer* timer;
- KLibFactory *kde3Factory(const QByteArray &factoryname);
- KLibFactory *kde4Factory();
+ KPluginFactory *kde3Factory(const QByteArray &factoryname);
+ KPluginFactory *kde4Factory();
};
KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary * \
handle ) @@ -177,7 +185,7 @@
return d->filename;
}
-KLibFactory* KLibraryPrivate::kde3Factory(const QByteArray &factoryname)
+KPluginFactory* KLibraryPrivate::kde3Factory(const QByteArray &factoryname)
{
QByteArray symname = "init_";
if(!factoryname.isEmpty()) {
@@ -198,12 +206,12 @@
return 0;
}
- typedef KLibFactory* (*t_func)();
+ typedef KPluginFactory* (*t_func)();
// Cast the void* to non-pointer type first - it's not legal to
// cast a pointer-to-object directly to a pointer-to-function.
ptrdiff_t tmp = reinterpret_cast<ptrdiff_t>(sym);
t_func func = reinterpret_cast<t_func>(tmp);
- KLibFactory* factory = func();
+ KPluginFactory* factory = func();
if( !factory )
{
@@ -216,7 +224,7 @@
return factory;
}
-KLibFactory *KLibraryPrivate::kde4Factory()
+KPluginFactory *KLibraryPrivate::kde4Factory()
{
const QByteArray symname("qt_plugin_instance");
if ( factories.contains( symname ) )
@@ -236,7 +244,7 @@
ptrdiff_t tmp = reinterpret_cast<ptrdiff_t>(sym);
t_func func = reinterpret_cast<t_func>(tmp);
QObject* instance = func();
- KLibFactory *factory = qobject_cast<KLibFactory *>(instance);
+ KPluginFactory *factory = qobject_cast<KPluginFactory *>(instance);
if( !factory )
{
@@ -250,9 +258,9 @@
}
-KLibFactory* KLibrary::factory(const char* factoryname)
+KPluginFactory* KLibrary::factory(const char* factoryname)
{
- KLibFactory *factory = d->kde4Factory();
+ KPluginFactory *factory = d->kde4Factory();
if (!factory)
factory = d->kde3Factory(factoryname);
@@ -552,7 +560,7 @@
d->close_pending( wrap );
}
-KLibFactory* KLibLoader::factory( const QString &_name, QLibrary::LoadHints hint )
+KPluginFactory* KLibLoader::factory( const QString &_name, QLibrary::LoadHints hint \
) {
KLibrary* lib = library( _name, hint );
if ( !lib )
Index: util/klibloader.h
===================================================================
--- util/klibloader.h (revision 704027)
+++ util/klibloader.h (working copy)
@@ -24,17 +24,14 @@
#include <QtCore/QStringList>
#include <QtCore/QHash>
#include <QtCore/QLibrary>
-#include <QtCore/qplugin.h>
+#include <QtCore/QtPlugin>
+#include "kpluginfactory.h"
+
class QString;
-class KLibFactory;
-class KLibFactoryPrivate;
class KLibraryPrivate;
class KLibLoaderPrivate;
-# define K_EXPORT_COMPONENT_FACTORY( libname, factory ) \
- extern "C" { KDE_EXPORT KLibFactory *init_##libname() { return new factory; } }
-
/**
* @short Represents a dynamically loaded library.
*
@@ -76,7 +73,7 @@
* K_EXPORT_COMPONENT_FACTORY.
* @return The factory of the library if there is any, otherwise 0
*/
- KLibFactory* factory( const char* factoryname = 0 );
+ KPluginFactory* factory( const char* factoryname = 0 );
/**
* Looks up a symbol from the library. This is a very low level
@@ -118,7 +115,7 @@
};
-
+#if 0
/**
* If you develop a library that is to be loaded dynamically at runtime, then
* you should return a pointer to your factory. The K_EXPORT_COMPONENT_FACTORY
@@ -160,6 +157,7 @@
class KDECORE_EXPORT KLibFactory : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(KLibFactory)
public:
/**
* Create a new factory.
@@ -248,10 +246,10 @@
const char* className = "QObject",
const QStringList &args = QStringList() ) = 0;
-
-private:
- KLibFactoryPrivate *const d;
+ KLibFactory(KLibFactoryPrivate &dd, QObject *parent);
+ KLibFactoryPrivate *const d_ptr;
};
+#endif
/**
* The KLibLoader allows you to load libraries dynamically at runtime.
@@ -287,11 +285,11 @@
* You can, however, give a library name ending in ".so"
* (or whatever is used on your platform), and the library
* will be loaded without resolving dependencies. Use with \
caution.
- * @return the KLibFactory, or 0 if the library does not exist or it does
+ * @return the KPluginFactory, or 0 if the library does not exist or it does
* not have a factory
* @see library
*/
- KLibFactory* factory( const QString &libname, QLibrary::LoadHints loadHint = 0);
+ KPluginFactory* factory( const QString &libname, QLibrary::LoadHints loadHint = \
0);
/**
* Loads and initializes a library. Loading a library multiple times is
@@ -399,16 +397,57 @@
* @param libraryName The library to open
* @param parent The parent object (see QObject constructor)
* @param args A list of string arguments, passed to the factory and possibly
- * to the component (see KLibFactory)
+ * to the component (see KPluginFactory)
* @param error
* @return A pointer to the newly created object or a null pointer if the
* factory was unable to create an object of the given type.
*/
template <typename T>
+ static T *createInstance(const QString &keyword, const QString &libname, QObject \
*parent = 0, + const QVariantList &args = \
QVariantList(), + int *error = 0 )
+ {
+ KLibrary *library = KLibLoader::self()->library( libname );
+ if ( !library )
+ {
+ if ( error )
+ *error = ErrNoLibrary;
+ return 0;
+ }
+ KPluginFactory *factory = library->factory();
+ if ( !factory )
+ {
+ library->unload();
+ if ( error )
+ *error = ErrNoFactory;
+ return 0;
+ }
+ QObject *object = factory->create<T>(keyword, parent, args);
+ T *res = qobject_cast<T *>( object );
+ if ( !res )
+ {
+ delete object;
+ library->unload();
+ if ( error )
+ *error = ErrNoComponent;
+ }
+ return res;
+ }
+
+ template <typename T>
static T *createInstance( const QString &libname, QObject *parent = 0,
- const QStringList &args = QStringList(),
+ const QVariantList &args = QVariantList(),
int *error = 0 )
{
+ return createInstance<T>(QString(), libname, parent, args, error);
+ }
+
+ template <typename T>
+ KDE_DEPRECATED
+ static T *createInstance( const QString &libname, QObject *parent,
+ const QStringList &args,
+ int *error = 0 )
+ {
KLibrary *library = KLibLoader::self()->library( libname );
if ( !library )
{
@@ -416,7 +455,7 @@
*error = ErrNoLibrary;
return 0;
}
- KLibFactory *factory = library->factory();
+ KPluginFactory *factory = library->factory();
if ( !factory )
{
library->unload();
@@ -424,7 +463,7 @@
*error = ErrNoFactory;
return 0;
}
- QObject *object = factory->create( parent, T::staticMetaObject.className(), \
args ); + QObject *object = factory->create<T>(parent, QVariantList() << \
args); T *res = qobject_cast<T *>( object );
if ( !res )
{
Index: util/klibloader_p.h
===================================================================
--- util/klibloader_p.h (revision 0)
+++ util/klibloader_p.h (revision 0)
@@ -0,0 +1,32 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KDECORE_KLIBLOADER_P_H
+#define KDECORE_KLIBLOADER_P_H
+
+#include "klibloader.h"
+
+class KLibFactoryPrivate
+{
+ Q_DECLARE_PUBLIC(KLibFactory)
+ protected:
+ KLibFactory *q_ptr;
+};
+
+#endif // KDECORE_KLIBLOADER_P_H
Index: util/kpluginfactory.cpp
===================================================================
--- util/kpluginfactory.cpp (revision 0)
+++ util/kpluginfactory.cpp (revision 0)
@@ -0,0 +1,174 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
+ Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "kpluginfactory.h"
+#include "kpluginfactory_p.h"
+
+#include <kaboutdata.h>
+
+
+KPluginFactory::KPluginFactory(const char *componentName, const char *catalogName, \
QObject *parent) + : QObject(parent), d_ptr(new KPluginFactoryPrivate)
+{
+ Q_D(KPluginFactory);
+ d->componentData = *createComponentData();
+ if (!d->componentData.isValid()) {
+ d->aboutData = new KAboutData(componentName, catalogName, \
KLocalizedString(), "", KLocalizedString()); + d->componentData = \
createComponentData(d->aboutData); + }
+}
+
+KPluginFactory::KPluginFactory(const KAboutData *aboutData, QObject *parent)
+ : QObject(parent), d_ptr(new KPluginFactoryPrivate)
+{
+ Q_D(KPluginFactory);
+ d->componentData = *createComponentData();
+ d->aboutData = aboutData;
+ if (!d->componentData.isValid()) {
+ d->componentData = createComponentData(d->aboutData);
+ }
+}
+
+KPluginFactory::KPluginFactory(QObject *parent)
+ : QObject(parent), d_ptr(new KPluginFactoryPrivate())
+{
+}
+
+
+KPluginFactory::KPluginFactory(KPluginFactoryPrivate &d, QObject *parent)
+ : QObject(parent), d_ptr(&d)
+{
+}
+
+KPluginFactory::~KPluginFactory()
+{
+ Q_D(KPluginFactory);
+
+ if (d->catalogInitialized && d->componentData.isValid()) {
+ KGlobal::locale()->removeCatalog(d->componentData.catalogName());
+ }
+
+ delete d_ptr;
+}
+
+KComponentData KPluginFactory::componentData() const
+{
+ Q_D(const KPluginFactory);
+ return d->componentData;
+}
+
+void KPluginFactory::registerPlugin(const char *iface, CreateInstanceFunction \
instanceFunction, const QString &keyword) +{
+ Q_D(KPluginFactory);
+ QString ident(iface);
+ ident.append(keyword);
+ Q_ASSERT(!d->createInstanceHash.contains(ident));
+ d->createInstanceHash.insert(ident, instanceFunction);
+}
+
+QObject *KPluginFactory::createObject(QObject *parent, const char *className, const \
QStringList &args) +{
+ return 0;
+}
+
+QObject *KPluginFactory::create(const char *iface, QObject *parent, const \
QVariantList &args, const QString &keyword) +{
+ Q_D(KPluginFactory);
+
+ QObject *obj = 0;
+
+ initializeMessageCatalog();
+
+ if (keyword.isEmpty() && (obj = createObject(parent, iface, \
variantListToStringList(args)))) { + objectCreated(obj);
+ return obj;
+ }
+
+ QString ident(iface);
+ ident.append(keyword);
+
+ QHash<QString, KPluginFactory::CreateInstanceFunction>::ConstIterator \
factoryMethode; + factoryMethode = d->createInstanceHash.find(ident);
+
+ if (factoryMethode == d->createInstanceHash.end())
+ return 0;
+
+ obj = (*factoryMethode)(parent, args);
+
+ if (obj) {
+ emit objectCreated(obj);
+ }
+ return obj;
+}
+
+void KPluginFactory::initializeMessageCatalog()
+{
+ Q_D(KPluginFactory);
+
+ if (!d->catalogInitialized) {
+ d->catalogInitialized = true;
+ setupTranslations();
+ }
+}
+
+void KPluginFactory::setupTranslations()
+{
+ Q_D(KPluginFactory);
+
+ if (!d->componentData.isValid())
+ return;
+
+ KGlobal::locale()->insertCatalog(d->componentData.catalogName());
+}
+
+KComponentData KPluginFactory::createComponentData(const KAboutData *aboutData)
+{
+ return KComponentData(aboutData, KComponentData::SkipMainComponentRegistration);
+}
+
+QStringList KPluginFactory::variantListToStringList(const QVariantList &list)
+{
+ QVariantList copy(list);
+ QStringList stringlist;
+
+ while (!copy.isEmpty())
+ stringlist << copy.takeFirst().toString();
+
+ return stringlist;
+}
+
+QVariantList KPluginFactory::stringListToVariantList(const QStringList &list)
+{
+ QStringList copy(list);
+ QVariantList variantlist;
+
+ while (!copy.isEmpty())
+ variantlist << QVariant(copy.takeFirst());
+
+ return variantlist;
+}
+
+KComponentData *KPluginFactory::createComponentData()
+{
+ return new KComponentData();
+}
+
+#include "kpluginfactory.moc"
Index: util/kpluginfactory.h
===================================================================
--- util/kpluginfactory.h (revision 0)
+++ util/kpluginfactory.h (revision 0)
@@ -0,0 +1,170 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
+ Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KDECORE_KPLUGINFACTORY_H
+#define KDECORE_KPLUGINFACTORY_H
+
+#include "kdecore_export.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+#include <kcomponentdata.h>
+
+class KPluginFactoryPrivate;
+
+#define K_REGISTER_PLUGIN_WITH_KEYWORD(impl, iface, keyword) \
+registerPlugin(iface::staticMetaObject.className(), &createInstance<impl>, keyword);
+
+#define K_REGISTER_PLUGIN(impl, iface) K_REGISTER_PLUGIN_WITH_KEYWORD(impl, iface, \
QString()) +
+#define K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \
+class name : public baseFactory \
+{ \
+ public: \
+ name(const char *, const char * = 0, QObject * = 0); \
+ name(const KAboutData *, QObject * = 0); \
+ static KComponentData componentData(); \
+ private: \
+ static KPluginFactory *s_instance; \
+};
+
+#define K_PLUGIN_FACTORY_DECLARATION(name) \
K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, KPluginFactory) +
+#define K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, \
pluginRegistrations) \ +KPluginFactory *name::s_instance = 0; \
+name::name(const char *componentName, const char *catalogName, QObject *parent) \
+ : baseFactory(componentName, catalogName, parent) \
+{ \
+ s_instance = this; \
+ pluginRegistrations \
+} \
+name::name(const KAboutData *aboutData, QObject *parent) \
+ : baseFactory(aboutData, parent) \
+{ \
+ pluginRegistrations \
+} \
+KComponentData name::componentData() \
+{ \
+ Q_ASSERT(s_instance); \
+ return s_instance->componentData(); \
+}
+
+#define K_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) \
K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, KPluginFactory, \
pluginRegistrations) +
+#define K_PLUGIN_FACTORY_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \
+ K_PLUGIN_FACTORY_DECLARATION(name, baseFactory) \
+ K_PLUGIN_FACTORY_DEFINITION(name, baseFactory, pluginRegistrations)
+
+#define K_PLUGIN_FACTORY(name, pluginRegistrations) \
K_PLUGIN_FACTORY_WITH_BASEFACTORY(name, KPluginFactory, pluginRegistrations) +
+class KDECORE_EXPORT KPluginFactory : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(KPluginFactory)
+public:
+ explicit KPluginFactory(const char *componentName, const char *catalogName = 0, \
QObject *parent = 0); + explicit KPluginFactory(const KAboutData *aboutData, \
QObject *parent = 0); + explicit KDE_CONSTRUCTOR_DEPRECATED KPluginFactory(QObject \
*parent); + virtual ~KPluginFactory();
+
+ KComponentData componentData() const;
+
+ template<typename T>
+ T *create(QObject *parent = 0, const QVariantList &args = QVariantList());
+
+ template<typename T>
+ T *create(const QString &keyword, QObject *parent, const QVariantList &args = \
QVariantList()); +
+ template<typename T>
+ KDE_DEPRECATED
+ T *create(QObject *parent, const QStringList &args)
+ {
+ return create<T>(parent, stringListToVariantList(args));
+ }
+
+ KDE_DEPRECATED QObject *create(QObject *parent = 0, const char *classname = \
"QObject", const QStringList &args = QStringList()) + {
+ return create(classname, parent, stringListToVariantList(args), \
QString()); + }
+
+Q_SIGNALS:
+ void objectCreated(QObject *object);
+
+protected:
+ typedef QObject *(*CreateInstanceFunction)(QObject *,const QVariantList &);
+
+ explicit KPluginFactory(KPluginFactoryPrivate &dd, QObject *parent = 0);
+
+ template<class impl>
+ static QObject *createInstance(QObject *parent, const QVariantList &args)
+ {
+ return new impl(parent, args);
+ }
+
+ void registerPlugin(const char *iface, CreateInstanceFunction instanceFunction, \
const QString &keyword); +
+ virtual KComponentData createComponentData(const KAboutData *aboutData);
+
+ virtual KDE_DEPRECATED KComponentData *createComponentData();
+
+ QVariantList stringListToVariantList(const QStringList &list);
+
+ QStringList variantListToStringList(const QVariantList &list);
+
+ virtual void setupTranslations();
+
+ void initializeMessageCatalog();
+
+ KPluginFactoryPrivate *const d_ptr;
+
+ virtual KDE_DEPRECATED QObject *createObject(QObject *parent, const char \
*className, const QStringList &args); +
+private:
+ QObject *create(const char *iface, QObject *parent, const QVariantList &args, \
const QString &keyword); +};
+
+KDE_DEPRECATED typedef KPluginFactory KLibFactory;
+
+template<typename T>
+T *KPluginFactory::create(QObject *parent, const QVariantList &args)
+{
+ QObject *o = create(T::staticMetaObject.className(), parent, args, QString());
+ T *t = qobject_cast<T *>(o);
+ if (!t) {
+ delete o;
+ }
+ return t;
+}
+
+template<typename T>
+T *KPluginFactory::create(const QString &keyword, QObject *parent, const \
QVariantList &args) +{
+ QObject *o = create(T::staticMetaObject.className(), parent, args, keyword);
+ T *t = qobject_cast<T *>(o);
+ if (!t) {
+ delete o;
+ }
+ return t;
+}
+
+
+#endif // KDECORE_KPLUGINFACTORY_H
Index: util/kpluginfactory_p.h
===================================================================
--- util/kpluginfactory_p.h (revision 0)
+++ util/kpluginfactory_p.h (revision 0)
@@ -0,0 +1,47 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KDECORE_KPLUGINFACTORY_P_H
+#define KDECORE_KPLUGINFACTORY_P_H
+
+#include "kpluginfactory.h"
+
+#include <QtCore/QHash>
+
+#include <kaboutdata.h>
+
+class KAboutData;
+
+class KPluginFactoryPrivate
+{
+public:
+ KPluginFactoryPrivate() : catalogInitialized(false), aboutData(0) {}
+ ~KPluginFactoryPrivate()
+ {
+ delete aboutData;
+ }
+
+ QHash<QString, KPluginFactory::CreateInstanceFunction> createInstanceHash;
+ KComponentData componentData;
+ bool catalogInitialized;
+ const KAboutData *aboutData;
+};
+
+#endif // KDECORE_KPLUGINFACTORY_P_H
Index: util/kpluginloader.cpp
===================================================================
--- util/kpluginloader.cpp (revision 0)
+++ util/kpluginloader.cpp (revision 0)
@@ -0,0 +1,173 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kpluginloader.h"
+
+#include <kcomponentdata.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include "kpluginfactory.h"
+#include <kservice.h>
+
+#include <QtCore/QLibrary>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+
+
+class KPluginLoader::Private
+{
+public:
+ Private(const QString &libname)
+ : name(libname), pluginVersion(-1), verificationData(0)
+ {}
+
+ const QString name;
+ quint32 pluginVersion;
+ KDEPluginVerificationData *verificationData;
+ QString errorString;
+};
+
+static inline QString makeLibName( const QString &libname )
+{
+#ifdef Q_OS_WIN
+ if (!libname.endsWith(".dll"))
+ return libname + ".dll";
+ return libname;
+#else
+ int pos = libname.lastIndexOf('/');
+ if (pos < 0)
+ pos = 0;
+ if (libname.indexOf('.', pos) < 0) {
+ const char* const extList[] = { ".so", ".dylib", ".bundle", ".sl" };
+ for (uint i = 0; i < sizeof(extList) / sizeof(*extList); ++i) {
+ if (QLibrary::isLibrary(libname + extList[i]))
+ return libname + extList[i];
+ }
+ }
+ return libname;
+#endif
+}
+
+static inline QString findLibraryInternal(const QString &name, const KComponentData \
&cData) +{
+ QString libname = makeLibName(name);
+
+ if (QFileInfo(name).fileName().startsWith("lib"))
+ kDebug(150) << "plugins shouldn't have a 'lib' suffix:" << libname;
+
+ QString libfile;
+ if (QDir::isRelativePath(libname)) {
+ libfile = cData.dirs()->findResource("module", libname);
+ if ( libfile.isEmpty() )
+ {
+ libfile = cData.dirs()->findResource("lib", libname);
+ if (!libfile.isEmpty())
+ kDebug(150) << "library" << libname << "not found under 'module' but \
under 'lib'"; + }
+ }
+ else {
+ libfile = libname;
+ }
+ return libfile;
+}
+
+KPluginLoader::KPluginLoader(const QString &plugin, const KComponentData \
&componentdata, QObject *parent) + : QPluginLoader(findLibraryInternal(plugin, \
componentdata), parent), d(new Private(plugin)) +{
+ load();
+}
+
+KPluginLoader::KPluginLoader(const KService &service, const KComponentData \
&componentdata, QObject *parent) +: \
QPluginLoader(findLibraryInternal(service.library(), componentdata), parent), d(new \
Private(service.library())) +{
+ Q_ASSERT(service.isValid());
+
+ if (service.isApplication()) {
+ d->errorString = i18n("The service provides no library, the Library key is \
missing in the .desktop file"); + return;
+ }
+ load();
+}
+
+KPluginFactory *KPluginLoader::factory()
+{
+ if (!isLoaded())
+ return 0;
+
+ QObject *obj = instance();
+
+ if (!obj)
+ return 0;
+
+ KPluginFactory *factory = qobject_cast<KPluginFactory *>(obj);
+
+ if (factory == 0) {
+ delete obj;
+ d->errorString = i18n("The library %1 does not offer a KDE 4 compatible \
factory." , d->name); + }
+
+ return factory;
+}
+
+bool KPluginLoader::load()
+{
+ if (!QPluginLoader::load())
+ return false;
+
+ QLibrary lib(fileName());
+ lib.load();
+ Q_ASSERT(lib.isLoaded());
+
+ d->verificationData = (KDEPluginVerificationData *) \
lib.resolve("kde_plugin_verification_data"); + if (d->verificationData) {
+ if ((d->verificationData->KDEVersion > KDE_VERSION) || (KDE_VERSION_MAJOR << \
16 != (d->verificationData->KDEVersion & 0xFF0000))) { + d->errorString = \
i18n("The plugin '%1' uses incompatible KDE library. (%2)", d->name, \
d->verificationData->KDEVersionString); + lib.unload();
+ unload();
+ return false;
+ }
+ }
+ else {
+ kDebug(150) << "The plugin" << d->name << "doesn't contain a \
kde_plugin_verification_data structure"; + }
+
+ quint32 *version = (quint32 *) lib.resolve("kde_plugin_version");
+ if (version)
+ d->pluginVersion = *version;
+ else
+ d->pluginVersion = -1;
+
+ lib.unload();
+
+ return true;
+}
+
+QString KPluginLoader::errorString() const
+{
+ if (!d->errorString.isEmpty())
+ return d->errorString;
+
+ return QPluginLoader::errorString();
+}
+
+quint32 KPluginLoader::pluginVersion() const
+{
+ return d->pluginVersion;
+}
+
+#include "kpluginloader.moc"
\ No newline at end of file
Index: util/kpluginloader.h
===================================================================
--- util/kpluginloader.h (revision 0)
+++ util/kpluginloader.h (revision 0)
@@ -0,0 +1,86 @@
+/* This file is part of the KDE project
+ Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KDECORE_KPLUGINLOADER_H
+#define KDECORE_KPLUGINLOADER_H
+
+#include <kglobal.h>
+#include <kdeversion.h>
+
+#include <QtCore/QPluginLoader>
+#include <QtCore/qplugin.h>
+
+struct KDEPluginVerificationData
+{
+ quint8 dataVersion;
+ quint32 KDEVersion;
+ const char *KDEVersionString;
+};
+
+#define K_PLUGIN_VERIFICATION_DATA \
+extern "C" KDE_EXPORT KDEPluginVerificationData kde_plugin_verification_data = \
+{ 1, KDE_VERSION, KDE_VERSION_STRING };
+
+#define K_EXPORT_PLUGIN_VERSION(version) \
+extern "C" KDE_EXPORT quint32 kde_plugin_version = version;
+
+#define K_EXPORT_PLUGIN2(library, factory) \
+Q_EXPORT_PLUGIN2(library, factory) \
+K_PLUGIN_VERIFICATION_DATA
+
+#define K_EXPORT_PLUGIN(factory) K_EXPORT_PLUGIN2(factory, factory)
+
+#define K_EXPORT_COMPONENT_FACTORY(library, factory) K_EXPORT_PLUGIN2(library, \
factory) +
+
+class KComponentData;
+class KPluginFactory;
+class KService;
+
+class KDECORE_EXPORT KPluginLoader : public QPluginLoader
+{
+ Q_OBJECT
+ Q_PROPERTY(QString fileName READ fileName)
+ Q_PROPERTY(QString pluginName READ fileName)
+public:
+ explicit KPluginLoader(const QString &plugin, const KComponentData \
&componentdata = KGlobal::mainComponent(), QObject *parent = 0); + explicit \
KPluginLoader(const KService &service, const KComponentData &componentdata = \
KGlobal::mainComponent(), QObject *parent = 0); + ~KPluginLoader();
+
+ KPluginFactory *factory();
+
+ QString pluginName() const;
+
+ bool isLoaded() const;
+
+ bool load();
+
+ quint32 pluginVersion() const;
+
+ QString errorString() const;
+
+private:
+ Q_DISABLE_COPY(KPluginLoader)
+
+ using QPluginLoader::setFileName;
+
+ class Private;
+ Private *const d;
+};
+
+
+#endif
[Attachment #6 (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic