┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2012-06-11 15:43:49 +0200
committerPeter Penz <[email protected]>2012-06-11 15:46:55 +0200
commit6c15705528f1a316d7896f7684761b2aae234c1f (patch)
treebbba0cb41f0f0160e8c42dc157b331c597de9628
parentdbf233ea28fc895e9e4c235cd95a9adba0c977a8 (diff)
Update "isExpandable" and "size"-roles
If the "isExpandable"- or "size"-role is shown for a folder, the number of sub-items must be watched to be able to update the state of those 2 roles. This fixes the issue that e.g. no expanding-toggle is shown if an sub-directory has been created inside an empty directory. BUG: 293972 FIXED-IN: 4.9.0
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp63
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h11
2 files changed, 71 insertions, 3 deletions
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index e07d1135e..55f5142f6 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -24,6 +24,7 @@
#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
+#include <KDirWatch>
#include <KFileItem>
#include <KGlobal>
#include <KIO/JobUiDelegate>
@@ -84,7 +85,9 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_pendingInvisibleItems(),
m_previewJobs(),
m_changedItemsTimer(0),
- m_changedItems()
+ m_changedItems(),
+ m_dirWatcher(0),
+ m_watchedDirs()
#ifdef HAVE_NEPOMUK
, m_nepomukResourceWatcher(0),
m_nepomukUriItems()
@@ -121,6 +124,11 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
#ifdef HAVE_NEPOMUK
m_resolvableRoles += KNepomukRolesProvider::instance().roles();
#endif
+
+ // When folders are expandable or the item-count is shown for folders, it is necessary
+ // to watch the number of items of the sub-folder to be able to react on changes.
+ m_dirWatcher = new KDirWatch(this);
+ connect(m_dirWatcher, SIGNAL(dirty(QString)), this, SLOT(slotDirWatchDirty(QString)));
}
KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -318,10 +326,31 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang
{
Q_UNUSED(itemRanges);
+ const bool allItemsRemoved = (m_model->count() == 0);
+
+ if (!m_watchedDirs.isEmpty()) {
+ // Don't let KDirWatch watch for removed items
+ if (allItemsRemoved) {
+ foreach (const QString& path, m_watchedDirs) {
+ m_dirWatcher->removeDir(path);
+ }
+ m_watchedDirs.clear();
+ } else {
+ QMutableSetIterator<QString> it(m_watchedDirs);
+ while (it.hasNext()) {
+ const QString& path = it.next();
+ if (m_model->index(KUrl(path)) < 0) {
+ m_dirWatcher->removeDir(path);
+ it.remove();
+ }
+ }
+ }
+ }
+
#ifdef HAVE_NEPOMUK
if (m_nepomukResourceWatcher) {
// Don't let the ResourceWatcher watch for removed items
- if (m_model->count() == 0) {
+ if (allItemsRemoved) {
m_nepomukResourceWatcher->setResources(QList<Nepomuk::Resource>());
m_nepomukResourceWatcher->stop();
m_nepomukUriItems.clear();
@@ -352,7 +381,7 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang
return;
}
- if (m_model->count() == 0) {
+ if (allItemsRemoved) {
// Most probably a directory change is done. Clear all pending items
// and also kill all ongoing preview-jobs.
resetPendingRoles();
@@ -585,6 +614,29 @@ void KFileItemModelRolesUpdater::applyChangedNepomukRoles(const Nepomuk::Resourc
#endif
}
+void KFileItemModelRolesUpdater::slotDirWatchDirty(const QString& path)
+{
+ const bool getSizeRole = m_roles.contains("size");
+ const bool getIsExpandableRole = m_roles.contains("isExpandable");
+
+ if (getSizeRole || getIsExpandableRole) {
+ const int index = m_model->index(KUrl(path));
+ if (index >= 0) {
+ QHash<QByteArray, QVariant> data;
+
+ const int count = subItemsCount(path);
+ if (getSizeRole) {
+ data.insert("size", count);
+ }
+ if (getIsExpandableRole) {
+ data.insert("isExpandable", count > 0);
+ }
+
+ m_model->setData(index, data);
+ }
+ }
+}
+
void KFileItemModelRolesUpdater::startUpdating(const KItemRangeList& itemRanges)
{
// If no valid index range is given assume that all items are visible.
@@ -968,6 +1020,11 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
if (getIsExpandableRole) {
data.insert("isExpandable", count > 0);
}
+
+ if (!m_dirWatcher->contains(path)) {
+ m_dirWatcher->addDir(path);
+ m_watchedDirs.insert(path);
+ }
} else if (getSizeRole) {
data.insert("size", -1); // -1 indicates an unknown number of items
}
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index c520a23e8..cabb00391 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -32,6 +32,7 @@
#include <QSize>
#include <QStringList>
+class KDirWatch;
class KFileItemModel;
class KJob;
class QPixmap;
@@ -161,6 +162,13 @@ private slots:
void applyChangedNepomukRoles(const Nepomuk::Resource& resource);
+ /**
+ * Is invoked if a directory watched by KDirWatch got dirty. Updates
+ * the "isExpandable"- and "size"-roles of the item that matches to
+ * the given path.
+ */
+ void slotDirWatchDirty(const QString& path);
+
private:
/**
* Updates the roles for the given item ranges. The roles for the currently
@@ -262,6 +270,9 @@ private:
QTimer* m_changedItemsTimer;
QSet<KFileItem> m_changedItems;
+ KDirWatch* m_dirWatcher;
+ mutable QSet<QString> m_watchedDirs; // Required as sadly KDirWatch does not offer a getter method
+ // to get all watched directories.
#ifdef HAVE_NEPOMUK
Nepomuk::ResourceWatcher* m_nepomukResourceWatcher;
mutable QHash<QUrl, KUrl> m_nepomukUriItems;