diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-12-13 12:47:36 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-12-14 22:59:33 +0100 |
commit | 04415264489cd96a4a542a2ae7db1c14558397a5 (patch) | |
tree | d7bb102efefdfd8523e4530008258ead2fa5058e /src/widgets/itemviews/qabstractitemview.cpp | |
parent | 1b71e2d894c2be7052518cdcb96020c9950e2dc7 (diff) |
QAIV: reset state if removing index while editing or committing
If the commit of data to a model index result in that index getting
filtered out, then the editor will be removed as part of committing the
data, and the index that the editor is associated with becomes invalid.
The subsequent call to closeEditor() will find that the index for the
editor is no longer valid.
This should not warn, and it should also not abort the clean-up process
early. Instead, identify that the editor that we want to closed is
already hidden. In that case, skip the warning and most of the cleanup
process, and proceed directly to the EndEditHint handling further down.
Add a test that simulates the two scenarios where this can happen:
either the committing of data results in the index being filtered out
by the existing filter; or the filter changes while editing, and the
index being edited gets removed. In both cases, we don't want to see a
warning, and the state of the item view should be reset correctly.
Pick-to: 6.7 6.6 6.5
Fixes: QTBUG-115765
Change-Id: If247172fdac9a1a9279dae96c078d32553d4ee5d
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: 🌴 Alexey Edelev 🌴 <alexey.edelev@qt.io>
Diffstat (limited to 'src/widgets/itemviews/qabstractitemview.cpp')
-rw-r--r-- | src/widgets/itemviews/qabstractitemview.cpp | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index b011f1bd77..b7c5cdaf7b 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2936,41 +2936,50 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE // Close the editor if (editor) { - bool isPersistent = d->persistent.contains(editor); - bool hadFocus = editor->hasFocus(); - QModelIndex index = d->indexForEditor(editor); + const bool isPersistent = d->persistent.contains(editor); + const QModelIndex index = d->indexForEditor(editor); if (!index.isValid()) { - qWarning("QAbstractItemView::closeEditor called with an editor that does not belong to this view"); - return; // the editor was not registered - } - - // start a timer that expires immediately when we return to the event loop - // to identify whether this close was triggered by a mousepress-initiated - // focus event - d->pressClosedEditorWatcher.start(0, this); - d->lastEditedIndex = index; - - if (!isPersistent) { - setState(NoState); - QModelIndex index = d->indexForEditor(editor); - editor->removeEventFilter(itemDelegateForIndex(index)); - d->removeEditor(editor); - } - if (hadFocus) { - if (focusPolicy() != Qt::NoFocus) - setFocus(); // this will send a focusLost event to the editor - else - editor->clearFocus(); + if (!editor->isVisible()) { + // The commit might have removed the index (e.g. it might get filtered), in + // which case the editor is already hidden and scheduled for deletion. We + // don't have to do anything, except reset the state, and continue with + // EndEditHint processing. + if (!isPersistent) + setState(NoState); + } else { + qWarning("QAbstractItemView::closeEditor called with an editor that does not belong to this view"); + return; + } } else { - d->checkPersistentEditorFocus(); - } + const bool hadFocus = editor->hasFocus(); + // start a timer that expires immediately when we return to the event loop + // to identify whether this close was triggered by a mousepress-initiated + // focus event + d->pressClosedEditorWatcher.start(0, this); + d->lastEditedIndex = index; + + if (!isPersistent) { + setState(NoState); + QModelIndex index = d->indexForEditor(editor); + editor->removeEventFilter(itemDelegateForIndex(index)); + d->removeEditor(editor); + } + if (hadFocus) { + if (focusPolicy() != Qt::NoFocus) + setFocus(); // this will send a focusLost event to the editor + else + editor->clearFocus(); + } else { + d->checkPersistentEditorFocus(); + } - QPointer<QWidget> ed = editor; - QCoreApplication::sendPostedEvents(editor, 0); - editor = ed; + QPointer<QWidget> ed = editor; + QCoreApplication::sendPostedEvents(editor, 0); + editor = ed; - if (!isPersistent && editor) - d->releaseEditor(editor, index); + if (!isPersistent && editor) + d->releaseEditor(editor, index); + } } // The EndEditHint part |