summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels/qabstractproxymodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/itemmodels/qabstractproxymodel.cpp')
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp95
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);