Fix QStandardItemModel signals on takeChild
takeItem and takeChild do not signal the change correctly to the external world, this change fixes the problem Fixes: QTBUG-89145 Change-Id: Ib4844ace53007068a2cd62eba64df99e6e45fdc0 Reviewed-by: David Faure <david.faure@kdab.com> (cherry picked from commit 811a6c6b77a94d86e28a0b00079e02a863391108) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
aba4da8a0e
commit
838b1d1b76
@ -1893,10 +1893,35 @@ QStandardItem *QStandardItem::takeChild(int row, int column)
|
||||
QStandardItem *item = nullptr;
|
||||
int index = d->childIndex(row, column);
|
||||
if (index != -1) {
|
||||
QModelIndex changedIdx;
|
||||
item = d->children.at(index);
|
||||
if (item)
|
||||
item->d_func()->setParentAndModel(nullptr, nullptr);
|
||||
if (item && d->model) {
|
||||
QStandardItemPrivate *const item_d = item->d_func();
|
||||
const int savedRows = item_d->rows;
|
||||
const int savedCols = item_d->columns;
|
||||
const QVector<QStandardItem*> savedChildren = item_d->children;
|
||||
if (savedRows > 0) {
|
||||
d->model->d_func()->rowsAboutToBeRemoved(item, 0, savedRows - 1);
|
||||
item_d->rows = 0;
|
||||
item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
|
||||
d->model->d_func()->rowsRemoved(item, 0, savedRows);
|
||||
}
|
||||
if (savedCols > 0) {
|
||||
d->model->d_func()->columnsAboutToBeRemoved(item, 0, savedCols - 1);
|
||||
item_d->columns = 0;
|
||||
if (!item_d->children.isEmpty())
|
||||
item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
|
||||
d->model->d_func()->columnsRemoved(item, 0, savedCols);
|
||||
}
|
||||
item_d->rows = savedRows;
|
||||
item_d->columns = savedCols;
|
||||
item_d->children = savedChildren;
|
||||
changedIdx = d->model->indexFromItem(item);
|
||||
item_d->setParentAndModel(nullptr, nullptr);
|
||||
}
|
||||
d->children.replace(index, nullptr);
|
||||
if (changedIdx.isValid())
|
||||
d->model->dataChanged(changedIdx, changedIdx);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ private slots:
|
||||
|
||||
void taskQTBUG_45114_setItemData();
|
||||
void setItemPersistentIndex();
|
||||
|
||||
void signalsOnTakeItem();
|
||||
private:
|
||||
QStandardItemModel *m_model = nullptr;
|
||||
QPersistentModelIndex persistent;
|
||||
@ -1738,5 +1738,52 @@ void tst_QStandardItemModel::setItemPersistentIndex()
|
||||
QVERIFY(!persistentIndex.isValid());
|
||||
}
|
||||
|
||||
void tst_QStandardItemModel::signalsOnTakeItem() // QTBUG-89145
|
||||
{
|
||||
QStandardItemModel m;
|
||||
m.insertColumns(0, 2);
|
||||
m.insertRows(0, 5);
|
||||
for (int i = 0; i < m.rowCount(); ++i) {
|
||||
for (int j = 0; j < m.columnCount(); ++j)
|
||||
m.setData(m.index(i, j), i + j);
|
||||
}
|
||||
const QModelIndex parentIndex = m.index(1, 0);
|
||||
m.insertColumns(0, 2, parentIndex);
|
||||
m.insertRows(0, 2, parentIndex);
|
||||
for (int i = 0; i < m.rowCount(parentIndex); ++i) {
|
||||
for (int j = 0; j < m.columnCount(parentIndex); ++j)
|
||||
m.setData(m.index(i, j, parentIndex), i + j + 100);
|
||||
}
|
||||
QAbstractItemModelTester mTester(&m, nullptr);
|
||||
QSignalSpy columnsRemovedSpy(&m, &QAbstractItemModel::columnsRemoved);
|
||||
QSignalSpy columnsAboutToBeRemovedSpy(&m, &QAbstractItemModel::columnsAboutToBeRemoved);
|
||||
QSignalSpy rowsRemovedSpy(&m, &QAbstractItemModel::rowsRemoved);
|
||||
QSignalSpy rowsAboutToBeRemovedSpy(&m, &QAbstractItemModel::rowsAboutToBeRemoved);
|
||||
QSignalSpy *const removeSpies[] = {&columnsRemovedSpy, &columnsAboutToBeRemovedSpy, &rowsRemovedSpy, &rowsAboutToBeRemovedSpy};
|
||||
QSignalSpy dataChangedSpy(&m, &QAbstractItemModel::dataChanged);
|
||||
QStandardItem *const takenItem = m.takeItem(1, 0);
|
||||
for (auto &&spy : removeSpies) {
|
||||
QCOMPARE(spy->count(), 1);
|
||||
const auto spyArgs = spy->takeFirst();
|
||||
QCOMPARE(spyArgs.at(0).value<QModelIndex>(), parentIndex);
|
||||
QCOMPARE(spyArgs.at(1).toInt(), 0);
|
||||
QCOMPARE(spyArgs.at(2).toInt(), 1);
|
||||
}
|
||||
QCOMPARE(dataChangedSpy.count(), 1);
|
||||
const auto dataChangedSpyArgs = dataChangedSpy.takeFirst();
|
||||
QCOMPARE(dataChangedSpyArgs.at(0).value<QModelIndex>(), m.index(1, 0));
|
||||
QCOMPARE(dataChangedSpyArgs.at(1).value<QModelIndex>(), m.index(1, 0));
|
||||
QCOMPARE(takenItem->data(Qt::EditRole).toInt(), 1);
|
||||
QCOMPARE(takenItem->rowCount(), 2);
|
||||
QCOMPARE(takenItem->columnCount(), 2);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 2; ++j)
|
||||
QCOMPARE(takenItem->child(i, j)->data(Qt::EditRole).toInt(), i + j + 100);
|
||||
}
|
||||
QCOMPARE(takenItem->model(), nullptr);
|
||||
QCOMPARE(takenItem->child(0, 0)->model(), nullptr);
|
||||
QCOMPARE(m.index(1, 0).data(), QVariant());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QStandardItemModel)
|
||||
#include "tst_qstandarditemmodel.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user