Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1990 - (hide annotations) (download)
Mon Dec 10 15:50:04 2012 UTC (11 years, 6 months ago) by niro
File size: 12357 byte(s)
-added udisks2 patches
1 niro 1990 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)