X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/dcf7529688170e1ba00cf743d7420bb35d5af6ec..4e4c8d01e364c8d49427115dc242d999052b1e4e:/src/iconmanager.cpp diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp index 471e69842..b334a3e5c 100644 --- a/src/iconmanager.cpp +++ b/src/iconmanager.cpp @@ -53,16 +53,18 @@ * QListView does not invoke QItemDelegate::sizeHint() when the * uniformItemSize property has been set to true, so this property is * set before exchanging a block of icons. It is important to reset - * it to false again before the event loop is entered, otherwise QListView + * it again before the event loop is entered, otherwise QListView * would not get the correct size hints after dispatching the layoutChanged() * signal. */ class LayoutBlocker { public: - LayoutBlocker(QAbstractItemView* view) : m_view(0) + LayoutBlocker(QAbstractItemView* view) : + m_uniformSizes(false), + m_view(qobject_cast(view)) { - if (view->inherits("QListView")) { - m_view = qobject_cast(view); + if (m_view != 0) { + m_uniformSizes = m_view->uniformItemSizes(); m_view->setUniformItemSizes(true); } } @@ -70,11 +72,12 @@ public: ~LayoutBlocker() { if (m_view != 0) { - m_view->setUniformItemSizes(false); + m_view->setUniformItemSizes(m_uniformSizes); } } private: + bool m_uniformSizes; QListView* m_view; }; @@ -82,6 +85,7 @@ IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* QObject(parent), m_showPreview(false), m_clearItemQueues(true), + m_pendingVisiblePreviews(0), m_view(parent), m_previewTimer(0), m_scrollAreaTimer(0), @@ -224,6 +228,8 @@ void IconManager::slotPreviewJobFinished(KJob* job) if ((m_previewJobs.count() == 0) && m_clearItemQueues) { m_pendingItems.clear(); m_dispatchedItems.clear(); + m_pendingVisiblePreviews = 0; + QMetaObject::invokeMethod(this, "dispatchPreviewQueue", Qt::QueuedConnection); } } @@ -245,36 +251,28 @@ void IconManager::updateCutItems() void IconManager::dispatchPreviewQueue() { - int previewsCount = m_previews.count(); + const int previewsCount = m_previews.count(); if (previewsCount > 0) { // Applying the previews to the model must be done step by step // in larger blocks: Applying a preview immediately when getting the signal // 'gotPreview()' from the PreviewJob is too expensive, as a relayout // of the view would be triggered for each single preview. - - int dispatchCount = 30; - if (dispatchCount > previewsCount) { - dispatchCount = previewsCount; - } - LayoutBlocker blocker(m_view); - for (int i = 0; i < dispatchCount; ++i) { + for (int i = 0; i < previewsCount; ++i) { const ItemInfo& preview = m_previews.first(); replaceIcon(preview.url, preview.pixmap); m_previews.pop_front(); + if (m_pendingVisiblePreviews > 0) { + --m_pendingVisiblePreviews; + } } - - previewsCount = m_previews.count(); } - const bool workingPreviewJobs = (m_previewJobs.count() > 0); - if (workingPreviewJobs) { - // poll for previews as long as not all preview jobs are finished + if (m_pendingVisiblePreviews > 0) { + // As long as there are pending previews for visible items, poll + // the preview queue each 200 ms. If there are no pending previews, + // the queue is dispatched in slotPreviewJobFinished(). m_previewTimer->start(200); - } else if (previewsCount > 0) { - // all preview jobs are finished but there are still pending previews - // in the queue -> poll more aggressively - m_previewTimer->start(10); } } @@ -566,6 +564,7 @@ void IconManager::orderItems(KFileItemList& items) // generated earlier. items.removeAt(index); items.insert(0, item); + ++m_pendingVisiblePreviews; } } } else { @@ -582,6 +581,7 @@ void IconManager::orderItems(KFileItemList& items) // generated earlier. items.insert(0, items[i]); items.removeAt(i + 1); + ++m_pendingVisiblePreviews; } } }