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:
parent
65f6ad26ed
commit
f37d3e2cd9
@ -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() ||
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user