diff options
Diffstat (limited to 'src/corelib/itemmodels/qabstractproxymodel.cpp')
-rw-r--r-- | src/corelib/itemmodels/qabstractproxymodel.cpp | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index c0321ee282..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,7 +177,8 @@ 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; @@ -176,16 +195,16 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) // 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()); } |