1/*
2 SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
3 SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
4 SPDX-FileCopyrightText: 2003, 2004, 2006 Matthias Kretz <kretz@kde.org>
5 SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
6 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
7
8 SPDX-License-Identifier: LGPL-2.0-only
9*/
10
11#include "kcmoduleloader.h"
12#include "kcmoduledata.h"
13#include "kcmoduleqml_p.h"
14#include "kquickconfigmoduleloader.h"
15#include <kcmutils_debug.h>
16
17#include <QJsonArray>
18#include <QLabel>
19#include <QLibrary>
20#include <QVBoxLayout>
21
22#include <KAboutData>
23#include <KAuthorized>
24#include <KLocalizedString>
25#include <KMessageBox>
26#include <KPluginFactory>
27#include <memory>
28#include <qqmlengine.h>
29
30#include "quick/kquickconfigmodule.h"
31
32using namespace KCModuleLoader;
33
34/*
35 * When something goes wrong in loading the module, this one
36 * jumps in as a "dummy" module.
37 */
38class KCMError : public KCModule
39{
40 Q_OBJECT
41public:
42 KCMError(const QString &msg, const QString &details, QWidget *parent)
43 : KCModule(parent, KPluginMetaData())
44 {
45 QString realDetails = details.trimmed();
46 if (realDetails.isNull()) {
47 realDetails = i18n(
48 "<qt><p>Possible reasons:<ul><li>An error occurred during your last "
49 "system upgrade, leaving an orphaned control module behind</li><li>You have old third party "
50 "modules lying around.</li></ul></p><p>Check these points carefully and try to remove "
51 "the module mentioned in the error message. If this fails, consider contacting "
52 "your distributor or packager.</p></qt>");
53 }
54
55 QVBoxLayout *topLayout = new QVBoxLayout(widget());
56 QLabel *lab = new QLabel(msg, widget());
57 {
58 // Similar to Kirigami.Heading: Primary, level 3
59 QFont font = lab->font();
60 font.setPointSizeF(font.pointSizeF() * 1.15);
61 font.setBold(true);
62 lab->setFont(font);
63 }
64 lab->setWordWrap(true);
65 lab->setTextInteractionFlags(lab->textInteractionFlags() | Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
66 topLayout->addWidget(lab);
67
68 lab = new QLabel(realDetails, widget());
69 lab->setWordWrap(true);
70 lab->setTextInteractionFlags(lab->textInteractionFlags() | Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
71 topLayout->addWidget(lab);
72 }
73};
74
75KCModule *KCModuleLoader::loadModule(const KPluginMetaData &metaData, QWidget *parent, const QVariantList &args, const std::shared_ptr<QQmlEngine> &eng)
76{
77 if (!KAuthorized::authorizeControlModule(pluginId: metaData.pluginId())) {
78 return new KCMError(i18n("The module %1 is disabled.", metaData.pluginId()), i18n("The module has been disabled by the system administrator."), parent);
79 }
80
81 const auto qmlKcm = KQuickConfigModuleLoader::loadModule(metaData, parent, args, engine: eng).plugin;
82 if (qmlKcm) {
83 if (!qmlKcm->mainUi()) {
84 return new KCMError(i18n("Error loading QML file."), qmlKcm->errorString(), parent);
85 }
86 qCDebug(KCMUTILS_LOG) << "loaded KCM" << metaData.fileName();
87 return new KCModuleQml(qmlKcm, parent);
88 }
89
90 const QVariantList pluginArgs = QVariantList(args) << metaData.rawData().value(key: QLatin1String("X-KDE-KCM-Args")).toArray().toVariantList();
91 const auto kcmoduleResult = KPluginFactory::instantiatePlugin<KCModule>(data: metaData, parent, args: pluginArgs);
92
93 if (kcmoduleResult) {
94 qCDebug(KCMUTILS_LOG) << "loaded KCM" << metaData.fileName();
95 return kcmoduleResult.plugin;
96 }
97
98 return new KCMError(QString(), kcmoduleResult.errorString, parent);
99}
100
101#include "kcmoduleloader.moc"
102

source code of kcmutils/src/kcmoduleloader.cpp