KDECore
kpluginfactory.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kpluginfactory.h"
00023 #include "kpluginfactory_p.h"
00024 #include <kdebug.h>
00025 #include <kglobal.h>
00026
00027 #include <QtCore/QObjectCleanupHandler>
00028
00029 K_GLOBAL_STATIC(QObjectCleanupHandler, factorycleanup)
00030
00031 KPluginFactory::KPluginFactory(const char *componentName, const char *catalogName, QObject *parent)
00032 : QObject(parent), d_ptr(new KPluginFactoryPrivate)
00033 {
00034 Q_D(KPluginFactory);
00035 d->q_ptr = this;
00036
00037 if (componentName)
00038 d->componentData = KComponentData(componentName, catalogName);
00039
00040 factorycleanup->add(this);
00041 }
00042
00043 KPluginFactory::KPluginFactory(const KAboutData *aboutData, QObject *parent)
00044 : QObject(parent), d_ptr(new KPluginFactoryPrivate)
00045 {
00046 Q_D(KPluginFactory);
00047 d->q_ptr = this;
00048 d->componentData = KComponentData(*aboutData);
00049
00050 factorycleanup->add(this);
00051 }
00052
00053 KPluginFactory::KPluginFactory(const KAboutData &aboutData, QObject *parent)
00054 : QObject(parent), d_ptr(new KPluginFactoryPrivate)
00055 {
00056 Q_D(KPluginFactory);
00057 d->q_ptr = this;
00058 d->componentData = KComponentData(aboutData);
00059
00060 factorycleanup->add(this);
00061 }
00062
00063 KPluginFactory::KPluginFactory(QObject *parent)
00064 : QObject(parent), d_ptr(new KPluginFactoryPrivate())
00065 {
00066 Q_D(KPluginFactory);
00067 d->q_ptr = this;
00068 factorycleanup->add(this);
00069 }
00070
00071 KPluginFactory::KPluginFactory(KPluginFactoryPrivate &d, QObject *parent)
00072 : QObject(parent), d_ptr(&d)
00073 {
00074 factorycleanup->add(this);
00075 }
00076
00077 KPluginFactory::~KPluginFactory()
00078 {
00079 Q_D(KPluginFactory);
00080
00081 if (d->catalogInitialized && d->componentData.isValid()) {
00082 KGlobal::locale()->removeCatalog(d->componentData.catalogName());
00083 }
00084
00085 delete d_ptr;
00086 }
00087
00088 KComponentData KPluginFactory::componentData() const
00089 {
00090 Q_D(const KPluginFactory);
00091 return d->componentData;
00092 }
00093
00094 void KPluginFactory::registerPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction)
00095 {
00096 Q_D(KPluginFactory);
00097
00098 Q_ASSERT(metaObject);
00099
00100
00101 if (!keyword.isEmpty()) {
00102 if (d->createInstanceHash.contains(keyword)) {
00103 kFatal(152) << "A plugin with the keyword" << keyword << "was already registered. A keyword must be unique!";
00104 }
00105 d->createInstanceHash.insert(keyword, KPluginFactoryPrivate::Plugin(metaObject, instanceFunction));
00106 } else {
00107 QList<KPluginFactoryPrivate::Plugin> clashes(d->createInstanceHash.values(keyword));
00108 const QMetaObject *superClass = metaObject->superClass();
00109 if (superClass) {
00110 foreach (const KPluginFactoryPrivate::Plugin &plugin, clashes) {
00111 for (const QMetaObject *otherSuper = plugin.first->superClass(); otherSuper;
00112 otherSuper = otherSuper->superClass()) {
00113 if (superClass == otherSuper) {
00114 kFatal(152) << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins.";
00115 }
00116 }
00117 }
00118 }
00119 foreach (const KPluginFactoryPrivate::Plugin &plugin, clashes) {
00120 superClass = plugin.first->superClass();
00121 if (superClass) {
00122 for (const QMetaObject *otherSuper = metaObject->superClass(); otherSuper;
00123 otherSuper = otherSuper->superClass()) {
00124 if (superClass == otherSuper) {
00125 kFatal(152) << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins.";
00126 }
00127 }
00128 }
00129 }
00130 d->createInstanceHash.insertMulti(keyword, KPluginFactoryPrivate::Plugin(metaObject, instanceFunction));
00131 }
00132 }
00133
00134 QObject *KPluginFactory::createObject(QObject *parent, const char *className, const QStringList &args)
00135 {
00136 Q_UNUSED(parent);
00137 Q_UNUSED(className);
00138 Q_UNUSED(args);
00139 return 0;
00140 }
00141
00142 KParts::Part *KPluginFactory::createPartObject(QWidget *parentWidget, QObject *parent, const char *classname, const QStringList &args)
00143 {
00144 Q_UNUSED(parent);
00145 Q_UNUSED(parentWidget);
00146 Q_UNUSED(classname);
00147 Q_UNUSED(args);
00148 return 0;
00149 }
00150
00151 QObject *KPluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString &keyword)
00152 {
00153 Q_D(KPluginFactory);
00154
00155 QObject *obj = 0;
00156
00157 if (!d->catalogInitialized) {
00158 d->catalogInitialized = true;
00159 setupTranslations();
00160 }
00161
00162 if (keyword.isEmpty()) {
00163
00164
00165 const char* kpartsIface = iface;
00166 if (args.contains(QVariant("Browser/View")))
00167 kpartsIface = "Browser/View";
00168
00169 const QStringList argsStringList = variantListToStringList(args);
00170
00171 if ((obj = reinterpret_cast<QObject *>(createPartObject(parentWidget, parent, kpartsIface, argsStringList)))) {
00172 objectCreated(obj);
00173 return obj;
00174 }
00175
00176 if ((obj = createObject(parent, iface, argsStringList))) {
00177 objectCreated(obj);
00178 return obj;
00179 }
00180 }
00181
00182 const QList<KPluginFactoryPrivate::Plugin> candidates(d->createInstanceHash.values(keyword));
00183
00184
00185 foreach (const KPluginFactoryPrivate::Plugin &plugin, candidates) {
00186 for (const QMetaObject *current = plugin.first; current; current = current->superClass()) {
00187 if (0 == qstrcmp(iface, current->className())) {
00188 if (obj) {
00189 kFatal(152) << "ambiguous interface requested from a DSO containing more than one plugin";
00190 }
00191 obj = plugin.second(parentWidget, parent, args);
00192 break;
00193 }
00194 }
00195 }
00196
00197 if (obj) {
00198 emit objectCreated(obj);
00199 }
00200 return obj;
00201 }
00202
00203 void KPluginFactory::setupTranslations()
00204 {
00205 Q_D(KPluginFactory);
00206
00207 if (!d->componentData.isValid())
00208 return;
00209
00210 KGlobal::locale()->insertCatalog(d->componentData.catalogName());
00211 }
00212
00213 void KPluginFactory::setComponentData(const KComponentData &kcd)
00214 {
00215 Q_D(KPluginFactory);
00216 d->componentData = kcd;
00217 }
00218
00219
00220 QStringList KPluginFactory::variantListToStringList(const QVariantList &list)
00221 {
00222 QStringList stringlist;
00223 Q_FOREACH(const QVariant& var, list)
00224 stringlist << var.toString();
00225 return stringlist;
00226 }
00227
00228
00229 QVariantList KPluginFactory::stringListToVariantList(const QStringList &list)
00230 {
00231 QVariantList variantlist;
00232 Q_FOREACH(const QString& str, list)
00233 variantlist << QVariant(str);
00234 return variantlist;
00235 }
00236
00237 #include "kpluginfactory.moc"