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;
|
QStandardItem *item = nullptr;
|
||||||
int index = d->childIndex(row, column);
|
int index = d->childIndex(row, column);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
|
QModelIndex changedIdx;
|
||||||
item = d->children.at(index);
|
item = d->children.at(index);
|
||||||
if (item)
|
if (item && d->model) {
|
||||||
item->d_func()->setParentAndModel(nullptr, nullptr);
|
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);
|
d->children.replace(index, nullptr);
|
||||||
|
if (changedIdx.isValid())
|
||||||
|
d->model->dataChanged(changedIdx, changedIdx);
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ private slots:
|
|||||||
|
|
||||||
void taskQTBUG_45114_setItemData();
|
void taskQTBUG_45114_setItemData();
|
||||||
void setItemPersistentIndex();
|
void setItemPersistentIndex();
|
||||||
|
void signalsOnTakeItem();
|
||||||
private:
|
private:
|
||||||
QStandardItemModel *m_model = nullptr;
|
QStandardItemModel *m_model = nullptr;
|
||||||
QPersistentModelIndex persistent;
|
QPersistentModelIndex persistent;
|
||||||
@ -1738,5 +1738,52 @@ void tst_QStandardItemModel::setItemPersistentIndex()
|
|||||||
QVERIFY(!persistentIndex.isValid());
|
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)
|
QTEST_MAIN(tst_QStandardItemModel)
|
||||||
#include "tst_qstandarditemmodel.moc"
|
#include "tst_qstandarditemmodel.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user