Magellan Linux

Contents of /trunk/kdelibs/patches/kdelibs-4.9.4-udisks2-kfileplacesdevicecache.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1990 - (show annotations) (download)
Mon Dec 10 15:50:04 2012 UTC (11 years, 4 months ago) by niro
File size: 12357 byte(s)
-added udisks2 patches
1 diff --git a/kfile/CMakeLists.txt b/kfile/CMakeLists.txt
2 index ceae140..c7c4d3d 100644
3 --- a/kfile/CMakeLists.txt
4 +++ b/kfile/CMakeLists.txt
5 @@ -20,6 +20,7 @@ set(kfile_LIB_SRCS
6 kfilefiltercombo.cpp
7 kfiletreeview.cpp
8 kfilewidget.cpp
9 + kfileplacesdevicecache.cpp
10 kfileplacesitem.cpp
11 kfileplacesmodel.cpp
12 kfileplacessharedbookmarks.cpp
13 @@ -63,6 +64,7 @@ install( FILES
14 kdirselectdialog.h
15 kdirsortfilterproxymodel.h
16 kfilefiltercombo.h
17 + kfileplacesdevicecache.h
18 kfileplacesmodel.h
19 kfileplacesview.h
20 kfilepreviewgenerator.h
21 diff --git a/kfile/kfileplacesdevicecache.cpp b/kfile/kfileplacesdevicecache.cpp
22 new file mode 100644
23 index 0000000..40f7242
24 --- /dev/null
25 +++ b/kfile/kfileplacesdevicecache.cpp
26 @@ -0,0 +1,174 @@
27 +/*
28 + Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com>
29 +
30 + This library is free software; you can redistribute it and/or
31 + modify it under the terms of the GNU Library General Public
32 + License version 2 as published by the Free Software Foundation.
33 +
34 + This library is distributed in the hope that it will be useful,
35 + but WITHOUT ANY WARRANTY; without even the implied warranty of
36 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 + Library General Public License for more details.
38 +
39 + You should have received a copy of the GNU Library General Public License
40 + along with this library; see the file COPYING.LIB. If not, write to
41 + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
42 + Boston, MA 02110-1301, USA.
43 +*/
44 +
45 +#include "kfileplacesdevicecache.h"
46 +
47 +#include <QMutex>
48 +#include <QtConcurrentRun>
49 +#include <QFutureWatcher>
50 +#include <QTimer>
51 +
52 +#include <kprotocolinfo.h>
53 +#include <solid/predicate.h>
54 +#include <solid/device.h>
55 +#include <solid/devicenotifier.h>
56 +#include <solid/genericinterface.h>
57 +
58 +#include <kdebug.h>
59 +
60 +KFilePlacesDeviceCache* KFilePlacesDeviceCache::s_instance = 0;
61 +
62 +class KFilePlacesDeviceCache::Private
63 +{
64 + public:
65 + Private(KFilePlacesDeviceCache *parent):
66 + queryRunning(false),
67 + q(parent)
68 + { }
69 +
70 + ~Private()
71 + { }
72 +
73 + /* This method runs asynchronously in thread */
74 + QSet<QString> listSolidDevicesAsync()
75 + {
76 + QSet<QString> udis;
77 +
78 + kDebug() << "Querying Solid devices...";
79 + const QList<Solid::Device>& deviceList = Solid::Device::listFromQuery(solidPredicate);
80 + kDebug() << "Retrieved" << deviceList.count() << "devices";
81 +
82 + Q_FOREACH (const Solid::Device& device, deviceList) {
83 + if (solidPredicate.matches(device)) {
84 + udis << device.udi();
85 + }
86 + }
87 +
88 + return udis;
89 + }
90 +
91 + void _k_slotDeviceAdded(const QString &udi)
92 + {
93 + devicesCache << udi;
94 +
95 + Q_EMIT q->deviceAdded(udi);
96 + }
97 +
98 + void _k_slotDeviceRemoved(const QString &udi)
99 + {
100 + if (!devicesCache.contains(udi)) {
101 + return;
102 + }
103 +
104 + devicesCache.remove(udi);
105 +
106 + Q_EMIT q->deviceRemoved(udi);
107 + }
108 +
109 + void _k_listSolidDevicesFinished()
110 + {
111 + Q_FOREACH (const QString& device, futureWatcher->result()) {
112 + _k_slotDeviceAdded(device);
113 + }
114 +
115 + delete futureWatcher;
116 + futureWatcher = 0;
117 +
118 + queryRunning = false;
119 + }
120 +
121 + Solid::Predicate solidPredicate;
122 +
123 + QFutureWatcher< QSet<QString> >* futureWatcher;
124 +
125 + /* Static */
126 + QSet<QString> devicesCache;
127 + bool queryRunning;
128 +
129 + KFilePlacesDeviceCache *q;
130 +};
131 +
132 +KFilePlacesDeviceCache::KFilePlacesDeviceCache():
133 + QObject(),
134 + d(new Private(this))
135 +{
136 + Solid::DeviceNotifier* notifier = Solid::DeviceNotifier::instance();
137 + connect(notifier, SIGNAL(deviceAdded(QString)), this, SLOT(_k_slotDeviceAdded(QString)));
138 + connect(notifier, SIGNAL(deviceRemoved(QString)), this, SLOT(_k_slotDeviceRemoved(QString)));
139 +
140 + QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
141 + " OR "
142 + "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
143 + " OR "
144 + "OpticalDisc.availableContent & 'Audio' ]"
145 + " OR "
146 + "StorageAccess.ignored == false ]");
147 +
148 + if (KProtocolInfo::isKnownProtocol("mtp")) {
149 + predicate.prepend("[");
150 + predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']");
151 + }
152 +
153 + d->solidPredicate = Solid::Predicate::fromString(predicate);
154 +}
155 +
156 +KFilePlacesDeviceCache* KFilePlacesDeviceCache::self()
157 +{
158 + static QMutex mutex;
159 +
160 + mutex.lock();
161 + if (s_instance == 0) {
162 + s_instance = new KFilePlacesDeviceCache();
163 + }
164 + mutex.unlock();
165 +
166 + return s_instance;
167 +}
168 +
169 +KFilePlacesDeviceCache::~KFilePlacesDeviceCache()
170 +{
171 + Solid::DeviceNotifier* notifier = Solid::DeviceNotifier::instance();
172 + disconnect(notifier, SIGNAL(deviceAdded(QString)));
173 + disconnect(notifier, SIGNAL(deviceRemoved(QString)));
174 +
175 + delete d;
176 +}
177 +
178 +const Solid::Predicate& KFilePlacesDeviceCache::predicate() const
179 +{
180 + return d->solidPredicate;
181 +}
182 +
183 +const QSet<QString>& KFilePlacesDeviceCache::devices() const
184 +{
185 + kDebug();
186 + if (d->devicesCache.isEmpty() && !d->queryRunning) {
187 + d->queryRunning = true;
188 + d->futureWatcher = new QFutureWatcher< QSet<QString> >;
189 + connect(d->futureWatcher, SIGNAL(finished()), this, SLOT(_k_listSolidDevicesFinished()));
190 +
191 + QFuture< QSet<QString> > future = QtConcurrent::run(d, &Private::listSolidDevicesAsync);
192 + d->futureWatcher->setFuture(future);
193 + }
194 +
195 + return d->devicesCache;
196 +}
197 +
198 +
199 +
200 +#include "kfileplacesdevicecache.moc"
201 diff --git a/kfile/kfileplacesdevicecache.h b/kfile/kfileplacesdevicecache.h
202 new file mode 100644
203 index 0000000..7293d03
204 --- /dev/null
205 +++ b/kfile/kfileplacesdevicecache.h
206 @@ -0,0 +1,96 @@
207 +/*
208 + Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com>
209 +
210 + This library is free software; you can redistribute it and/or
211 + modify it under the terms of the GNU Library General Public
212 + License version 2 as published by the Free Software Foundation.
213 +
214 + This library is distributed in the hope that it will be useful,
215 + but WITHOUT ANY WARRANTY; without even the implied warranty of
216 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
217 + Library General Public License for more details.
218 +
219 + You should have received a copy of the GNU Library General Public License
220 + along with this library; see the file COPYING.LIB. If not, write to
221 + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
222 + Boston, MA 02110-1301, USA.
223 +*/
224 +
225 +#ifndef KFILEPLACESDEVICECACHE_H
226 +#define KFILEPLACESDEVICECACHE_H
227 +
228 +#include <kfile_export.h>
229 +
230 +#include <QObject>
231 +#include <QSet>
232 +
233 +#include <solid/predicate.h>
234 +
235 +/**
236 + * @short Asynchronous cache for Solid devices
237 + *
238 + * Purpose of this cache is to load Solid devices asynchronously, because
239 + * udisks2 backend can take quite a lot of time to enumerate devices, and
240 + * since Solid does not have async API, the UI thread is blocked for too long.
241 + *
242 + * When libsolid2 with asynchronous API is available, this class can go away.
243 + *
244 + * The cache keeps itself up-to-date and notifies listeners when a
245 + * new devices is added or removed.
246 + */
247 +class KFILE_EXPORT KFilePlacesDeviceCache : public QObject
248 +{
249 + Q_OBJECT
250 +
251 +public:
252 + /**
253 + * Returns a global instance of the cache
254 + */
255 + static KFilePlacesDeviceCache* self();
256 +
257 + /**
258 + * Returns list of Solid devices.
259 + *
260 + * This method always returns immediatelly. When there are no
261 + * devices in the cache, it returns an empty list and will asynchronously
262 + * query Solid for devices and will notify listeners by emitting
263 + * deviceAdded() signal for each devices loaded.
264 + */
265 + const QSet<QString>& devices() const;
266 +
267 + /**
268 + * Returns Solid::Predicate used to obtain devices from Solid
269 + */
270 + const Solid::Predicate& predicate() const;
271 +
272 +Q_SIGNALS:
273 + /**
274 + * Emitted whenever a new device is discovered.
275 + *
276 + * @param udi UDI (Universal Device ID) of the newly discovered device
277 + */
278 + void deviceAdded(const QString& udi);
279 +
280 + /**
281 + * Emitted whenever a device is removed from system
282 + *
283 + * @param udi UDI (Universal Device ID) of the removed device
284 + */
285 + void deviceRemoved(const QString& udi);
286 +
287 +private:
288 + Q_PRIVATE_SLOT(d, void _k_listSolidDevicesFinished())
289 + Q_PRIVATE_SLOT(d, void _k_slotDeviceAdded(const QString&))
290 + Q_PRIVATE_SLOT(d, void _k_slotDeviceRemoved(const QString&))
291 +
292 + class Private;
293 + Private * const d;
294 + friend class Private;
295 +
296 + explicit KFilePlacesDeviceCache();
297 + virtual ~KFilePlacesDeviceCache();
298 +
299 + static KFilePlacesDeviceCache* s_instance;
300 +};
301 +
302 +#endif // KFILEPLACESDEVICECACHE_H
303 diff --git a/kfile/kfileplacesmodel.cpp b/kfile/kfileplacesmodel.cpp
304 index 0192926..e0b01c6 100644
305 --- a/kfile/kfileplacesmodel.cpp
306 +++ b/kfile/kfileplacesmodel.cpp
307 @@ -20,6 +20,7 @@
308 #include "kfileplacesmodel.h"
309 #include "kfileplacesitem_p.h"
310 #include "kfileplacessharedbookmarks_p.h"
311 +#include "kfileplacesdevicecache.h"
312
313 #ifdef _WIN32_WCE
314 #include "Windows.h"
315 @@ -49,14 +50,12 @@
316 #include <kio/netaccess.h>
317 #include <kprotocolinfo.h>
318
319 -#include <solid/devicenotifier.h>
320 #include <solid/storageaccess.h>
321 #include <solid/storagedrive.h>
322 #include <solid/storagevolume.h>
323 #include <solid/opticaldrive.h>
324 #include <solid/opticaldisc.h>
325 #include <solid/portablemediaplayer.h>
326 -#include <solid/predicate.h>
327
328 class KFilePlacesModel::Private
329 {
330 @@ -74,7 +73,6 @@ public:
331 QSet<QString> availableDevices;
332 QMap<QObject*, QPersistentModelIndex> setupInProgress;
333
334 - Solid::Predicate predicate;
335 KBookmarkManager *bookmarkManager;
336 KFilePlacesSharedBookmarks * sharedBookmarks;
337
338 @@ -149,30 +147,12 @@ KFilePlacesModel::KFilePlacesModel(QObject *parent)
339 // create after, so if we have own places, they are added afterwards, in case of equal priorities
340 d->sharedBookmarks = new KFilePlacesSharedBookmarks(d->bookmarkManager);
341
342 - QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
343 - " OR "
344 - "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
345 - " OR "
346 - "OpticalDisc.availableContent & 'Audio' ]"
347 - " OR "
348 - "StorageAccess.ignored == false ]");
349 -
350 - if (KProtocolInfo::isKnownProtocol("mtp")) {
351 - predicate.prepend("[");
352 - predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']");
353 - }
354 -
355 - d->predicate = Solid::Predicate::fromString(predicate);
356 -
357 - Q_ASSERT(d->predicate.isValid());
358 -
359 connect(d->bookmarkManager, SIGNAL(changed(QString,QString)),
360 this, SLOT(_k_reloadBookmarks()));
361 connect(d->bookmarkManager, SIGNAL(bookmarksChanged(QString)),
362 this, SLOT(_k_reloadBookmarks()));
363
364 - d->_k_reloadBookmarks();
365 - QTimer::singleShot(0, this, SLOT(_k_initDeviceList()));
366 + d->_k_initDeviceList();
367 }
368
369 KFilePlacesModel::~KFilePlacesModel()
370 @@ -313,30 +293,21 @@ QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
371
372 void KFilePlacesModel::Private::_k_initDeviceList()
373 {
374 - Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance();
375 -
376 - connect(notifier, SIGNAL(deviceAdded(QString)),
377 + KFilePlacesDeviceCache *cache = KFilePlacesDeviceCache::self();
378 + connect(cache, SIGNAL(deviceAdded(QString)),
379 q, SLOT(_k_deviceAdded(QString)));
380 - connect(notifier, SIGNAL(deviceRemoved(QString)),
381 + connect(cache, SIGNAL(deviceRemoved(QString)),
382 q, SLOT(_k_deviceRemoved(QString)));
383
384 - const QList<Solid::Device> &deviceList = Solid::Device::listFromQuery(predicate);
385 -
386 - foreach(const Solid::Device &device, deviceList) {
387 - availableDevices << device.udi();
388 - }
389 + availableDevices = cache->devices();
390
391 _k_reloadBookmarks();
392 }
393
394 void KFilePlacesModel::Private::_k_deviceAdded(const QString &udi)
395 {
396 - Solid::Device d(udi);
397 -
398 - if (predicate.matches(d)) {
399 - availableDevices << udi;
400 - _k_reloadBookmarks();
401 - }
402 + availableDevices << udi;
403 + _k_reloadBookmarks();
404 }
405
406 void KFilePlacesModel::Private::_k_deviceRemoved(const QString &udi)