]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Prevent generating previews all the time during downloading a large file
authorPeter Penz <peter.penz19@gmail.com>
Mon, 9 Jan 2012 21:10:12 +0000 (22:10 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Mon, 9 Jan 2012 21:18:24 +0000 (22:18 +0100)
When downloading a large file the preview should not be recreated each time
a change-notification has been received. Create the preview after getting
the first file change, but postpone creating the next previews until no change
has been done during a longer period of time.

BUG: 290698
FIXED-IN: 4.8.0

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

index 0ecc0e9731d420b2198e6cc2ef095010f7598054..b00868a477d59a4dd20b88496ab2be792332cf44 100644 (file)
@@ -72,7 +72,9 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
     m_pendingVisibleItems(),
     m_pendingInvisibleItems(),
     m_previewJobs(),
-    m_resolvePendingRolesTimer(0)
+    m_resolvePendingRolesTimer(0),
+    m_changedItemsTimer(0),
+    m_changedItems()
 {
     Q_ASSERT(model);
 
@@ -95,6 +97,13 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
     m_resolvePendingRolesTimer->setInterval(1);
     m_resolvePendingRolesTimer->setSingleShot(true);
     connect(m_resolvePendingRolesTimer, SIGNAL(timeout()), this, SLOT(resolvePendingRoles()));
+
+    // Use a timer to prevent that each call of slotItemsChanged() results in a synchronous
+    // resolving of the roles. Postpone the resolving until no update has been done for 2 seconds.
+    m_changedItemsTimer = new QTimer(this);
+    m_changedItemsTimer->setInterval(2000);
+    m_changedItemsTimer->setSingleShot(true);
+    connect(m_changedItemsTimer, SIGNAL(timeout()), this, SLOT(resolveChangedItems()));
 }
 
 KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -270,9 +279,14 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang
         // Most probably a directory change is done. Clear all pending items
         // and also kill all ongoing preview-jobs.
         resetPendingRoles();
+
+        m_changedItems.clear();
+        m_changedItemsTimer->stop();
     } else {
         // Remove all items from m_pendingVisibleItems and m_pendingInvisibleItems
-        // that are not part of the model anymore.
+        // that are not part of the model anymore. The items from m_changedItems
+        // don't need to be handled here, removed items are just skipped in
+        // resolveChangedItems().
         for (int i = 0; i <= 1; ++i) {
             QSet<KFileItem>& pendingItems = (i == 0) ? m_pendingVisibleItems : m_pendingInvisibleItems;
             QMutableSetIterator<KFileItem> it(pendingItems);
@@ -290,7 +304,22 @@ void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRang
                                                   const QSet<QByteArray>& roles)
 {
     Q_UNUSED(roles);
-    startUpdating(itemRanges);
+
+    if (m_changedItemsTimer->isActive()) {
+        // A call of slotItemsChanged() has been done recently. Postpone the resolving
+        // of the roles until the timer has exceeded.
+        foreach (const KItemRange& itemRange, itemRanges) {
+            int index = itemRange.index;
+            for (int count = itemRange.count; count >= 0; --count) {
+                m_changedItems.insert(m_model->fileItem(index));
+                ++index;
+            }
+        }
+    } else {
+        // No call of slotItemsChanged() has been done recently, resolve the roles now.
+        startUpdating(itemRanges);
+    }
+    m_changedItemsTimer->start();
 }
 
 void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPixmap& pixmap)
@@ -470,6 +499,26 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles()
 #endif
 }
 
+void KFileItemModelRolesUpdater::resolveChangedItems()
+{
+    if (m_changedItems.isEmpty()) {
+        return;
+    }
+
+    KItemRangeList itemRanges;
+
+    QSetIterator<KFileItem> it(m_changedItems);
+    while (it.hasNext()) {
+        const KFileItem& item = it.next();
+        const int index = m_model->index(item);
+        if (index >= 0) {
+            itemRanges.append(KItemRange(index, 1));
+        }
+    }
+
+    startUpdating(itemRanges);
+}
+
 void KFileItemModelRolesUpdater::startUpdating(const KItemRangeList& itemRanges)
 {
     // If no valid index range is given assume that all items are visible.
index b7d8ceab0ff5ceb8361c0aad9144b93934af4051..5ed45a6ec638c6277bbe5cdc65db15ee03955a5a 100644 (file)
@@ -126,6 +126,13 @@ private slots:
     void resolvePendingRoles();
     void resolveNextPendingRoles();
 
+    /**
+     * Resolves items that have not been resolved yet after the change has been
+     * notified by slotItemsChanged(). Is invoked if the m_changedItemsTimer
+     * exceeds.
+     */
+    void resolveChangedItems();
+
 private:
     /**
      * Updates the roles for the given item ranges. The roles for the currently
@@ -189,6 +196,14 @@ private:
     QList<KJob*> m_previewJobs;
 
     QTimer* m_resolvePendingRolesTimer;
+
+    // When downloading or copying large files, the slot slotItemsChanged()
+    // will be called periodically within a quite short delay. To prevent
+    // a high CPU-load by generating e.g. previews for each notification, the update
+    // will be postponed until no file change has been done within a longer period
+    // of time.
+    QTimer* m_changedItemsTimer;
+    QSet<KFileItem> m_changedItems;
 };
 
 #endif