File indexing completed on 2024-05-12 17:10:48
0001 /*************************************************************************** 0002 * Copyright (C) 2008-2010 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 "EditPage.h" 0021 0022 #include "actioneditwidget.h" 0023 #include "ErrorOverlay.h" 0024 0025 #include <powerdevilactionconfig.h> 0026 #include <powerdevilprofilegenerator.h> 0027 #include <powerdevilpowermanagement.h> 0028 0029 #include <powerdevil_debug.h> 0030 #include <Kirigami/TabletModeWatcher> 0031 0032 #include <QCheckBox> 0033 #include <QFormLayout> 0034 #include <QLabel> 0035 #include <QTabBar> 0036 0037 #include <QDBusMessage> 0038 #include <QDBusReply> 0039 #include <QDBusConnection> 0040 #include <QDBusConnectionInterface> 0041 #include <QDBusMetaType> 0042 #include <QDBusServiceWatcher> 0043 0044 #include <KConfigGroup> 0045 #include <QDebug> 0046 #include <KMessageBox> 0047 #include <KAboutData> 0048 #include <KPluginFactory> 0049 #include <KLocalizedString> 0050 0051 #include <Solid/Battery> 0052 #include <Solid/Device> 0053 0054 K_PLUGIN_CLASS_WITH_JSON(EditPage, "kcm_powerdevilprofilesconfig.json") 0055 0056 EditPage::EditPage(QWidget *parent, const QVariantList &args) 0057 : KCModule(parent, args) 0058 { 0059 setButtons(Apply | Help | Default); 0060 0061 // KAboutData *about = 0062 // new KAboutData("powerdevilprofilesconfig", "powerdevilprofilesconfig", ki18n("Power Profiles Configuration"), 0063 // "", ki18n("A profile configurator for KDE Power Management System"), 0064 // KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), 0065 // ki18n("From this module, you can manage KDE Power Management System's power profiles, by tweaking " 0066 // "existing ones or creating new ones.")); 0067 // 0068 // about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", 0069 // "http://drfav.wordpress.com"); 0070 // 0071 // setAboutData(about); 0072 0073 setupUi(this); 0074 0075 m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig); 0076 0077 if (m_profilesConfig->groupList().isEmpty()) { 0078 auto interface = Kirigami::TabletModeWatcher::self(); 0079 0080 PowerDevil::ProfileGenerator::generateProfiles( 0081 interface->isTabletMode(), 0082 PowerDevil::PowerManagement::instance()->isVirtualMachine(), 0083 PowerDevil::PowerManagement::instance()->canSuspend(), 0084 PowerDevil::PowerManagement::instance()->canHibernate() 0085 ); 0086 m_profilesConfig->reparseConfiguration(); 0087 } 0088 0089 qCDebug(POWERDEVIL) << "loaded profiles" << m_profilesConfig.data()->groupList() << m_profilesConfig.data()->entryMap().keys(); 0090 0091 // Create widgets for each profile 0092 ActionEditWidget *editWidget = new ActionEditWidget("AC", tabWidget); 0093 m_editWidgets.insert("AC", editWidget); 0094 acWidgetLayout->addWidget(editWidget); 0095 connect(editWidget, &ActionEditWidget::changed, this, &EditPage::onChanged); 0096 0097 editWidget = new ActionEditWidget("Battery", tabWidget); 0098 m_editWidgets.insert("Battery", editWidget); 0099 batteryWidgetLayout->addWidget(editWidget); 0100 connect(editWidget, &ActionEditWidget::changed, this, &EditPage::onChanged); 0101 0102 editWidget = new ActionEditWidget("LowBattery", tabWidget); 0103 m_editWidgets.insert("LowBattery", editWidget); 0104 lowBatteryWidgetLayout->addWidget(editWidget); 0105 connect(editWidget, &ActionEditWidget::changed, this, &EditPage::onChanged); 0106 0107 QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", 0108 QDBusConnection::sessionBus(), 0109 QDBusServiceWatcher::WatchForRegistration | 0110 QDBusServiceWatcher::WatchForUnregistration, 0111 this); 0112 0113 connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &EditPage::onServiceRegistered); 0114 connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &EditPage::onServiceUnregistered); 0115 0116 bool hasBattery = false; 0117 const auto batteries = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); 0118 for(const Solid::Device &device : batteries) { 0119 const Solid::Battery *b = qobject_cast<const Solid::Battery*> (device.asDeviceInterface(Solid::DeviceInterface::Battery)); 0120 if (b->isPowerSupply() && (b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery)) { 0121 hasBattery = true; 0122 break; 0123 } 0124 } 0125 0126 if (!hasBattery) { 0127 tabWidget->setTabEnabled(1, false); 0128 tabWidget->setTabEnabled(2, false); 0129 tabWidget->tabBar()->hide(); 0130 } 0131 0132 if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { 0133 onServiceRegistered("org.kde.Solid.PowerManagement"); 0134 } else { 0135 onServiceUnregistered("org.kde.Solid.PowerManagement"); 0136 } 0137 } 0138 0139 void EditPage::onChanged(bool value) 0140 { 0141 ActionEditWidget *editWidget = qobject_cast< ActionEditWidget* >(sender()); 0142 if (!editWidget) { 0143 return; 0144 } 0145 0146 m_profileEdited[editWidget->configName()] = value; 0147 0148 if (value) { 0149 Q_EMIT changed(true); 0150 } 0151 0152 checkAndEmitChanged(); 0153 } 0154 0155 void EditPage::load() 0156 { 0157 qCDebug(POWERDEVIL) << "Loading routine called"; 0158 for (QHash< QString, ActionEditWidget* >::const_iterator i = m_editWidgets.constBegin(); 0159 i != m_editWidgets.constEnd(); ++i) { 0160 i.value()->load(); 0161 0162 m_profileEdited[i.value()->configName()] = false; 0163 } 0164 } 0165 0166 void EditPage::save() 0167 { 0168 for (auto it = m_editWidgets.constBegin(); it != m_editWidgets.constEnd(); ++it) { 0169 (*it)->save(); 0170 } 0171 0172 notifyDaemon(); 0173 0174 Q_EMIT changed(false); 0175 } 0176 0177 void EditPage::notifyDaemon() 0178 { 0179 QDBusConnection::sessionBus().asyncCall( 0180 QDBusMessage::createMethodCall( 0181 QStringLiteral("org.kde.Solid.PowerManagement"), 0182 QStringLiteral("/org/kde/Solid/PowerManagement"), 0183 QStringLiteral("org.kde.Solid.PowerManagement"), 0184 QStringLiteral("refreshStatus") 0185 ) 0186 ); 0187 } 0188 0189 void EditPage::restoreDefaultProfiles() 0190 { 0191 // Confirm 0192 int ret = KMessageBox::warningContinueCancel(this, i18n("The KDE Power Management System will now generate a set of defaults " 0193 "based on your computer's capabilities. This will also erase " 0194 "all existing modifications you made. " 0195 "Are you sure you want to continue?"), i18n("Restore Default Profiles")); 0196 if (ret == KMessageBox::Continue) { 0197 qCDebug(POWERDEVIL) << "Restoring defaults."; 0198 auto interface = Kirigami::TabletModeWatcher::self(); 0199 0200 PowerDevil::ProfileGenerator::generateProfiles( 0201 interface->isTabletMode(), 0202 PowerDevil::PowerManagement::instance()->isVirtualMachine(), 0203 PowerDevil::PowerManagement::instance()->canSuspend(), 0204 PowerDevil::PowerManagement::instance()->canHibernate() 0205 ); 0206 0207 load(); 0208 0209 notifyDaemon(); 0210 } 0211 } 0212 0213 void EditPage::defaults() 0214 { 0215 restoreDefaultProfiles(); 0216 } 0217 0218 void EditPage::checkAndEmitChanged() 0219 { 0220 bool value = false; 0221 for (QHash< QString, bool >::const_iterator i = m_profileEdited.constBegin(); 0222 i != m_profileEdited.constEnd(); ++i) { 0223 if (i.value()) { 0224 value = i.value(); 0225 } 0226 } 0227 0228 Q_EMIT changed(value); 0229 } 0230 0231 void EditPage::onServiceRegistered(const QString& service) 0232 { 0233 Q_UNUSED(service); 0234 0235 QDBusPendingCallWatcher *currentProfileWatcher = new QDBusPendingCallWatcher(QDBusConnection::sessionBus().asyncCall( 0236 QDBusMessage::createMethodCall( 0237 QStringLiteral("org.kde.Solid.PowerManagement"), 0238 QStringLiteral("/org/kde/Solid/PowerManagement"), 0239 QStringLiteral("org.kde.Solid.PowerManagement"), 0240 QStringLiteral("currentProfile") 0241 ) 0242 ), this); 0243 0244 QObject::connect(currentProfileWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { 0245 QDBusPendingReply<QString> reply = *watcher; 0246 0247 if (!reply.isError()) { 0248 const QString ¤tProfile = reply.value(); 0249 if (currentProfile == QLatin1String("Battery")) { 0250 tabWidget->setCurrentIndex(1); 0251 } else if (currentProfile == QLatin1String("LowBattery")) { 0252 tabWidget->setCurrentIndex(2); 0253 } 0254 } 0255 0256 watcher->deleteLater(); 0257 }); 0258 0259 if (m_errorOverlay) { 0260 m_errorOverlay->deleteLater(); 0261 m_errorOverlay = nullptr; 0262 } 0263 } 0264 0265 void EditPage::onServiceUnregistered(const QString& service) 0266 { 0267 Q_UNUSED(service); 0268 0269 if (m_errorOverlay) { 0270 m_errorOverlay->deleteLater(); 0271 } 0272 0273 m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running."), 0274 this); 0275 } 0276 0277 #include "EditPage.moc"