Make the statusbar space info use the new KIO::fileSystemFreeSpace job.

REVIEW: 120137
BUG: 245226
This commit is contained in:
Mathias Tillman 2014-09-14 18:53:05 +02:00
parent 4de8cf43e6
commit d380d27f47
7 changed files with 99 additions and 85 deletions

View file

@ -17,20 +17,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include <KIO/FileSystemFreeSpaceJob>
#include "mountpointobserver.h"
#include "mountpointobservercache.h"
MountPointObserver::MountPointObserver(const QString& mountPoint, QObject* parent) :
MountPointObserver::MountPointObserver(const QUrl& url, QObject* parent) :
QObject(parent),
m_mountPoint(mountPoint),
m_referenceCount(0),
m_spaceInfo(KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint))
m_url(url),
m_referenceCount(0)
{
}
MountPointObserver* MountPointObserver::observerForPath(const QString& path)
MountPointObserver* MountPointObserver::observerForUrl(const QUrl& url)
{
MountPointObserver* observer = MountPointObserverCache::instance()->observerForPath(path);
MountPointObserver* observer = MountPointObserverCache::instance()->observerForUrl(url);
return observer;
}
@ -39,10 +40,16 @@ void MountPointObserver::update()
if (m_referenceCount == 0) {
delete this;
} else {
const KDiskFreeSpaceInfo spaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(m_mountPoint);
if (spaceInfo.size() != m_spaceInfo.size() || spaceInfo.available() != m_spaceInfo.available()) {
m_spaceInfo = spaceInfo;
emit spaceInfoChanged();
}
KIO::FileSystemFreeSpaceJob* job = KIO::fileSystemFreeSpace(m_url);
connect(job, &KIO::FileSystemFreeSpaceJob::result, this, &MountPointObserver::freeSpaceResult);
}
}
void MountPointObserver::freeSpaceResult(KIO::Job* job, KIO::filesize_t size, KIO::filesize_t available)
{
if (!job->error()) {
emit spaceInfoChanged(size, available);
} else {
emit spaceInfoChanged(0, 0);
}
}

View file

@ -20,9 +20,10 @@
#ifndef MOUNTPOINTOBSERVER_H
#define MOUNTPOINTOBSERVER_H
#include <KDiskFreeSpaceInfo>
#include <KIO/Job>
#include <QObject>
#include <QUrl>
/**
* A MountPointObserver can be used to determine the free space on a mount
@ -52,15 +53,10 @@ class MountPointObserver : public QObject
{
Q_OBJECT
explicit MountPointObserver(const QString& mountPoint, QObject* parent = 0);
explicit MountPointObserver(const QUrl& url, QObject* parent = 0);
virtual ~MountPointObserver() {}
public:
/**
* Obtains information about the available space on the observed mount point.
*/
KDiskFreeSpaceInfo spaceInfo() const { return m_spaceInfo; }
/**
* Call this function to indicate that the caller intends to continue using this object. An
* internal reference count is increased then. When the observer is not needed any more,
@ -80,28 +76,30 @@ public:
}
/**
* Returns a MountPointObserver for the given \a path. If the caller intends to continue using
* Returns a MountPointObserver for the given \a url. If the caller intends to continue using
* the returned object, it must call its ref() method.
*/
static MountPointObserver* observerForPath(const QString& path);
static MountPointObserver* observerForUrl(const QUrl& url);
signals:
/**
* This signal is emitted if the information that spaceInfo() will return has changed.
* This signal is emitted when the size has been retrieved.
*/
void spaceInfoChanged();
void spaceInfoChanged(quint64 size, quint64 available);
public slots:
/**
* If this slot is invoked, MountPointObserver checks if the available space on the observed
* mount point has changed, and emits spaceInfoChanged() if that is the case.
* If this slot is invoked, MountPointObserver starts a new driveSize job
* to get the drive's size.
*/
void update();
private slots:
void freeSpaceResult(KIO::Job* job, KIO::filesize_t size, KIO::filesize_t available);
private:
const QString m_mountPoint;
const QUrl m_url;
int m_referenceCount;
KDiskFreeSpaceInfo m_spaceInfo;
friend class MountPointObserverCache;
};

