not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / runners / powerdevil / PowerDevilRunner.cpp
blob532a7afde5467f212d989ed17758623d79c75282
1 /***************************************************************************
2 * Copyright 2008 by Dario Freddi <drf@kdemod.ath.cx> *
3 * Copyright 2008 by Sebastian Kügler <sebas@kde.org> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
19 ***************************************************************************/
21 #include "PowerDevilRunner.h"
23 #include <QDBusInterface>
24 #include <QDBusReply>
26 #include <KIcon>
27 #include <KLocale>
28 #include <KDebug>
29 #include <KDirWatch>
30 #include <KStandardDirs>
31 #include <KRun>
33 #include <solid/control/powermanager.h>
35 PowerDevilRunner::PowerDevilRunner( QObject *parent, const QVariantList &args )
36 : Plasma::AbstractRunner( parent ),
37 m_dbus( QDBusConnection::sessionBus() )
39 Q_UNUSED( args )
41 /* Let's define all the words here. m_words contains all the words that
42 * will eventually trigger a match in the runner.
44 * FIXME: I made all the words translatable, though I don't know if that's
45 * the right way to go.
48 m_words << i18nc( "Note this is a KRunner keyword", "power profile" ) <<
49 i18nc( "Note this is a KRunner keyword", "cpu policy" ) <<
50 i18nc( "Note this is a KRunner keyword", "power governor" ) <<
51 i18nc( "Note this is a KRunner keyword", "power scheme" ) <<
52 i18nc( "Note this is a KRunner keyword", "screen brightness" ) <<
53 i18nc( "Note this is a KRunner keyword", "suspend" );
55 setObjectName( "PowerDevil" );
56 updateStatus();
57 initUpdateTriggers();
60 PowerDevilRunner::~PowerDevilRunner()
64 void PowerDevilRunner::initUpdateTriggers()
67 // listen for changes to the profiles
68 KDirWatch *profilesWatch = new KDirWatch(this);
69 profilesWatch->addFile(KStandardDirs::locate("config", "powerdevilprofilesrc"));
70 connect(profilesWatch,SIGNAL(dirty(QString)),this,SLOT(updateStatus()));
71 connect(profilesWatch,SIGNAL(created(QString)),this,SLOT(updateStatus()));
72 connect(profilesWatch,SIGNAL(deleted(QString)),this,SLOT(updateStatus()));
74 // Also receive updates triggered through the DBus
75 QStringList modules;
76 QDBusInterface kdedInterface("org.kde.kded", "/kded", "org.kde.kded");
77 QDBusReply<QStringList> reply = kdedInterface.call("loadedModules");
79 if (!reply.isValid()) {
80 return;
83 modules = reply.value();
85 if (modules.contains("powerdevil")) {
86 if (!m_dbus.connect("org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil",
87 "profileChanged", this, SLOT(updateStatus()))) {
88 kDebug() << "error!";
90 if (!m_dbus.connect("org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil",
91 "stateChanged", this, SLOT(updateStatus()))) {
92 kDebug() << "error!";
95 QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.kded", "/modules/powerdevil",
96 "org.kde.PowerDevil", "streamData");
97 m_dbus.call(msg);
101 void PowerDevilRunner::updateStatus()
103 // Governors
105 QDBusMessage msg = QDBusMessage::createMethodCall( "org.kde.kded",
106 "/modules/powerdevil", "org.kde.PowerDevil", "getSupportedGovernors" );
107 QDBusReply<QVariantMap> govs = m_dbus.call( msg );
108 m_supportedGovernors = govs.value().keys();
109 foreach( const QString &governor, m_supportedGovernors ) {
110 m_governorData[governor] = govs.value()[governor].toInt();
114 // Profiles and their icons
116 KConfig *profilesConfig = new KConfig( "powerdevilprofilesrc", KConfig::SimpleConfig );
117 m_availableProfiles = profilesConfig->groupList();
118 foreach( const QString &profile, m_availableProfiles ) {
119 KConfigGroup *settings = new KConfigGroup( profilesConfig, profile );
120 if ( settings->readEntry( "iconname" ).isEmpty() ) {
121 m_profileIcon[profile] = "preferences-system-power-management";
122 } else {
123 m_profileIcon[profile] = settings->readEntry("iconname");
125 delete settings;
127 delete profilesConfig;
130 // Schemes
132 QDBusMessage msg = QDBusMessage::createMethodCall( "org.kde.kded",
133 "/modules/powerdevil", "org.kde.PowerDevil", "getSupportedSchemes" );
134 QDBusReply<QStringList> schemes = m_dbus.call( msg );
135 m_supportedSchemes = schemes.value();
138 // Suspend
140 QDBusMessage msg = QDBusMessage::createMethodCall( "org.kde.kded",
141 "/modules/powerdevil", "org.kde.PowerDevil", "getSupportedSuspendMethods" );
142 QDBusReply<QVariantMap> methods = m_dbus.call( msg );
143 m_suspendMethods = methods.value().keys();
144 foreach( const QString &method, m_suspendMethods ) {
145 m_suspendData[method] = methods.value()[method].toInt();
150 void PowerDevilRunner::match( Plasma::RunnerContext &context )
152 QString term = context.query();
154 foreach( const QString &word, m_words ) {
155 if ( term.startsWith( word, Qt::CaseInsensitive ) ) {
156 if ( word == i18nc( "Note this is a KRunner keyword", "power profile" ) ) {
157 foreach( const QString &profile, m_availableProfiles ) {
158 if ( term.split( ' ' ).count() == 3 ) {
159 if ( !profile.startsWith( term.split( ' ' ).at( 2 ) ) ) {
160 continue;
163 Plasma::QueryMatch match( this );
164 match.setType( Plasma::QueryMatch::ExactMatch );
165 match.setIcon( KIcon( m_profileIcon[profile] ) );
166 match.setText( i18n( "Set Profile to '%1'", profile ) );
167 match.setData( profile );
168 match.setRelevance( 1 );
169 match.setId( "ProfileChange" );
170 context.addMatch( term, match );
172 } else if ( word == i18nc( "Note this is a KRunner keyword", "cpu policy" ) ||
173 word == i18nc( "Note this is a KRunner keyword", "power governor" ) ) {
174 foreach( const QString &ent, m_supportedGovernors ) {
175 if ( term.split( ' ' ).count() == 3 ) {
176 if ( !ent.startsWith( term.split( ' ' ).at( 2 ) ) ) {
177 continue;
180 Plasma::QueryMatch match( this );
181 match.setType( Plasma::QueryMatch::ExactMatch );
183 switch (m_governorData[ent]) {
184 case (int) Solid::Control::PowerManager::Performance:
185 match.setIcon( KIcon( "preferences-system-performance" ) );
186 break;
187 case (int) Solid::Control::PowerManager::OnDemand:
188 match.setIcon( KIcon( "system-switch-user" ) );
189 break;
190 case (int) Solid::Control::PowerManager::Conservative:
191 match.setIcon( KIcon( "user-invisible" ) );
192 break;
193 case (int) Solid::Control::PowerManager::Powersave:
194 match.setIcon( KIcon( "preferences-system-power-management" ) );
195 break;
196 case (int) Solid::Control::PowerManager::Userspace:
197 match.setIcon( KIcon( "kuser" ) );
198 break;
199 default:
200 match.setIcon( KIcon( "preferences-system-power-management" ) );
201 break;
204 match.setText( i18n( "Set CPU frequency scaling policy to '%1'", ent ) );
205 match.setData( m_governorData[ent] );
206 match.setRelevance( 1 );
207 match.setId( "GovernorChange" );
208 context.addMatch( term, match );
210 } else if ( word == i18nc( "Note this is a KRunner keyword", "power scheme" ) ) {
211 foreach( const QString &ent, m_supportedSchemes ) {
212 if ( term.split( ' ' ).count() == 3 ) {
213 if ( !ent.startsWith( term.split( ' ' ).at( 2 ) ) ) {
214 continue;
218 Plasma::QueryMatch match( this );
220 match.setType( Plasma::QueryMatch::ExactMatch );
222 match.setIcon( KIcon( "preferences-system-power-management" ) );
223 match.setText( i18n( "Set Powersaving Scheme to '%1'", ent ) );
224 match.setData( ent );
226 match.setRelevance( 1 );
227 match.setId( "SchemeChange" );
228 context.addMatch( term, match );
230 } else if ( word == i18nc( "Note this is a KRunner keyword", "screen brightness" ) ) {
231 if ( term.split( ' ' ).count() == 3 ) {
232 bool test;
233 int b = term.split( ' ' ).at( 2 ).toInt( &test );
234 if ( test ) {
235 int brightness = qBound( 0, b, 100 );
236 Plasma::QueryMatch match( this );
237 match.setType( Plasma::QueryMatch::ExactMatch );
238 match.setIcon( KIcon( "preferences-system-power-management" ) );
239 match.setText( i18n( "Set Brightness to %1", brightness ) );
240 match.setData( brightness );
241 match.setRelevance( 1 );
242 match.setId( "BrightnessChange" );
243 context.addMatch( term, match );
245 } else if ( term.split( ' ' ).count() == 2 ) {
246 Plasma::QueryMatch match1( this );
247 match1.setType( Plasma::QueryMatch::ExactMatch );
248 match1.setIcon( KIcon( "preferences-system-power-management" ) );
249 match1.setText( i18n( "Dim screen totally" ) );
250 match1.setRelevance( 1 );
251 match1.setId( "DimTotal" );
252 context.addMatch( term, match1 );
254 Plasma::QueryMatch match2( this );
255 match2.setType( Plasma::QueryMatch::ExactMatch );
256 match2.setIcon( KIcon( "preferences-system-power-management" ) );
257 match2.setText( i18n( "Dim screen by half" ) );
258 match2.setRelevance( 1 );
259 match2.setId( "DimHalf" );
260 context.addMatch( term, match2 );
262 Plasma::QueryMatch match3( this );
263 match3.setType( Plasma::QueryMatch::ExactMatch );
264 match3.setIcon( KIcon( "video-display" ) );
265 match3.setText( i18n( "Turn off screen" ) );
266 match3.setRelevance( 1 );
267 match3.setId( "TurnOffScreen" );
268 context.addMatch( term, match3 );
270 } else if ( word == i18nc( "Note this is a KRunner keyword", "suspend" ) ) {
271 foreach( const QString &ent, m_suspendMethods ) {
272 Plasma::QueryMatch match( this );
273 match.setType( Plasma::QueryMatch::ExactMatch );
275 switch (m_suspendData[ent]) {
276 case 1:
277 case 2:
278 match.setIcon( KIcon( "system-suspend" ) );
279 break;
280 case 4:
281 match.setIcon( KIcon( "system-suspend-hibernate" ) );
282 break;
283 default:
284 match.setIcon( KIcon( "preferences-system-power-management" ) );
285 break;
288 match.setText( ent );
289 match.setData( m_suspendData[ent] );
290 match.setRelevance( 1 );
291 match.setId( "Suspend" );
292 context.addMatch( term, match );
299 void PowerDevilRunner::run( const Plasma::RunnerContext &context, const Plasma::QueryMatch &match )
301 Q_UNUSED( context )
303 QDBusInterface iface( "org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil", m_dbus );
304 if ( match.id() == "PowerDevil_ProfileChange" ) {
305 iface.call( "refreshStatus" );
306 iface.call( "setProfile", match.data().toString() );
307 } else if ( match.id() == "PowerDevil_GovernorChange" ) {
308 iface.call( "setGovernor", match.data().toInt() );
309 } else if ( match.id() == "PowerDevil_SchemeChange" ) {
310 iface.call( "setPowersavingScheme", match.data().toString() );
311 } else if ( match.id() == "PowerDevil_BrightnessChange" ) {
312 iface.call( "setBrightness", match.data().toInt() );
313 } else if ( match.id() == "PowerDevil_DimTotal" ) {
314 iface.call( "setBrightness", 0 );
315 } else if ( match.id() == "PowerDevil_DimHalf" ) {
316 iface.call( "setBrightness", -2 );
317 } else if ( match.id() == "PowerDevil_TurnOffScreen" ) {
318 iface.call( "turnOffScreen" );
319 } else if ( match.id() == "PowerDevil_Suspend" ) {
320 iface.call( "suspend", match.data().toInt() );
324 #include "PowerDevilRunner.moc"