Fix segfault when delegates change properties on editors.

The solution is similar to that
in b84e180263 which affected
QSortFilterProxyModel.

Task-number: QTBUG-25370

Change-Id: I6bbb9d9786bcb2c9fa8027ab8a7cc13664784b8d
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Stephen Kelly 2012-10-02 18:15:33 +02:00 committed by The Qt Project
parent 65f6ad26ed
commit f37d3e2cd9
2 changed files with 62 additions and 2 deletions

View File

@ -4118,8 +4118,12 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo
// we are counting on having relatively few editors
const bool checkIndexes = tl.isValid() && br.isValid();
const QModelIndex parent = tl.parent();
QIndexEditorHash::const_iterator it = indexEditorHash.constBegin();
for (; it != indexEditorHash.constEnd(); ++it) {
// QTBUG-25370: We need to copy the indexEditorHash, because while we're
// iterating over it, we are calling methods which can allow user code to
// call a method on *this which can modify the member indexEditorHash.
const QIndexEditorHash indexEditorHashCopy = indexEditorHash;
QIndexEditorHash::const_iterator it = indexEditorHashCopy.constBegin();
for (; it != indexEditorHashCopy.constEnd(); ++it) {
QWidget *editor = it.value().widget.data();
const QModelIndex index = it.key();
if (it.value().isStatic || !editor || !index.isValid() ||

View File

@ -226,6 +226,7 @@ private slots:
void QTBUG6753_selectOnSelection();
void testDelegateDestroyEditor();
void testClickedSignal();
void testChangeEditorState();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@ -1534,5 +1535,60 @@ void tst_QAbstractItemView::testClickedSignal()
}
class StateChangeDelegate : public QItemDelegate {
Q_OBJECT
public:
explicit StateChangeDelegate(QObject* parent = 0) :
QItemDelegate(parent)
{}
void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE {
static bool w = true;
editor->setEnabled(w);
w = !w;
}
};
class StateChangeModel : public QStandardItemModel {
Q_OBJECT
public:
explicit StateChangeModel(QObject *parent = 0) :
QStandardItemModel(parent)
{}
void emitDataChanged() {
emit dataChanged(index(0, 0), index(0, 1));
}
};
void tst_QAbstractItemView::testChangeEditorState()
{
// Test for QTBUG-25370
StateChangeModel model;
{
QStandardItem* item = new QStandardItem("a");
model.setItem(0, 0, item);
}
{
QStandardItem* item = new QStandardItem("b");
model.setItem(0, 1, item);
}
QTableView view;
view.setEditTriggers(QAbstractItemView::CurrentChanged);
view.setItemDelegate(new StateChangeDelegate);
view.setModel(&model);
view.show();
QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
model.emitDataChanged();
// No segfault - the test passes.
}
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"