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 if ((obj = reinterpret_cast<QObject *>(createPartObject(parentWidget, parent, kpartsIface, variantListToStringList(args))))) {
00170 objectCreated(obj);
00171 return obj;
00172 }
00173
00174 if ((obj = createObject(parent, iface, variantListToStringList(args)))) {
00175 objectCreated(obj);
00176 return obj;
00177 }
00178 }
00179
00180 const QList<KPluginFactoryPrivate::Plugin> candidates(d->createInstanceHash.values(keyword));
00181
00182
00183 foreach (const KPluginFactoryPrivate::Plugin &plugin, candidates) {
00184 for (const QMetaObject *current = plugin.first; current; current = current->superClass()) {
00185 if (0 == qstrcmp(iface, current->className())) {
00186 if (obj) {
00187 kFatal(152) << "ambiguous interface requested from a DSO containing more than one plugin";
00188 }
00189 obj = plugin.second(parentWidget, parent, args);
00190 break;
00191 }
00192 }
00193 }
00194
00195 if (obj) {
00196 emit objectCreated(obj);
00197 }
00198 return obj;
00199 }
00200
00201 void KPluginFactory::setupTranslations()
00202 {
00203 Q_D(KPluginFactory);
00204
00205 if (!d->componentData.isValid())
00206 return;
00207
00208 KGlobal::locale()->insertCatalog(d->componentData.catalogName());
00209 }
00210
00211 void KPluginFactory::setComponentData(const KComponentData &kcd)
00212 {
00213 Q_D(KPluginFactory);
00214 d->componentData = kcd;
00215 }
00216
00217
00218 QStringList KPluginFactory::variantListToStringList(const QVariantList &list)
00219 {
00220 QStringList stringlist;
00221 Q_FOREACH(const QVariant& var, list)
00222 stringlist << var.toString();
00223 return stringlist;
00224 }
00225
00226
00227 QVariantList KPluginFactory::stringListToVariantList(const QStringList &list)
00228 {
00229 QVariantList variantlist;
00230 Q_FOREACH(const QString& str, list)
00231 variantlist << QVariant(str);
00232 return variantlist;
00233 }
00234
00235 #include "kpluginfactory.moc"