diff options
author | David Faure <[email protected]> | 2025-06-27 13:01:58 +0200 |
---|---|---|
committer | David Faure <[email protected]> | 2025-06-30 17:40:07 +0200 |
commit | 729ee33a881cc4a829bacc75e323c3bedadf6f0e (patch) | |
tree | 5a48557d5236ad0f12935109b0d417919dfe32f3 | |
parent | 1fed7005c5bc19a284ce394fea1d383388a5b366 (diff) |
QIdentityProxyModel: call data() from subclasses in match()
The implementation of match() was only looking into the source model,
without considering the fact that data() could be reimplemented in
a QIdentityProxyModel subclass (a very common usage pattern for the
class, part of the documentation).
The simplest solution is to let the default implementation from
QAbstractItemModel do matching the usual way, calling data().
Fixes: QTBUG-78013
Pick-to: 6.10 6.9 6.8
Change-Id: If984ffa5f8dbdfe9a76eaec8b82648d705cfecd4
Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r-- | src/corelib/itemmodels/qidentityproxymodel.cpp | 14 | ||||
-rw-r--r-- | tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp | 34 |
2 files changed, 35 insertions, 13 deletions
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index 1a97dd5b05d..afe4dca5071 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -197,19 +197,7 @@ QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) cons */ QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const { - Q_D(const QIdentityProxyModel); - Q_ASSERT(start.isValid() ? start.model() == this : true); - if (!d->model) - return QModelIndexList(); - - const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags); - QModelIndexList::const_iterator it = sourceList.constBegin(); - const QModelIndexList::const_iterator end = sourceList.constEnd(); - QModelIndexList proxyList; - proxyList.reserve(sourceList.size()); - for ( ; it != end; ++it) - proxyList.append(mapFromSource(*it)); - return proxyList; + return QAbstractProxyModel::match(start, role, value, hits, flags); } /*! diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index c99242c927b..79d94c9b45c 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -67,6 +67,7 @@ private slots: void testSetHandleLayoutChanges(); void testSetHandleDataChanges(); + void matchCustomRole(); protected: void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); @@ -576,5 +577,38 @@ void tst_QIdentityProxyModel::testSetHandleDataChanges() QVERIFY(!model.isConnected(signal)); } +class CustomRoleProxyModel : public QIdentityProxyModel +{ +public: + using QIdentityProxyModel::QIdentityProxyModel; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + Q_ASSERT(index.isValid()); + if (role == Qt::UserRole) + return QStringLiteral("CustomUserData-%1").arg(index.row()); + return QIdentityProxyModel::data(index, role); + } +}; + +void tst_QIdentityProxyModel::matchCustomRole() +{ + QStandardItemModel sourceModel; + for (int i = 0; i < 5; ++i) + sourceModel.appendRow(new QStandardItem(QString("Item %1").arg(i))); + + CustomRoleProxyModel proxyModel; + proxyModel.setSourceModel(&sourceModel); + + const QString targetValue = QStringLiteral("CustomUserData-3"); + + const QModelIndexList matches = proxyModel.match(proxyModel.index(0, 0), Qt::UserRole, + targetValue, 1, Qt::MatchExactly); + + QCOMPARE(matches.size(), 1); + QCOMPARE(matches.first().row(), 3); + QCOMPARE(proxyModel.data(matches.first(), Qt::UserRole).toString(), targetValue); +} + QTEST_MAIN(tst_QIdentityProxyModel) #include "tst_qidentityproxymodel.moc" |