Implement clearItemData in common models

A virtual method clearItemData was added to QAIM for Qt6.
This patch implements that method to all Qt concrete models for which
it makes sense.

Task-number: QTBUG-69616
Change-Id: If980fcfc36f723128bc56ec4587c5c3a338dbbcc
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Luca Beldi 2018-09-03 10:13:53 +01:00
parent e5d0289413
commit 551e11c286
16 changed files with 202 additions and 1 deletions

View File

@ -313,6 +313,17 @@ bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation
return d->model->setHeaderData(sourceSection, orientation, value, role);
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
\reimp
*/
bool QAbstractProxyModel::clearItemData(const QModelIndex &index)
{
Q_D(QAbstractProxyModel);
return d->model->clearItemData(mapToSource(index));
}
#endif
/*!
\reimp
*/

View File

@ -78,6 +78,9 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles) override;
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
QModelIndex buddy(const QModelIndex &index) const override;
bool canFetchMore(const QModelIndex &parent) const override;

View File

@ -197,6 +197,16 @@ bool QStringListModel::setData(const QModelIndex &index, const QVariant &value,
return false;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
\reimp
*/
bool QStringListModel::clearItemData(const QModelIndex &index)
{
return setData(index, QVariant(), Qt::EditRole);
}
#endif
/*!
Inserts \a count rows into the model, beginning at the given \a row.

View File

@ -59,6 +59,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
Qt::ItemFlags flags(const QModelIndex &index) const override;

View File

@ -3005,11 +3005,17 @@ bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value
return true;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
\reimp
*/
#else
/*!
\since 5.12
Removes the data stored in all the roles for the given \a index.
\sa setData(), data()
*/
#endif
bool QStandardItemModel::clearItemData(const QModelIndex &index)
{
if (!checkIndex(index, CheckIndexOption::IndexIsValid))

View File

@ -607,6 +607,16 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
return true;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
\reimp
*/
bool QStringListModel::clearItemData(const QModelIndex &index)
{
return setData(index, QVariant(), Qt::EditRole);
}
#endif
/*!
This function simply calls QSqlQueryModel::setQuery(\a query).
You should normally not call it on a QSqlTableModel. Instead, use

View File

@ -74,6 +74,9 @@ public:
QSqlRecord record(int row) const;
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

View File

@ -227,6 +227,22 @@ bool QListModel::setData(const QModelIndex &index, const QVariant &value, int ro
return true;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool QListModel::clearItemData(const QModelIndex &index)
{
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
return false;
QListWidgetItem *item = items.at(index.row());
const auto beginIter = item->d->values.cbegin();
const auto endIter = item->d->values.cend();
if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); }))
return true; //it's already cleared
item->d->values.clear();
emit dataChanged(index, index, QVector<int>{});
return true;
}
#endif
QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles;

View File

@ -100,6 +100,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;

View File

@ -480,6 +480,24 @@ bool QTableModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
return true;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool QTableModel::clearItemData(const QModelIndex &index)
{
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
return false;
QTableWidgetItem *itm = item(index);
if (!itm)
return false;
const auto beginIter = itm->values.cbegin();
const auto endIter = itm->values.cend();
if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); }))
return true; //it's already cleared
itm->values.clear();
emit dataChanged(index, index, QVector<int>{});
return true;
}
#endif
Qt::ItemFlags QTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())

View File

@ -129,6 +129,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;

View File

@ -390,6 +390,27 @@ bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int ro
return false;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool QTreeModel::clearItemData(const QModelIndex &index)
{
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
return false;
QTreeWidgetItem *itm = item(index);
if (!itm)
return false;
const auto beginIter = itm->values.at(index.column()).cbegin();
const auto endIter = itm->values.at(index.column()).cend();
if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); })
&& !itm->d->display.at(index.column()).isValid()) {
return true; //it's already cleared
}
itm->d->display[index.column()] = QVariant();
itm->values[index.column()].clear();
emit dataChanged(index, index, QVector<int>{});
return true;
}
#endif
QMap<int, QVariant> QTreeModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles;

View File

@ -99,7 +99,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool clearItemData(const QModelIndex &index) override;
#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;

View File

@ -116,6 +116,9 @@ private slots:
void QTBUG14363_completerWithAnyKeyPressedEditTriggers();
void mimeData();
void QTBUG50891_ensureSelectionModelSignalConnectionsAreSet();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
protected slots:
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last)
@ -1743,5 +1746,27 @@ void tst_QListWidget::QTBUG50891_ensureSelectionModelSignalConnectionsAreSet()
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void tst_QListWidget::clearItemData()
{
QListWidget list;
for (int i = 0 ; i < 4; ++i)
new QListWidgetItem(QString::number(i), &list);
QSignalSpy dataChangeSpy(list.model(), &QAbstractItemModel::dataChanged);
QVERIFY(dataChangeSpy.isValid());
QVERIFY(!list.model()->clearItemData(QModelIndex()));
QCOMPARE(dataChangeSpy.size(), 0);
QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
QVERIFY(!list.model()->index(0, 0).data().isValid());
QCOMPARE(dataChangeSpy.size(), 1);
const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), list.model()->index(0, 0));
QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), list.model()->index(0, 0));
QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
QCOMPARE(dataChangeSpy.size(), 0);
}
#endif
QTEST_MAIN(tst_QListWidget)
#include "tst_qlistwidget.moc"

View File

@ -89,6 +89,9 @@ private slots:
void itemWithHeaderItems();
void mimeData();
void selectedRowAfterSorting();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
private:
QTableWidget *testWidget;
@ -1610,5 +1613,28 @@ void tst_QTableWidget::selectedRowAfterSorting()
}
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void tst_QTableWidget::clearItemData()
{
QTableWidget table(3,3);
for (int r = 0; r < 3; r++)
for (int c = 0; c < 3; c++)
table.setItem(r,c,new QTableWidgetItem(QStringLiteral("0")));
QSignalSpy dataChangeSpy(table.model(), &QAbstractItemModel::dataChanged);
QVERIFY(dataChangeSpy.isValid());
QVERIFY(!table.model()->clearItemData(QModelIndex()));
QCOMPARE(dataChangeSpy.size(), 0);
QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
QVERIFY(!table.model()->index(0, 0).data().isValid());
QCOMPARE(dataChangeSpy.size(), 1);
const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), table.model()->index(0, 0));
QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), table.model()->index(0, 0));
QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
QCOMPARE(dataChangeSpy.size(), 0);
}
#endif
QTEST_MAIN(tst_QTableWidget)
#include "tst_qtablewidget.moc"

View File

@ -161,6 +161,9 @@ private slots:
void getMimeDataWithInvalidItem();
void testVisualItemRect();
void reparentHiddenItem();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
public slots:
void itemSelectionChanged();
@ -3529,5 +3532,43 @@ void tst_QTreeWidget::reparentHiddenItem()
QVERIFY(grandChild->isHidden());
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void tst_QTreeWidget::clearItemData()
{
QTreeWidget tree;
QAbstractItemModel* model = tree.model();
QVERIFY(model->insertColumn(0));
QVERIFY(model->insertRow(0));
const QModelIndex parentIdx = model->index(0, 0);
QVERIFY(model->insertColumn(0, parentIdx));
QVERIFY(model->insertRow(0, parentIdx));
const QModelIndex childIdx = model->index(0, 0, parentIdx);
model->setData(parentIdx, QStringLiteral("parent"));
model->setData(parentIdx, QStringLiteral("parent"), Qt::UserRole);
model->setData(childIdx, QStringLiteral("child"));
QSignalSpy dataChangeSpy(model, &QAbstractItemModel::dataChanged);
QVERIFY(dataChangeSpy.isValid());
QVERIFY(!model->clearItemData(QModelIndex()));
QCOMPARE(dataChangeSpy.size(), 0);
QVERIFY(model->clearItemData(parentIdx));
QVERIFY(!model->data(parentIdx).isValid());
QVERIFY(!model->data(parentIdx, Qt::UserRole).isValid());
QCOMPARE(dataChangeSpy.size(), 1);
QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), parentIdx);
QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), parentIdx);
QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
QVERIFY(model->clearItemData(parentIdx));
QCOMPARE(dataChangeSpy.size(), 0);
QVERIFY(model->clearItemData(childIdx));
QVERIFY(!model->data(childIdx).isValid());
QCOMPARE(dataChangeSpy.size(), 1);
dataChangeArgs = dataChangeSpy.takeFirst();
QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), childIdx);
QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), childIdx);
QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
}
#endif
QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc"