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 <tqfile.h>
00025 #include <tqlabel.h>
00026 #include <tqlayout.h>
00027
00028 #include <tdeapplication.h>
00029 #include <kdebug.h>
00030 #include <tdelocale.h>
00031 #include <tdemessagebox.h>
00032 #include <tdeparts/componentfactory.h>
00033
00034 #include "tdecmoduleloader.h"
00035
00036
00037
00042 class KCMError : public TDECModule
00043 {
00044 public:
00045 KCMError( const TQString& msg, const TQString& details, TQWidget* parent )
00046 : TDECModule( parent, "KCMError" )
00047 {
00048 TQVBoxLayout* topLayout = new TQVBoxLayout( this );
00049 topLayout->addWidget( new TQLabel( msg, this ) );
00050 topLayout->addWidget( new TQLabel( details, this ) );
00051 }
00052 };
00053
00054
00055
00056
00057
00058 TDECModule* TDECModuleLoader::load(const TDECModuleInfo &mod, const TQString &libname,
00059 KLibLoader *loader, ErrorReporting report, TQWidget * parent,
00060 const char * name, const TQStringList & args )
00061 {
00062
00063
00064
00065 KLibrary *lib = loader->library(TQFile::encodeName(libname.arg(mod.library())));
00066 if (lib) {
00067 TQString initSym("init_");
00068 initSym += libname.arg(mod.library());
00069
00070 if ( lib->hasSymbol(TQFile::encodeName(initSym)) )
00071 {
00072 KLibFactory *factory = lib->factory();
00073 if ( factory )
00074 {
00075 TDECModule *module = KParts::ComponentFactory::createInstanceFromFactory<TDECModule>( factory, TQT_TQOBJECT(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 TQString factory("create_%1");
00085 void *create = lib->symbol(TQFile::encodeName(factory.arg(mod.handle())));
00086
00087 if (create)
00088 {
00089
00090 TDECModule* (*func)(TQWidget *, const char *);
00091 func = (TDECModule* (*)(TQWidget *, const char *)) create;
00092 return func( parent, name ? name : mod.handle().latin1() );
00093 }
00094 else
00095 {
00096 TQString 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 TQString::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() ), TQString::null, parent );
00113 return 0;
00114 }
00115
00116 TDECModule* TDECModuleLoader::loadModule(const TDECModuleInfo &mod, bool withfallback, TQWidget * parent, const char * name, const TQStringList & args )
00117 {
00118 return loadModule( mod, None, withfallback, parent, name, args );
00119 }
00120
00121 TDECModule* TDECModuleLoader::loadModule(const TDECModuleInfo &mod, ErrorReporting report, bool withfallback, TQWidget * parent, const char * name, const TQStringList & args )
00122 {
00123
00124
00125
00126
00127
00128
00129 if ( !mod.service() )
00130 {
00131 if ( mod.moduleName() == "kcmlisa" || mod.moduleName() == "kcmkiolan" )
00132 {
00133 return reportError( report,
00134 i18n("The module %1 could not be found.")
00135 .arg( mod.moduleName() ),
00136 i18n("<qt><p>The Lisa and lan:/ ioslave modules "
00137 "are not installed by default in Kubuntu, because they are obsolete "
00138 "and replaced by zeroconf.<br> If you still wish to use them, you "
00139 "should install the lisa package from the Universe repository.</p></qt>"),
00140 parent );
00141 } else {
00142 return reportError( report,
00143 i18n("The module %1 could not be found.")
00144 .arg( mod.moduleName() ),
00145 i18n("<qt><p>The diagnostics is:<br>The desktop file %1 could not be found.</p></qt>").arg(mod.fileName()),
00146 parent );
00147 }
00148 }
00149
00150 if (!mod.library().isEmpty())
00151 {
00152
00153
00154 KLibLoader *loader = KLibLoader::self();
00155
00156 TDECModule *module = load(mod, "kcm_%1", loader, report, parent, name, args );
00157
00158
00159
00160
00161 if (!KLibLoader::findLibrary( TQCString( "libkcm_" ) + TQFile::encodeName( mod.library() ) ).isEmpty() )
00162 module = load(mod, "libkcm_%1", loader, report, parent, name, args );
00163 if (module)
00164 return module;
00165 return reportError( report,
00166 i18n("The module %1 could not be loaded.")
00167 .arg( mod.moduleName() ), TQString::null, parent );
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 if(withfallback)
00179 {
00180 TDEApplication::startServiceByDesktopPath(mod.fileName(), TQString::null);
00181 }
00182 else
00183 {
00184 return reportError( report,
00185 i18n("The module %1 is not a valid configuration module.")
00186 .arg( mod.moduleName() ), i18n("<qt><p>The diagnostics is:<br>The desktop file %1 does not specify a library.</qt>").arg(mod.fileName()), parent );
00187 }
00188
00189 return 0;
00190 }
00191
00192 TDECModule* TDECModuleLoader::loadModule(const TQString &module, TQWidget *parent,
00193 const char *name, const TQStringList & args)
00194 {
00195 return loadModule(TDECModuleInfo(module), None, false, parent, name, args);
00196 }
00197
00198 TDECModule* TDECModuleLoader::loadModule(const TQString &module, ErrorReporting
00199 report, TQWidget *parent, const char *name, const TQStringList & args)
00200 {
00201 return loadModule(TDECModuleInfo(module), report, false, parent, name, args);
00202 }
00203
00204 void TDECModuleLoader::unloadModule(const TDECModuleInfo &mod)
00205 {
00206
00207 KLibLoader *loader = KLibLoader::self();
00208
00209
00210 TQString libname("libkcm_%1");
00211 loader->unloadLibrary(TQFile::encodeName(libname.arg(mod.library())));
00212
00213 libname = "kcm_%1";
00214 loader->unloadLibrary(TQFile::encodeName(libname.arg(mod.library())));
00215 }
00216
00217 void TDECModuleLoader::showLastLoaderError(TQWidget *parent)
00218 {
00219 KMessageBox::detailedError(parent,
00220 i18n("There was an error loading the module."),i18n("<qt><p>The diagnostics is:<br>%1"
00221 "<p>Possible reasons:</p><ul><li>An error occurred during your last "
00222 "TDE upgrade leaving an orphaned control module<li>You have old third party "
00223 "modules lying around.</ul><p>Check these points carefully and try to remove "
00224 "the module mentioned in the error message. If this fails, consider contacting "
00225 "your distributor or packager.</p></qt>")
00226 .arg(KLibLoader::self()->lastErrorMessage()));
00227
00228 }
00229
00230 bool TDECModuleLoader::testModule( const TQString& module )
00231 {
00232 return testModule( TDECModuleInfo( module ) );
00233 }
00234
00235 bool TDECModuleLoader::testModule( const TDECModuleInfo& module )
00236 {
00237 if (!module.service())
00238 {
00239 kdDebug(1208) << "Module '" << module.fileName() << "' not found." << endl;
00240 return true;
00241 }
00242
00243 bool doLoad = module.service()->property( "X-TDE-Test-Module", TQVariant::Bool ).toBool();
00244 if( !doLoad )
00245 {
00246 return true;
00247 }
00248 else
00249 {
00256 KLibLoader* loader = KLibLoader::self();
00257 KLibrary* library = loader->library( TQFile::encodeName((TQString("kcm_%1").arg(module.library()))) );
00258 if( library )
00259 {
00260 void *test_func = library->symbol( TQString(TQString("test_%1").arg(module.factoryName())).utf8() );
00261 if( test_func )
00262 {
00263 bool (*func)() = (bool(*)())test_func;
00264 if( func() )
00265 {
00266 return true;
00267 }
00268 else
00269 {
00270 return false;
00271 }
00272 }
00273 else
00274 {
00275 kdDebug(1208) << "The test function for module '" << module.fileName() << "' could not be found." << endl;
00276 return true;
00277 }
00278 }
00279 kdDebug(1208) << "The library '" << module.library() << "' could not be found." << endl;
00280 return true;
00281 }
00282 }
00283
00284 TDECModule* TDECModuleLoader::reportError( ErrorReporting report, const TQString & text,
00285 TQString details, TQWidget * parent )
00286 {
00287 if( details.isNull() )
00288 details = i18n("<qt><p>The diagnostics is:<br>%1"
00289 "<p>Possible reasons:</p><ul><li>An error occurred during your last "
00290 "TDE upgrade leaving an orphaned control module<li>You have old third party "
00291 "modules lying around.</ul><p>Check these points carefully and try to remove "
00292 "the module mentioned in the error message. If this fails, consider contacting "
00293 "your distributor or packager.</p></qt>").arg(KLibLoader::self()->lastErrorMessage());
00294 if( report & Dialog )
00295 KMessageBox::detailedError( parent, text, details );
00296 if( report & Inline )
00297 return new KCMError( text, details, parent );
00298 return 0;
00299 }
00300
00301
00302