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>
This commit is contained in:
Friedemann Kleint 2014-07-16 15:20:17 +02:00
parent 83c6e74a0c
commit 9c774b7621

View File

@ -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.
@ -976,6 +976,22 @@ static QItemSelection mergeIndexes(const QVector<QPersistentModelIndex> &indexes
return rowSpans;
}
/*!
\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
@ -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);