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 "qml/kquickconfigmodule.h"
31
32using namespace KCModuleLoader;
33
34/***************************************************************/
35/**
36 * When something goes wrong in loading the module, this one
37 * jumps in as a "dummy" module.
38 */
39class KCMError : public KCModule
40{
41 Q_OBJECT
42public:
43 KCMError(const QString &msg, const QString &details, QWidget *parent)
44 : KCModule(parent, KPluginMetaData())
45 {
46 QString realDetails = details.trimmed();
47 if (realDetails.isNull()) {
48 realDetails = i18n(
49 "<qt><p>Possible reasons:<ul><li>An error occurred during your last "
50 "system upgrade, leaving an orphaned control module behind</li><li>You have old third party "
51 "modules lying around.</li></ul></p><p>Check these points carefully and try to remove "
52 "the module mentioned in the error message. If this fails, consider contacting "
53 "your distributor or packager.</p></qt>");
54 }
55
56 QVBoxLayout *topLayout = new QVBoxLayout(widget());
57 QLabel *lab = new QLabel(msg, widget());
58 {
59 // Similar to Kirigami.Heading: Primary, level 3
60 QFont font = lab->font();
61 font.setPointSizeF(font.pointSizeF() * 1.15);
62 font.setBold(true);
63 lab->setFont(font);
64 }
65 lab->setWordWrap(true);
66 lab->setTextInteractionFlags(lab->textInteractionFlags() | Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
67 topLayout->addWidget(lab);
68
69 lab = new QLabel(realDetails, widget());
70 lab->setWordWrap(true);
71 lab->setTextInteractionFlags(lab->textInteractionFlags() | Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
72 topLayout->addWidget(lab);
73 }
74};
75
76KCModule *KCModuleLoader::loadModule(const KPluginMetaData &metaData, QWidget *parent, const QVariantList &args, const std::shared_ptr<QQmlEngine> &eng)
77{
78 if (!KAuthorized::authorizeControlModule(metaData.pluginId())) {
79 return new KCMError(i18n("The module %1 is disabled.", metaData.pluginId()), i18n("The module has been disabled by the system administrator."), parent);
80 }
81
82 const auto qmlKcm = KQuickConfigModuleLoader::loadModule(metaData, parent, args, eng).plugin;
83 if (qmlKcm) {
84 if (!qmlKcm->mainUi()) {
85 return new KCMError(i18n("Error loading QML file."), qmlKcm->errorString(), parent);
86 }
87 qCDebug(KCMUTILS_LOG) << "loaded KCM" << metaData.fileName();
88 return new KCModuleQml(qmlKcm, parent);
89 }
90
91 const QVariantList pluginArgs = QVariantList(args) << metaData.rawData().value(QLatin1String("X-KDE-KCM-Args")).toArray().toVariantList();
92 const auto kcmoduleResult = KPluginFactory::instantiatePlugin<KCModule>(metaData, parent, pluginArgs);
93
94 if (kcmoduleResult) {
95 qCDebug(KCMUTILS_LOG) << "loaded KCM" << metaData.fileName();
96 return kcmoduleResult.plugin;
97 }
98
99 return new KCMError(QString(), kcmoduleResult.errorString, parent);
100}
101
102#include "kcmoduleloader.moc"
103

source code of kcmutils/src/kcmoduleloader.cpp