summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp33
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.h1
-rw-r--r--src/gui/itemmodels/qstandarditemmodel_p.h2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp17
-rw-r--r--src/widgets/itemviews/qlistwidget.h1
-rw-r--r--src/widgets/itemviews/qlistwidget_p.h2
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp40
-rw-r--r--tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp12
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp30
9 files changed, 99 insertions, 39 deletions
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index 519995e82a..d1e0604caf 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -278,8 +278,24 @@ void QStandardItemPrivate::setItemData(const QMap<int, QVariant> &roles)
if (newValues != values) {
values.swap(newValues);
- if (model)
- model->d_func()->itemChanged(q);
+ if (model) {
+ QVector<int> roleKeys;
+ roleKeys.reserve(roles.size() + 1);
+ bool hasEditRole = false;
+ bool hasDisplayRole = false;
+ for (auto it = roles.keyBegin(); it != roles.keyEnd(); ++it) {
+ roleKeys.push_back(*it);
+ if (*it == Qt::EditRole)
+ hasEditRole = true;
+ else if (*it == Qt::DisplayRole)
+ hasDisplayRole = true;
+ }
+ if (hasEditRole && !hasDisplayRole)
+ roleKeys.push_back(Qt::DisplayRole);
+ else if (!hasEditRole && hasDisplayRole)
+ roleKeys.push_back(Qt::EditRole);
+ model->d_func()->itemChanged(q, roleKeys);
+ }
}
}
@@ -554,7 +570,7 @@ bool QStandardItemPrivate::insertColumns(int column, int count, const QList<QSta
/*!
\internal
*/
-void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
+void QStandardItemModelPrivate::itemChanged(QStandardItem *item, const QVector<int> &roles)
{
Q_Q(QStandardItemModel);
Q_ASSERT(item);
@@ -570,8 +586,8 @@ void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
}
} else {
// Normal item
- QModelIndex index = q->indexFromItem(item);
- emit q->dataChanged(index, index);
+ const QModelIndex index = q->indexFromItem(item);
+ emit q->dataChanged(index, index, roles);
}
}
@@ -885,6 +901,9 @@ void QStandardItem::setData(const QVariant &value, int role)
{
Q_D(QStandardItem);
role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
+ const QVector<int> roles((role == Qt::DisplayRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
QVector<QStandardItemData>::iterator it;
for (it = d->values.begin(); it != d->values.end(); ++it) {
if ((*it).role == role) {
@@ -896,13 +915,13 @@ void QStandardItem::setData(const QVariant &value, int role)
d->values.erase(it);
}
if (d->model)
- d->model->d_func()->itemChanged(this);
+ d->model->d_func()->itemChanged(this, roles);
return;
}
}
d->values.append(QStandardItemData(role, value));
if (d->model)
- d->model->d_func()->itemChanged(this);
+ d->model->d_func()->itemChanged(this, roles);
}
/*!
diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h
index c54e7b27d9..d8f06b629a 100644
--- a/src/gui/itemmodels/qstandarditemmodel.h
+++ b/src/gui/itemmodels/qstandarditemmodel.h
@@ -419,6 +419,7 @@ public:
bool dropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
Q_SIGNALS:
+ // ### Qt 6: add changed roles
void itemChanged(QStandardItem *item);
protected:
diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h
index caee3ea34c..bd28ec3029 100644
--- a/src/gui/itemmodels/qstandarditemmodel_p.h
+++ b/src/gui/itemmodels/qstandarditemmodel_p.h
@@ -200,7 +200,7 @@ public:
}
void sort(QStandardItem *parent, int column, Qt::SortOrder order);
- void itemChanged(QStandardItem *item);
+ void itemChanged(QStandardItem *item, const QVector<int> &roles = QVector<int>());
void rowsAboutToBeInserted(QStandardItem *parent, int start, int end);
void columnsAboutToBeInserted(QStandardItem *parent, int start, int end);
void rowsAboutToBeRemoved(QStandardItem *parent, int start, int end);
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index ad8aac1415..1fedad80aa 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -412,10 +412,10 @@ QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator(
return std::lower_bound(begin, end, item, QListModelGreaterThan());
}
-void QListModel::itemChanged(QListWidgetItem *item)
+void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles)
{
- QModelIndex idx = index(item);
- emit dataChanged(idx, idx);
+ const QModelIndex idx = index(item);
+ emit dataChanged(idx, idx, roles);
}
QStringList QListModel::mimeTypes() const
@@ -711,8 +711,12 @@ void QListWidgetItem::setData(int role, const QVariant &value)
}
if (!found)
d->values.append(QWidgetItemData(role, value));
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
- model->itemChanged(this);
+ if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : nullptr)) {
+ const QVector<int> roles((role == Qt::DisplayRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
+ model->itemChanged(this, roles);
+ }
}
/*!
@@ -954,7 +958,8 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
\sa Qt::ItemFlags
*/
-void QListWidgetItem::setFlags(Qt::ItemFlags aflags) {
+void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
+{
itemFlags = aflags;
if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
model->itemChanged(this);
diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h
index 3caa5ce6f2..8a31411429 100644
--- a/src/widgets/itemviews/qlistwidget.h
+++ b/src/widgets/itemviews/qlistwidget.h
@@ -269,6 +269,7 @@ Q_SIGNALS:
void itemDoubleClicked(QListWidgetItem *item);
void itemActivated(QListWidgetItem *item);
void itemEntered(QListWidgetItem *item);
+ // ### Qt 6: add changed roles
void itemChanged(QListWidgetItem *item);
void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h
index 492b05ff07..30b5016db6 100644
--- a/src/widgets/itemviews/qlistwidget_p.h
+++ b/src/widgets/itemviews/qlistwidget_p.h
@@ -119,7 +119,7 @@ public:
const QList<QListWidgetItem*>::iterator &end,
Qt::SortOrder order, QListWidgetItem *item);
- void itemChanged(QListWidgetItem *item);
+ void itemChanged(QListWidgetItem *item, const QVector<int> &roles = QVector<int>());
// dnd
QStringList mimeTypes() const override;
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
index 852d9adb46..7cae554963 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
@@ -34,6 +34,8 @@
Q_DECLARE_METATYPE(QModelIndex)
+static const int s_filterRole = Qt::UserRole + 1;
+
class ModelSignalSpy : public QObject {
Q_OBJECT
public:
@@ -67,7 +69,7 @@ private Q_SLOTS:
mSignals << QStringLiteral("rowsMoved");
}
void onDataChanged(const QModelIndex &from, const QModelIndex& ) {
- mSignals << QStringLiteral("dataChanged(%1)").arg(from.data().toString());
+ mSignals << QStringLiteral("dataChanged(%1)").arg(from.data(Qt::DisplayRole).toString());
}
void onLayoutChanged() {
mSignals << QStringLiteral("layoutChanged");
@@ -78,7 +80,7 @@ private Q_SLOTS:
private:
QString textForRowSpy(const QModelIndex &parent, int start, int end)
{
- QString txt = parent.data().toString();
+ QString txt = parent.data(Qt::DisplayRole).toString();
if (!txt.isEmpty())
txt += QLatin1Char('.');
txt += QString::number(start+1);
@@ -95,13 +97,14 @@ public:
TestModel(QAbstractItemModel *sourceModel)
: QSortFilterProxyModel()
{
+ setFilterRole(s_filterRole);
setRecursiveFilteringEnabled(true);
setSourceModel(sourceModel);
}
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
{
- return sourceModel()->index(sourceRow, 0, sourceParent).data(Qt::UserRole +1).toBool()
+ return sourceModel()->index(sourceRow, 0, sourceParent).data(s_filterRole).toBool()
&& QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}
};
@@ -114,7 +117,7 @@ public:
// - - E
// as a single string, englobing children in brackets, like this:
// [A[B[C D] E]]
-// In addition, items that match the filtering (data(UserRole+1) == true) have a * after their value.
+// In addition, items that match the filtering (data(s_filterRole) == true) have a * after their value.
static QString treeAsString(const QAbstractItemModel &model, const QModelIndex &parent = QModelIndex())
{
QString ret;
@@ -126,8 +129,8 @@ static QString treeAsString(const QAbstractItemModel &model, const QModelIndex &
ret += ' ';
}
const QModelIndex child = model.index(row, 0, parent);
- ret += child.data().toString();
- if (child.data(Qt::UserRole+1).toBool())
+ ret += child.data(Qt::DisplayRole).toString();
+ if (child.data(s_filterRole).toBool())
ret += QLatin1Char('*');
ret += treeAsString(model, child);
}
@@ -146,7 +149,7 @@ static void fillModel(QStandardItemModel &model, const QString &str)
const QChar ch = str.at(i);
if ((ch == '[' || ch == ']' || ch == ' ') && !data.isEmpty()) {
if (data.endsWith('*')) {
- item->setData(true, Qt::UserRole + 1);
+ item->setData(true, s_filterRole);
data.chop(1);
}
item->setText(data);
@@ -231,10 +234,10 @@ private Q_SLOTS:
QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[ME*]]]"));
+ // filterRole is Qt::UserRole + 1, so parents are not checked and
+ // therefore no dataChanged for parents
QCOMPARE(spy.mSignals, QStringList()
- << QStringLiteral("dataChanged(ME)")
- << QStringLiteral("dataChanged(1.1)")
- << QStringLiteral("dataChanged(1)"));
+ << QStringLiteral("dataChanged(ME)"));
}
// Test changing a role that is unrelated to the filtering, in a hidden item.
@@ -319,8 +322,8 @@ private Q_SLOTS:
ModelSignalSpy spy(proxy);
// When changing the data on the designated item to show this row
QStandardItem *itemToChange = itemByText(model, add);
- QVERIFY(!itemToChange->data().toBool());
- itemToChange->setData(true);
+ QVERIFY(!itemToChange->data(s_filterRole).toBool());
+ itemToChange->setData(true, s_filterRole);
// The proxy should update as expected
QCOMPARE(treeAsString(proxy), expectedProxyStr);
@@ -408,8 +411,8 @@ private Q_SLOTS:
// When changing the data on the designated item to exclude this row again
QStandardItem *itemToChange = itemByText(model, remove);
- QVERIFY(itemToChange->data().toBool());
- itemToChange->setData(false);
+ QVERIFY(itemToChange->data(s_filterRole).toBool());
+ itemToChange->setData(false, s_filterRole);
// The proxy should update as expected
QCOMPARE(treeAsString(proxy), expectedProxyStr);
@@ -431,7 +434,7 @@ private Q_SLOTS:
ModelSignalSpy spy(proxy);
QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0);
QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1"));
- item_1_1_1_1->setData(true);
+ item_1_1_1_1->setData(true, s_filterRole);
item_1_1_1->appendRow(item_1_1_1_1);
QCOMPARE(treeAsString(proxy), QStringLiteral("[1[1.1[1.1.1[1.1.1.1*]]]]"));
@@ -456,7 +459,7 @@ private Q_SLOTS:
ModelSignalSpy spy(proxy);
{
QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1"));
- item_1_1_1_1->setData(true);
+ item_1_1_1_1->setData(true, s_filterRole);
QStandardItem *item_1_1_1 = model.item(0)->child(0)->child(0);
item_1_1_1->appendRow(item_1_1_1_1);
}
@@ -484,7 +487,7 @@ private Q_SLOTS:
{
QStandardItem *item_1_1_1 = new QStandardItem(QStringLiteral("1.1.1"));
QStandardItem *item_1_1_1_1 = new QStandardItem(QStringLiteral("1.1.1.1"));
- item_1_1_1_1->setData(true);
+ item_1_1_1_1->setData(true, s_filterRole);
item_1_1_1->appendRow(item_1_1_1_1);
QStandardItem *item_1_1 = model.item(0)->child(0);
@@ -511,7 +514,7 @@ private Q_SLOTS:
{
QStandardItem *item_1_1_2 = new QStandardItem(QStringLiteral("1.1.2"));
QStandardItem *item_1_1_2_1 = new QStandardItem(QStringLiteral("1.1.2.1"));
- item_1_1_2_1->setData(true);
+ item_1_1_2_1->setData(true, s_filterRole);
item_1_1_2->appendRow(item_1_1_2_1);
QStandardItem *item_1_1 = model.item(0)->child(0);
@@ -706,6 +709,7 @@ private Q_SLOTS:
ModelSignalSpy spy(proxy);
//qDebug() << "setFilterFixedString";
+ proxy.setFilterRole(Qt::DisplayRole);
proxy.setFilterFixedString(filter);
QCOMPARE(treeAsString(proxy), expectedProxyStr);
diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
index c0ef4f271e..d393ac70da 100644
--- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
+++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
@@ -137,6 +137,7 @@ private:
QVector<QModelIndex> rcParent;
QVector<int> rcFirst;
QVector<int> rcLast;
+ QVector<int> currentRoles;
//return true if models have the same structure, and all child have the same text
bool compareModels(QStandardItemModel *model1, QStandardItemModel *model2);
@@ -186,6 +187,12 @@ void tst_QStandardItemModel::init()
connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(columnsRemoved(QModelIndex,int,int)));
+ connect(m_model, &QAbstractItemModel::dataChanged,
+ this, [this](const QModelIndex &, const QModelIndex &, const QVector<int> &roles)
+ {
+ currentRoles = roles;
+ });
+
rcFirst.fill(-1);
rcLast.fill(-1);
}
@@ -712,15 +719,20 @@ void tst_QStandardItemModel::checkChildren()
void tst_QStandardItemModel::data()
{
+ currentRoles.clear();
// bad args
m_model->setData(QModelIndex(), "bla", Qt::DisplayRole);
+ QCOMPARE(currentRoles, {});
QIcon icon;
for (int r=0; r < m_model->rowCount(); ++r) {
for (int c=0; c < m_model->columnCount(); ++c) {
m_model->setData(m_model->index(r,c), "initialitem", Qt::DisplayRole);
+ QCOMPARE(currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole}));
m_model->setData(m_model->index(r,c), "tooltip", Qt::ToolTipRole);
+ QCOMPARE(currentRoles, {Qt::ToolTipRole});
m_model->setData(m_model->index(r,c), icon, Qt::DecorationRole);
+ QCOMPARE(currentRoles, {Qt::DecorationRole});
}
}
diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
index d4cb54b9ff..f7332a15f5 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
@@ -1381,20 +1381,38 @@ void tst_QListWidget::changeDataWithSorting_data()
<< false;
}
+class QListWidgetDataChanged : public QListWidget
+{
+ Q_OBJECT
+public:
+ using QListWidget::QListWidget;
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) override
+ {
+ QListWidget::dataChanged(topLeft, bottomRight, roles);
+ currentRoles = roles;
+ }
+ QVector<int> currentRoles;
+};
+
void tst_QListWidget::itemData()
{
- QListWidget widget;
+ QListWidgetDataChanged widget;
QListWidgetItem item(&widget);
item.setFlags(item.flags() | Qt::ItemIsEditable);
item.setData(Qt::DisplayRole, QString("0"));
+ QCOMPARE(widget.currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole}));
item.setData(Qt::CheckStateRole, Qt::PartiallyChecked);
- item.setData(Qt::UserRole + 0, QString("1"));
- item.setData(Qt::UserRole + 1, QString("2"));
- item.setData(Qt::UserRole + 2, QString("3"));
- item.setData(Qt::UserRole + 3, QString("4"));
+ QCOMPARE(widget.currentRoles, {Qt::CheckStateRole});
+ for (int i = 0; i < 4; ++i)
+ {
+ item.setData(Qt::UserRole + i, QString::number(i + 1));
+ QCOMPARE(widget.currentRoles, {Qt::UserRole + i});
+ }
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
QCOMPARE(flags.count(), 6);
- QCOMPARE(flags[Qt::UserRole + 0].toString(), QString("1"));
+ for (int i = 0; i < 4; ++i)
+ QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
}
void tst_QListWidget::changeDataWithSorting()