From d9dbd3398a258d04ec4517fd13e795b437c869d6 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 10 Apr 2012 16:30:50 +0200 Subject: Improvements for slow sorting roles If the sorting is done for data which is resolved asynchronously (e.g. rating), it is important to give a visual feedback about the state of the sorting. This is done now by a progress indication in the statusbar. Also optimizations for "Sort by type" have been done: Although resolving a type can be expensive in the most often case it is a very cheap operation. So it the sorting is done by type, try to resolve the type synchronously for at least 200 ms to prevent a asynchronous resorting. This is usually sufficient to have resolved types even for directories with several thousands of items. BUG: 292733 FIXED-IN: 4.9.0 --- src/kitemviews/kfileitemmodel.cpp | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/kitemviews/kfileitemmodel.cpp') diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 7644ae5ef..685af8972 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -38,6 +38,7 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) : m_naturalSorting(KGlobalSettings::naturalSorting()), m_sortFoldersFirst(true), m_sortRole(NameRole), + m_sortProgressPercent(-1), m_roles(), m_caseSensitivity(Qt::CaseInsensitive), m_itemData(), @@ -878,6 +879,13 @@ void KFileItemModel::insertItems(const KFileItemList& items) return; } + if (m_sortRole == TypeRole) { + // Try to resolve the MIME-types synchronously to prevent a reordering of + // the items when sorting by type (per default MIME-types are resolved + // asynchronously by KFileItemModelRolesUpdater). + determineMimeTypes(items, 200); + } + #ifdef KFILEITEMMODEL_DEBUG QElapsedTimer timer; timer.start(); @@ -1829,6 +1837,34 @@ KFileItemList KFileItemModel::childItems(const KFileItem& item) const return items; } +void KFileItemModel::emitSortProgress(int resolvedCount) +{ + // Be tolerant against a resolvedCount with a wrong range. + // Although there should not be a case where KFileItemModelRolesUpdater + // (= caller) provides a wrong range, it is important to emit + // a useful progress information even if there is an unexpected + // implementation issue. + + const int itemCount = count(); + if (resolvedCount >= itemCount) { + m_sortProgressPercent = -1; + if (m_resortAllItemsTimer->isActive()) { + m_resortAllItemsTimer->stop(); + resortAllItems(); + } + + emit sortProgress(100); + } else if (itemCount > 0) { + resolvedCount = qBound(0, resolvedCount, itemCount); + + const int progress = resolvedCount * 100 / itemCount; + if (m_sortProgressPercent != progress) { + m_sortProgressPercent = progress; + emit sortProgress(progress); + } + } +} + const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count) { static const RoleInfoMap rolesInfoMap[] = { @@ -1861,4 +1897,18 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count) return rolesInfoMap; } +void KFileItemModel::determineMimeTypes(const KFileItemList& items, int timeout) +{ + QElapsedTimer timer; + timer.start(); + foreach (KFileItem item, items) { + item.determineMimeType(); + if (timer.elapsed() > timeout) { + // Don't block the user interface, let the remaining items + // be resolved asynchronously. + return; + } + } +} + #include "kfileitemmodel.moc" -- cgit v1.3