diff options
author | Gabriel de Dietrich <gabriel.dietrich-de@nokia.com> | 2010-03-18 09:47:44 (GMT) |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dietrich-de@nokia.com> | 2010-03-18 10:07:47 (GMT) |
commit | 692f12d89e6d2cf33ca2965ccd155d30ce3d32e8 (patch) | |
tree | aa9c63a9009c0f02d26619b461c9341a82264c3e /src/gui/itemviews/qlistview.cpp | |
parent | 6dcdab8d9ee66f420a525400d873cfccf78c7003 (diff) | |
download | Qt-692f12d89e6d2cf33ca2965ccd155d30ce3d32e8.zip Qt-692f12d89e6d2cf33ca2965ccd155d30ce3d32e8.tar.gz Qt-692f12d89e6d2cf33ca2965ccd155d30ce3d32e8.tar.bz2 |
Optimized visualRegionForSelection in various item views classes
When the number of selected items is large (a few thousands), the
computation of visualRegionForSelection can take a long time (up to a
few seconds). Analysis with valgrind shows that most of the time is
spent in miRegionOp (in qregion.cpp), which is being called by
QRegion::operator+=. The visualRegionForSelection virtual method being
called only to update the view after selection, we can safely ignore
those item's rectangles outside the viewport, thus both reducing the
number of calls to miRegionOp and the actual cost of each call.
This, however, introduces a behaviour change in
visualRegionForSelection, as the returned region will *not* contain
any rectangle *not* intersecting the viewport.
Reviewed-by: Thierry
Task-number: QTBUG-884
Diffstat (limited to 'src/gui/itemviews/qlistview.cpp')
-rw-r--r-- | src/gui/itemviews/qlistview.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index b2def39..39ca75a 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1387,6 +1387,9 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl /*! \reimp + + Since 4.7, the returned region only contains rectangles intersecting + (or included in) the viewport. */ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) const { @@ -1394,6 +1397,7 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con // ### NOTE: this is a potential bottleneck in non-static mode int c = d->column; QRegion selectionRegion; + const QRect &viewportRect = d->viewport->rect(); for (int i = 0; i < selection.count(); ++i) { if (!selection.at(i).isValid()) continue; @@ -1405,8 +1409,11 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con int t = selection.at(i).topLeft().row(); int b = selection.at(i).bottomRight().row(); if (d->viewMode == IconMode || d->isWrapping()) { // in non-static mode, we have to go through all selected items - for (int r = t; r <= b; ++r) - selectionRegion += QRegion(visualRect(d->model->index(r, c, parent))); + for (int r = t; r <= b; ++r) { + const QRect &rect = visualRect(d->model->index(r, c, parent)); + if (viewportRect.intersects(rect)) + selectionRegion += rect; + } } else { // in static mode, we can optimize a bit while (t <= b && d->isHidden(t)) ++t; while (b >= t && d->isHidden(b)) --b; @@ -1414,7 +1421,8 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con const QModelIndex bottom = d->model->index(b, c, parent); QRect rect(visualRect(top).topLeft(), visualRect(bottom).bottomRight()); - selectionRegion += QRegion(rect); + if (viewportRect.intersects(rect)) + selectionRegion += rect; } } |