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. *
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 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
***************************************************************************/
20
#include "solidrunner.h"
21
#include "devicewrapper.h"
31
#include <Plasma/Plasma>
32
#include <Plasma/DataEngineManager>
35
#include <Solid/Device>
37
using namespace Plasma;
39
SolidRunner::SolidRunner(QObject* parent, const QVariantList& args)
40
: AbstractRunner(parent, args),
44
setObjectName( QLatin1String("Solid" ));
46
m_engineManager = Plasma::DataEngineManager::self();
48
addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds devices whose name match :q:")));
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.")));
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.")));
66
SolidRunner::~SolidRunner()
70
void SolidRunner::init()
73
m_hotplugEngine = dataEngine("hotplug");
74
m_solidDeviceEngine = dataEngine("soliddevice");
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();
84
void SolidRunner::cleanActionsForDevice(DeviceWrapper * dev)
86
const QStringList actionIds = dev->actionIds();
87
if (!actionIds.isEmpty()) {
88
foreach (const QString& id, actionIds) {
94
QList<QAction*> SolidRunner::actionsForMatch(const Plasma::QueryMatch &match)
96
QList<QAction*> actions;
98
DeviceWrapper* dev = m_deviceList.value(match.data().toString());
100
QStringList actionIds = dev->actionIds();
101
kDebug() << actionIds;
102
if (!actionIds.isEmpty()) {
103
foreach (const QString& id, actionIds) {
104
actions << action(id);
111
void SolidRunner::match(Plasma::RunnerContext& context)
113
m_currentContext = context;
114
createOrUpdateMatches(m_deviceList.keys());
117
void SolidRunner::createOrUpdateMatches(const QStringList &udiList)
119
const QString term = m_currentContext.query();
121
if (!m_currentContext.isValid()) {
125
if (!m_currentContext.singleRunnerQueryMode() && (term.length() < 3)) {
128
QList<Plasma::QueryMatch> matches;
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)) {
141
keywords.removeFirst();
144
if (!keywords.isEmpty()) {
145
if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "mount") , Qt::CaseInsensitive)) {
147
onlyMountable = true;
148
keywords.removeFirst();
149
} else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unmount") , Qt::CaseInsensitive)) {
152
keywords.removeFirst();
153
} else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "eject") , Qt::CaseInsensitive)) {
157
keywords.removeFirst();
158
} else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unlock") , Qt::CaseInsensitive)) {
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)) {
166
onlyEncrypted = true;
167
keywords.removeFirst();
171
if (!keywords.isEmpty()) {
172
deviceDescription = keywords[0];
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);
191
match.setType(Plasma::QueryMatch::CompletionMatch);
198
if (!matches.isEmpty()) {
199
kDebug () << matches.count();
200
m_currentContext.addMatches(term, matches);
204
Plasma::QueryMatch SolidRunner::deviceMatch(DeviceWrapper * device)
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());
212
match.setSubtext(device->defaultAction());
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()));
220
void SolidRunner::run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match)
224
DeviceWrapper *device = m_deviceList.value(match.data().toString());
226
device->runAction(match.selectedAction());
230
void SolidRunner::registerAction(QString &id, QString icon, QString text, QString desktop)
232
QAction* action = addAction(id, KIcon(icon), text);
233
action->setData(desktop);
236
void SolidRunner::refreshMatch(QString &id)
238
if (!m_currentContext.isValid()) {
242
QueryMatch match(this);
244
m_currentContext.removeMatch(match.id());
245
QStringList deviceList;
247
createOrUpdateMatches(deviceList);
250
void SolidRunner::onSourceAdded(const QString &name)
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 &)));
257
m_deviceList.insert(name, device);
258
m_udiOrderedList << name;
259
m_hotplugEngine->connectSource(name, device);
260
m_solidDeviceEngine->connectSource(name, device);
263
void SolidRunner::onSourceRemoved(const QString &name)
265
DeviceWrapper * device = m_deviceList.value(name);
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());
282
void SolidRunner::fillPreviousDevices()
284
foreach (const QString &source, m_hotplugEngine->sources()) {
285
onSourceAdded(source);
289
#include "solidrunner.moc"