QAbstractItemView: close all child editors when parent is removed
QAIV::rowsAboutToBeRemoved() closed all child editors when the child was a direct ancestor of the removed index but forgot to check if the index is an indirect ancestor. Some of those editors were removed later in updateEditorGeometries() but not all as the testcase in the bug report showed. Pick-to: 6.6 6.5 Fixes: QTBUG-103476 Change-Id: I90b3d3bff3857aa79f96eecf23d980928693b7bc Reviewed-by: David Faure <david.faure@kdab.com> (cherry picked from commit 1d799e91082092821a04885bd9d069febefc37da) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
96775c7c11
commit
8501df2c09
@ -3532,10 +3532,21 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
|
||||
}
|
||||
|
||||
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
|
||||
const auto findDirectChildOf = [](const QModelIndex &parent, QModelIndex child)
|
||||
{
|
||||
while (child.isValid()) {
|
||||
const auto parentIndex = child.parent();
|
||||
if (parentIndex == parent)
|
||||
return child;
|
||||
child = parentIndex;
|
||||
}
|
||||
return QModelIndex();
|
||||
};
|
||||
QEditorIndexHash::iterator i = d->editorIndexHash.begin();
|
||||
while (i != d->editorIndexHash.end()) {
|
||||
const QModelIndex index = i.value();
|
||||
if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
|
||||
const QModelIndex directChild = findDirectChildOf(parent, index);
|
||||
if (directChild.isValid() && directChild.row() >= start && directChild.row() <= end) {
|
||||
QWidget *editor = i.key();
|
||||
QEditorInfo info = d->indexEditorHash.take(index);
|
||||
i = d->editorIndexHash.erase(i);
|
||||
|
@ -109,6 +109,7 @@ private slots:
|
||||
void QTBUG6407_extendedSelection();
|
||||
void QTBUG6753_selectOnSelection();
|
||||
void testDelegateDestroyEditor();
|
||||
void testDelegateDestroyEditorChild();
|
||||
void testClickedSignal();
|
||||
void testChangeEditorState();
|
||||
void deselectInSingleSelection();
|
||||
@ -176,17 +177,19 @@ public:
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const override
|
||||
{
|
||||
openedEditor = new QWidget(parent);
|
||||
virtualCtorCallCount++;
|
||||
return openedEditor;
|
||||
}
|
||||
void destroyEditor(QWidget *editor, const QModelIndex &) const override
|
||||
{
|
||||
calledVirtualDtor = true;
|
||||
virtualDtorCallCount++;
|
||||
editor->deleteLater();
|
||||
}
|
||||
void changeSize() { size = QSize(50, 50); emit sizeHintChanged(QModelIndex()); }
|
||||
mutable QWidget *openedEditor = nullptr;
|
||||
QSize size;
|
||||
mutable bool calledVirtualDtor = false;
|
||||
mutable int virtualCtorCallCount = 0;
|
||||
mutable int virtualDtorCallCount = 0;
|
||||
};
|
||||
|
||||
class DialogItemDelegate : public QStyledItemDelegate
|
||||
@ -1616,9 +1619,31 @@ void tst_QAbstractItemView::testDelegateDestroyEditor()
|
||||
table.setItemDelegate(&delegate);
|
||||
table.edit(table.model()->index(1, 1));
|
||||
QAbstractItemView *tv = &table;
|
||||
QVERIFY(!delegate.calledVirtualDtor);
|
||||
QCOMPARE(delegate.virtualDtorCallCount, 0);
|
||||
tv->closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint);
|
||||
QVERIFY(delegate.calledVirtualDtor);
|
||||
QCOMPARE(delegate.virtualDtorCallCount, 1);
|
||||
}
|
||||
|
||||
void tst_QAbstractItemView::testDelegateDestroyEditorChild()
|
||||
{
|
||||
QTreeWidget tree;
|
||||
MyAbstractItemDelegate delegate;
|
||||
tree.setItemDelegate(&delegate);
|
||||
QTreeWidgetItem *topLevel = new QTreeWidgetItem;
|
||||
QTreeWidgetItem *levelOne1 = new QTreeWidgetItem(topLevel);
|
||||
QTreeWidgetItem *levelTwo1 = new QTreeWidgetItem(levelOne1);
|
||||
QTreeWidgetItem *levelOne2 = new QTreeWidgetItem(topLevel);
|
||||
QTreeWidgetItem *levelTwo2 = new QTreeWidgetItem(levelOne2);
|
||||
tree.insertTopLevelItem(0, topLevel);
|
||||
tree.openPersistentEditor(levelOne1);
|
||||
tree.openPersistentEditor(levelTwo1);
|
||||
tree.openPersistentEditor(levelOne2);
|
||||
tree.openPersistentEditor(levelTwo2);
|
||||
QCOMPARE(delegate.virtualCtorCallCount, 4);
|
||||
levelOne1->removeChild(levelTwo1);
|
||||
QCOMPARE(delegate.virtualDtorCallCount, 1);
|
||||
topLevel->removeChild(levelOne2);
|
||||
QCOMPARE(delegate.virtualDtorCallCount, 3);
|
||||
}
|
||||
|
||||
void tst_QAbstractItemView::testClickedSignal()
|
||||
|
Loading…
x
Reference in New Issue
Block a user