summaryrefslogtreecommitdiffstats
path: root/src/gui/itemviews/qtableview.cpp
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dietrich-de@nokia.com>2010-03-18 09:47:44 (GMT)
committerGabriel de Dietrich <gabriel.dietrich-de@nokia.com>2010-03-18 10:07:47 (GMT)
commit692f12d89e6d2cf33ca2965ccd155d30ce3d32e8 (patch)
treeaa9c63a9009c0f02d26619b461c9341a82264c3e /src/gui/itemviews/qtableview.cpp
parent6dcdab8d9ee66f420a525400d873cfccf78c7003 (diff)
downloadQt-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/qtableview.cpp')
-rw-r--r--src/gui/itemviews/qtableview.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 702a8bb..43445b4 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -1858,6 +1858,9 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF
Returns the rectangle from the viewport of the items in the given
\a selection.
+
+ Since 4.7, the returned region only contains rectangles intersecting
+ (or included in) the viewport.
*/
QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) const
{
@@ -1867,6 +1870,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
return QRegion();
QRegion selectionRegion;
+ const QRect &viewportRect = d->viewport->rect();
bool verticalMoved = verticalHeader()->sectionsMoved();
bool horizontalMoved = horizontalHeader()->sectionsMoved();
@@ -1876,8 +1880,11 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
if (range.parent() != d->root || !range.isValid())
continue;
for (int r = range.top(); r <= range.bottom(); ++r)
- for (int c = range.left(); c <= range.right(); ++c)
- selectionRegion += QRegion(visualRect(d->model->index(r, c, d->root)));
+ for (int c = range.left(); c <= range.right(); ++c) {
+ const QRect &rangeRect = visualRect(d->model->index(r, c, d->root));
+ if (viewportRect.intersects(rangeRect))
+ selectionRegion += rangeRect;
+ }
}
} else if (horizontalMoved) {
for (int i = 0; i < selection.count(); ++i) {
@@ -1889,9 +1896,11 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
if (top > bottom)
qSwap<int>(top, bottom);
int height = bottom - top;
- for (int c = range.left(); c <= range.right(); ++c)
- selectionRegion += QRegion(QRect(columnViewportPosition(c), top,
- columnWidth(c), height));
+ for (int c = range.left(); c <= range.right(); ++c) {
+ const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
+ if (viewportRect.intersects(rangeRect))
+ selectionRegion += rangeRect;
+ }
}
} else if (verticalMoved) {
for (int i = 0; i < selection.count(); ++i) {
@@ -1903,9 +1912,11 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
if (left > right)
qSwap<int>(left, right);
int width = right - left;
- for (int r = range.top(); r <= range.bottom(); ++r)
- selectionRegion += QRegion(QRect(left, rowViewportPosition(r),
- width, rowHeight(r)));
+ for (int r = range.top(); r <= range.bottom(); ++r) {
+ const QRect rangeRect(left, rowViewportPosition(r), width, rowHeight(r));
+ if (viewportRect.intersects(rangeRect))
+ selectionRegion += rangeRect;
+ }
}
} else { // nothing moved
const int gridAdjust = showGrid() ? 1 : 0;
@@ -1926,12 +1937,17 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
rleft = columnViewportPosition(range.right());
rright = columnViewportPosition(range.left()) + columnWidth(range.left());
}
- selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
+ const QRect rangeRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
+ if (viewportRect.intersects(rangeRect))
+ selectionRegion += rangeRect;
if (d->hasSpans()) {
foreach (QSpanCollection::Span *s,
d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) {
- if (range.contains(s->top(), s->left(), range.parent()))
- selectionRegion += d->visualSpanRect(*s);
+ if (range.contains(s->top(), s->left(), range.parent())) {
+ const QRect &visualSpanRect = d->visualSpanRect(*s);
+ if (viewportRect.intersects(visualSpanRect))
+ selectionRegion += visualSpanRect;
+ }
}
}
}