]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Performance improvement when showing previews inside directories having several 1000...
authorPeter Penz <peter.penz19@gmail.com>
Tue, 24 Jun 2008 23:01:21 +0000 (23:01 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Tue, 24 Jun 2008 23:01:21 +0000 (23:01 +0000)
CCMAIL: fredrik@kde.org
CCMAIL: faure@kde.org
CCMAIL: ereslibre@kde.org

svn path=/trunk/KDE/kdebase/apps/; revision=824118

src/iconmanager.cpp

index 94432102c1f2169328b0e27425230414ddb5544d..471e69842f96aca2b6e3dd75edb401be2e13ec2e 100644 (file)
 #include <QAbstractItemView>
 #include <QClipboard>
 #include <QColor>
+#include <QListView>
 #include <QPainter>
 #include <QScrollBar>
 #include <QIcon>
 
+/**
+ * If the passed item view is an instance of QListView, expensive
+ * layout operations are blocked in the constructor and are unblocked
+ * again in the destructor.
+ *
+ * This helper class is a workaround for the following huge performance
+ * problem when having directories with several 1000 items:
+ * - each change of an icon emits a dataChanged() signal from the model
+ * - QListView iterates through all items on each dataChanged() signal
+ *   and invokes QItemDelegate::sizeHint()
+ * - the sizeHint() implementation of KFileItemDelegate is quite complex,
+ *   invoking it 1000 times for each icon change might block the UI
+ *
+ * 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
+ * would not get the correct size hints after dispatching the layoutChanged()
+ * signal.
+ */
+class LayoutBlocker {
+public:
+    LayoutBlocker(QAbstractItemView* view) : m_view(0)
+    {
+        if (view->inherits("QListView")) {
+            m_view = qobject_cast<QListView*>(view);
+            m_view->setUniformItemSizes(true);
+        }
+    }
+
+    ~LayoutBlocker()
+    {
+        if (m_view != 0) {
+            m_view->setUniformItemSizes(false);
+        }
+    }
+
+private:
+    QListView* m_view;
+};
+
 IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model) :
     QObject(parent),
     m_showPreview(false),
@@ -215,6 +257,7 @@ void IconManager::dispatchPreviewQueue()
             dispatchCount = previewsCount;
         }
 
+        LayoutBlocker blocker(m_view);
         for (int i = 0; i < dispatchCount; ++i) {
             const ItemInfo& preview = m_previews.first();
             replaceIcon(preview.url, preview.pixmap);