• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kutils
 

kutils

kcmoduleloader.cpp
00001 /*
00002   Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
00003   Copyright (c) 2000 Matthias Elter <elter@kde.org>
00004   Copyright (c) 2003,2004 Matthias Kretz <kretz@kde.org>
00005   Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
00006 
00007   This file is part of the KDE project
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Library General Public
00011   License version 2, as published by the Free Software Foundation.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016   Library General Public License for more details.
00017 
00018   You should have received a copy of the GNU Library General Public License
00019   along with this library; see the file COPYING.LIB.  If not, write to
00020   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021   Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include <tqfile.h>
00025 #include <tqlabel.h>
00026 #include <tqlayout.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 TQString& msg, const TQString& details, TQWidget* parent )
00046             : KCModule( 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 KCModule* KCModuleLoader::load(const KCModuleInfo &mod, const TQString &libname,
00059     KLibLoader *loader, ErrorReporting report, TQWidget * parent,
00060     const char * name, const TQStringList & args )
00061 {
00062   // attempt to load modules with ComponentFactory, only if the symbol init_<lib> exists
00063   // (this is because some modules, e.g. kcmkio with multiple modules in the library,
00064   // cannot be ported to KGenericFactory)
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         KCModule *module = KParts::ComponentFactory::createInstanceFromFactory<KCModule>( factory, TQT_TQOBJECT(parent), name ? name : mod.handle().latin1(), args );
00076         if (module)
00077           return module;
00078       }
00079       // else do a fallback
00080       kdDebug(1208) << "Unable to load module using ComponentFactory. Falling back to old loader." << endl;
00081     }
00082 
00083     // get the create_ function
00084     TQString factory("create_%1");
00085     void *create = lib->symbol(TQFile::encodeName(factory.arg(mod.handle())));
00086 
00087     if (create)
00088     {
00089       // create the module
00090       KCModule* (*func)(TQWidget *, const char *);
00091       func = (KCModule* (*)(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 KCModule* KCModuleLoader::loadModule(const KCModuleInfo &mod, bool withfallback, TQWidget * parent, const char * name, const TQStringList & args )
00117 {
00118   return loadModule( mod, None, withfallback, parent, name, args );
00119 }
00120 
00121 KCModule* KCModuleLoader::loadModule(const KCModuleInfo &mod, ErrorReporting report, bool withfallback, TQWidget * parent, const char * name, const TQStringList & args )
00122 {
00123   /*
00124    * Simple libraries as modules are the easiest case:
00125    *  We just have to load the library and get the module
00126    *  from the factory.
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     // get the library loader instance
00153 
00154     KLibLoader *loader = KLibLoader::self();
00155 
00156     KCModule *module = load(mod, "kcm_%1", loader, report, parent, name, args );
00157     /*
00158      * Only try to load libkcm_* if it exists, otherwise KLibLoader::lastErrorMessage would say
00159      * "libkcm_foo not found" instead of the real problem with loading kcm_foo.
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    * Ok, we could not load the library.
00172    * Try to run it as an executable.
00173    * This must not be done when calling from kcmshell, or you'll
00174    * have infinite recursion
00175    * (startService calls kcmshell which calls modloader which calls startService...)
00176    *
00177    */
00178   if(withfallback)
00179   {
00180     KApplication::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 KCModule* KCModuleLoader::loadModule(const TQString &module, TQWidget *parent,
00193       const char *name, const TQStringList & args)
00194 {
00195   return loadModule(KCModuleInfo(module), None, false, parent, name, args);
00196 }
00197 
00198 KCModule* KCModuleLoader::loadModule(const TQString &module, ErrorReporting
00199     report, TQWidget *parent, const char *name, const TQStringList & args)
00200 {
00201   return loadModule(KCModuleInfo(module), report, false, parent, name, args);
00202 }
00203 
00204 void KCModuleLoader::unloadModule(const KCModuleInfo &mod)
00205 {
00206   // get the library loader instance
00207   KLibLoader *loader = KLibLoader::self();
00208 
00209   // try to unload the library
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 KCModuleLoader::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         "KDE 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 KCModuleLoader::testModule( const TQString& module )
00231 {
00232   return testModule( KCModuleInfo( module ) );
00233 }
00234 
00235 bool KCModuleLoader::testModule( const KCModuleInfo& 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-KDE-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 KCModule* KCModuleLoader::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         "KDE 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 // vim: ts=2 sw=2 et
00302 

kutils

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

kutils

Skip menu "kutils"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kutils by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |