File indexing completed on 2024-12-29 05:05:45

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in>
0004     SPDX-FileCopyrightText: 2020, 2022 Alexander Lohnau <alexander.lohnau@gmx.de>
0005     SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-only
0008 */
0009 
0010 #include "kcm.h"
0011 
0012 #include <KCModuleData>
0013 #include <KCMultiDialog>
0014 #include <KConfigGroup>
0015 #include <KPluginFactory>
0016 #include <KRunner/RunnerManager>
0017 
0018 #include <QDBusConnection>
0019 #include <QDBusMessage>
0020 #include <QDBusMetaType>
0021 
0022 class KRunnerData : public KCModuleData
0023 {
0024     Q_OBJECT
0025 public:
0026     using KCModuleData::KCModuleData;
0027 
0028     bool isDefaults() const override
0029     {
0030         const QList<KPluginMetaData> runnerData = KRunner::RunnerManager::runnerMetaDataList();
0031         KConfigGroup cfgGroup(m_krunnerConfig, QStringLiteral("Plugins"));
0032         if (cfgGroup.group("Favorites").readEntry("plugins", SearchConfigModule::defaultFavoriteIds()) != SearchConfigModule::defaultFavoriteIds()) {
0033             return false;
0034         }
0035         return std::all_of(runnerData.begin(), runnerData.end(), [&cfgGroup](const KPluginMetaData &pluginData) {
0036             return pluginData.isEnabled(cfgGroup) != pluginData.isEnabledByDefault();
0037         });
0038     }
0039 
0040 private:
0041     const KSharedConfigPtr m_krunnerConfig = KSharedConfig::openConfig("krunnerrc");
0042 };
0043 
0044 K_PLUGIN_FACTORY_WITH_JSON(SearchConfigModuleFactory, "kcm_plasmasearch.json", registerPlugin<SearchConfigModule>(); registerPlugin<KRunnerData>();)
0045 
0046 SearchConfigModule::SearchConfigModule(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
0047     : KQuickManagedConfigModule(parent, data)
0048     , m_model(new KPluginModel(this))
0049     , m_config(KSharedConfig::openConfig("krunnerrc"))
0050 {
0051     qDBusRegisterMetaType<QByteArrayList>();
0052     qDBusRegisterMetaType<QHash<QString, QByteArrayList>>();
0053 
0054     if (!args.isEmpty()) {
0055         m_pluginID = args.at(0).toString();
0056     }
0057     qDBusRegisterMetaType<QByteArrayList>();
0058     qDBusRegisterMetaType<QHash<QString, QByteArrayList>>();
0059 
0060     connect(m_model, &KPluginModel::defaulted, this, [this](bool isDefaults) {
0061         checkNeedsSave();
0062         setRepresentsDefaults(isDefaults);
0063     });
0064     connect(m_model, &KPluginModel::isSaveNeededChanged, this, &SearchConfigModule::checkNeedsSave);
0065 }
0066 
0067 void SearchConfigModule::load()
0068 {
0069     reloadPlugins();
0070 
0071     if (!m_pluginID.isEmpty()) {
0072         const KPluginMetaData data = m_model->findConfigForPluginId(m_pluginID);
0073         if (data.isValid()) {
0074             showKCM(data);
0075         } else {
0076             qWarning() << "Could not find plugin with id" << m_pluginID;
0077         }
0078         m_pluginID.clear(); // Clear this to avoid showing the plugin's config again if we reset the KCM
0079     }
0080 }
0081 
0082 void SearchConfigModule::reloadPlugins()
0083 {
0084     m_model->clear();
0085 
0086     m_model->setConfig(m_config->group("Plugins"));
0087     m_initialFavs = m_config->group("Plugins").group("Favorites").readEntry("plugins", defaultFavoriteIds());
0088 
0089     QList<KPluginMetaData> metaDataList = KRunner::RunnerManager::runnerMetaDataList();
0090     auto it = std::partition(metaDataList.begin(), metaDataList.end(), [this](const KPluginMetaData &plugin) {
0091         return m_initialFavs.contains(plugin.pluginId());
0092     });
0093 
0094     m_favoriteMetaDataList = QList<KPluginMetaData>(metaDataList.begin(), it);
0095     std::sort(m_favoriteMetaDataList.begin(), m_favoriteMetaDataList.end(), [this](const KPluginMetaData &data1, const KPluginMetaData &data2) {
0096         return m_initialFavs.indexOf(data1.pluginId()) < m_initialFavs.indexOf(data2.pluginId());
0097     });
0098     m_model->addUnsortablePlugins(m_favoriteMetaDataList, m_favoriteCategory);
0099     m_model->addPlugins(QList<KPluginMetaData>(it, metaDataList.end()), m_normalCategory);
0100     setNeedsSave(false);
0101 }
0102 void SearchConfigModule::addToFavorites(const KPluginMetaData &data)
0103 {
0104     m_model->removePlugin(data);
0105     m_favoriteMetaDataList << data;
0106     m_model->addUnsortablePlugins({data}, m_favoriteCategory);
0107     checkNeedsSave();
0108 }
0109 void SearchConfigModule::removeFromFavorites(const KPluginMetaData &data)
0110 {
0111     m_model->removePlugin(data);
0112     m_favoriteMetaDataList.removeOne(data);
0113     m_model->addPlugins({data}, m_normalCategory);
0114     checkNeedsSave();
0115 }
0116 
0117 void SearchConfigModule::movePlugin(const KPluginMetaData &data, int destIndex)
0118 {
0119     m_favoriteMetaDataList.removeOne(data);
0120     m_favoriteMetaDataList.insert(destIndex, data);
0121     checkNeedsSave();
0122 
0123     for (int row = 0; row < m_model->rowCount(); ++row) {
0124         QModelIndex index = m_model->index(row, 0); // 0 for column as we don't have multiple columns
0125         QVariant value = m_model->data(index, KPluginModel::IdRole);
0126         if (value == data.pluginId()) {
0127             m_model->moveRow(QModelIndex(), index.row(), QModelIndex(), destIndex);
0128             return;
0129         }
0130     }
0131 }
0132 
0133 void SearchConfigModule::showKCM(const KPluginMetaData &data, const QVariantList args, const KPluginMetaData &krunnerPluginData) const
0134 {
0135     auto dlg = new KCMultiDialog();
0136     dlg->addModule(data, args);
0137     dlg->show();
0138     connect(dlg, qOverload<>(&KCMultiDialog::configCommitted), dlg, [krunnerPluginData]() {
0139         QDBusMessage message =
0140             QDBusMessage::createSignal(QStringLiteral("/krunnerrc"), QStringLiteral("org.kde.kconfig.notify"), QStringLiteral("ConfigChanged"));
0141         QHash<QString, QByteArrayList> changes = {
0142             {QStringLiteral("Runners"), {krunnerPluginData.pluginId().toLocal8Bit()}},
0143         };
0144         message.setArguments({QVariant::fromValue(std::move(changes))});
0145         QDBusConnection::sessionBus().send(message);
0146     });
0147 }
0148 
0149 void SearchConfigModule::save()
0150 {
0151     KQuickManagedConfigModule::save();
0152     KConfigGroup grp = m_config->group(QStringLiteral("Plugins")).group(QStringLiteral("Favorites"));
0153     grp.writeEntry("plugins", getFavPluginIds(), KConfigGroup::Notify);
0154     m_model->save();
0155 
0156     QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/krunnerrc"), QStringLiteral("org.kde.kconfig.notify"), QStringLiteral("ConfigChanged"));
0157     QHash<QString, QByteArrayList> changes{{QStringLiteral("Plugins"), {}}};
0158     message.setArguments({QVariant::fromValue(std::move(changes))});
0159     QDBusConnection::sessionBus().send(message);
0160 }
0161 
0162 void SearchConfigModule::defaults()
0163 {
0164     KQuickManagedConfigModule::defaults();
0165 
0166     m_model->defaults();
0167 }
0168 
0169 void SearchConfigModule::setDefaultIndicatorVisible(QWidget *widget, bool visible)
0170 {
0171     widget->setProperty("_kde_highlight_neutral", visible);
0172     widget->update();
0173 }
0174 
0175 #include "kcm.moc"