View file

@ -51,33 +51,38 @@ MountPointObserverCache* MountPointObserverCache::instance()
return &s_MountPointObserverCache->instance;
}
MountPointObserver* MountPointObserverCache::observerForPath(const QString& path)
MountPointObserver* MountPointObserverCache::observerForUrl(const QUrl& url)
{
// Try to share the observer with other paths that have the same mount point.
QString mountPointPath;
KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(path);
if (mountPoint) {
mountPointPath = mountPoint->mountPoint();
QUrl cachedObserverUrl;
// If the url is a local path we can extract the root dir by checking the mount points.
if (url.isLocalFile()) {
// Try to share the observer with other paths that have the same mount point.
KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(url.toLocalFile());
if (mountPoint) {
cachedObserverUrl = QUrl::fromLocalFile(mountPoint->mountPoint());
} else {
// Even if determining the mount point failed, the observer might still
// be able to retrieve information about the url.
cachedObserverUrl = url.toLocalFile();
}
} else {
// Even if determining the mount point failed, KDiskFreeSpaceInfo might still
// be able to retrieve information about the path.
mountPointPath = path;
cachedObserverUrl = url.url();
}
MountPointObserver* observer = m_observerForMountPoint.value(mountPointPath);
MountPointObserver* observer = m_observerForMountPoint.value(cachedObserverUrl);
if (!observer) {
observer = new MountPointObserver(mountPointPath, this);
m_observerForMountPoint.insert(mountPointPath, observer);
m_mountPointForObserver.insert(observer, mountPointPath);
observer = new MountPointObserver(cachedObserverUrl, this);
m_observerForMountPoint.insert(cachedObserverUrl, observer);
m_mountPointForObserver.insert(observer, cachedObserverUrl);
Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count());
connect(observer, SIGNAL(destroyed(QObject*)), this, SLOT(slotObserverDestroyed(QObject*)));
connect(observer, &MountPointObserver::destroyed, this, &MountPointObserverCache::slotObserverDestroyed);
if (!m_updateTimer->isActive()) {
m_updateTimer->start(10000);
}
connect(m_updateTimer, SIGNAL(timeout()), observer, SLOT(update()));
connect(m_updateTimer, &QTimer::timeout, observer, &MountPointObserver::update);
}
return observer;
@ -86,9 +91,9 @@ MountPointObserver* MountPointObserverCache::observerForPath(const QString& path
void MountPointObserverCache::slotObserverDestroyed(QObject* observer)
{
Q_ASSERT(m_mountPointForObserver.contains(observer));
const QString& path = m_mountPointForObserver.value(observer);
Q_ASSERT(m_observerForMountPoint.contains(path));
m_observerForMountPoint.remove(path);
const QUrl& url = m_mountPointForObserver.value(observer);
Q_ASSERT(m_observerForMountPoint.contains(url));
m_observerForMountPoint.remove(url);
m_mountPointForObserver.remove(observer);
Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count());

View file

@ -37,9 +37,9 @@ public:
static MountPointObserverCache* instance();
/**
* Returns a MountPointObserver for the given \a path. A new observer is created if necessary.
* Returns a MountPointObserver for the given \a url. A new observer is created if necessary.
*/
MountPointObserver* observerForPath(const QString& path);
MountPointObserver* observerForUrl(const QUrl& url);
private slots:
/**
@ -48,8 +48,8 @@ private slots:
void slotObserverDestroyed(QObject* observer);
private:
QHash<QString, MountPointObserver*> m_observerForMountPoint;
QHash<QObject*, QString> m_mountPointForObserver;
QHash<QUrl, MountPointObserver*> m_observerForMountPoint;
QHash<QObject*, QUrl> m_mountPointForObserver;
QTimer* m_updateTimer;
friend class MountPointObserverCacheSingleton;

View file

@ -25,13 +25,14 @@
SpaceInfoObserver::SpaceInfoObserver(const KUrl& url, QObject* parent) :
QObject(parent),
m_mountPointObserver(0)
m_mountPointObserver(0),
m_dataSize(0),
m_dataAvailable(0)
{
if (url.isLocalFile()) {
m_mountPointObserver = MountPointObserver::observerForPath(url.toLocalFile());
m_mountPointObserver->ref();
connect(m_mountPointObserver, SIGNAL(spaceInfoChanged()), this, SIGNAL(valuesChanged()));
}
m_mountPointObserver = MountPointObserver::observerForUrl(url);
m_mountPointObserver->ref();
connect(m_mountPointObserver, &MountPointObserver::spaceInfoChanged, this, &SpaceInfoObserver::spaceInfoChanged);
m_mountPointObserver->update();
}
SpaceInfoObserver::~SpaceInfoObserver()
@ -44,46 +45,41 @@ SpaceInfoObserver::~SpaceInfoObserver()
quint64 SpaceInfoObserver::size() const
{
if (m_mountPointObserver && m_mountPointObserver->spaceInfo().isValid()) {
return m_mountPointObserver->spaceInfo().size();
} else {
return 0;
}
return m_dataSize;
}
quint64 SpaceInfoObserver::available() const
{
if (m_mountPointObserver && m_mountPointObserver->spaceInfo().isValid()) {
return m_mountPointObserver->spaceInfo().available();
} else {
return 0;
}
return m_dataAvailable;
}
void SpaceInfoObserver::setUrl(const KUrl& url)
{
if (url.isLocalFile()) {
MountPointObserver* newObserver = MountPointObserver::observerForPath(url.toLocalFile());
if (newObserver != m_mountPointObserver) {
if (m_mountPointObserver) {
disconnect(m_mountPointObserver, SIGNAL(spaceInfoChanged()), this, SIGNAL(valuesChanged()));
m_mountPointObserver->deref();
m_mountPointObserver = 0;
}
m_mountPointObserver = newObserver;
m_mountPointObserver->ref();
connect(m_mountPointObserver, SIGNAL(spaceInfoChanged()), this, SIGNAL(valuesChanged()));
emit valuesChanged();
}
} else {
MountPointObserver* newObserver = MountPointObserver::observerForUrl(url);
if (newObserver != m_mountPointObserver) {
if (m_mountPointObserver) {
disconnect(m_mountPointObserver, SIGNAL(spaceInfoChanged()), this, SIGNAL(valuesChanged()));
disconnect(m_mountPointObserver, &MountPointObserver::spaceInfoChanged, this, &SpaceInfoObserver::spaceInfoChanged);
m_mountPointObserver->deref();
m_mountPointObserver = 0;
emit valuesChanged();
}
m_mountPointObserver = newObserver;
m_mountPointObserver->ref();
connect(m_mountPointObserver, &MountPointObserver::spaceInfoChanged, this, &SpaceInfoObserver::spaceInfoChanged);
// If newObserver is cached it won't call update until the next timer update,
// so update the observer now.
m_mountPointObserver->update();
}
}
void SpaceInfoObserver::spaceInfoChanged(quint64 size, quint64 available)
{
// Make sure that the size has actually changed
if (m_dataSize != size || m_dataAvailable != available) {
m_dataSize = size;
m_dataAvailable = available;
emit valuesChanged();
}
}

View file

@ -22,6 +22,8 @@
#include <QObject>
#include <KIO/Job>
class KUrl;
class MountPointObserver;
@ -40,12 +42,18 @@ public:
signals:
/**
* This signal is emitted if the information that size() and/or available() will return has changed.
* This signal is emitted when the size or available space changes.
*/
void valuesChanged();
private slots:
void spaceInfoChanged(quint64 size, quint64 available);
private:
MountPointObserver* m_mountPointObserver;
quint64 m_dataSize;
quint64 m_dataAvailable;
};
#endif

View file

@ -57,7 +57,7 @@ void StatusBarSpaceInfo::showEvent(QShowEvent* event)
KCapacityBar::showEvent(event);
m_observer.reset(new SpaceInfoObserver(m_url, this));
slotValuesChanged();
connect(m_observer.data(), SIGNAL(valuesChanged()), this, SLOT(slotValuesChanged()));
connect(m_observer.data(), &SpaceInfoObserver::valuesChanged, this, &StatusBarSpaceInfo::slotValuesChanged);
}
void StatusBarSpaceInfo::hideEvent(QHideEvent* event)