00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qfile.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027
00028 #include <kapplication.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032 #include <kparts/componentfactory.h>
00033
00034 #include "kcmoduleloader.h"
00035
00036
00037
00042 class KCMError : public KCModule
00043 {
00044 public:
00045 KCMError( const QString& msg, const QString& details, QWidget* parent )
00046 : KCModule( parent, "KCMError" )
00047 {
00048 QVBoxLayout* topLayout = new QVBoxLayout( this );
00049 topLayout->addWidget( new QLabel( msg, this ) );
00050 topLayout->addWidget( new QLabel( details, this ) );
00051 }
00052 };
00053
00054
00055
00056
00057
00058 KCModule* KCModuleLoader::load(const KCModuleInfo &mod, const QString &libname,
00059 KLibLoader *loader, ErrorReporting report, QWidget * parent,
00060 const char * name, const QStringList & args )
00061 {
00062
00063
00064
00065 KLibrary *lib = loader->library(QFile::encodeName(libname.arg(mod.library())));
00066 if (lib) {
00067 QString initSym("init_");
00068 initSym += libname.arg(mod.library());
00069
00070 if ( lib->hasSymbol(QFile::encodeName(initSym)) )
00071 {
00072 KLibFactory *factory = lib->factory();
00073 if ( factory )
00074 {
00075 KCModule *module = KParts::ComponentFactory::createInstanceFromFactory<KCModule>( factory, parent, name ? name : mod.handle().latin1(), args );
00076 if (module)
00077 return module;
00078 }
00079
00080 kdDebug(1208) << "Unable to load module using ComponentFactory. Falling back to old loader." << endl;
00081 }
00082
00083
00084 QString factory("create_%1");
00085 void *create = lib->symbol(QFile::encodeName(factory.arg(mod.handle())));
00086
00087 if (create)
00088 {
00089
00090 KCModule* (*func)(QWidget *, const char *);
00091 func = (KCModule* (*)(QWidget *, const char *)) create;
00092 return func( parent, name ? name : mod.handle().latin1() );
00093 }
00094 else
00095 {
00096 QString libFileName = lib->fileName();
00097 lib->unload();
00098 return reportError( report, i18n("<qt>There was an error when loading the module '%1'.<br><br>"
00099 "The desktop file (%2) as well as the library (%3) was found but "
00100 "yet the module could not be loaded properly. Most likely "
00101 "the factory declaration was wrong, or the "
00102 "create_* function was missing.</qt>")
00103 .arg( mod.moduleName() )
00104 .arg( mod.fileName() )
00105 .arg( libFileName ),
00106 QString::null, parent );
00107 }
00108
00109 lib->unload();
00110 }
00111 return reportError( report, i18n("The specified library %1 could not be found.")
00112 .arg( mod.library() ), QString::null, parent );
00113 return 0;
00114 }
00115
00116 KCModule* KCModuleLoader::loadModule(const KCModuleInfo &mod, bool withfallback, QWidget * parent, const char * name, const QStringList & args )
00117 {
00118 return loadModule( mod, None, withfallback, parent, name, args );
00119 }
00120
00121 KCModule* KCModuleLoader::loadModule(const KCModuleInfo &mod, ErrorReporting report, bool withfallback, QWidget * parent, const char * name, const QStringList & args )
00122 {
00123
00124
00125
00126
00127
00128
00129 if ( !mod.service() )
00130 {
00131 return reportError( report,
00132 i18n("The module %1 could not be found.")
00133 .arg( mod.moduleName() ), i18n("<qt><p>The diagnostics is:<br>The desktop file %1 could not be found.</qt>").arg(mod.fileName()), parent );
00134 }
00135
00136 if (!mod.library().isEmpty())
00137 {
00138
00139
00140 KLibLoader *loader = KLibLoader::self();
00141
00142 KCModule *module = load(mod, "kcm_%1", loader, report, parent, name, args );
00143
00144
00145
00146
00147 if (!KLibLoader::findLibrary( QCString( "libkcm_" ) + QFile::encodeName( mod.library() ) ).isEmpty() )
00148 module = load(mod, "libkcm_%1", loader, report, parent, name, args );
00149 if (module)
00150 return module;
00151 return reportError( report,
00152 i18n("The module %1 could not be loaded.")
00153 .arg( mod.moduleName() ), QString::null, parent );
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 if(withfallback)
00165 {
00166 KApplication::startServiceByDesktopPath(mod.fileName(), QString::null);
00167 }
00168 else
00169 {
00170 return reportError( report,
00171 i18n("The module %1 is not a valid configuration module.")
00172 .arg( mod.moduleName() ), i18n("<qt><p>The diagnostics is:<br>The desktop file %1 does not specify a library.</qt>").arg(mod.fileName()), parent );
00173 }
00174
00175 return 0;
00176 }
00177
00178 KCModule* KCModuleLoader::loadModule(const QString &module, QWidget *parent,
00179 const char *name, const QStringList & args)
00180 {
00181 return loadModule(KCModuleInfo(module), None, false, parent, name, args);
00182 }
00183
00184 KCModule* KCModuleLoader::loadModule(const QString &module, ErrorReporting
00185 report, QWidget *parent, const char *name, const QStringList & args)
00186 {
00187 return loadModule(KCModuleInfo(module), report, false, parent, name, args);
00188 }
00189
00190 void KCModuleLoader::unloadModule(const KCModuleInfo &mod)
00191 {
00192
00193 KLibLoader *loader = KLibLoader::self();
00194
00195
00196 QString libname("libkcm_%1");
00197 loader->unloadLibrary(QFile::encodeName(libname.arg(mod.library())));
00198
00199 libname = "kcm_%1";
00200 loader->unloadLibrary(QFile::encodeName(libname.arg(mod.library())));
00201 }
00202
00203 void KCModuleLoader::showLastLoaderError(QWidget *parent)
00204 {
00205 KMessageBox::detailedError(parent,
00206 i18n("There was an error loading the module."),i18n("<qt><p>The diagnostics is:<br>%1"
00207 "<p>Possible reasons:</p><ul><li>An error occurred during your last "
00208 "KDE upgrade leaving an orphaned control module<li>You have old third party "
00209 "modules lying around.</ul><p>Check these points carefully and try to remove "
00210 "the module mentioned in the error message. If this fails, consider contacting "
00211 "your distributor or packager.</p></qt>")
00212 .arg(KLibLoader::self()->lastErrorMessage()));
00213
00214 }
00215
00216 bool KCModuleLoader::testModule( const QString& module )
00217 {
00218 return testModule( KCModuleInfo( module ) );
00219 }
00220
00221 bool KCModuleLoader::testModule( const KCModuleInfo& module )
00222 {
00223 if (!module.service())
00224 {
00225 kdDebug(1208) << "Module '" << module.fileName() << "' not found." << endl;
00226 return true;
00227 }
00228
00229 bool doLoad = module.service()->property( "X-KDE-Test-Module", QVariant::Bool ).toBool();
00230 if( !doLoad )
00231 {
00232 return true;
00233 }
00234 else
00235 {
00242 KLibLoader* loader = KLibLoader::self();
00243 KLibrary* library = loader->library( QFile::encodeName((QString("kcm_%1").arg(module.library()))) );
00244 if( library )
00245 {
00246 void *test_func = library->symbol( QString("test_%1").arg(module.factoryName()).utf8() );
00247 if( test_func )
00248 {
00249 bool (*func)() = (bool(*)())test_func;
00250 if( func() )
00251 {
00252 return true;
00253 }
00254 else
00255 {
00256 return false;
00257 }
00258 }
00259 else
00260 {
00261 kdDebug(1208) << "The test function for module '" << module.fileName() << "' could not be found." << endl;
00262 return true;
00263 }
00264 }
00265 kdDebug(1208) << "The library '" << module.library() << "' could not be found." << endl;
00266 return true;
00267 }
00268 }
00269
00270 KCModule* KCModuleLoader::reportError( ErrorReporting report, const QString & text,
00271 QString details, QWidget * parent )
00272 {
00273 if( details.isNull() )
00274 details = i18n("<qt><p>The diagnostics is:<br>%1"
00275 "<p>Possible reasons:</p><ul><li>An error occurred during your last "
00276 "KDE upgrade leaving an orphaned control module<li>You have old third party "
00277 "modules lying around.</ul><p>Check these points carefully and try to remove "
00278 "the module mentioned in the error message. If this fails, consider contacting "
00279 "your distributor or packager.</p></qt>").arg(KLibLoader::self()->lastErrorMessage());
00280 if( report & Dialog )
00281 KMessageBox::detailedError( parent, text, details );
00282 if( report & Inline )
00283 return new KCMError( text, details, parent );
00284 return 0;
00285 }
00286
00287
00288