diff options
author | Jesus Fernandez <jesus.fernandez@qt.io> | 2017-06-20 12:51:40 +0200 |
---|---|---|
committer | Jesus Fernandez <Jesus.Fernandez@qt.io> | 2017-07-27 19:41:06 +0000 |
commit | 763b0a68beb3b1502f6f4c1b979f0a576fc9980b (patch) | |
tree | 3020d7a24db0e6437f2b3fb7678b6b55f4e6daab | |
parent | 7c45c6a3c44f73aac5a7422ce66235bf32b510e3 (diff) |
Fix QStandardItem::setChild crash when passing a null pointer
Passing a null pointer as a parameter to the setChild function no
longer crashes when calling the
QStandardItemModelPrivate::itemChanged signal. The child is removed
from the model.
The patch also fixes the behavior of deleting a item. A
dataChanged signal is emitted.
Change-Id: I027e8b0d84fe33c5fca056df870f0e60a020824b
Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r-- | src/gui/itemmodels/qstandarditemmodel.cpp | 15 | ||||
-rw-r--r-- | tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp | 27 |
2 files changed, 40 insertions, 2 deletions
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 1d6e2924b1..07e372b1ae 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -148,8 +148,14 @@ void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item, if (model && emitChanged) emit model->layoutChanged(); - if (emitChanged && model) - model->d_func()->itemChanged(item); + if (emitChanged && model) { + if (item) { + model->d_func()->itemChanged(item); + } else { + const QModelIndex idx = model->index(row, column, q->index()); + emit model->dataChanged(idx, idx); + } + } } @@ -174,7 +180,9 @@ void QStandardItemPrivate::childDeleted(QStandardItem *child) { int index = childIndex(child); Q_ASSERT(index != -1); + const auto modelIndex = child->index(); children.replace(index, 0); + emit model->dataChanged(modelIndex, modelIndex); } /*! @@ -476,6 +484,7 @@ bool QStandardItemPrivate::insertColumns(int column, int count, const QList<QSta void QStandardItemModelPrivate::itemChanged(QStandardItem *item) { Q_Q(QStandardItemModel); + Q_ASSERT(item); if (item->d_func()->parent == 0) { // Header item int idx = columnHeaderItems.indexOf(item); @@ -1721,6 +1730,8 @@ bool QStandardItem::hasChildren() const item) takes ownership of \a item. If necessary, the row count and column count are increased to fit the item. + \note Passing a null pointer as \a item removes the item. + \sa child() */ void QStandardItem::setChild(int row, int column, QStandardItem *item) diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp index cff26be7bb..2f5537adfe 100644 --- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -117,6 +117,9 @@ private slots: void useCase2(); void useCase3(); + void setNullChild(); + void deleteChild(); + void rootItemFlags(); #ifdef QT_BUILD_INTERNAL void treeDragAndDrop(); @@ -1364,6 +1367,30 @@ void tst_QStandardItemModel::useCase3() delete childItem; } +void tst_QStandardItemModel::setNullChild() +{ + QStandardItemModel model; + model.setColumnCount(2); + createChildren(&model, model.invisibleRootItem(), 0); + QStandardItem *item = model.item(0); + QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); + item->setChild(0, nullptr); + QCOMPARE(item->child(0), nullptr); + QCOMPARE(spy.count(), 1); +} + +void tst_QStandardItemModel::deleteChild() +{ + QStandardItemModel model; + model.setColumnCount(2); + createChildren(&model, model.invisibleRootItem(), 0); + QStandardItem *item = model.item(0); + QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); + delete item->child(0); + QCOMPARE(item->child(0), nullptr); + QCOMPARE(spy.count(), 1); +} + void tst_QStandardItemModel::rootItemFlags() { QStandardItemModel model(6, 4); |