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

« back to all changes in this revision

Viewing changes to plasma/generic/runners/solid/solidrunner.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 2009 by Jacopo De Simoi <wilderkde@gmail.com>               *
 
3
 *   This program is free software; you can redistribute it and/or modify  *
 
4
 *   it under the terms of the GNU General Public License as published by  *
 
5
 *   the Free Software Foundation; either version 2 of the License, or     *
 
6
 *   (at your option) any later version.                                   *
 
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 General Public License     *
 
14
 *   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
//own
 
20
#include "solidrunner.h"
 
21
#include "devicewrapper.h"
 
22
 
 
23
//Qt
 
24
#include <QAction>
 
25
 
 
26
//KDE
 
27
#include <KDebug>
 
28
#include <KIcon>
 
29
 
 
30
//Plasma
 
31
#include <Plasma/Plasma>
 
32
#include <Plasma/DataEngineManager>
 
33
 
 
34
//Solid
 
35
#include <Solid/Device>
 
36
 
 
37
using namespace Plasma;
 
38
 
 
39
SolidRunner::SolidRunner(QObject* parent, const QVariantList& args)
 
40
    : AbstractRunner(parent, args),
 
41
      m_deviceList()
 
42
{
 
43
    Q_UNUSED(args)
 
44
    setObjectName( QLatin1String("Solid" ));
 
45
 
 
46
    m_engineManager = Plasma::DataEngineManager::self();
 
47
 
 
48
    addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds devices whose name match :q:")));
 
49
 
 
50
    setDefaultSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "device"),
 
51
                                   i18n("Lists all devices and allows them to be mounted, unmounted or ejected.")));
 
52
    addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "mount"),
 
53
                                   i18n("Lists all devices which can be mounted, and allows them to be mounted.")));
 
54
    addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "unlock"),
 
55
                                   i18n("Lists all encrypted devices which can be unlocked, and allows them to be unlocked.")));
 
56
    addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "unmount"),
 
57
                                   i18n("Lists all devices which can be unmounted, and allows them to be unmounted.")));
 
58
    addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "lock"),
 
59
                                   i18n("Lists all encrypted devices which can be locked, and allows them to be locked.")));
 
60
 
 
61
    addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "eject"),
 
62
                                   i18n("Lists all devices which can be ejected, and allows them to be ejected.")));
 
63
 
 
64
}
 
65
 
 
66
SolidRunner::~SolidRunner()
 
67
{
 
68
}
 
69
 
 
70
void SolidRunner::init()
 
71
{
 
72
 
 
73
  m_hotplugEngine = dataEngine("hotplug");
 
74
  m_solidDeviceEngine = dataEngine("soliddevice");
 
75
 
 
76
  //connect to engine when a device is plugged
 
77
  connect(m_hotplugEngine, SIGNAL(sourceAdded(const QString&)),
 
78
          this, SLOT(onSourceAdded(const QString&)));
 
79
  connect(m_hotplugEngine, SIGNAL(sourceRemoved(const QString&)),
 
80
          this, SLOT(onSourceRemoved(const QString&)));
 
81
  fillPreviousDevices();
 
82
}
 
83
 
 
84
void SolidRunner::cleanActionsForDevice(DeviceWrapper * dev)
 
85
{
 
86
    const QStringList actionIds = dev->actionIds();
 
87
    if (!actionIds.isEmpty()) {
 
88
        foreach (const QString& id, actionIds) {
 
89
            removeAction(id);
 
90
        }
 
91
    }
 
92
}
 
93
 
 
94
QList<QAction*> SolidRunner::actionsForMatch(const Plasma::QueryMatch &match)
 
95
{
 
96
    QList<QAction*> actions;
 
97
 
 
98
    DeviceWrapper* dev = m_deviceList.value(match.data().toString());
 
99
    if (dev) {
 
100
        QStringList actionIds = dev->actionIds();
 
101
        kDebug() << actionIds;
 
102
        if (!actionIds.isEmpty()) {
 
103
            foreach (const QString& id, actionIds) {
 
104
                actions << action(id);
 
105
            }
 
106
        }
 
107
    }
 
108
    return actions;
 
109
}
 
