diff options
Diffstat (limited to 'src/corelib/itemmodels/qabstractproxymodel.cpp')
-rw-r--r-- | src/corelib/itemmodels/qabstractproxymodel.cpp | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index 99324a0cd5..abdeefb4da 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -55,6 +55,41 @@ void QAbstractProxyModelPrivate::_q_sourceModelDestroyed() model = QAbstractItemModelPrivate::staticEmptyModel(); } +void QAbstractProxyModelPrivate::emitHeaderDataChanged() +{ + Q_Q(QAbstractProxyModel); + + if (updateHorizontalHeader) { + if (auto columnCount = q->columnCount(); columnCount > 0) + emit q->headerDataChanged(Qt::Horizontal, 0, columnCount - 1); + } + + if (updateVerticalHeader) { + if (auto rowCount = q->rowCount(); rowCount > 0) + emit q->headerDataChanged(Qt::Vertical, 0, rowCount - 1); + } + + updateHorizontalHeader = false; + updateVerticalHeader = false; +} + +void QAbstractProxyModelPrivate::scheduleHeaderUpdate(Qt::Orientation orientation) +{ + const bool isUpdateScheduled = updateHorizontalHeader || updateVerticalHeader; + + if (orientation == Qt::Horizontal && !updateHorizontalHeader) + updateHorizontalHeader = true; + else if (orientation == Qt::Vertical && !updateVerticalHeader) + updateVerticalHeader = true; + else + return; + + if (!isUpdateScheduled) { + Q_Q(QAbstractProxyModel); + QMetaObject::invokeMethod(q, [this]() { emitHeaderDataChanged(); }, Qt::QueuedConnection); + } +} + void QAbstractProxyModelPrivate::_q_sourceModelRowsAboutToBeInserted(const QModelIndex &parent, int, int) { if (parent.isValid()) @@ -66,25 +101,16 @@ void QAbstractProxyModelPrivate::_q_sourceModelRowsInserted(const QModelIndex &p { if (parent.isValid()) return; - if (sourceHadZeroRows) { - Q_Q(QAbstractProxyModel); - const int columnCount = q->columnCount(); - if (columnCount > 0) - emit q->headerDataChanged(Qt::Horizontal, 0, columnCount - 1); - } + if (sourceHadZeroRows) + scheduleHeaderUpdate(Qt::Horizontal); } - void QAbstractProxyModelPrivate::_q_sourceModelRowsRemoved(const QModelIndex &parent, int, int) { if (parent.isValid()) return; - if (model->rowCount() == 0) { - Q_Q(QAbstractProxyModel); - const int columnCount = q->columnCount(); - if (columnCount > 0) - emit q->headerDataChanged(Qt::Horizontal, 0, columnCount - 1); - } + if (model->rowCount() == 0) + scheduleHeaderUpdate(Qt::Horizontal); } void QAbstractProxyModelPrivate::_q_sourceModelColumnsAboutToBeInserted(const QModelIndex &parent, int, int) @@ -98,24 +124,16 @@ void QAbstractProxyModelPrivate::_q_sourceModelColumnsInserted(const QModelIndex { if (parent.isValid()) return; - if (sourceHadZeroColumns) { - Q_Q(QAbstractProxyModel); - const int rowCount = q->rowCount(); - if (rowCount > 0) - emit q->headerDataChanged(Qt::Vertical, 0, rowCount - 1); - } + if (sourceHadZeroColumns) + scheduleHeaderUpdate(Qt::Vertical); } void QAbstractProxyModelPrivate::_q_sourceModelColumnsRemoved(const QModelIndex &parent, int, int) { if (parent.isValid()) return; - if (model->columnCount() == 0) { - Q_Q(QAbstractProxyModel); - const int rowCount = q->rowCount(); - if (rowCount > 0) - emit q->headerDataChanged(Qt::Vertical, 0, rowCount - 1); - } + if (model->columnCount() == 0) + scheduleHeaderUpdate(Qt::Vertical); } /*! @@ -159,31 +177,34 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) d->model.removeBindingUnlessInWrapper(); // Special case to handle nullptr models. Otherwise we will have unwanted // notifications. - if (!sourceModel && d->model == QAbstractItemModelPrivate::staticEmptyModel()) + const QAbstractItemModel *currentModel = d->model.valueBypassingBindings(); + if (!sourceModel && currentModel == QAbstractItemModelPrivate::staticEmptyModel()) return; static const struct { const char *signalName; const char *slotName; } connectionTable[] = { + // clang-format off { SIGNAL(destroyed()), SLOT(_q_sourceModelDestroyed()) }, - { SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), SLOT(_q_sourceModelRowsAboutToBeInserted(QModelIndex, int, int)) }, - { SIGNAL(rowsInserted(QModelIndex, int, int)), SLOT(_q_sourceModelRowsInserted(QModelIndex, int, int)) }, - { SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(_q_sourceModelRowsRemoved(QModelIndex, int, int)) }, - { SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), SLOT(_q_sourceModelColumnsAboutToBeInserted(QModelIndex, int, int)) }, - { SIGNAL(columnsInserted(QModelIndex, int, int)), SLOT(_q_sourceModelColumnsInserted(QModelIndex, int, int)) }, - { SIGNAL(columnsRemoved(QModelIndex, int, int)), SLOT(_q_sourceModelColumnsRemoved(QModelIndex, int, int)) } + { SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), SLOT(_q_sourceModelRowsAboutToBeInserted(QModelIndex,int,int)) }, + { SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(_q_sourceModelRowsInserted(QModelIndex,int,int)) }, + { SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(_q_sourceModelRowsRemoved(QModelIndex,int,int)) }, + { SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), SLOT(_q_sourceModelColumnsAboutToBeInserted(QModelIndex,int,int)) }, + { SIGNAL(columnsInserted(QModelIndex,int,int)), SLOT(_q_sourceModelColumnsInserted(QModelIndex,int,int)) }, + { SIGNAL(columnsRemoved(QModelIndex,int,int)), SLOT(_q_sourceModelColumnsRemoved(QModelIndex,int,int)) } + // clang-format on }; - if (sourceModel != d->model) { - if (d->model) { + if (sourceModel != currentModel) { + if (currentModel) { for (const auto &c : connectionTable) - disconnect(d->model, c.signalName, this, c.slotName); + disconnect(currentModel, c.signalName, this, c.slotName); } if (sourceModel) { d->model.setValueBypassingBindings(sourceModel); for (const auto &c : connectionTable) - connect(d->model, c.signalName, this, c.slotName); + connect(sourceModel, c.signalName, this, c.slotName); } else { d->model.setValueBypassingBindings(QAbstractItemModelPrivate::staticEmptyModel()); } @@ -443,7 +464,7 @@ QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const { Q_D(const QAbstractProxyModel); QModelIndexList list; - list.reserve(indexes.count()); + list.reserve(indexes.size()); for (const QModelIndex &index : indexes) list << mapToSource(index); return d->model->mimeData(list); |