• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

kpluginloader.cpp

Go to the documentation of this file.
00001 /*  This file is part of the KDE project
00002     Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License version 2 as published by the Free Software Foundation.
00007 
00008     This library is distributed in the hope that it will be useful,
00009     but WITHOUT ANY WARRANTY; without even the implied warranty of
00010     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011     Library General Public License for more details.
00012 
00013     You should have received a copy of the GNU Library General Public License
00014     along with this library; see the file COPYING.LIB.  If not, write to
00015     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016     Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "kpluginloader.h"
00020 
00021 #include <kcomponentdata.h>
00022 #include <kstandarddirs.h>
00023 #include <klocale.h>
00024 #include "kpluginfactory.h"
00025 #include <kservice.h>
00026 #include "klibrary.h"
00027 #include <kdebug.h>
00028 
00029 #include <QtCore/QLibrary>
00030 #include <QtCore/QDir>
00031 #include <QtCore/QFileInfo>
00032 
00033 
00034 class KPluginLoaderPrivate
00035 {
00036     Q_DECLARE_PUBLIC(KPluginLoader)
00037 protected:
00038     KPluginLoaderPrivate(const QString &libname)
00039         : name(libname), pluginVersion(-1), verificationData(0), lib(0)
00040     {}
00041     ~KPluginLoaderPrivate()
00042     {
00043         delete lib;
00044     }
00045 
00046     KPluginLoader *q_ptr;
00047     const QString name;
00048     quint32 pluginVersion;
00049     KDEPluginVerificationData *verificationData;
00050     QString errorString;
00051 
00052     KLibrary *lib;
00053 };
00054 
00055 inline QString makeLibName( const QString &libname )
00056 {
00057 #ifdef Q_OS_WIN
00058     if (!libname.endsWith(".dll"))
00059         return libname + ".dll";
00060     return libname;
00061 #else
00062     int pos = libname.lastIndexOf('/');
00063     if (pos < 0)
00064       pos = 0;
00065     if (libname.indexOf('.', pos) < 0) {
00066         const char* const extList[] = { ".so", ".dylib", ".bundle", ".sl" };
00067         for (uint i = 0; i < sizeof(extList) / sizeof(*extList); ++i) {
00068            if (QLibrary::isLibrary(libname + extList[i]))
00069                return libname + extList[i];
00070         }
00071     }
00072     return libname;
00073 #endif
00074 }
00075 
00076 #ifdef Q_OS_WIN
00077 extern QString fixLibPrefix(const QString& libname);
00078 #endif
00079 
00080 inline QString findLibraryInternal(const QString &name, const KComponentData &cData)
00081 {
00082     QString libname = makeLibName(name);
00083 
00084     QFileInfo fileinfo(name);
00085     bool hasPrefix = fileinfo.fileName().startsWith("lib");
00086 
00087     if (hasPrefix)
00088         kDebug(150) << "plugins should not have a 'lib' prefix:" << libname;
00089 
00090     QString libfile;
00091     if (QDir::isRelativePath(libname)) {
00092         libfile = cData.dirs()->findResource("module", libname);
00093         if (libfile.isEmpty()) {
00094 #ifdef Q_OS_WIN
00095             libname = fixLibPrefix(libname);
00096 #else
00097             if (!hasPrefix)
00098                 libname = fileinfo.path() + QLatin1String("/lib") + fileinfo.fileName();
00099 #endif
00100             libfile = cData.dirs()->findResource("lib", libname);
00101             if (!libfile.isEmpty())
00102                 kDebug(150) << "library" << libname << "not found under 'module' but under 'lib'";
00103         }
00104     }
00105     else {
00106         libfile = libname;
00107     }
00108     return libfile;
00109 }
00110 
00111 bool KPluginLoader::isLoaded() const
00112 {
00113     return QPluginLoader::isLoaded() || d_ptr->lib;
00114 }
00115 
00116 KPluginLoader::KPluginLoader(const QString &plugin, const KComponentData &componentdata, QObject *parent)
00117     : QPluginLoader(findLibraryInternal(plugin, componentdata), parent), d_ptr(new KPluginLoaderPrivate(plugin))
00118 {
00119     d_ptr->q_ptr = this;
00120     load();
00121 }
00122 
00123 KPluginLoader::KPluginLoader(const KService &service, const KComponentData &componentdata, QObject *parent)
00124 : QPluginLoader(findLibraryInternal(service.library(), componentdata), parent), d_ptr(new KPluginLoaderPrivate(service.library()))
00125 {
00126     d_ptr->q_ptr = this;
00127     Q_D(KPluginLoader);
00128     Q_ASSERT(service.isValid());
00129 
00130     if (service.isApplication()) {
00131         d->errorString = i18n("The service '%1' provides no library or the Library key is missing in the .desktop file.", service.name());
00132         return;
00133     }
00134     load();
00135 }
00136 
00137 KPluginLoader::~KPluginLoader()
00138 {
00139     delete d_ptr;
00140 }
00141 
00142 KPluginFactory *KPluginLoader::factory()
00143 {
00144     Q_D(KPluginLoader);
00145 
00146     if (!isLoaded())
00147         return 0;
00148 
00149 
00150     if (d->lib) {
00151         return d->lib->factory(d->name.toUtf8());
00152     }
00153 
00154     QObject *obj = instance();
00155 
00156     if (!obj)
00157         return 0;
00158 
00159     KPluginFactory *factory = qobject_cast<KPluginFactory *>(obj);
00160 
00161     if (factory == 0) {
00162         delete obj;
00163         d->errorString = i18n("The library %1 does not offer a KDE 4 compatible factory." , d->name);
00164     }
00165 
00166     return factory;
00167 }
00168 
00169 bool KPluginLoader::load()
00170 {
00171     Q_D(KPluginLoader);
00172     if (!QPluginLoader::load()) {
00173         d->lib = new KLibrary(d->name);
00174         if (d->lib->load())
00175             return true;
00176 
00177         return false;
00178     }
00179 
00180     QLibrary lib(fileName());
00181     lib.load();
00182     Q_ASSERT(lib.isLoaded());
00183 
00184     d->verificationData = (KDEPluginVerificationData *) lib.resolve("kde_plugin_verification_data");
00185     if (d->verificationData) {
00186         if ((d->verificationData->KDEVersion > KDE_VERSION) || (KDE_VERSION_MAJOR << 16 != (d->verificationData->KDEVersion & 0xFF0000))) {
00187             d->errorString = i18n("The plugin '%1' uses an incompatible KDE library (%2).", d->name, d->verificationData->KDEVersionString);
00188             lib.unload();
00189             unload();
00190             return false;
00191         }
00192     } else {
00193         kDebug(150) << "The plugin" << d->name << "doesn't contain a kde_plugin_verification_data structure";
00194     }
00195 
00196     quint32 *version = (quint32 *) lib.resolve("kde_plugin_version");
00197     if (version)
00198         d->pluginVersion = *version;
00199     else
00200         d->pluginVersion = -1;
00201 
00202     lib.unload();
00203 
00204     return true;
00205 }
00206 
00207 QString KPluginLoader::errorString() const
00208 {
00209     Q_D(const KPluginLoader);
00210     if (!d->errorString.isEmpty())
00211         return d->errorString;
00212 
00213     return QPluginLoader::errorString();
00214 }
00215 
00216 quint32 KPluginLoader::pluginVersion() const
00217 {
00218     Q_D(const KPluginLoader);
00219     return d->pluginVersion;
00220 }
00221 
00222 QString KPluginLoader::pluginName() const
00223 {
00224     Q_D(const KPluginLoader);
00225     return d->name;
00226 }
00227 
00228 #include "kpluginloader.moc"

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal