summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <[email protected]>2024-09-10 13:04:53 +0200
committerDavid Faure <[email protected]>2024-09-12 17:13:46 +0200
commitcbc5b4fbe12b6c4410bf482cd1caac933c8b63ea (patch)
treef3f150900fa5aac3a5b2e4e69e87759cc4130c39
parent9001262b5535e8fce11fdc8297737954d5d61f5d (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.cpp31
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 &current, 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)