summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp8
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp56
2 files changed, 62 insertions, 2 deletions
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index e34123a1d2..b30bdbbc6b 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -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() ||
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 3be28b8e9b..8ccd13ff3e 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -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"