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 lib->
unload();
00097
return reportError( report, i18n(
"<qt>There was an error when loading the module '%1'.<br><br>"
00098
"The desktop file (%2) as well as the library (%3) was found but "
00099
"yet the module could not be loaded properly. Most likely "
00100
"the factory declaration was wrong, or the "
00101
"create_* function was missing.</qt>")
00102 .arg( mod.
moduleName() )
00103 .arg( mod.
fileName() )
00104 .arg( lib->
fileName() ),
00105 QString::null, parent );
00106 }
00107
00108 lib->
unload();
00109 }
00110
return reportError( report, i18n(
"The specified library %1 could not be found.")
00111 .arg( mod.
library() ), QString::null, parent );
00112
return 0;
00113 }
00114
00115
KCModule* KCModuleLoader::loadModule(
const KCModuleInfo &mod,
bool withfallback,
QWidget * parent,
const char * name,
const QStringList & args )
00116 {
00117
return loadModule( mod, None, withfallback, parent, name, args );
00118 }
00119
00120
KCModule* KCModuleLoader::loadModule(
const KCModuleInfo &mod, ErrorReporting report,
bool withfallback,
QWidget * parent,
const char * name,
const QStringList & args )
00121 {
00122
00123
00124
00125
00126
00127
00128
if ( !mod.
service() )
00129 {
00130
return reportError( report,
00131 i18n(
"The module %1 could not be found.")
00132 .arg( mod.
moduleName() ), i18n(
"<qt><p>The diagnostics is:<br>The desktop file %1 could not be found.</qt>").arg(mod.
fileName()), parent );
00133 }
00134
00135
if (!mod.
library().isEmpty())
00136 {
00137
00138
00139
KLibLoader *loader =
KLibLoader::self();
00140
00141
KCModule *module = load(mod,
"kcm_%1", loader, report, parent, name, args );
00142
00143
00144
00145
00146
if (!
KLibLoader::findLibrary(
QCString(
"libkcm_" ) + QFile::encodeName( mod.
library() ) ).isEmpty() )
00147 module = load(mod,
"libkcm_%1", loader, report, parent, name, args );
00148
if (module)
00149
return module;
00150
return reportError( report,
00151 i18n(
"The module %1 could not be loaded.")
00152 .arg( mod.
moduleName() ), QString::null, parent );
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
if(withfallback)
00164 {
00165
KApplication::startServiceByDesktopPath(mod.
fileName(), QString::null);
00166 }
00167
else
00168 {
00169
return reportError( report,
00170 i18n(
"The module %1 is not a valid configuration module.")
00171 .arg( mod.
moduleName() ), i18n(
"<qt><p>The diagnostics is:<br>The desktop file %1 does not specify a library.</qt>").arg(mod.
fileName()), parent );
00172 }
00173
00174
return 0;
00175 }
00176
00177
KCModule* KCModuleLoader::loadModule(
const QString &module,
QWidget *parent,
00178
const char *name,
const QStringList & args)
00179 {
00180
return loadModule(
KCModuleInfo(module), None,
false, parent, name, args);
00181 }
00182
00183
KCModule* KCModuleLoader::loadModule(
const QString &module, ErrorReporting
00184 report,
QWidget *parent,
const char *name,
const QStringList & args)
00185 {
00186
return loadModule(
KCModuleInfo(module), report,
false, parent, name, args);
00187 }
00188
00189
void KCModuleLoader::unloadModule(
const KCModuleInfo &mod)
00190 {
00191
00192
KLibLoader *loader =
KLibLoader::self();
00193
00194
00195
QString libname(
"libkcm_%1");
00196 loader->
unloadLibrary(QFile::encodeName(libname.arg(mod.
library())));
00197
00198 libname =
"kcm_%1";
00199 loader->
unloadLibrary(QFile::encodeName(libname.arg(mod.
library())));
00200 }
00201
00202
void KCModuleLoader::showLastLoaderError(
QWidget *parent)
00203 {
00204
KMessageBox::detailedError(parent,
00205 i18n(
"There was an error loading the module."),i18n(
"<qt><p>The diagnostics is:<br>%1"
00206
"<p>Possible reasons:</p><ul><li>An error occurred during your last "
00207
"KDE upgrade leaving an orphaned control module<li>You have old third party "
00208
"modules lying around.</ul><p>Check these points carefully and try to remove "
00209
"the module mentioned in the error message. If this fails, consider contacting "
00210
"your distributor or packager.</p></qt>")
00211 .arg(KLibLoader::self()->lastErrorMessage()));
00212
00213 }
00214
00215
bool KCModuleLoader::testModule(
const QString& module )
00216 {
00217
return testModule(
KCModuleInfo( module ) );
00218 }
00219
00220
bool KCModuleLoader::testModule(
const KCModuleInfo& module )
00221 {
00222
if (!module.
service())
00223 {
00224
kdDebug(1208) <<
"Module '" << module.
fileName() <<
"' not found." <<
endl;
00225
return true;
00226 }
00227
00228
bool doLoad = module.
service()->property(
"X-KDE-Test-Module", QVariant::Bool ).toBool();
00229
if( !doLoad )
00230 {
00231
return true;
00232 }
00233
else
00234 {
00241
KLibLoader* loader =
KLibLoader::self();
00242
KLibrary*
library = loader->
library( QFile::encodeName((
QString(
"kcm_%1").arg(module.
library()))) );
00243
if( library )
00244 {
00245
void *test_func = library->
symbol(
QString(
"test_%1").arg(module.
factoryName()).utf8() );
00246
if( test_func )
00247 {
00248 bool (*func)() = (bool(*)())test_func;
00249
if( func() )
00250 {
00251
return true;
00252 }
00253
else
00254 {
00255
return false;
00256 }
00257 }
00258
else
00259 {
00260
kdDebug(1208) <<
"The test function for module '" << module.
fileName() <<
"' could not be found." <<
endl;
00261
return true;
00262 }
00263 }
00264
kdDebug(1208) <<
"The library '" << module.
library() <<
"' could not be found." <<
endl;
00265
return true;
00266 }
00267 }
00268
00269
KCModule* KCModuleLoader::reportError( ErrorReporting report,
const QString & text,
00270
QString details,
QWidget * parent )
00271 {
00272
if( details.isNull() )
00273 details = i18n(
"<qt><p>The diagnostics is:<br>%1"
00274
"<p>Possible reasons:</p><ul><li>An error occurred during your last "
00275
"KDE upgrade leaving an orphaned control module<li>You have old third party "
00276
"modules lying around.</ul><p>Check these points carefully and try to remove "
00277
"the module mentioned in the error message. If this fails, consider contacting "
00278
"your distributor or packager.</p></qt>").arg(KLibLoader::self()->lastErrorMessage());
00279
if( report & Dialog )
00280
KMessageBox::detailedError( parent, text, details );
00281
if( report & Inline )
00282
return new KCMError( text, details, parent );
00283
return 0;
00284 }
00285
00286
00287