]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Details view: Improve performance
authorPeter Penz <peter.penz19@gmail.com>
Tue, 27 Sep 2011 18:42:58 +0000 (20:42 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Tue, 27 Sep 2011 18:45:16 +0000 (20:45 +0200)
When inserting items or when updating the item-roles there is no
need to recalculate the column-widths for all items to get an
optimized column-width.

src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h

index 50f28fe5b85b989585251421b3d5141bc8f06cc3..f1594b10b01171768251c740281623a1b2a14017 100644 (file)
@@ -167,31 +167,42 @@ QSizeF KFileItemListView::itemSizeHint(int index) const
     return QSize();
 }
 
     return QSize();
 }
 
-QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes() const
+QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes(const KItemRangeList& itemRanges) const
 {
     QElapsedTimer timer;
     timer.start();
 
     QHash<QByteArray, QSizeF> sizes;
 
 {
     QElapsedTimer timer;
     timer.start();
 
     QHash<QByteArray, QSizeF> sizes;
 
-    const int itemCount = model()->count();
-    for (int i = 0; i < itemCount; ++i) {
-        foreach (const QByteArray& visibleRole, visibleRoles()) {
-            QSizeF maxSize = sizes.value(visibleRole, QSizeF(0, 0));
-            const QSizeF itemSize = visibleRoleSizeHint(i, visibleRole);
-            maxSize = maxSize.expandedTo(itemSize);
-            sizes.insert(visibleRole, maxSize);
-        }
+    int calculatedItemCount = 0;
+    bool maxTimeExceeded = false;
+    foreach (const KItemRange& itemRange, itemRanges) {
+        const int startIndex = itemRange.index;
+        const int endIndex = startIndex + itemRange.count - 1;
+
+        for (int i = startIndex; i <= endIndex; ++i) {
+            foreach (const QByteArray& visibleRole, visibleRoles()) {
+                QSizeF maxSize = sizes.value(visibleRole, QSizeF(0, 0));
+                const QSizeF itemSize = visibleRoleSizeHint(i, visibleRole);
+                maxSize = maxSize.expandedTo(itemSize);
+                sizes.insert(visibleRole, maxSize);
+            }
 
 
-        if (i > 100 && timer.elapsed() > 200) {
-            // When having several thousands of items calculating the sizes can get
-            // very expensive. We accept a possibly too small role-size in favour
-            // of having no blocking user interface.
-            #ifdef KFILEITEMLISTVIEW_DEBUG
-                kDebug() << "Timer exceeded, stopped after" << i << "items";
-            #endif
+            if (calculatedItemCount > 100 && timer.elapsed() > 200) {
+                // When having several thousands of items calculating the sizes can get
+                // very expensive. We accept a possibly too small role-size in favour
+                // of having no blocking user interface.
+                #ifdef KFILEITEMLISTVIEW_DEBUG
+                    kDebug() << "Timer exceeded, stopped after" << calculatedItemCount << "items";
+                #endif
+                maxTimeExceeded = true;
+                break;
+            }
+        }
+        if (maxTimeExceeded) {
             break;
         }
             break;
         }
+        ++calculatedItemCount;
     }
 
     // Stretch the width of the first role so that the full visible view-width
     }
 
     // Stretch the width of the first role so that the full visible view-width
@@ -213,7 +224,11 @@ QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes() const
     }
 
 #ifdef KFILEITEMLISTVIEW_DEBUG
     }
 
 #ifdef KFILEITEMLISTVIEW_DEBUG
-    kDebug() << "[TIME] Calculated dynamic item size for " << itemCount << "items:" << timer.elapsed();
+    int rangesItemCount = 0;
+    foreach (const KItemRange& itemRange, itemRanges) {
+        rangesItemCount += itemRange.count;
+    }
+    kDebug() << "[TIME] Calculated dynamic item size for " << rangesItemCount << "items:" << timer.elapsed();
 #endif
     return sizes;
 }
 #endif
     return sizes;
 }
index 696322f8f1ff9696d166966750a9735d471d7b2c..125c861421e869d65ede8069655622d656c5472d 100644 (file)
@@ -61,7 +61,7 @@ public:
     virtual QSizeF itemSizeHint(int index) const;
 
     /** @reimp */
     virtual QSizeF itemSizeHint(int index) const;
 
     /** @reimp */
-    virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
+    virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const;
 
     /** @reimp */
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
 
     /** @reimp */
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
index 6d96c099911624314baea458a81792be49715d0d..1224ff6bd4324bcb0fb8d7ed01ef28a438d6ef95 100644 (file)
@@ -404,8 +404,9 @@ QSizeF KItemListView::itemSizeHint(int index) const
     return itemSize();
 }
 
     return itemSize();
 }
 
-QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes() const
+QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes(const KItemRangeList& itemRanges) const
 {
 {
+    Q_UNUSED(itemRanges);
     return QHash<QByteArray, QSizeF>();
 }
 
     return QHash<QByteArray, QSizeF>();
 }
 
@@ -604,7 +605,7 @@ void KItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
 
 void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 {
 
 void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 {
-    updateVisibleRoleSizes();
+    updateVisibleRoleSizes(itemRanges);
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
@@ -761,7 +762,7 @@ void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges,
 {
     const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
     if (updateSizeHints) {
 {
     const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
     if (updateSizeHints) {
-        updateVisibleRoleSizes();
+        updateVisibleRoleSizes(itemRanges);
     }
 
     foreach (const KItemRange& itemRange, itemRanges) {
     }
 
     foreach (const KItemRange& itemRange, itemRanges) {
@@ -1381,13 +1382,48 @@ QHash<QByteArray, qreal> KItemListView::headerRolesWidths() const
     return rolesWidths;
 }
 
     return rolesWidths;
 }
 
-void KItemListView::updateVisibleRoleSizes()
+void KItemListView::updateVisibleRoleSizes(const KItemRangeList& itemRanges)
 {
     if (!m_itemSize.isEmpty() || m_useHeaderWidths) {
         return;
     }
 
 {
     if (!m_itemSize.isEmpty() || m_useHeaderWidths) {
         return;
     }
 
-    m_visibleRolesSizes = visibleRolesSizes();
+    const int itemCount = m_model->count();
+    int rangesItemCount = 0;
+    foreach (const KItemRange& range, itemRanges) {
+        rangesItemCount += range.count;
+    }
+
+    if (itemCount == rangesItemCount) {
+        // The sizes of all roles need to be determined
+        m_visibleRolesSizes = visibleRolesSizes(itemRanges);
+    } else {
+        // Only a sub range of the roles need to be determined.
+        // The chances are good that the sizes of the sub ranges
+        // already fit into the available sizes and hence no
+        // expensive update might be required.
+        bool updateRequired = false;
+
+        const QHash<QByteArray, QSizeF> updatedSizes = visibleRolesSizes(itemRanges);
+        QHashIterator<QByteArray, QSizeF> it(updatedSizes);
+        while (it.hasNext()) {
+            it.next();
+            const QByteArray& role = it.key();
+            const QSizeF& updatedSize = it.value();
+            const QSizeF currentSize = m_visibleRolesSizes.value(role);
+            if (updatedSize.width() > currentSize.width() || updatedSize.height() > currentSize.height()) {
+                m_visibleRolesSizes.insert(role, updatedSize);
+                updateRequired = true;
+            }
+        }
+
+        if (!updateRequired) {
+            // All the updated sizes are smaller than the current sizes and no change
+            // of the roles-widths is required
+            return;
+        }
+    }
+
     if (m_header) {
         m_header->setVisibleRolesWidths(headerRolesWidths());
     }
     if (m_header) {
         m_header->setVisibleRolesWidths(headerRolesWidths());
     }
@@ -1421,6 +1457,11 @@ void KItemListView::updateVisibleRoleSizes()
     }
 }
 
     }
 }
 
+void KItemListView::updateVisibleRoleSizes()
+{
+    updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()));
+}
+
 int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
 {
     int inc = 0;
 int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
 {
     int inc = 0;
index d6b0d5a77692a45564ffdbe932123a0eecf96c50..091d2c36b90b6ff46f77c58bbf666b6f276b48de 100644 (file)
@@ -160,11 +160,12 @@ public:
     virtual QSizeF itemSizeHint(int index) const;
 
     /**
     virtual QSizeF itemSizeHint(int index) const;
 
     /**
+     * @param itemRanges Items that must be checked for getting the visible roles sizes.
      * @return The size of each visible role in case if KItemListView::itemSize()
      *         is empty. This allows to have dynamic but equal role sizes between
      *         all items. Per default an empty hash is returned.
      */
      * @return The size of each visible role in case if KItemListView::itemSize()
      *         is empty. This allows to have dynamic but equal role sizes between
      *         all items. Per default an empty hash is returned.
      */
-    virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
+    virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const;
 
     /**
      * @return The bounding rectangle of the item relative to the top/left of
 
     /**
      * @return The bounding rectangle of the item relative to the top/left of
@@ -340,6 +341,11 @@ private:
      * if the m_itemRect is empty and no custom header-widths are used
      * (see m_useHeaderWidths).
      */
      * if the m_itemRect is empty and no custom header-widths are used
      * (see m_useHeaderWidths).
      */
+    void updateVisibleRoleSizes(const KItemRangeList& itemRanges);
+
+    /**
+     * Convenience method for updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()).
+     */
     void updateVisibleRoleSizes();
 
     /**
     void updateVisibleRoleSizes();
 
     /**