diff options
| author | Peter Penz <[email protected]> | 2012-06-11 15:43:49 +0200 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2012-06-11 15:46:55 +0200 |
| commit | 6c15705528f1a316d7896f7684761b2aae234c1f (patch) | |
| tree | bbba0cb41f0f0160e8c42dc157b331c597de9628 /src | |
| parent | dbf233ea28fc895e9e4c235cd95a9adba0c977a8 (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
Diffstat (limited to 'src')
| -rw-r--r-- | src/kitemviews/kfileitemmodelrolesupdater.cpp | 63 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemmodelrolesupdater.h | 11 |
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; |
