if plasma-overlay can't talk to krunner_lock, it'll die, so that the user isn't stuck...
[kdebase.git] / workspace / plasma / shells / screensaver / containment / desktop.cpp
blobf86fe168e18eef1f2375bc7d47cb9a6392101df2
1 /*
2 * Copyright 2007 by Aaron Seigo <aseigo@kde.org>
3 * Copyright 2008 by Chani Armitage <chanika@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License version 2,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "desktop.h"
22 #include <QAction>
23 #include <QApplication>
24 //#include <QDesktopWidget>
25 #include <QGraphicsScene>
26 #include <QGraphicsView>
27 #include <QPainter>
28 #include <QDBusConnection>
29 #include <QDBusInterface>
30 #include <QDBusMessage>
32 //#include <KAuthorized>
33 #include <KDebug>
34 //#include <KWindowSystem>
35 //#include <KActionCollection>
36 #include <KConfigDialog>
38 #include "plasma/corona.h"
39 #include "plasma/theme.h"
40 //#include "kworkspace/kworkspace.h"
41 //#include "knewstuff2/engine.h"
43 //TODO offer a way to change the theme and other such not-really-our-responsibility things
45 using namespace Plasma;
47 SaverDesktop::SaverDesktop(QObject *parent, const QVariantList &args)
48 : Containment(parent, args),
49 m_lockDesktopAction(0),
50 m_appletBrowserAction(0)
54 SaverDesktop::~SaverDesktop()
58 void SaverDesktop::init()
60 Containment::init();
61 setHasConfigurationInterface(true);
63 bool unlocked = immutability() == Mutable;
64 //re-wire the lock action so we can check for a password
65 QAction *lock = action("lock widgets");
66 if (lock) {
67 lock->disconnect(this);
68 connect(lock, SIGNAL(triggered(bool)), this, SLOT(toggleLock()));
69 lock->setText(unlocked ? i18n("Lock") : i18n("Unlock"));
72 //remove the desktop actions
73 //FIXME do we really need to removeToolBoxTool?
74 QAction *unwanted = action("zoom in");
75 removeToolBoxTool(unwanted);
76 delete unwanted;
77 unwanted = action("zoom out");
78 removeToolBoxTool(unwanted);
79 delete unwanted;
80 unwanted = action("add sibling containment");
81 removeToolBoxTool(unwanted);
82 delete unwanted;
84 lock = new QAction(unlocked ? i18n("Quit") : i18n("Unlock and Quit"), this);
85 lock->setIcon(KIcon("system-lock-screen"));
86 //TODO kbd shortcut
87 lock->setShortcutContext(Qt::WidgetShortcut);
88 lock->setShortcut(QKeySequence("esc"));
89 connect(lock, SIGNAL(triggered(bool)), this, SLOT(unlockDesktop()));
90 addAction("unlock desktop", lock);
91 addToolBoxTool(lock);
93 QAction *a = action("configure");
94 if (a) {
95 a->setText(i18n("Settings"));
96 addToolBoxTool(a);
99 //rearrange the toolboxtools
100 a = action("add widgets");
101 if (a) {
102 removeToolBoxTool(a);
103 addToolBoxTool(a);
107 void SaverDesktop::constraintsEvent(Plasma::Constraints constraints)
109 if (constraints & Plasma::ImmutableConstraint) {
110 bool unlocked = immutability() == Mutable;
111 QAction *a = action("lock widgets");
112 if (a) {
113 a->setText(unlocked ? i18n("Lock") : i18n("Unlock"));
115 a = action("unlock desktop");
116 if (a) {
117 a->setText(unlocked ? i18n("Quit") : i18n("Unlock and Quit"));
122 QList<QAction*> SaverDesktop::contextualActions()
124 if (!m_appletBrowserAction) {
125 m_appletBrowserAction = action("add widgets");
126 m_lockDesktopAction = action("lock widgets");
128 QAction *config = action("configure");
130 QList<QAction*> actions;
131 actions.append(m_appletBrowserAction);
132 if (config) {
133 actions.append(config);
135 actions.append(m_lockDesktopAction);
137 return actions;
140 void SaverDesktop::paintInterface(QPainter *painter,
141 const QStyleOptionGraphicsItem *option,
142 const QRect& contentsRect)
144 //kDebug() << "paintInterface of background";
146 //TODO learn how the new wallpaper plugins work
147 painter->save();
149 if (painter->worldMatrix() == QMatrix()) {
150 // draw the background untransformed when possible;(saves lots of per-pixel-math)
151 painter->resetTransform();
154 // blit the background (saves all the per-pixel-products that blending does)
155 painter->setCompositionMode(QPainter::CompositionMode_Source);
157 QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
158 //FIXME should I use the contents rect or the exposed rect?
159 painter->fillRect(contentsRect, color);
162 // for pixmaps we draw only the exposed part (untransformed since the
163 // bitmapBackground already has the size of the viewport)
164 //painter->drawPixmap(option->exposedRect, m_bitmapBackground, option->exposedRect);
165 //kDebug() << "draw pixmap of background to" << option->exposedRect;
167 // restore transformation and composition mode
168 painter->restore();
171 void SaverDesktop::toggleLock()
173 //requre a password to unlock
174 if (!corona()) {
175 return; //I'm lazy, I know this'll never happen
177 QDBusInterface lockprocess("org.kde.krunner_lock", "/LockProcess",
178 "org.kde.krunner_lock.LockProcess", QDBusConnection::sessionBus(), this);
179 if (corona()->immutability() == Mutable) {
180 corona()->setImmutability(UserImmutable);
181 lockprocess.call(QDBus::NoBlock, "startLock");
182 kDebug() << "blaaaaaaaaaaaaaaaaa!!!!";
183 emit locked();
184 } else if (corona()->immutability() == UserImmutable) {
185 QList<QVariant> args;
186 args << i18n("Unlock Plasma Widgets");
187 bool sent = lockprocess.callWithCallback("checkPass", args, this, SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError)));
188 kDebug() << sent;
192 void SaverDesktop::unlock(QDBusMessage reply)
194 //assuming everything went as expected
195 bool success = reply.arguments().first().toBool();
196 kDebug() << success;
197 if (success) {
198 corona()->setImmutability(Mutable);
199 emit unlocked(); //FIXME bad code
203 void SaverDesktop::dbusError(QDBusError error)
205 //Q_UNUSED(error)
206 kDebug() << error.errorString(error.type());
207 kDebug() << "bailing out";
208 //ok, now i care. if it was the quit call and it failed, we shouldn't leave the user stuck in
209 //plasma-overlay forever.
210 qApp->quit();
213 void SaverDesktop::unlockDesktop()
215 QDBusInterface lockprocess("org.kde.krunner_lock", "/LockProcess",
216 "org.kde.krunner_lock.LockProcess", QDBusConnection::sessionBus(), this);
217 bool sent = (lockprocess.isValid() &&
218 lockprocess.callWithCallback("quit", QList<QVariant>(), this, SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError))));
219 //the unlock slot above is a dummy that should never be called.
220 //somehow I need a valid reply slot or the error slot is never ever used.
221 if (!sent) {
222 //ah crud.
223 kDebug() << "bailing out!";
224 qApp->quit();
228 void SaverDesktop::createConfigurationInterface(KConfigDialog *parent)
230 emit delegateConfigurationInterface(parent);
233 K_EXPORT_PLASMA_APPLET(saverdesktop, SaverDesktop)
235 #include "desktop.moc"