2 * Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License version 2 as
6 * published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU Library General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "sessionrunner.h"
25 #include <KActionCollection>
26 #include <KAuthorized>
29 #include <KMessageBox>
31 #include "kworkspace/kworkspace.h"
33 #include "screensaver_interface.h"
35 SessionRunner::SessionRunner(QObject
*parent
, const QVariantList
&args
)
36 : Plasma::AbstractRunner(parent
, args
)
38 KGlobal::locale()->insertCatalog("krunner_sessions");
41 setObjectName("Sessions");
42 setPriority(LowPriority
);
43 setIgnoredTypes(Plasma::RunnerContext::Directory
| Plasma::RunnerContext::File
|
44 Plasma::RunnerContext::NetworkLocation
);
47 SessionRunner::~SessionRunner()
51 void SessionRunner::matchCommands(QList
<Plasma::QueryMatch
> &matches
, const QString
& term
)
53 if (term
.compare(i18nc("log out command","logout"), Qt::CaseInsensitive
) == 0 ||
54 term
.compare(i18n("log out"), Qt::CaseInsensitive
) == 0) {
55 Plasma::QueryMatch
match(this);
56 match
.setText(i18nc("log out command","Logout"));
57 match
.setIcon(KIcon("system-log-out"));
58 match
.setData(LogoutAction
);
59 match
.setType(Plasma::QueryMatch::ExactMatch
);
60 match
.setRelevance(0.9);
62 } else if (term
.compare(i18nc("restart computer command", "restart"), Qt::CaseInsensitive
) == 0 ||
63 term
.compare(i18nc("restart computer command", "reboot"), Qt::CaseInsensitive
) == 0) {
64 Plasma::QueryMatch
match(this);
65 match
.setText(i18n("Restart the computer"));
66 match
.setIcon(KIcon("system-restart"));
67 match
.setData(RestartAction
);
68 match
.setType(Plasma::QueryMatch::ExactMatch
);
69 match
.setRelevance(0.9);
71 } else if (term
.compare(i18nc("shutdown computer command","shutdown"), Qt::CaseInsensitive
) == 0) {
72 Plasma::QueryMatch
match(this);
73 match
.setText(i18n("Shutdown the computer"));
74 match
.setIcon(KIcon("system-shutdown"));
75 match
.setData(ShutdownAction
);
76 match
.setType(Plasma::QueryMatch::ExactMatch
);
77 match
.setRelevance(0.9);
79 } else if (term
.compare(i18nc("lock screen command","lock"), Qt::CaseInsensitive
) == 0) {
80 Plasma::QueryMatch
match(this);
81 match
.setText(i18n("Lock the screen"));
82 match
.setIcon(KIcon("system-lock-screen"));
83 match
.setData(LockAction
);
84 match
.setType(Plasma::QueryMatch::ExactMatch
);
85 match
.setRelevance(0.9);
90 void SessionRunner::match(Plasma::RunnerContext
&context
)
92 const QString term
= context
.query();
94 bool matchUser
= false;
96 QList
<Plasma::QueryMatch
> matches
;
98 if (term
.size() < 3) {
101 // first compare with SESSIONS. this must *NOT* be translated (i18n)
102 // as it is used as an internal command trigger (e.g. via d-bus),
103 // not as a user supplied query. and yes, "Ugh, magic strings"
104 bool listAll
= (term
== "SESSIONS");
107 //no luck, try switch user command
108 if (term
.startsWith(i18nc("switch user command","switch"), Qt::CaseInsensitive
)) {
109 // interestingly, this means that if one wants to switch to a
110 // session named "switch", they'd have to enter
111 // switch switch. ha!
113 // we don't know the size of 'switch' translated to your language, do we?
114 QStringList words
= term
.split(" ");
115 int switchCmdSize
= words
.at(0).size();
117 user
= term
.right(term
.size() - switchCmdSize
).trimmed();
119 // can't match anything below, since it's just "switch"
120 if (matchUser
&& user
.isEmpty()) {
124 // we know it's not SESSION or "switch <something>", so let's
125 // try some other possibilities
126 matchCommands(matches
, term
);
130 //kDebug() << "session switching to" << (listAll ? "all sessions" : term);
132 bool switchUser
= listAll
||
133 term
.compare(i18n("switch user"), Qt::CaseInsensitive
) == 0 ||
134 term
.compare(i18n("new session"), Qt::CaseInsensitive
) == 0;
137 KAuthorized::authorizeKAction("start_new_session") &&
139 dm
.numReserve() >= 0) {
140 Plasma::QueryMatch
match(this);
141 match
.setType(Plasma::QueryMatch::ExactMatch
);
142 match
.setIcon(KIcon("system-switch-user"));
143 match
.setText(i18n("New Session"));
147 // now add the active sessions
148 if (listAll
|| matchUser
) {
150 dm
.localSessions(sessions
);
152 foreach (const SessEnt
& session
, sessions
) {
153 if (!session
.vt
|| session
.self
) {
157 QString name
= KDisplayManager::sess2Str(session
);
158 Plasma::QueryMatch::Type type
= Plasma::QueryMatch::NoMatch
;
159 qreal relevance
= 0.7;
162 type
= Plasma::QueryMatch::ExactMatch
;
164 } else if (matchUser
) {
165 if (name
.compare(user
, Qt::CaseInsensitive
) == 0) {
166 // we need an elif branch here because we don't
167 // want the last conditional to be checked if !listAll
168 type
= Plasma::QueryMatch::ExactMatch
;
170 } else if (name
.contains(user
, Qt::CaseInsensitive
)) {
171 type
= Plasma::QueryMatch::PossibleMatch
;
175 if (type
!= Plasma::QueryMatch::NoMatch
) {
176 Plasma::QueryMatch
match(this);
178 match
.setRelevance(relevance
);
179 match
.setIcon(KIcon("user-identity"));
181 match
.setData(session
.session
);
187 context
.addMatches(term
, matches
);
190 void SessionRunner::run(const Plasma::RunnerContext
&context
, const Plasma::QueryMatch
&match
)
193 if (match
.data().type() == QVariant::Int
) {
194 KWorkSpace::ShutdownType type
= KWorkSpace::ShutdownTypeDefault
;
196 switch (match
.data().toInt()) {
198 type
= KWorkSpace::ShutdownTypeNone
;
201 type
= KWorkSpace::ShutdownTypeReboot
;
204 type
= KWorkSpace::ShutdownTypeHalt
;
212 if (type
!= KWorkSpace::ShutdownTypeDefault
) {
213 KWorkSpace::ShutdownConfirm confirm
= KWorkSpace::ShutdownConfirmDefault
;
214 KWorkSpace::requestShutDown(confirm
, type
);
219 if (!match
.data().toString().isEmpty()) {
220 QString sessionName
= match
.text();
223 if (dm
.localSessions(sessions
)) {
224 foreach (const SessEnt
&session
, sessions
) {
225 if (sessionName
== KDisplayManager::sess2Str(session
)) {
226 dm
.lockSwitchVT(session
.vt
);
235 //TODO: this message is too verbose and too technical.
236 int result
= KMessageBox::warningContinueCancel(
238 i18n("<p>You have chosen to open another desktop session.<br />"
239 "The current session will be hidden "
240 "and a new login screen will be displayed.<br />"
241 "An F-key is assigned to each session; "
242 "F%1 is usually assigned to the first session, "
243 "F%2 to the second session and so on. "
244 "You can switch between sessions by pressing "
245 "Ctrl, Alt and the appropriate F-key at the same time. "
246 "Additionally, the KDE Panel and Desktop menus have "
247 "actions for switching between sessions.</p>",
249 i18n("Warning - New Session"),
250 KGuiItem(i18n("&Start New Session"), "fork"),
251 KStandardGuiItem::cancel(),
252 ":confirmNewSession",
253 KMessageBox::PlainCaption
| KMessageBox::Notify
);
255 if (result
== KMessageBox::Cancel
) {
263 void SessionRunner::lock()
265 QString
interface("org.freedesktop.ScreenSaver");
266 org::freedesktop::ScreenSaver
screensaver(interface
, "/ScreenSaver",
267 QDBusConnection::sessionBus());
268 if (screensaver
.isValid()) {
273 #include "sessionrunner.moc"