2 Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
3 Copyright (c) 2000 Matthias Elter <elter@kde.org>
4 Copyright (c) 2003,2004,2006 Matthias Kretz <kretz@kde.org>
5 Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
7 This file is part of the KDE project
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License version 2, as published by the Free Software Foundation.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
24 #include "kcmoduleloader.h"
26 #include <QtCore/QFile>
27 #include <QtGui/QLabel>
28 #include <QtGui/QLayout>
30 #include <kpluginloader.h>
33 #include <kmessagebox.h>
34 #include <klibloader.h>
36 using namespace KCModuleLoader
;
38 /***************************************************************/
40 * When something goes wrong in loading the module, this one
41 * jumps in as a "dummy" module.
43 class KCMError
: public KCModule
46 KCMError( const QString
& msg
, const QString
& details
, QWidget
* parent
)
47 : KCModule( KGlobal::mainComponent(), parent
)
49 QVBoxLayout
* topLayout
= new QVBoxLayout( this );
50 QLabel
*lab
= new QLabel( msg
, this );
51 lab
->setWordWrap(true);
52 topLayout
->addWidget( lab
);
53 lab
= new QLabel(details
, this );
54 lab
->setWordWrap(true);
55 topLayout
->addWidget( lab
);
58 /***************************************************************/
60 KCModule
*KCModuleLoader::loadModule(const QString
&module
, ErrorReporting report
, QWidget
*parent
, const QStringList
&args
)
62 return loadModule( KCModuleInfo( module
), report
, parent
, args
);
65 KCModule
* KCModuleLoader::loadModule(const KCModuleInfo
& mod
, ErrorReporting report
, QWidget
* parent
, const QStringList
& args
)
68 * Simple libraries as modules are the easiest case:
69 * We just have to load the library and get the module
74 return reportError( report
,
75 i18n("The module %1 could not be found.",
76 mod
.moduleName() ), i18n("<qt><p>The diagnostics is:<br />The desktop file %1 could not be found.</p></qt>", mod
.fileName()), parent
);
77 if( mod
.service()->noDisplay() )
78 return reportError( report
, i18n( "The module %1 is disabled.", mod
.moduleName() ),
79 i18n( "<qt><p>Either the hardware/software the module configures is not available or the module has been disabled by the administrator.</p></qt>" ),
82 if (!mod
.library().isEmpty())
86 foreach (const QString
&arg
, args
) {
89 KCModule
*module
= KService::createInstance
<KCModule
>(mod
.service(), parent
, args2
, &error
);
93 // might be using K_EXPORT_COMPONENT_FACTORY
95 module
= KService::createInstance
<KCModule
>(mod
.service(), parent
, args
, &error2
);
97 kWarning(1208) << "This module still uses K_EXPORT_COMPONENT_FACTORY. Please port it to use KPluginFactory and K_EXPORT_PLUGIN.";
100 error
+= KLibLoader::errorString(error2
);
103 // get the create_ function
104 KLibrary
*lib
= KLibLoader::self()->library(mod
.library());
106 KCModule
*(*create
)(QWidget
*, const char *);
107 QByteArray
factorymethod("create_");
108 factorymethod
+= mod
.handle().toLatin1();
109 create
= reinterpret_cast<KCModule
*(*)(QWidget
*, const char*)>(lib
->resolveFunction(factorymethod
));
111 return create(parent
, mod
.handle().toLatin1());
112 kFatal(1208) << "This module still uses a custom factory method (" << factorymethod
<< "). This is not supported anymore. Please fix the module.";
114 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";
120 return reportError(report
, error
, QString(), parent
);
124 * Ok, we could not load the library.
125 * Try to run it as an executable.
126 * This must not be done when calling from kcmshell, or you'll
127 * have infinite recursion
128 * (startService calls kcmshell which calls modloader which calls startService...)
131 return reportError( report
,
132 i18n("The module %1 is not a valid configuration module.", mod
.moduleName() ),
133 i18n("<qt>The diagnostics is:<br />The desktop file %1 does not specify a library.</qt>", mod
.fileName()), parent
);
137 void KCModuleLoader::unloadModule(const KCModuleInfo
&mod
)
139 // get the library loader instance
140 KLibLoader
*loader
= KLibLoader::self();
142 // try to unload the library
143 QString
libname("lib%1");
144 loader
->unloadLibrary(libname
.arg(mod
.library()));
146 loader
->unloadLibrary(mod
.library());
149 void KCModuleLoader::showLastLoaderError(QWidget
*parent
)
151 KMessageBox::detailedError(parent
,
152 i18n("There was an error loading the module."),i18n("<qt>The diagnostics is:<br />%1"
153 "<p>Possible reasons:</p><ul><li>An error occurred during your last "
154 "KDE upgrade leaving an orphaned control module</li><li>You have old third party "
155 "modules lying around.</li></ul><p>Check these points carefully and try to remove "
156 "the module mentioned in the error message. If this fails, consider contacting "
157 "your distributor or packager.</p></qt>",
158 KLibLoader::self()->lastErrorMessage()));
162 KCModule
* KCModuleLoader::reportError( ErrorReporting report
, const QString
& text
,
163 const QString
&details
, QWidget
* parent
)
165 QString realDetails
= details
;
166 if (realDetails
.isNull()) {
167 realDetails
= i18n("<qt><p>Possible reasons:<ul><li>An error occurred during your last "
168 "KDE upgrade leaving an orphaned control module</li><li>You have old third party "
169 "modules lying around.</li></ul></p><p>Check these points carefully and try to remove "
170 "the module mentioned in the error message. If this fails, consider contacting "
171 "your distributor or packager.</p></qt>");
173 if (report
& KCModuleLoader::Dialog
) {
174 KMessageBox::detailedError(parent
, text
, realDetails
);
176 if (report
& KCModuleLoader::Inline
) {
177 return new KCMError(text
, realDetails
, parent
);