diff options
3 files changed, 49 insertions, 5 deletions
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index e816add91d..83dcf68314 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2360,6 +2360,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, bool wrap = flags & Qt::MatchWrap; bool allHits = (hits == -1); QString text; // only convert to a string if it is needed + const int column = start.column(); QModelIndex p = parent(start); int from = start.row(); int to = rowCount(p); @@ -2367,7 +2368,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, // iterates twice if wrapping for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) { for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) { - QModelIndex idx = index(r, start.column(), p); + QModelIndex idx = index(r, column, p); if (!idx.isValid()) continue; QVariant v = data(idx, role); @@ -2406,10 +2407,13 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, result.append(idx); } } - if (recurse && hasChildren(idx)) { // search the hierarchy - result += match(index(0, idx.column(), idx), role, - (text.isEmpty() ? value : text), - (allHits ? -1 : hits - result.count()), flags); + if (recurse) { + const auto parent = column != 0 ? idx.sibling(idx.row(), 0) : idx; + if (hasChildren(parent)) { // search the hierarchy + result += match(index(0, column, parent), role, + (text.isEmpty() ? value : text), + (allHits ? -1 : hits - result.count()), flags); + } } } // prepare for the next iteration diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp index 50e87f21ac..ccce5a44e5 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp @@ -2363,6 +2363,45 @@ void tst_QSortFilterProxyModel::match() QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i)); } +QList<QStandardItem *> createStandardItemList(const QString &prefix, int n) +{ + QList<QStandardItem *> result; + for (int i = 0; i < n; ++i) + result.append(new QStandardItem(prefix + QString::number(i))); + return result; +} + +// QTBUG-73864, recursive search in a tree model. + +void tst_QSortFilterProxyModel::matchTree() +{ + QStandardItemModel model(0, 2); + // Header00 Header01 + // Header10 Header11 + // Item00 Item01 + // Item10 Item11 + model.appendRow(createStandardItemList(QLatin1String("Header0"), 2)); + auto headerRow = createStandardItemList(QLatin1String("Header1"), 2); + model.appendRow(headerRow); + headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item0"), 2)); + headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item1"), 2)); + + auto item11 = model.match(model.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20, + Qt::MatchRecursive).value(0); + QVERIFY(item11.isValid()); + QCOMPARE(item11.data().toString(), QLatin1String("Item11")); + + // Repeat in proxy model + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + auto proxyItem11 = proxy.match(proxy.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20, + Qt::MatchRecursive).value(0); + QVERIFY(proxyItem11.isValid()); + QCOMPARE(proxyItem11.data().toString(), QLatin1String("Item11")); + + QCOMPARE(proxy.mapToSource(proxyItem11).internalId(), item11.internalId()); +} + void tst_QSortFilterProxyModel::insertIntoChildrenlessItem() { QStandardItemModel model; diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h index d598a60932..8ae97165b8 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h @@ -109,6 +109,7 @@ private slots: void selectionFilteredOut(); void match_data(); void match(); + void matchTree(); void insertIntoChildrenlessItem(); void invalidateMappedChildren(); void insertRowIntoFilteredParent(); |