diff options
| author | Frank Reininghaus <[email protected]> | 2014-05-22 18:42:17 +0200 |
|---|---|---|
| committer | Frank Reininghaus <[email protected]> | 2014-05-22 18:42:17 +0200 |
| commit | 4fe788f1157426e819f1ba31d1ee6388759cfd18 (patch) | |
| tree | b2bf5e060e0658238fcc288d2f071a1959a76994 /src/statusbar/mountpointobservercache.cpp | |
| parent | f27c1242371db1e69edab78f0bbca05206f47adf (diff) | |
Keep the "free space" information updated in all visible views
The old code would watch the free space on a mount point, i.e.,
determine the free space again, in 10-second intervals, only until the
view became invisible once (even if it was invisible only for a very
short moment, i.e., while splitting the view).
This commit ensures that the mount point is watched again as soon as
the corresponding view becomes visible again.
Moreover, the object that watches the free space for a mount point is
shared among all views that show URLs that belong to this mount point.
To achieve this, there is a central cache which can be used to obtain
an existing MountPointObserver for a certain path. If necessary, a new
MountPointObserver is created and added to the cache.
The MountPointObserver is removed from the cache and destroyed only if
no views use it any more, and no new users appear until the next update
(which happens every 10 seconds). This prevents that the free space is
measured repeatedly when changing the current directory on the same
mount point.
Many thanks to Emmanuel Pescosta for the initial ideas to factor out
the "free space" code and to establish a central storage for the
"observer" objects, and for providing many good suggestions how to
improve the code!
BUG: 327708
REVIEW: 118208
FIXED-IN: 4.14.0
Diffstat (limited to 'src/statusbar/mountpointobservercache.cpp')
| -rw-r--r-- | src/statusbar/mountpointobservercache.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/statusbar/mountpointobservercache.cpp b/src/statusbar/mountpointobservercache.cpp new file mode 100644 index 000000000..aff0c8e2f --- /dev/null +++ b/src/statusbar/mountpointobservercache.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frank Reininghaus <[email protected]> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "mountpointobservercache.h" + +#include "mountpointobserver.h" + +#include <KGlobal> +#include <KMountPoint> + +#include <QTimer> + +class MountPointObserverCacheSingleton +{ +public: + MountPointObserverCache instance; +}; +K_GLOBAL_STATIC(MountPointObserverCacheSingleton, s_MountPointObserverCache) + + +MountPointObserverCache::MountPointObserverCache() : + m_observerForMountPoint(), + m_mountPointForObserver(), + m_updateTimer(0) +{ + m_updateTimer = new QTimer(this); +} + +MountPointObserverCache::~MountPointObserverCache() +{ +} + +MountPointObserverCache* MountPointObserverCache::instance() +{ + return &s_MountPointObserverCache->instance; +} + +MountPointObserver* MountPointObserverCache::observerForPath(const QString& path) +{ + // 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(); + } else { + // Even if determining the mount point failed, KDiskFreeSpaceInfo might still + // be able to retrieve information about the path. + mountPointPath = path; + } + + MountPointObserver* observer = m_observerForMountPoint.value(mountPointPath); + if (!observer) { + observer = new MountPointObserver(mountPointPath, this); + m_observerForMountPoint.insert(mountPointPath, observer); + m_mountPointForObserver.insert(observer, mountPointPath); + Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count()); + + connect(observer, SIGNAL(destroyed(QObject*)), this, SLOT(slotObserverDestroyed(QObject*))); + + if (!m_updateTimer->isActive()) { + m_updateTimer->start(10000); + } + + connect(m_updateTimer, SIGNAL(timeout()), observer, SLOT(update())); + } + + return observer; +} + +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); + m_mountPointForObserver.remove(observer); + + Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count()); + + if (m_mountPointForObserver.isEmpty()) { + m_updateTimer->stop(); + } +} |