110
 
 
111
void SolidRunner::match(Plasma::RunnerContext& context)
 
112
{
 
113
    m_currentContext = context;
 
114
    createOrUpdateMatches(m_deviceList.keys());
 
115
}
 
116
 
 
117
void SolidRunner::createOrUpdateMatches(const QStringList &udiList)
 
118
{
 
119
    const QString term = m_currentContext.query();
 
120
 
 
121
    if (!m_currentContext.isValid()) {
 
122
        return;
 
123
    }
 
124
 
 
125
    if (!m_currentContext.singleRunnerQueryMode() && (term.length() < 3)) {
 
126
        return;
 
127
    }
 
128
    QList<Plasma::QueryMatch> matches;
 
129
 
 
130
    // keyword match: when term starts with "device" we list all devices
 
131
    QStringList keywords = term.split(" ");
 
132
    QString deviceDescription;
 
133
    bool onlyMounted = false;
 
134
    bool onlyMountable = false;
 
135
    bool onlyEncrypted = false;
 
136
    bool onlyOptical = false;
 
137
    bool forceEject = false;
 
138
    bool showDevices = false;
 
139
    if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "device") , Qt::CaseInsensitive)) {
 
140
        showDevices = true;
 
141
        keywords.removeFirst();
 
142
    }
 
143
 
 
144
    if (!keywords.isEmpty()) {
 
145
        if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "mount") , Qt::CaseInsensitive)) {
 
146
            showDevices = true;
 
147
            onlyMountable = true;
 
148
            keywords.removeFirst();
 
149
        } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unmount") , Qt::CaseInsensitive)) {
 
150
            showDevices = true;
 
151
            onlyMounted = true;
 
152
            keywords.removeFirst();
 
153
        } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "eject") , Qt::CaseInsensitive)) {
 
154
            showDevices = true;
 
155
            onlyOptical = true;
 
156
            forceEject = true;
 
157
            keywords.removeFirst();
 
158
        } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unlock") , Qt::CaseInsensitive)) {
 
159
            showDevices = true;
 
160
            onlyMountable = true;
 
161
            onlyEncrypted = true;
 
162
            keywords.removeFirst();
 
163
        } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "lock") , Qt::CaseInsensitive)) {
 
164
            showDevices = true;
 
165
            onlyMounted = true;
 
166
            onlyEncrypted = true;
 
167
            keywords.removeFirst();
 
168
        }
 
169
    }
 
170
 
 
171
    if (!keywords.isEmpty()) {
 
172
        deviceDescription = keywords[0];
 
173
    }
 
174
 
 
175
    foreach (const QString& udi,  udiList) {
 
176
        DeviceWrapper * dev = m_deviceList.value(udi);
 
177
        if ((deviceDescription.isEmpty() && showDevices) || dev->description().contains(deviceDescription, Qt::CaseInsensitive)) {
 
178
            // This is getting quite messy indeed
 
179
            if (((!onlyEncrypted) || (onlyEncrypted && dev->isEncryptedContainer())) &&
 
180
                ((!onlyOptical) || (onlyOptical && dev->isOpticalDisc())) &&
 
181
                ((onlyMounted && dev->isAccessible()) ||
 
182
                 (onlyMountable && dev->isStorageAccess() && !dev->isAccessible()) ||
 
183
                 (!onlyMounted && !onlyMountable))) {
 
184
                dev->setForceEject(forceEject);
 
185
                Plasma::QueryMatch match = deviceMatch(dev);
 
186
                if (dev->description().compare(deviceDescription, Qt::CaseInsensitive)) {
 
187
                    match.setType(Plasma::QueryMatch::ExactMatch);
 
188
                } else if (deviceDescription.isEmpty()) {
 
189
                    match.setType(Plasma::QueryMatch::PossibleMatch);
 
190
                } else {
 
191
                    match.setType(Plasma::QueryMatch::CompletionMatch);
 
192
                }
 
193
                matches << match;
 
194
            }
 
195
        }
 
196
    }
 
