Commit f98d645e7b260fa5098360a5cc4fbb381a30004a

QTreeView: Optimise QTreeViewPrivate::viewIndex

... by first looking around the last find item.

This was already done, but only for the 4 closest item. Now start
searching from the last index and continue.

Reviewed-by: Gabriel
Task-number: QTBUG-8886
  
24072407
24082408/*!
24092409 \internal
2410 This function assume that left is a (grand-)child of the parent of left.
24102411*/
2411static bool treeViewItemLessThan(const QTreeViewItem &left,
2412 const QTreeViewItem &right)
2412static bool treeViewItemLessThanInInsert(const QTreeViewItem &left, const QTreeViewItem &right)
24132413{
24142414 if (left.level != right.level) {
24152415 Q_ASSERT(left.level > right.level);
24962496 QVector<QTreeViewItem>::iterator it;
24972497 it = qLowerBound(d->viewItems.begin() + firstChildItem,
24982498 d->viewItems.begin() + lastChildItem + 1,
2499 insertedItems.at(0), treeViewItemLessThan);
2499 insertedItems.at(0), treeViewItemLessThanInInsert);
25002500 insertPos = it - d->viewItems.begin();
25012501
25022502 // update stale model indexes of siblings
33973397
33983398 const int totalCount = viewItems.count();
33993399 const QModelIndex index = _index.sibling(_index.row(), 0);
3400 const int row = index.row();
3401 const quint64 internalId = index.internalId();
34003402
3401
3402 // A quick check near the last item to see if we are just incrementing
3403 const int start = lastViewedItem > 2 ? lastViewedItem - 2 : 0;
3404 const int end = lastViewedItem < totalCount - 2 ? lastViewedItem + 2 : totalCount;
3405 int row = index.row();
3406 for (int i = start; i < end; ++i) {
3407 const QModelIndex &idx = viewItems.at(i).index;
3408 if (idx.row() == row) {
3409 if (idx.internalId() == index.internalId()) {
3410 lastViewedItem = i;
3411 return i;
3412 }
3403 // We start nearest to the lastViewedItem
3404 int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem);
3405 for (int i = 0; i < localCount; ++i) {
3406 const QModelIndex &idx1 = viewItems.at(lastViewedItem + i).index;
3407 if (idx1.row() == row && idx1.internalId() == internalId) {
3408 lastViewedItem = lastViewedItem + i;
3409 return lastViewedItem;
34133410 }
3411 const QModelIndex &idx2 = viewItems.at(lastViewedItem - i - 1).index;
3412 if (idx2.row() == row && idx2.internalId() == internalId) {
3413 lastViewedItem = lastViewedItem - i - 1;
3414 return lastViewedItem;
3415 }
34143416 }
34153417
3416 // NOTE: this function is slow if the item is outside the visible area
3417 // search in visible items first and below
3418 int t = firstVisibleItem();
3419 t = t > 100 ? t - 100 : 0; // start 100 items above the visible area
3420
3421 for (int i = t; i < totalCount; ++i) {
3422 const QModelIndex &idx = viewItems.at(i).index;
3423 if (idx.row() == row) {
3424 if (idx.internalId() == index.internalId()) {
3425 lastViewedItem = i;
3426 return i;
3427 }
3418 for (int j = qMax(0, lastViewedItem + localCount); j < totalCount; ++j) {
3419 const QModelIndex &idx = viewItems.at(j).index;
3420 if (idx.row() == row && idx.internalId() == internalId) {
3421 lastViewedItem = j;
3422 return j;
34283423 }
34293424 }
3430 // search from top to first visible
3431 for (int j = 0; j < t; ++j) {
3425 for (int j = qMin(totalCount, lastViewedItem - localCount) - 1; j >= 0; --j) {
34323426 const QModelIndex &idx = viewItems.at(j).index;
3433 if (idx.row() == row) {
3434 if (idx.internalId() == index.internalId()) {
3435 lastViewedItem = j;
3436 return j;
3437 }
3427 if (idx.row() == row && idx.internalId() == internalId) {
3428 lastViewedItem = j;
3429 return j;
34383430 }
34393431 }
3432
34403433 // nothing found
34413434 return -1;
34423435}
37543754void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent,
37553755 int start, int end, bool after)
37563756{
3757 Q_Q(QTreeView);
37583757 // if we are going to do a complete relayout anyway, there is no need to update
37593758 if (delayedPendingLayout) {
37603759 _q_rowsRemoved(parent, start, end);