File indexing completed on 2024-05-12 17:10:47

0001 /***************************************************************************
0002  *   Copyright (C) 2008-2011 by Dario Freddi <drf@kde.org>                 *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0018  ***************************************************************************/
0019 
0020 
0021 #include "actioneditwidget.h"
0022 
0023 #include "actionconfigwidget.h"
0024 
0025 #include <powerdevilaction.h>
0026 #include <powerdevilactionconfig.h>
0027 
0028 #include <powerdevil_debug.h>
0029 
0030 #include <QCheckBox>
0031 #include <QVBoxLayout>
0032 
0033 #include <QDBusConnection>
0034 #include <QDBusMessage>
0035 #include <QDBusPendingReply>
0036 
0037 #include <KConfigGroup>
0038 #include <KPluginFactory>
0039 #include <KPluginMetaData>
0040 #include <QDebug>
0041 
0042 ActionEditWidget::ActionEditWidget(const QString &configName, QWidget *parent)
0043     : QWidget(parent)
0044     , m_configName(configName)
0045     , m_profilesConfig(KSharedConfig::openConfig(QStringLiteral("powermanagementprofilesrc"), KConfig::SimpleConfig | KConfig::CascadeConfig))
0046 {
0047     ActionConfigWidget *actionConfigWidget = new ActionConfigWidget(nullptr);
0048     QMultiMap< int, QList<QPair<QString, QWidget*> > > widgets;
0049 
0050     // Load all the plugins
0051     const QVector<KPluginMetaData> offers = KPluginMetaData::findPlugins(QStringLiteral("powerdevil/action"));
0052 
0053     for (const KPluginMetaData &offer : offers) {
0054         // Does it have a runtime requirement?
0055         if (offer.value(QStringLiteral("X-KDE-PowerDevil-Action-HasRuntimeRequirement"), false)) {
0056             qCDebug(POWERDEVIL) << offer.name() << " has a runtime requirement";
0057 
0058             QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement",
0059                                                                "org.kde.Solid.PowerManagement", "isActionSupported");
0060             call.setArguments(QVariantList() << offer.value("X-KDE-PowerDevil-Action-ID"));
0061             QDBusPendingReply< bool > reply = QDBusConnection::sessionBus().asyncCall(call);
0062             reply.waitForFinished();
0063 
0064             if (reply.isValid()) {
0065                 if (!reply.value()) {
0066                     qCDebug(POWERDEVIL) << "The action " << offer.value("X-KDE-PowerDevil-Action-ID") << " appears not to be supported by the core.";
0067                     continue;
0068                 }
0069             } else {
0070                 qCDebug(POWERDEVIL) << "There was a problem in contacting DBus!! Assuming the action is ok.";
0071             }
0072         }
0073 
0074         //try to load the specified library
0075         KPluginMetaData uiLib(QJsonObject(), offer.value(QStringLiteral("X-KDE-PowerDevil-Action-UIComponentLibrary")));
0076         auto actionConfig = KPluginFactory::instantiatePlugin<PowerDevil::ActionConfig>(uiLib).plugin;
0077         if (!actionConfig) {
0078             continue;
0079         }
0080 
0081         connect(actionConfig, &PowerDevil::ActionConfig::changed, this, &ActionEditWidget::onChanged);
0082 
0083         QCheckBox *checkbox = new QCheckBox(offer.name());
0084         connect(checkbox, &QCheckBox::stateChanged, this, &ActionEditWidget::onChanged);
0085         m_actionsHash.insert(offer.value(QStringLiteral("X-KDE-PowerDevil-Action-ID")), checkbox);
0086         m_actionsConfigHash.insert(offer.value(QStringLiteral("X-KDE-PowerDevil-Action-ID")), actionConfig);
0087 
0088         QList<QPair<QString, QWidget*> > offerWidgets = actionConfig->buildUi();
0089         offerWidgets.prepend(qMakePair<QString,QWidget*>(QString(), checkbox));
0090         widgets.insert(100 - offer.value(QStringLiteral("X-KDE-PowerDevil-Action-ConfigPriority"), 0), offerWidgets);
0091     }
0092 
0093     for (QMultiMap< int, QList<QPair<QString, QWidget*> > >::const_iterator i = widgets.constBegin(); i != widgets.constEnd(); ++i) {
0094         actionConfigWidget->addWidgets(i.value());
0095     }
0096 
0097     QVBoxLayout *lay = new QVBoxLayout(this);
0098     lay->addWidget(actionConfigWidget);
0099     lay->addStretch();
0100     setLayout(lay);
0101 }
0102 
0103 ActionEditWidget::~ActionEditWidget()
0104 {
0105 
0106 }
0107 
0108 void ActionEditWidget::load()
0109 {
0110     KConfigGroup group = configGroup();
0111 
0112     qCDebug(POWERDEVIL) << m_profilesConfig.data()->entryMap().keys();
0113 
0114     if (!group.isValid()) {
0115         return;
0116     }
0117     qCDebug(POWERDEVIL) << "Ok, KConfigGroup ready" << group.entryMap().keys();
0118 
0119     // Iterate over the possible actions
0120     for (QHash< QString, QCheckBox* >::const_iterator i = m_actionsHash.constBegin(); i != m_actionsHash.constEnd(); ++i) {
0121         i.value()->setChecked(group.groupList().contains(i.key()));
0122 
0123         KConfigGroup actionGroup = group.group(i.key());
0124         m_actionsConfigHash[i.key()]->setConfigGroup(actionGroup);
0125         m_actionsConfigHash[i.key()]->load();
0126     }
0127 
0128     Q_EMIT changed(false);
0129 }
0130 
0131 void ActionEditWidget::save()
0132 {
0133     KConfigGroup group = configGroup();
0134 
0135     if (!group.isValid()) {
0136         qCDebug(POWERDEVIL) << "Could not perform a save operation, group is not valid!";
0137         return;
0138     }
0139 
0140     // Iterate over the possible actions
0141     for (QHash< QString, QCheckBox* >::const_iterator i = m_actionsHash.constBegin(); i != m_actionsHash.constEnd(); ++i) {
0142         if (i.value()->isChecked()) {
0143             // Perform the actual save
0144             m_actionsConfigHash[i.key()]->save();
0145         } else {
0146             // Erase the group
0147             group.deleteGroup(i.key());
0148         }
0149     }
0150 
0151     group.sync();
0152 
0153     // After saving, reload the config to make sure we'll pick up changes.
0154     m_profilesConfig.data()->reparseConfiguration();
0155 
0156     Q_EMIT changed(false);
0157 }
0158 
0159 void ActionEditWidget::onChanged()
0160 {
0161     Q_EMIT changed(true);
0162 }
0163 
0164 QString ActionEditWidget::configName() const
0165 {
0166     return m_configName;
0167 }
0168 
0169 KConfigGroup ActionEditWidget::configGroup()
0170 {
0171     if (!m_configName.contains('/')) {
0172         return KConfigGroup(m_profilesConfig, m_configName);
0173     } else {
0174         QStringList names = m_configName.split('/');
0175         KConfigGroup retgroup(m_profilesConfig, names.first());
0176 
0177         QStringList::const_iterator i = names.constBegin();
0178         ++i;
0179 
0180         while (i != names.constEnd()) {
0181             retgroup = retgroup.group(*i);
0182             ++i;
0183         }
0184 
0185         return retgroup;
0186     }
0187 }