~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to krunner/krunnerapp.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
 
3
 *
 
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
 
7
 *
 
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
 
12
 *
 
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.
 
17
 */
 
18
 
 
19
#include "krunnerapp.h"
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <unistd.h>
 
24
 
 
25
#include <QClipboard>
 
26
#include <QObject>
 
27
#include <QProcess>
 
28
#include <QTimer>
 
29
#include <QtDBus/QtDBus>
 
30
#include <QLineEdit>
 
31
 
 
32
#include <KAction>
 
33
#include <KActionCollection>
 
34
#include <KCrash>
 
35
#include <KDialog>
 
36
#include <KAuthorized>
 
37
#include <KGlobalAccel>
 
38
#include <KGlobalSettings>
 
39
#include <KLocale>
 
40
#include <KMessageBox>
 
41
#include <KWindowSystem>
 
42
 
 
43
#include <Plasma/RunnerManager>
 
44
#include <Plasma/AbstractRunner>
 
45
 
 
46
#include "kworkspace/kdisplaymanager.h"
 
47
#include "panelshadows.h"
 
48
 
 
49
#include "appadaptor.h"
 
50
#include "kworkspace.h"
 
51
#include "ksystemactivitydialog.h"
 
52
#include "interfaces/default/interface.h"
 
53
#include "interfaces/quicksand/qs_dialog.h"
 
54
#ifdef Q_WS_X11
 
55
#include "startupid.h"
 
56
#endif
 
57
#include "klaunchsettings.h"
 
58
#include "krunnersettings.h"
 
59
 
 
60
#ifdef Q_WS_X11
 
61
#include <X11/extensions/Xrender.h>
 
62
#endif
 
63
 
 
64
KRunnerApp* KRunnerApp::self()
 
65
{
 
66
    if (!kapp) {
 
67
        return new KRunnerApp();
 
68
    }
 
69
 
 
70
    return qobject_cast<KRunnerApp*>(kapp);
 
71
}
 
72
 
 
73
KRunnerApp::KRunnerApp()
 
74
    : KUniqueApplication(),
 
75
      m_interface(0),
 
76
      m_shadows(new PanelShadows(this)),
 
77
      m_tasks(0),
 
78
      m_startupId(NULL),
 
79
      m_firstTime(true)
 
80
{
 
81
    initialize();
 
82
    connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanUp()));
 
83
}
 
84
 
 
85
KRunnerApp::~KRunnerApp()
 
86
{
 
87
}
 
88
 
 
89
void KRunnerApp::cleanUp()
 
90
{
 
91
    disconnect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
 
92
    kDebug() << "deleting interface";
 
93
    delete m_shadows;
 
94
    delete m_interface;
 
95
    m_interface = 0;
 
96
    delete m_runnerManager;
 
97
    m_runnerManager = 0;
 
98
#ifndef Q_WS_WIN
 
99
    delete m_tasks;
 
100
    m_tasks = 0;
 
101
#endif
 
102
    KGlobal::config()->sync();
 
103
}
 
104
 
 
105
KActionCollection* KRunnerApp::actionCollection()
 
106
{
 
107
    return m_actionCollection;
 
108
}
 
109
 
 
110
void KRunnerApp::initialize()
 
111
{
 
112
    setWindowIcon(KIcon(QLatin1String("system-run")));
 
113
 
 
114
    setQuitOnLastWindowClosed(false);
 
115
    KCrash::setFlags(KCrash::AutoRestart);
 
116
    initializeStartupNotification();
 
117
 
 
118
    connect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
 
119
 
 
120
    m_runnerManager = new Plasma::RunnerManager;
 
121
 
 
122
    new AppAdaptor(this);
 
123
    QDBusConnection::sessionBus().registerObject(QLatin1String("/App"), this);
 
124
 
 
125
    // Global keys
 
126
    m_actionCollection = new KActionCollection(this);
 
127
    KAction* a = 0;
 
128
 
 
129
    if (KAuthorized::authorize(QLatin1String("run_command"))) {
 
130
        a = m_actionCollection->addAction(QLatin1String("Run Command"));
 
131
        a->setText(i18n("Run Command"));
 
132
        a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::Key_F2));
 
