diff options
author | David Faure <[email protected]> | 2024-09-10 13:04:53 +0200 |
---|---|---|
committer | David Faure <[email protected]> | 2024-09-12 17:13:46 +0200 |
commit | cbc5b4fbe12b6c4410bf482cd1caac933c8b63ea (patch) | |
tree | f3f150900fa5aac3a5b2e4e69e87759cc4130c39 | |
parent | 9001262b5535e8fce11fdc8297737954d5d61f5d (diff) |
QAbstractItemView: use QPMI in currentChanged in case of layoutChanged
If the model's setData() emits layoutChanged, it invalidates QModelIndexes
that this code is working with, so we have to use a persistent model
index for 'current' to protect against that. For 'previous', Volker
Hilsheimer had the idea of moving code around so we're done with it
before calling commitData().
Fixes: QTBUG-127852
Pick-to: 6.8
Change-Id: Ieb6ebc9603e7a753d78aab11ce81ad87d71f5084
Reviewed-by: Christian Ehrlicher <[email protected]>
-rw-r--r-- | src/widgets/itemviews/qabstractitemview.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 0d8236828fa..9d27f1db172 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3817,38 +3817,43 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI Q_D(QAbstractItemView); Q_ASSERT(d->model); + QPersistentModelIndex persistentCurrent(current); // in case commitData() moves things around (QTBUG-127852) + if (previous.isValid()) { QModelIndex buddy = d->model->buddy(previous); QWidget *editor = d->editorForIndex(buddy).widget.data(); + if (isVisible()) { + update(previous); + } if (editor && !d->persistent.contains(editor)) { - commitData(editor); - if (current.row() != previous.row()) + const bool rowChanged = current.row() != previous.row(); + commitData(editor); // might invalidate previous, don't use after this line (QTBUG-127852) + if (rowChanged) closeEditor(editor, QAbstractItemDelegate::SubmitModelCache); else closeEditor(editor, QAbstractItemDelegate::NoHint); } - if (isVisible()) { - update(previous); - } } - QItemSelectionModel::SelectionFlags command = selectionCommand(current, nullptr); + const QModelIndex newCurrent = persistentCurrent; + + QItemSelectionModel::SelectionFlags command = selectionCommand(newCurrent, nullptr); if ((command & QItemSelectionModel::Current) == 0) - d->currentSelectionStartIndex = current; + d->currentSelectionStartIndex = newCurrent; - if (current.isValid() && !d->autoScrollTimer.isActive()) { + if (newCurrent.isValid() && !d->autoScrollTimer.isActive()) { if (isVisible()) { if (d->autoScroll) - scrollTo(current); - update(current); - edit(current, CurrentChanged, nullptr); - if (current.row() == (d->model->rowCount(d->root) - 1)) + scrollTo(newCurrent); + update(newCurrent); + edit(newCurrent, CurrentChanged, nullptr); + if (newCurrent.row() == (d->model->rowCount(d->root) - 1)) d->fetchMore(); } else { d->shouldScrollToCurrentOnShow = d->autoScroll; } } - setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable))); + setAttribute(Qt::WA_InputMethodEnabled, (newCurrent.isValid() && (newCurrent.flags() & Qt::ItemIsEditable))); } #if QT_CONFIG(draganddrop) |