File indexing completed on 2024-05-12 17:10:48
0001 /*************************************************************************** 0002 * Copyright (C) 2008 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 #include "GeneralPage.h" 0021 0022 #include "ErrorOverlay.h" 0023 #include "PowerDevilSettings.h" 0024 0025 #include "actions/bundled/suspendsession.h" 0026 0027 #include "powerdevilpowermanagement.h" 0028 0029 #include <Solid/Device> 0030 #include <Solid/DeviceInterface> 0031 #include <Solid/Battery> 0032 0033 #include <QDBusMessage> 0034 #include <QDBusReply> 0035 #include <QDBusConnection> 0036 #include <QDBusConnectionInterface> 0037 #include <QDBusMetaType> 0038 #include <QDBusServiceWatcher> 0039 0040 #include <KNotifyConfigWidget> 0041 #include <KPluginFactory> 0042 #include <KSharedConfig> 0043 #include <KAboutData> 0044 #include <KLocalizedString> 0045 0046 #include <kauth_version.h> 0047 #include <KAuth/Action> 0048 #include <KAuth/ExecuteJob> 0049 0050 K_PLUGIN_CLASS_WITH_JSON(GeneralPage, "kcm_powerdevilglobalconfig.json") 0051 0052 GeneralPage::GeneralPage(QWidget *parent, const QVariantList &args) 0053 : KCModule(parent, args) 0054 { 0055 setButtons(Apply | Help); 0056 0057 // KAboutData *about = 0058 // new KAboutData("powerdevilglobalconfig", "powerdevilglobalconfig", ki18n("Global Power Management Configuration"), 0059 // "", ki18n("A global power management configurator for KDE Power Management System"), 0060 // KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), 0061 // ki18n("From this module, you can configure the main Power Management daemon, assign profiles to " 0062 // "states, and do some advanced fine tuning on battery handling")); 0063 // 0064 // about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", 0065 // "http://drfav.wordpress.com"); 0066 // 0067 // setAboutData(about); 0068 0069 setupUi(this); 0070 0071 fillUi(); 0072 0073 QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", 0074 QDBusConnection::sessionBus(), 0075 QDBusServiceWatcher::WatchForRegistration | 0076 QDBusServiceWatcher::WatchForUnregistration, 0077 this); 0078 0079 connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &GeneralPage::onServiceRegistered); 0080 connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &GeneralPage::onServiceUnregistered); 0081 0082 if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { 0083 onServiceRegistered("org.kde.Solid.PowerManagement"); 0084 } else { 0085 onServiceUnregistered("org.kde.Solid.PowerManagement"); 0086 } 0087 } 0088 0089 GeneralPage::~GeneralPage() 0090 { 0091 } 0092 0093 void GeneralPage::fillUi() 0094 { 0095 bool hasPowerSupplyBattery = false; 0096 bool hasPeripheralBattery = false; 0097 0098 const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); 0099 for (const Solid::Device &device : devices) { 0100 const Solid::Battery *b = qobject_cast<const Solid::Battery*> (device.asDeviceInterface(Solid::DeviceInterface::Battery)); 0101 if (b->isPowerSupply()) { 0102 hasPowerSupplyBattery = true; 0103 } else { 0104 hasPeripheralBattery = true; 0105 } 0106 } 0107 0108 BatteryCriticalCombo->addItem(QIcon::fromTheme("dialog-cancel"), i18n("Do nothing"), PowerDevil::BundledActions::SuspendSession::None); 0109 if (PowerDevil::PowerManagement::instance()->canSuspend()) { 0110 BatteryCriticalCombo->addItem(QIcon::fromTheme("system-suspend"), i18nc("Suspend to RAM", "Sleep"), PowerDevil::BundledActions::SuspendSession::ToRamMode); 0111 } 0112 if (PowerDevil::PowerManagement::instance()->canHibernate()) { 0113 BatteryCriticalCombo->addItem(QIcon::fromTheme("system-suspend-hibernate"), i18n("Hibernate"), PowerDevil::BundledActions::SuspendSession::ToDiskMode); 0114 } 0115 BatteryCriticalCombo->addItem(QIcon::fromTheme("system-shutdown"), i18n("Shut down"), PowerDevil::BundledActions::SuspendSession::ShutdownMode); 0116 0117 notificationsButton->setIcon(QIcon::fromTheme("preferences-desktop-notification")); 0118 0119 // modified fields... 0120 0121 connect(notificationsButton, &QAbstractButton::clicked, this, &GeneralPage::configureNotifications); 0122 0123 connect(lowSpin, SIGNAL(valueChanged(int)), SLOT(changed())); 0124 connect(criticalSpin, SIGNAL(valueChanged(int)), SLOT(changed())); 0125 connect(lowPeripheralSpin, SIGNAL(valueChanged(int)), SLOT(changed())); 0126 0127 connect(BatteryCriticalCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed())); 0128 0129 connect(chargeStartThresholdSpin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GeneralPage::markAsChanged); 0130 connect(chargeStopThresholdSpin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GeneralPage::onChargeStopThresholdChanged); 0131 chargeStopThresholdMessage->hide(); 0132 0133 connect(pausePlayersCheckBox, SIGNAL(stateChanged(int)), SLOT(changed())); 0134 0135 if (!hasPowerSupplyBattery) { 0136 BatteryCriticalLabel->hide(); 0137 BatteryCriticalCombo->hide(); 0138 lowLabel->hide(); 0139 lowSpin->hide(); 0140 criticalLabel->hide(); 0141 criticalSpin->hide(); 0142 } 0143 0144 if (!hasPeripheralBattery) { 0145 lowPeripheralLabel->hide(); 0146 lowPeripheralSpin->hide(); 0147 } 0148 0149 if (!hasPowerSupplyBattery && !hasPeripheralBattery) { 0150 batteryLevelsLabel->hide(); 0151 } 0152 } 0153 0154 void GeneralPage::load() 0155 { 0156 lowSpin->setValue(PowerDevilSettings::batteryLowLevel()); 0157 criticalSpin->setValue(PowerDevilSettings::batteryCriticalLevel()); 0158 lowPeripheralSpin->setValue(PowerDevilSettings::peripheralBatteryLowLevel()); 0159 0160 BatteryCriticalCombo->setCurrentIndex(BatteryCriticalCombo->findData(PowerDevilSettings::batteryCriticalAction())); 0161 0162 pausePlayersCheckBox->setChecked(PowerDevilSettings::pausePlayersOnSuspend()); 0163 0164 KAuth::Action action(QStringLiteral("org.kde.powerdevil.chargethresholdhelper.getthreshold")); 0165 action.setHelperId(QStringLiteral("org.kde.powerdevil.chargethresholdhelper")); 0166 KAuth::ExecuteJob *job = action.execute(); 0167 job->exec(); 0168 0169 if (!job->error()) { 0170 const auto data = job->data(); 0171 m_chargeStartThreshold = data.value(QStringLiteral("chargeStartThreshold")).toInt(); 0172 chargeStartThresholdSpin->setValue(m_chargeStartThreshold); 0173 m_chargeStopThreshold = data.value(QStringLiteral("chargeStopThreshold")).toInt(); 0174 chargeStopThresholdSpin->setValue(m_chargeStopThreshold); 0175 0176 setChargeThresholdSupported(true); 0177 } else { 0178 qDebug() << "org.kde.powerdevil.chargethresholdhelper.getthreshold failed" << job->errorText(); 0179 setChargeThresholdSupported(false); 0180 } 0181 0182 Q_EMIT changed(false); 0183 } 0184 0185 void GeneralPage::configureNotifications() 0186 { 0187 KNotifyConfigWidget::configure(this, "powerdevil"); 0188 } 0189 0190 void GeneralPage::save() 0191 { 0192 PowerDevilSettings::setBatteryLowLevel(lowSpin->value()); 0193 PowerDevilSettings::setBatteryCriticalLevel(criticalSpin->value()); 0194 PowerDevilSettings::setPeripheralBatteryLowLevel(lowPeripheralSpin->value()); 0195 0196 PowerDevilSettings::setBatteryCriticalAction(BatteryCriticalCombo->itemData(BatteryCriticalCombo->currentIndex()).toInt()); 0197 0198 PowerDevilSettings::setPausePlayersOnSuspend(pausePlayersCheckBox->checkState() == Qt::Checked); 0199 0200 PowerDevilSettings::self()->save(); 0201 0202 if ((m_chargeStartThreshold != -1 && chargeStartThresholdSpin->value() != m_chargeStartThreshold) || ( 0203 m_chargeStopThreshold != -1 && chargeStopThresholdSpin->value() != m_chargeStopThreshold)) { 0204 KAuth::Action action(QStringLiteral("org.kde.powerdevil.chargethresholdhelper.setthreshold")); 0205 action.setHelperId(QStringLiteral("org.kde.powerdevil.chargethresholdhelper")); 0206 action.setArguments({ 0207 {QStringLiteral("chargeStartThreshold"), m_chargeStartThreshold != -1 ? chargeStartThresholdSpin->value() : -1}, 0208 {QStringLiteral("chargeStopThreshold"), m_chargeStopThreshold != -1 ? chargeStopThresholdSpin->value() : -1} 0209 }); 0210 KAuth::ExecuteJob *job = action.execute(); 0211 job->exec(); 0212 if (!job->error()) { 0213 m_chargeStartThreshold = m_chargeStartThreshold != -1 ? chargeStartThresholdSpin->value() : -1; 0214 m_chargeStopThreshold = m_chargeStopThreshold != -1 ? chargeStopThresholdSpin->value() : -1; 0215 } 0216 } 0217 0218 // Notify Daemon 0219 QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", 0220 "org.kde.Solid.PowerManagement", "refreshStatus"); 0221 0222 // Perform call 0223 QDBusConnection::sessionBus().asyncCall(call); 0224 0225 // And now we are set with no change 0226 Q_EMIT changed(false); 0227 } 0228 0229 void GeneralPage::defaults() 0230 { 0231 KCModule::defaults(); 0232 } 0233 0234 void GeneralPage::setChargeThresholdSupported(bool supported) 0235 { 0236 batteryThresholdLabel->setVisible(supported); 0237 batteryThresholdExplanation->setVisible(supported); 0238 0239 chargeStartThresholdLabel->setVisible(supported && m_chargeStartThreshold != -1); 0240 chargeStartThresholdSpin->setVisible(supported && m_chargeStartThreshold != -1); 0241 0242 chargeStopThresholdLabel->setVisible(supported && m_chargeStopThreshold != -1); 0243 chargeStopThresholdSpin->setVisible(supported && m_chargeStopThreshold != -1); 0244 } 0245 0246 void GeneralPage::onServiceRegistered(const QString& service) 0247 { 0248 Q_UNUSED(service); 0249 0250 if (m_errorOverlay) { 0251 m_errorOverlay->deleteLater(); 0252 m_errorOverlay = nullptr; 0253 } 0254 } 0255 0256 void GeneralPage::onServiceUnregistered(const QString& service) 0257 { 0258 Q_UNUSED(service); 0259 0260 if (m_errorOverlay) { 0261 m_errorOverlay->deleteLater(); 0262 } 0263 0264 m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running."), 0265 this); 0266 } 0267 0268 void GeneralPage::onChargeStopThresholdChanged(int threshold) 0269 { 0270 if (threshold > m_chargeStopThreshold) { 0271 // Only show message if there is actually a charging or fully charged battery 0272 const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); 0273 for (const Solid::Device &device : devices) { 0274 const Solid::Battery *b = qobject_cast<const Solid::Battery*>(device.asDeviceInterface(Solid::DeviceInterface::Battery)); 0275 if (b->chargeState() == Solid::Battery::Charging || b->chargeState() == Solid::Battery::FullyCharged) { 0276 chargeStopThresholdMessage->animatedShow(); 0277 break; 0278 } 0279 } 0280 } else if (chargeStopThresholdMessage->isVisible()) { 0281 chargeStopThresholdMessage->animatedHide(); 0282 } 0283 0284 markAsChanged(); 0285 } 0286 0287 #include "GeneralPage.moc"