summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-07-16 15:20:17 +0200
committerFriedemann Kleint <Friedemann.Kleint@digia.com>2014-07-17 11:26:29 +0200
commit9c774b7621fdc99c03fad1b424b09b82057dc748 (patch)
treed8d0f6df91df5514d1caf9b7c4b4628054bc2121 /src/corelib
parent83c6e74a0c7d8de883b923f14e59b66bf05fa57f (diff)
QItemSelectionModel: Sort persistent model indexes taking parent into account.
When sorting a tree model with large sub-trees and and a large selection, the existing sort function would mix indexes of different parents, causing a fragmented selection, which slows down painting. Task-number: QTBUG-33954 Change-Id: Ia585fc1e5de9a1a3f6124a58c9c7c40fcbdbfb6a Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index 883aa5b982..0a75d5998a 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -979,6 +979,22 @@ static QItemSelection mergeIndexes(const QVector<QPersistentModelIndex> &indexes
/*!
\internal
+ Sort predicate function for QItemSelectionModelPrivate::_q_layoutChanged(),
+ sorting by parent first in addition to operator<(). This is to prevent
+ fragmentation of the selection by grouping indexes with the same row, column
+ of different parents next to each other, which may happen when a selection
+ spans sub-trees.
+*/
+static bool qt_PersistentModelIndexLessThan(const QPersistentModelIndex &i1, const QPersistentModelIndex &i2)
+{
+ const QModelIndex parent1 = i1.parent();
+ const QModelIndex parent2 = i2.parent();
+ return parent1 == parent2 ? i1 < i2 : parent1 < parent2;
+}
+
+/*!
+ \internal
+
Merge the selected indexes into selection ranges again.
*/
void QItemSelectionModelPrivate::_q_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint hint)
@@ -1011,8 +1027,10 @@ void QItemSelectionModelPrivate::_q_layoutChanged(const QList<QPersistentModelIn
if (hint != QAbstractItemModel::VerticalSortHint) {
// sort the "new" selection, as preparation for merging
- std::stable_sort(savedPersistentIndexes.begin(), savedPersistentIndexes.end());
- std::stable_sort(savedPersistentCurrentIndexes.begin(), savedPersistentCurrentIndexes.end());
+ std::stable_sort(savedPersistentIndexes.begin(), savedPersistentIndexes.end(),
+ qt_PersistentModelIndexLessThan);
+ std::stable_sort(savedPersistentCurrentIndexes.begin(), savedPersistentCurrentIndexes.end(),
+ qt_PersistentModelIndexLessThan);
// update the selection by merging the individual indexes
ranges = mergeIndexes(savedPersistentIndexes);