Fix tree recursion in QAbstractItemModel::match()
Recurse down the sibling at column 0 of the index instead down the index. Change-Id: Ie78d8b28eab7438ca3f83ee0df177115ca82806e Fixes: QTBUG-73864 Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
03fadc26e7
commit
b01248ebbd
@ -2360,6 +2360,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
|
|||||||
bool wrap = flags & Qt::MatchWrap;
|
bool wrap = flags & Qt::MatchWrap;
|
||||||
bool allHits = (hits == -1);
|
bool allHits = (hits == -1);
|
||||||
QString text; // only convert to a string if it is needed
|
QString text; // only convert to a string if it is needed
|
||||||
|
const int column = start.column();
|
||||||
QModelIndex p = parent(start);
|
QModelIndex p = parent(start);
|
||||||
int from = start.row();
|
int from = start.row();
|
||||||
int to = rowCount(p);
|
int to = rowCount(p);
|
||||||
@ -2367,7 +2368,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
|
|||||||
// iterates twice if wrapping
|
// iterates twice if wrapping
|
||||||
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
|
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
|
||||||
for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) {
|
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())
|
if (!idx.isValid())
|
||||||
continue;
|
continue;
|
||||||
QVariant v = data(idx, role);
|
QVariant v = data(idx, role);
|
||||||
@ -2406,10 +2407,13 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
|
|||||||
result.append(idx);
|
result.append(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (recurse && hasChildren(idx)) { // search the hierarchy
|
if (recurse) {
|
||||||
result += match(index(0, idx.column(), idx), role,
|
const auto parent = column != 0 ? idx.sibling(idx.row(), 0) : idx;
|
||||||
(text.isEmpty() ? value : text),
|
if (hasChildren(parent)) { // search the hierarchy
|
||||||
(allHits ? -1 : hits - result.count()), flags);
|
result += match(index(0, column, parent), role,
|
||||||
|
(text.isEmpty() ? value : text),
|
||||||
|
(allHits ? -1 : hits - result.count()), flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prepare for the next iteration
|
// prepare for the next iteration
|
||||||
|
@ -2363,6 +2363,45 @@ void tst_QSortFilterProxyModel::match()
|
|||||||
QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
|
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()
|
void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
|
||||||
{
|
{
|
||||||
QStandardItemModel model;
|
QStandardItemModel model;
|
||||||
|
@ -109,6 +109,7 @@ private slots:
|
|||||||
void selectionFilteredOut();
|
void selectionFilteredOut();
|
||||||
void match_data();
|
void match_data();
|
||||||
void match();
|
void match();
|
||||||
|
void matchTree();
|
||||||
void insertIntoChildrenlessItem();
|
void insertIntoChildrenlessItem();
|
||||||
void invalidateMappedChildren();
|
void invalidateMappedChildren();
|
||||||
void insertRowIntoFilteredParent();
|
void insertRowIntoFilteredParent();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user