┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp149
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h14
2 files changed, 76 insertions, 87 deletions
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 186739075..28024fd68 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -88,7 +88,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_resolvableRoles(),
m_enabledPlugins(),
m_pendingSortRoleItems(),
- m_pendingSortRoleIndexes(),
m_pendingIndexes(),
m_pendingPreviewItems(),
m_previewJob(),
@@ -261,8 +260,9 @@ void KFileItemModelRolesUpdater::setPaused(bool paused)
resolveNextSortRole();
} else {
m_state = Idle;
- startUpdating();
}
+
+ startUpdating();
}
}
@@ -345,16 +345,13 @@ void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList& itemRan
applySortProgressToModel();
- // If there are still items whose sort role is unknown, return
- // and handle them asynchronously.
- if (!m_pendingSortRoleItems.isEmpty()) {
- if (m_state != ResolvingSortRole) {
- // Trigger the asynchronous determination of the sort role.
- killPreviewJob();
- m_state = ResolvingSortRole;
- resolveNextSortRole();
- }
- return;
+ // If there are still items whose sort role is unknown, check if the
+ // asynchronous determination of the sort role is already in progress,
+ // and start it if that is not the case.
+ if (!m_pendingSortRoleItems.isEmpty() && m_state != ResolvingSortRole) {
+ killPreviewJob();
+ m_state = ResolvingSortRole;
+ resolveNextSortRole();
}
}
@@ -419,7 +416,6 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang
m_finishedItems.clear();
m_pendingSortRoleItems.clear();
- m_pendingSortRoleIndexes.clear();
m_pendingIndexes.clear();
m_pendingPreviewItems.clear();
m_recentlyChangedItems.clear();
@@ -449,9 +445,6 @@ void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, QLi
Q_UNUSED(itemRange);
Q_UNUSED(movedToIndexes);
- // The indexes of the items with missing sort role are not valid any more.
- m_pendingSortRoleIndexes.clear();
-
// The visible items might have changed.
startUpdating();
}
@@ -492,7 +485,6 @@ void KFileItemModelRolesUpdater::slotSortRoleChanged(const QByteArray& current,
if (m_resolvableRoles.contains(current)) {
m_pendingSortRoleItems.clear();
- m_pendingSortRoleIndexes.clear();
m_finishedItems.clear();
const int count = m_model->count();
@@ -519,7 +511,6 @@ void KFileItemModelRolesUpdater::slotSortRoleChanged(const QByteArray& current,
} else {
m_state = Idle;
m_pendingSortRoleItems.clear();
- m_pendingSortRoleIndexes.clear();
applySortProgressToModel();
}
}
@@ -636,55 +627,20 @@ void KFileItemModelRolesUpdater::resolveNextSortRole()
return;
}
- if (m_pendingSortRoleItems.count() != m_pendingSortRoleIndexes.count()) {
- // The indexes with missing sort role have to be updated.
- m_pendingSortRoleIndexes.clear();
- foreach (const KFileItem& item, m_pendingSortRoleItems) {
- const int index = m_model->index(item);
- if (index < 0) {
- m_pendingSortRoleItems.remove(item);
- } else {
- m_pendingSortRoleIndexes.append(index);
- }
- }
-
- std::sort(m_pendingSortRoleIndexes.begin(), m_pendingSortRoleIndexes.end());
- }
-
- // Try to update an item in the visible range.
- QList<int>::iterator it = std::lower_bound(m_pendingSortRoleIndexes.begin(),
- m_pendingSortRoleIndexes.end(),
- m_firstVisibleIndex);
-
- // It seems that there is no such item. Start with the first item in the list.
- if (it == m_pendingSortRoleIndexes.end()) {
- it = m_pendingSortRoleIndexes.begin();
- }
-
- while (it != m_pendingSortRoleIndexes.end()) {
- // TODO: Note that removing an index from the list m_pendingSortRoleIndexes
- // at a random position is O(N). We might need a better solution
- // to make sure that this does not harm the performance if
- // many items have to be sorted.
- const int index = *it;
- const KFileItem item = m_model->fileItem(index);
+ QSet<KFileItem>::iterator it = m_pendingSortRoleItems.begin();
+ while (it != m_pendingSortRoleItems.end()) {
+ const KFileItem item = *it;
+ const int index = m_model->index(item);
// Continue if the sort role has already been determined for the
// item, and the item has not been changed recently.
if (!m_changedItems.contains(item) && m_model->data(index).contains(m_model->sortRole())) {
- m_pendingSortRoleItems.remove(item);
- m_pendingSortRoleIndexes.erase(it);
-
- // Check if we are at the end of the list (note that the list's end has changed).
- if (it != m_pendingSortRoleIndexes.end()) {
- ++it;
- }
+ it = m_pendingSortRoleItems.erase(it);
continue;
}
applySortRole(index);
- m_pendingSortRoleItems.remove(item);
- m_pendingSortRoleIndexes.erase(it);
+ m_pendingSortRoleItems.erase(it);
break;
}
@@ -836,9 +792,7 @@ void KFileItemModelRolesUpdater::slotDirWatchDirty(const QString& path)
void KFileItemModelRolesUpdater::startUpdating()
{
- // Updating the items in and near the visible area makes sense only
- // if sorting is finished.
- if (m_state == ResolvingSortRole || m_state == Paused) {
+ if (m_state == Paused) {
return;
}
@@ -848,16 +802,6 @@ void KFileItemModelRolesUpdater::startUpdating()
return;
}
- int lastVisibleIndex = m_lastVisibleIndex;
- if (lastVisibleIndex <= 0) {
- // Guess a reasonable value for the last visible index if the view
- // has not told us about the real value yet.
- lastVisibleIndex = qMin(m_firstVisibleIndex + m_maximumVisibleItems, m_model->count() - 1);
- if (lastVisibleIndex <= 0) {
- lastVisibleIndex = qMin(200, m_model->count() - 1);
- }
- }
-
// Terminate all updates that are currently active.
killPreviewJob();
m_pendingIndexes.clear();
@@ -866,12 +810,13 @@ void KFileItemModelRolesUpdater::startUpdating()
timer.start();
// Determine the icons for the visible items synchronously.
- int index;
- for (index = m_firstVisibleIndex; index <= lastVisibleIndex && timer.elapsed() < MaxBlockTimeout; ++index) {
- const KFileItem item = m_model->fileItem(index);
- applyResolvedRoles(item, ResolveFast);
+ updateVisibleIcons();
+
+ // A detailed update of the items in and near the visible area
+ // only makes sense if sorting is finished.
+ if (m_state == ResolvingSortRole) {
+ return;
}
- const int firstIndexWithoutIcon = index;
// Start the preview job or the asynchronous resolving of all roles.
QList<int> indexes = indexesToResolve();
@@ -896,6 +841,51 @@ void KFileItemModelRolesUpdater::startUpdating()
}
}
+void KFileItemModelRolesUpdater::updateVisibleIcons()
+{
+ int lastVisibleIndex = m_lastVisibleIndex;
+ if (lastVisibleIndex <= 0) {
+ // Guess a reasonable value for the last visible index if the view
+ // has not told us about the real value yet.
+ lastVisibleIndex = qMin(m_firstVisibleIndex + m_maximumVisibleItems, m_model->count() - 1);
+ if (lastVisibleIndex <= 0) {
+ lastVisibleIndex = qMin(200, m_model->count() - 1);
+ }
+ }
+
+ QElapsedTimer timer;
+ timer.start();
+
+ // Try to determine the final icons for all visible items.
+ int index;
+ for (index = m_firstVisibleIndex; index <= lastVisibleIndex && timer.elapsed() < MaxBlockTimeout; ++index) {
+ const KFileItem item = m_model->fileItem(index);
+ applyResolvedRoles(item, ResolveFast);
+ }
+
+ if (index > lastVisibleIndex) {
+ return;
+ }
+
+ // If this didn't work before MaxBlockTimeout was reached, at least
+ // prevent that the user sees 'unknown' icons.
+ disconnect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
+ this, SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>)));
+
+ while (index <= lastVisibleIndex) {
+ if (!m_model->data(index).contains("iconName")) {
+ const KFileItem item = m_model->fileItem(index);
+ QHash<QByteArray, QVariant> data;
+ data.insert("iconName", item.iconName());
+ m_model->setData(index, data);
+ }
+ ++index;
+ }
+
+ connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
+ this, SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>)));
+}
+
void KFileItemModelRolesUpdater::startPreviewJob()
{
m_state = PreviewJobRunning;
@@ -1032,11 +1022,6 @@ void KFileItemModelRolesUpdater::applySortRole(int index)
QHash<QByteArray, QVariant> data;
const KFileItem item = m_model->fileItem(index);
- if (index >= m_firstVisibleIndex && index <= m_lastVisibleIndex) {
- // Determine the icon.
- applyResolvedRoles(item, ResolveFast);
- }
-
if (m_model->sortRole() == "type") {
if (!item.isMimeTypeKnown()) {
item.determineMimeType();
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index 2a5a4041c..605c36f81 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -224,6 +224,15 @@ private:
void startUpdating();
/**
+ * Loads the icons for the visible items. After 200 ms, the function
+ * stops determining mime types and only loads preliminary icons.
+ * This is a compromise that prevents that
+ * (a) the GUI is blocked for more than 200 ms, and
+ * (b) "unknown" icons could be shown in the view.
+ */
+ void updateVisibleIcons();
+
+ /**
* Creates previews for the items starting from the first item in
* m_pendingPreviewItems.
* @see slotGotPreview()
@@ -311,11 +320,6 @@ private:
// Items for which the sort role still has to be determined.
QSet<KFileItem> m_pendingSortRoleItems;
- // While the sort role is being resolved, we also keep the indexes
- // in a sorted list. The reason is that this enables us to determine
- // both the sort role and the icon for the visible items first.
- QList<int> m_pendingSortRoleIndexes;
-
// Indexes of items which still have to be handled by
// resolveNextPendingRoles().
QList<int> m_pendingIndexes;