133
        connect(a, SIGNAL(triggered(bool)), SLOT(displayOrHide()));
 
134
 
 
135
        a = m_actionCollection->addAction(QLatin1String("Run Command on clipboard contents"));
 
136
        a->setText(i18n("Run Command on clipboard contents"));
 
137
        a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::SHIFT+Qt::Key_F2));
 
138
        connect(a, SIGNAL(triggered(bool)), SLOT(displayWithClipboardContents()));
 
139
    }
 
140
 
 
141
    a = m_actionCollection->addAction(QLatin1String("Show System Activity"));
 
142
    a->setText(i18n("Show System Activity"));
 
143
    a->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_Escape));
 
144
    connect(a, SIGNAL(triggered(bool)), SLOT(showTaskManager()));
 
145
 
 
146
    if (KAuthorized::authorize(QLatin1String("switch_user"))) {
 
147
        a = m_actionCollection->addAction(QLatin1String("Switch User"));
 
148
        a->setText(i18n("Switch User"));
 
149
        a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_Insert));
 
150
        connect(a, SIGNAL(triggered(bool)), SLOT(switchUser()));
 
151
    }
 
152
 
 
153
    //FIXME: lock/logout should be in the session management runner which also provides similar
 
154
    // functions
 
155
#ifdef Q_WS_X11
 
156
    if (KAuthorized::authorize(QLatin1String("lock_screen"))) {
 
157
        a = m_actionCollection->addAction(QLatin1String("Lock Session"));
 
158
        a->setText(i18n("Lock Session"));
 
159
        a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_L));
 
160
        connect(a, SIGNAL(triggered(bool)), &m_saver, SLOT(Lock()));
 
161
    }
 
162
#endif
 
163
 
 
164
    //Setup the interface after we have set up the actions
 
165
    //TODO: if !KAuthorized::authorize("run_comand") (and !"switch_user" i suppose?)
 
166
    //      then we probably don't need the interface at all. would be another place
 
167
    //      for some small improvements in footprint in that case
 
168
    switch (KRunnerSettings::interface()) {
 
169
        default:
 
170
        case KRunnerSettings::EnumInterface::CommandOriented:
 
171
            m_interface = new Interface(m_runnerManager);
 
172
            break;
 
173
        case KRunnerSettings::EnumInterface::TaskOriented:
 
174
            m_interface = new QsDialog(m_runnerManager);
 
175
            break;
 
176
    }
 
177
 
 
178
    m_shadows->addWindow(m_interface);
 
179
 
 
180
#ifdef Q_WS_X11
 
181
    //FIXME: if argb visuals enabled Qt will always set WM_CLASS as "qt-subapplication" no matter what
 
182
    //the application name is we set the proper XClassHint here, hopefully won't be necessary anymore when
 
183
    //qapplication will manage apps with argvisuals in a better way
 
184
    XClassHint classHint;
 
185
    classHint.res_name = const_cast<char*>("krunner");
 
186
    classHint.res_class = const_cast<char*>("krunner");
 
187
    XSetClassHint(QX11Info::display(), m_interface->winId(), &classHint);
 
188
#endif
 
189
 
 
190
 
 
191
    m_actionCollection->readSettings();
 
192
    if (KAuthorized::authorize(QLatin1String("run_command"))) {
 
193
        //m_runnerManager->setAllowedRunners(QStringList() << "shell");
 
194
        m_runnerManager->reloadConfiguration(); // pre-load the runners
 
195
 
 
196
        // Single runner mode actions shortcuts
 
197
 
 
198
        foreach (const QString &runnerId, m_runnerManager->singleModeAdvertisedRunnerIds()) {
 
199
            a = m_actionCollection->addAction(runnerId);
 
200
            a->setText(i18nc("Run krunner restricting the search only to runner %1", "Run Command (runner \"%1\" only)",
 
201
                       m_runnerManager->runnerName(runnerId)));
 
202
            a->setGlobalShortcut(KShortcut());
 
203
            connect(a, SIGNAL(triggered(bool)), SLOT(singleRunnerModeActionTriggered()));
 
204
        }
 
205
    }
 
