1 /***************************************************************************
2 * Copyright 2008 by Dario Freddi <drf@kdemod.ath.cx> *
3 * Copyright 2008 by Sebastian Kügler <sebas@kde.org> *
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. *
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. *
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>
30 #include <KStandardDirs>
33 #include <solid/control/powermanager.h>
35 PowerDevilRunner::PowerDevilRunner( QObject
*parent
, const QVariantList
&args
)
36 : Plasma::AbstractRunner( parent
),
37 m_dbus( QDBusConnection::sessionBus() )
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" );
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
76 QDBusInterface
kdedInterface("org.kde.kded", "/kded", "org.kde.kded");
77 QDBusReply
<QStringList
> reply
= kdedInterface
.call("loadedModules");
79 if (!reply
.isValid()) {
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()))) {
90 if (!m_dbus
.connect("org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil",
91 "stateChanged", this, SLOT(updateStatus()))) {
95 QDBusMessage msg
= QDBusMessage::createMethodCall("org.kde.kded", "/modules/powerdevil",
96 "org.kde.PowerDevil", "streamData");
101 void PowerDevilRunner::updateStatus()
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";
123 m_profileIcon
[profile
] = settings
->readEntry("iconname");
127 delete profilesConfig
;
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();
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 ) ) ) {
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 ) ) ) {
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" ) );
187 case (int) Solid::Control::PowerManager::OnDemand
:
188 match
.setIcon( KIcon( "system-switch-user" ) );
190 case (int) Solid::Control::PowerManager::Conservative
:
191 match
.setIcon( KIcon( "user-invisible" ) );
193 case (int) Solid::Control::PowerManager::Powersave
:
194 match
.setIcon( KIcon( "preferences-system-power-management" ) );
196 case (int) Solid::Control::PowerManager::Userspace
:
197 match
.setIcon( KIcon( "kuser" ) );
200 match
.setIcon( KIcon( "preferences-system-power-management" ) );
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 ) ) ) {
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 ) {
233 int b
= term
.split( ' ' ).at( 2 ).toInt( &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
]) {
278 match
.setIcon( KIcon( "system-suspend" ) );
281 match
.setIcon( KIcon( "system-suspend-hibernate" ) );
284 match
.setIcon( KIcon( "preferences-system-power-management" ) );
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
)
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"