]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Update "isExpandable" and "size"-roles
authorPeter Penz <peter.penz19@gmail.com>
Mon, 11 Jun 2012 13:43:49 +0000 (15:43 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Mon, 11 Jun 2012 13:46:55 +0000 (15:46 +0200)
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

src/kitemviews/kfileitemmodelrolesupdater.cpp
src/kitemviews/kfileitemmodelrolesupdater.h

index e07d1135e78f0994a191ccb3b9f39f88501e68a7..55f5142f638789c883d202e8659c28e3e8e8dd7d 100644 (file)
@@ -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
         }
index c520a23e889c2fd11897d2731985f6a6ca54ffc7..cabb003917107079537d685615ff149da93ae3bf 100644 (file)
@@ -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;