206
}
 
207
 
 
208
void KRunnerApp::singleRunnerModeActionTriggered()
 
209
{
 
210
    KAction * action = qobject_cast<KAction*>(sender());
 
211
    if (action) {
 
212
        displaySingleRunner(action->objectName());
 
213
    }
 
214
}
 
215
 
 
216
void KRunnerApp::querySingleRunner(const QString& runnerId, const QString &term)
 
217
{
 
218
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
219
        return;
 
220
    }
 
221
 
 
222
    m_runnerManager->setSingleModeRunnerId(runnerId);
 
223
    m_runnerManager->setSingleMode(!runnerId.isEmpty());
 
224
 
 
225
    if (m_runnerManager->singleMode()) {
 
226
        m_interface->display(term);
 
227
    }
 
228
}
 
229
 
 
230
QStringList KRunnerApp::singleModeAdvertisedRunnerIds() const
 
231
{
 
232
    return m_runnerManager->singleModeAdvertisedRunnerIds();
 
233
}
 
234
 
 
235
void KRunnerApp::initializeStartupNotification()
 
236
{
 
237
    // Startup notification
 
238
    KLaunchSettings::self()->readConfig();
 
239
#ifdef Q_WS_X11
 
240
    if (!KLaunchSettings::busyCursor()) {
 
241
        delete m_startupId;
 
242
        m_startupId = NULL;
 
243
    } else {
 
244
        if (m_startupId == NULL ) {
 
245
            m_startupId = new StartupId;
 
246
        }
 
247
 
 
248
        m_startupId->configure();
 
249
    }
 
250
#endif
 
251
}
 
252
 
 
253
void KRunnerApp::showTaskManager()
 
254
{
 
255
    showTaskManagerWithFilter(QString());
 
256
}
 
257
void KRunnerApp::showTaskManagerWithFilter(const QString &filterText)
 
258
{
 
259
#ifndef Q_WS_WIN
 
260
    //kDebug(1204) << "Launching KSysGuard...";
 
261
    if (!m_tasks) {
 
262
        m_tasks = new KSystemActivityDialog;
 
263
        connect(m_tasks, SIGNAL(finished()),
 
264
                this, SLOT(taskDialogFinished()));
 
265
    }
 
266
    m_tasks->run();
 
267
    m_tasks->setFilterText(filterText);
 
268
#endif
 
269
}
 
270
 
 
271
void KRunnerApp::display()
 
272
{
 
273
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
274
        return;
 
275
    }
 
276
 
 
277
    m_runnerManager->setSingleMode(false);
 
278
    m_interface->display();
 
279
}
 
280
 
 
281
void KRunnerApp::displaySingleRunner(const QString &runnerId)
 
282
{
 
283
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
284
        return;
 
285
    }
 
286
 
 
287
    m_runnerManager->setSingleModeRunnerId(runnerId);
 
288
    m_runnerManager->setSingleMode(!runnerId.isEmpty());
 
289
    m_interface->display();
 
290
}
 
291
 
 
292
void KRunnerApp::displayOrHide()
 
293
{
 
294
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
295
        m_interface->hide();
 
296
        return;
 
297
    }
 
298
 
 
299
    if (!m_interface->isVisible()) {
 
300
        m_runnerManager->setSingleMode(false);
 
301
    }
 
302
 
 
303
    if (m_interface->freeFloating()) {
 
304
        if (m_interface->isVisible()) {
 
305
            m_interface->hide();
 
306
        } else {
 
307
            m_interface->display();
 
308
        }
 
309
    } else if (m_interface->isActiveWindow()) {
 
310
        m_interface->hide();
 
311
    } else {
 
312
        m_interface->display();
 
313
    }
 
