File indexing completed on 2024-11-10 04:56:46

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include "genericscriptedconfig.h"
0010 
0011 #include "config-kwin.h"
0012 
0013 #include <kwineffects_interface.h>
0014 
0015 #include <KLocalizedString>
0016 #include <KLocalizedTranslator>
0017 #include <kconfigloader.h>
0018 
0019 #include <QFile>
0020 #include <QLabel>
0021 #include <QStandardPaths>
0022 #include <QUiLoader>
0023 #include <QVBoxLayout>
0024 
0025 namespace KWin
0026 {
0027 
0028 QObject *GenericScriptedConfigFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args)
0029 {
0030     if (qstrcmp(iface, "KCModule") == 0) {
0031         if (args.count() < 2) {
0032             qWarning() << Q_FUNC_INFO << "expects two arguments (plugin id, package type)";
0033             return nullptr;
0034         }
0035 
0036         const QString pluginId = args.at(0).toString();
0037         const QString packageType = args.at(1).toString();
0038 
0039         if (packageType == QLatin1StringView("KWin/Effect")) {
0040             return new ScriptedEffectConfig(pluginId, parentWidget, args);
0041         } else if (packageType == QLatin1StringView("KWin/Script")) {
0042             return new ScriptingConfig(pluginId, parentWidget, args);
0043         } else {
0044             qWarning() << Q_FUNC_INFO << "got unknown package type:" << packageType;
0045         }
0046     }
0047 
0048     return nullptr;
0049 }
0050 
0051 GenericScriptedConfig::GenericScriptedConfig(const QString &keyword, QWidget *parent, const QVariantList &args)
0052     : KCModule(parent, KPluginMetaData())
0053     , m_packageName(keyword)
0054     , m_translator(new KLocalizedTranslator(this))
0055 {
0056     QCoreApplication::instance()->installTranslator(m_translator);
0057 }
0058 
0059 GenericScriptedConfig::~GenericScriptedConfig()
0060 {
0061 }
0062 
0063 void GenericScriptedConfig::createUi()
0064 {
0065     QVBoxLayout *layout = new QVBoxLayout(widget());
0066 
0067     const QString packageRoot = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0068                                                        QLatin1String("kwin/") + typeName() + QLatin1Char('/') + m_packageName,
0069                                                        QStandardPaths::LocateDirectory);
0070     if (packageRoot.isEmpty()) {
0071         layout->addWidget(new QLabel(i18nc("Error message", "Could not locate package metadata")));
0072         return;
0073     }
0074 
0075     const KPluginMetaData metaData = KPluginMetaData::fromJsonFile(packageRoot + QLatin1String("/metadata.json"));
0076     if (!metaData.isValid()) {
0077         layout->addWidget(new QLabel(i18nc("Required file does not exist", "%1 does not contain a valid metadata.json file", qPrintable(packageRoot))));
0078         return;
0079     }
0080 
0081     const QString kconfigXTFile = packageRoot + QLatin1String("/contents/config/main.xml");
0082     if (!QFileInfo::exists(kconfigXTFile)) {
0083         layout->addWidget(new QLabel(i18nc("Required file does not exist", "%1 does not exist", qPrintable(kconfigXTFile))));
0084         return;
0085     }
0086 
0087     const QString uiPath = packageRoot + QLatin1String("/contents/ui/config.ui");
0088     if (!QFileInfo::exists(uiPath)) {
0089         layout->addWidget(new QLabel(i18nc("Required file does not exist", "%1 does not exist", qPrintable(uiPath))));
0090         return;
0091     }
0092 
0093     const QString localePath = packageRoot + QLatin1String("/contents/locale");
0094     if (QFileInfo::exists(localePath)) {
0095         KLocalizedString::addDomainLocaleDir(metaData.value("X-KWin-Config-TranslationDomain").toUtf8(), localePath);
0096     }
0097 
0098     QFile xmlFile(kconfigXTFile);
0099     KConfigGroup cg = configGroup();
0100     KConfigLoader *configLoader = new KConfigLoader(cg, &xmlFile, this);
0101     // load the ui file
0102     QUiLoader *loader = new QUiLoader(this);
0103     loader->setLanguageChangeEnabled(true);
0104     QFile uiFile(uiPath);
0105     m_translator->setTranslationDomain(metaData.value("X-KWin-Config-TranslationDomain"));
0106 
0107     uiFile.open(QFile::ReadOnly);
0108     QWidget *customConfigForm = loader->load(&uiFile, widget());
0109     m_translator->addContextToMonitor(customConfigForm->objectName());
0110     uiFile.close();
0111 
0112     // send a custom event to the translator to retranslate using our translator
0113     QEvent le(QEvent::LanguageChange);
0114     QCoreApplication::sendEvent(customConfigForm, &le);
0115 
0116     layout->addWidget(customConfigForm);
0117     addConfig(configLoader, customConfigForm);
0118 }
0119 
0120 void GenericScriptedConfig::save()
0121 {
0122     KCModule::save();
0123     reload();
0124 }
0125 
0126 void GenericScriptedConfig::reload()
0127 {
0128 }
0129 
0130 ScriptedEffectConfig::ScriptedEffectConfig(const QString &keyword, QWidget *parent, const QVariantList &args)
0131     : GenericScriptedConfig(keyword, parent, args)
0132 {
0133     createUi();
0134 }
0135 
0136 ScriptedEffectConfig::~ScriptedEffectConfig()
0137 {
0138 }
0139 
0140 QString ScriptedEffectConfig::typeName() const
0141 {
0142     return QStringLiteral("effects");
0143 }
0144 
0145 KConfigGroup ScriptedEffectConfig::configGroup()
0146 {
0147     return KSharedConfig::openConfig(KWIN_CONFIG)->group(QLatin1String("Effect-") + packageName());
0148 }
0149 
0150 void ScriptedEffectConfig::reload()
0151 {
0152     OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
0153                                          QStringLiteral("/Effects"),
0154                                          QDBusConnection::sessionBus());
0155     interface.reconfigureEffect(packageName());
0156 }
0157 
0158 ScriptingConfig::ScriptingConfig(const QString &keyword, QWidget *parent, const QVariantList &args)
0159     : GenericScriptedConfig(keyword, parent, args)
0160 {
0161     createUi();
0162 }
0163 
0164 ScriptingConfig::~ScriptingConfig()
0165 {
0166 }
0167 
0168 KConfigGroup ScriptingConfig::configGroup()
0169 {
0170     return KSharedConfig::openConfig(KWIN_CONFIG)->group(QLatin1String("Script-") + packageName());
0171 }
0172 
0173 QString ScriptingConfig::typeName() const
0174 {
0175     return QStringLiteral("scripts");
0176 }
0177 
0178 void ScriptingConfig::reload()
0179 {
0180     // TODO: what to call
0181 }
0182 
0183 } // namespace
0184 
0185 #include "moc_genericscriptedconfig.cpp"