197
 
 
198
    if (!matches.isEmpty()) {
 
199
        kDebug () << matches.count();
 
200
        m_currentContext.addMatches(term, matches);
 
201
    }
 
202
}
 
203
 
 
204
Plasma::QueryMatch SolidRunner::deviceMatch(DeviceWrapper * device)
 
205
{
 
206
    Plasma::QueryMatch match(this);
 
207
    match.setId(device->id());
 
208
    match.setData(device->id());
 
209
    match.setIcon(device->icon());
 
210
    match.setText(device->description());
 
211
 
 
212
    match.setSubtext(device->defaultAction());
 
213
 
 
214
    //Put them in order such that the last added device is on top.
 
215
    match.setRelevance(0.5+0.1*qreal(m_udiOrderedList.indexOf(device->id()))/qreal(m_udiOrderedList.count()));
 
216
 
 
217
    return match;
 
218
}
 
219
 
 
220
void SolidRunner::run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match)
 
221
{
 
222
    Q_UNUSED(context)
 
223
 
 
224
    DeviceWrapper *device = m_deviceList.value(match.data().toString());
 
225
    if (device) {
 
226
        device->runAction(match.selectedAction());
 
227
    }
 
228
}
 
229
 
 
230
void SolidRunner::registerAction(QString &id, QString icon, QString text, QString desktop)
 
231
{
 
232
    QAction* action = addAction(id, KIcon(icon), text);
 
233
    action->setData(desktop);
 
234
}
 
235
 
 
236
void SolidRunner::refreshMatch(QString &id)
 
237
{
 
238
    if (!m_currentContext.isValid()) {
 
239
        return;
 
240
    }
 
241
 
 
242
    QueryMatch match(this);
 
243
    match.setId(id);
 
244
    m_currentContext.removeMatch(match.id());
 
245
    QStringList deviceList;
 
246
    deviceList << id;
 
247
    createOrUpdateMatches(deviceList);
 
248
}
 
249
 
 
250
void SolidRunner::onSourceAdded(const QString &name)
 
251
{
 
252
    DeviceWrapper * device = new DeviceWrapper(name);
 
253
    connect(device, SIGNAL(registerAction(QString &, QString , QString, QString )),
 
254
            this,  SLOT(registerAction(QString &, QString, QString, QString)));
 
255
    connect(device, SIGNAL(refreshMatch(QString &)), this, SLOT(refreshMatch(QString &)));
 
256
 
 
257
    m_deviceList.insert(name, device);
 
258
    m_udiOrderedList << name;
 
259
    m_hotplugEngine->connectSource(name, device);
 
260
    m_solidDeviceEngine->connectSource(name, device);
 
261
}
 
262
 
 
263
void SolidRunner::onSourceRemoved(const QString &name)
 
264
{
 
265
    DeviceWrapper * device = m_deviceList.value(name);
 
266
    if (device) {
 
267
            m_hotplugEngine->disconnectSource(name, device);
 
268
            m_solidDeviceEngine->disconnectSource(name, device);
 
269
            disconnect(device, 0, this, 0);
 
270
            cleanActionsForDevice(device);
 
271
            m_deviceList.remove(name);
 
272
            m_udiOrderedList.removeAll(name);
 
273
            if (m_currentContext.isValid()) {
 
274
                QueryMatch match(this);
 
275
                match.setId(device->id());
 
276
                m_currentContext.removeMatch(match.id());
 
277
            }
 
278
            delete device;
 
279
    }
 
280
}
 
281
 
 
282
void SolidRunner::fillPreviousDevices()
 
283
{
 
284
    foreach (const QString &source, m_hotplugEngine->sources()) {
 
285
        onSourceAdded(source);
 
286
    }
 
287
}
 
288
 
 
289
#include "solidrunner.moc"