From 50ef3ae2f3417d01491999cef51daf338e3806ce Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 24 Nov 2011 23:05:22 +0100 Subject: Notify about moves in the source model more efficiently. Change-Id: I5ea2a2dddc1b39a3d2b405bda815f42df7c07c75 Reviewed-by: Olivier Goffart --- src/widgets/itemviews/qsortfilterproxymodel.cpp | 137 ++++++++++++++++++++---- src/widgets/itemviews/qsortfilterproxymodel.h | 4 + 2 files changed, 123 insertions(+), 18 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qsortfilterproxymodel.cpp b/src/widgets/itemviews/qsortfilterproxymodel.cpp index 74999de426..90f5719782 100644 --- a/src/widgets/itemviews/qsortfilterproxymodel.cpp +++ b/src/widgets/itemviews/qsortfilterproxymodel.cpp @@ -218,6 +218,12 @@ public: int start, int end); void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end); + void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); + void _q_sourceRowsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end); void _q_sourceColumnsInserted(const QModelIndex &source_parent, @@ -226,6 +232,12 @@ public: int start, int end); void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end); + void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); + void _q_sourceColumnsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); void _q_clearMapping(); @@ -1299,6 +1311,54 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( source_items_removed(source_parent, start, end, Qt::Vertical); } +void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + // Because rows which are contiguous in the source model might not be contiguous + // in the proxy due to sorting, the best thing we can do here is be specific about what + // parents are having their children changed. + // Optimize: Emit move signals if the proxy is not sorted. Will need to account for rows + // being filtered out though. + + saved_persistent_indexes.clear(); + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutAboutToBeChanged(parents); + if (persistent.indexes.isEmpty()) + return; + saved_persistent_indexes = store_persistent_indexes(); +} + +void QSortFilterProxyModelPrivate::_q_sourceRowsMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + // Optimize: We only need to clear and update the persistent indexes which are children of + // sourceParent or destParent + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + + update_persistent_indexes(saved_persistent_indexes); + saved_persistent_indexes.clear(); + + if (dynamic_sortfilter && update_source_sort_column()) { + //update_source_sort_column might have created wrong mapping so we have to clear it again + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + } + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutChanged(parents); +} + void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( const QModelIndex &source_parent, int start, int end) { @@ -1355,6 +1415,47 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( proxy_sort_column = q->mapFromSource(model->index(0,source_sort_column, source_parent)).column(); } +void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + saved_persistent_indexes.clear(); + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutAboutToBeChanged(parents); + + if (persistent.indexes.isEmpty()) + return; + saved_persistent_indexes = store_persistent_indexes(); +} + +void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + + update_persistent_indexes(saved_persistent_indexes); + saved_persistent_indexes.clear(); + + if (dynamic_sortfilter && update_source_sort_column()) { + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + } + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutChanged(parents); +} + /*! \since 4.1 \class QSortFilterProxyModel @@ -1576,22 +1677,22 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); - - disconnect(d->model, SIGNAL(layoutChanged()), - this, SLOT(_q_sourceLayoutChanged())); - disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutChanged())); + this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))); + + disconnect(d->model, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_sourceLayoutAboutToBeChanged())); + + disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_sourceLayoutChanged())); disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); @@ -1629,22 +1730,22 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int))); - connect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); - - connect(d->model, SIGNAL(layoutChanged()), - this, SLOT(_q_sourceLayoutChanged())); - connect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); connect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutChanged())); + this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); connect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); connect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))); + + connect(d->model, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_sourceLayoutAboutToBeChanged())); + + connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_sourceLayoutChanged())); connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); diff --git a/src/widgets/itemviews/qsortfilterproxymodel.h b/src/widgets/itemviews/qsortfilterproxymodel.h index 68d92be841..1ce84ec11e 100644 --- a/src/widgets/itemviews/qsortfilterproxymodel.h +++ b/src/widgets/itemviews/qsortfilterproxymodel.h @@ -185,10 +185,14 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)) Q_PRIVATE_SLOT(d_func(), void _q_clearMapping()) }; -- cgit v1.2.3