314
}
 
315
 
 
316
void KRunnerApp::query(const QString &term)
 
317
{
 
318
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
319
        return;
 
320
    }
 
321
 
 
322
    m_interface->display(term);
 
323
}
 
324
 
 
325
void KRunnerApp::displayWithClipboardContents()
 
326
{
 
327
    if (!KAuthorized::authorize(QLatin1String("run_command"))) {
 
328
        return;
 
329
    }
 
330
 
 
331
    QString clipboardData = QApplication::clipboard()->text(QClipboard::Selection);
 
332
    m_interface->display(clipboardData);
 
333
}
 
334
 
 
335
void KRunnerApp::switchUser()
 
336
{
 
337
    const KService::Ptr service = KService::serviceByStorageId(QLatin1String("plasma-runner-sessions.desktop"));
 
338
    KPluginInfo info(service);
 
339
 
 
340
    if (info.isValid()) {
 
341
        SessList sessions;
 
342
        KDisplayManager dm;
 
343
        dm.localSessions(sessions);
 
344
 
 
345
        if (sessions.isEmpty()) {
 
346
            // no sessions to switch between, let's just start up another session directly
 
347
            Plasma::AbstractRunner *sessionRunner = m_runnerManager->runner(info.pluginName());
 
348
            if (sessionRunner) {
 
349
                Plasma::QueryMatch switcher(sessionRunner);
 
350
                sessionRunner->run(*m_runnerManager->searchContext(), switcher);
 
351
            }
 
352
        } else {
 
353
            m_runnerManager->setSingleModeRunnerId(info.pluginName());
 
354
            m_runnerManager->setSingleMode(true);
 
355
            m_interface->display();
 
356
            //TODO: ugh, magic strings. See sessions/sessionrunner.cpp
 
357
            m_runnerManager->launchQuery(QLatin1String("SESSIONS"), info.pluginName());
 
358
        }
 
359
    }
 
360
}
 
361
 
 
362
void KRunnerApp::clearHistory()
 
363
{
 
364
    m_interface->clearHistory();
 
365
}
 
366
 
 
367
void KRunnerApp::taskDialogFinished()
 
368
{
 
369
#ifndef Q_WS_WIN
 
370
    m_tasks->deleteLater();
 
371
    m_tasks = 0;
 
372
#endif
 
373
}
 
374
 
 
375
int KRunnerApp::newInstance()
 
376
{
 
377
    if (m_firstTime) {
 
378
        m_firstTime = false;
 
379
    } else {
 
380
        display();
 
381
    }
 
382
 
 
383
    return KUniqueApplication::newInstance();
 
384
    //return 0;
 
385
}
 
386
 
 
387
bool KRunnerApp::hasCompositeManager() const
 
388
{
 
389
#ifdef Q_WS_X11
 
390
    return KWindowSystem::compositingActive();
 
391
#else
 
392
    return false;
 
393
#endif
 
394
}
 
395
 
 
396
void KRunnerApp::reloadConfig()
 
397
{
 
398
    //Prevent Interface destructor from triggering this method
 
399
    disconnect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
 
400
 
 
401
    const int interface = KRunnerSettings::interface();
 
402
    if (!qobject_cast<QsDialog*>(m_interface) &&
 
403
        interface == KRunnerSettings::EnumInterface::TaskOriented) {
 
404
        m_interface->deleteLater();
 
405
        m_interface = new QsDialog(m_runnerManager);
 
406
    } else if (!qobject_cast<Interface*>(m_interface) &&
 
407
               interface == KRunnerSettings::EnumInterface::CommandOriented) {
 
408
        m_interface->deleteLater();
 
409
        m_interface = new Interface(m_runnerManager);
 
410
    }
 
411
 
 
412
    m_interface->setFreeFloating(KRunnerSettings::freeFloating());
 
413
    connect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
 
414
    display();
 
415
}
 
416
 
 
417
#include "krunnerapp.moc"