KUtils
kcmoduleloader.cpp
Go to the documentation of this file.
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,2006 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 "kcmoduleloader.h" 00025 00026 #include <QtCore/QFile> 00027 #include <QtGui/QLabel> 00028 #include <QtGui/QLayout> 00029 00030 #include <klibrary.h> 00031 #include <kpluginloader.h> 00032 #include <kdebug.h> 00033 #include <klocale.h> 00034 #include <kmessagebox.h> 00035 00036 using namespace KCModuleLoader; 00037 00038 /***************************************************************/ 00043 class KCMError : public KCModule 00044 { 00045 public: 00046 KCMError( const QString& msg, const QString& details, QWidget* parent ) 00047 : KCModule( KGlobal::mainComponent(), parent ) 00048 { 00049 QVBoxLayout* topLayout = new QVBoxLayout( this ); 00050 QLabel *lab = new QLabel( msg, this ); 00051 lab->setWordWrap(true); 00052 topLayout->addWidget( lab ); 00053 lab = new QLabel(details, this ); 00054 lab->setWordWrap(true); 00055 topLayout->addWidget( lab ); 00056 } 00057 }; 00058 /***************************************************************/ 00059 00060 KCModule *KCModuleLoader::loadModule(const QString &module, ErrorReporting report, QWidget *parent, const QStringList &args) 00061 { 00062 return loadModule( KCModuleInfo( module ), report, parent, args ); 00063 } 00064 00065 KCModule* KCModuleLoader::loadModule(const KCModuleInfo& mod, ErrorReporting report, QWidget* parent, const QStringList& args ) 00066 { 00067 /* 00068 * Simple libraries as modules are the easiest case: 00069 * We just have to load the library and get the module 00070 * from the factory. 00071 */ 00072 00073 if ( !mod.service() ) 00074 return reportError( report, 00075 i18n("The module %1 could not be found.", 00076 mod.moduleName() ), i18n("<qt><p>The diagnosis is:<br />The desktop file %1 could not be found.</p></qt>", mod.fileName()), parent ); 00077 if( mod.service()->noDisplay() ) 00078 return reportError( report, i18n( "The module %1 is disabled.", mod.moduleName() ), 00079 i18n( "<qt><p>Either the hardware/software the module configures is not available or the module has been disabled by the administrator.</p></qt>" ), 00080 parent ); 00081 00082 if (!mod.library().isEmpty()) 00083 { 00084 QString error; 00085 QVariantList args2; 00086 foreach (const QString &arg, args) { 00087 args2 << arg; 00088 } 00089 KCModule *module = mod.service()->createInstance<KCModule>(parent, args2, &error); 00090 if (module) { 00091 return module; 00092 } 00093 #ifndef KDE_NO_DEPRECATED 00094 // might be using K_EXPORT_COMPONENT_FACTORY 00095 int error2 = 0; 00096 module = KService::createInstance<KCModule>(mod.service(), parent, args, &error2); 00097 if (module) { 00098 kWarning(1208) << "This module still uses K_EXPORT_COMPONENT_FACTORY. Please port it to use KPluginFactory and K_EXPORT_PLUGIN."; 00099 return module; 00100 } 00101 error += KLibLoader::errorString(error2); 00102 #endif 00103 //#ifndef NDEBUG 00104 { 00105 // get the create_ function 00106 KLibrary lib(mod.library()); 00107 if (lib.load()) { 00108 KCModule *(*create)(QWidget *, const char *); 00109 QByteArray factorymethod("create_"); 00110 factorymethod += mod.handle().toLatin1(); 00111 create = reinterpret_cast<KCModule *(*)(QWidget *, const char*)>(lib.resolveFunction(factorymethod)); 00112 if (create) { 00113 return create(parent, mod.handle().toLatin1()); 00114 kFatal(1208) << "This module still uses a custom factory method (" << factorymethod << "). This is not supported anymore. Please fix the module."; 00115 } else { 00116 kWarning(1208) << "This module has no valid entry symbol at all. The reason could be that it's still using K_EXPORT_COMPONENT_FACTORY with a custom X-KDE-FactoryName which is not supported anymore"; 00117 } 00118 lib.unload(); 00119 } 00120 } 00121 //#endif // NDEBUG 00122 return reportError(report, error, QString(), parent); 00123 } 00124 00125 /* 00126 * Ok, we could not load the library. 00127 * Try to run it as an executable. 00128 * This must not be done when calling from kcmshell, or you'll 00129 * have infinite recursion 00130 * (startService calls kcmshell which calls modloader which calls startService...) 00131 * 00132 */ 00133 return reportError( report, 00134 i18n("The module %1 is not a valid configuration module.", mod.moduleName() ), 00135 i18n("<qt>The diagnosis is:<br />The desktop file %1 does not specify a library.</qt>", mod.fileName()), parent ); 00136 } 00137 00138 00139 void KCModuleLoader::unloadModule(const KCModuleInfo &mod) 00140 { 00141 // get the library loader instance 00142 KPluginLoader loader(mod.library()); 00143 loader.unload(); 00144 } 00145 00146 #ifndef KDE_NO_DEPRECATED 00147 void KCModuleLoader::showLastLoaderError(QWidget *parent) 00148 { 00149 KMessageBox::detailedError(parent, 00150 i18n("There was an error loading the module."),i18n("<qt>The diagnosis is:<br />%1" 00151 "<p>Possible reasons:</p><ul><li>An error occurred during your last " 00152 "KDE upgrade leaving an orphaned control module</li><li>You have old third party " 00153 "modules lying around.</li></ul><p>Check these points carefully and try to remove " 00154 "the module mentioned in the error message. If this fails, consider contacting " 00155 "your distributor or packager.</p></qt>", 00156 KLibLoader::self()->lastErrorMessage())); 00157 00158 } 00159 #endif 00160 00161 KCModule* KCModuleLoader::reportError( ErrorReporting report, const QString & text, 00162 const QString &details, QWidget * parent ) 00163 { 00164 QString realDetails = details; 00165 if (realDetails.isNull()) { 00166 realDetails = i18n("<qt><p>Possible reasons:<ul><li>An error occurred during your last " 00167 "KDE upgrade leaving an orphaned control module</li><li>You have old third party " 00168 "modules lying around.</li></ul></p><p>Check these points carefully and try to remove " 00169 "the module mentioned in the error message. If this fails, consider contacting " 00170 "your distributor or packager.</p></qt>"); 00171 } 00172 if (report & KCModuleLoader::Dialog) { 00173 KMessageBox::detailedError(parent, text, realDetails); 00174 } 00175 if (report & KCModuleLoader::Inline) { 00176 return new KCMError(text, realDetails, parent); 00177 } 00178 return 0; 00179 } 00180 00181 // vim: ts=4
KDE 4.6 API Reference