summaryrefslogtreecommitdiffstats
path: root/src/gui/itemviews/qlistview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemviews/qlistview.cpp')
-rw-r--r--src/gui/itemviews/qlistview.cpp145
1 files changed, 87 insertions, 58 deletions
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 4652b91..40f28d4 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -709,6 +709,31 @@ void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
selectionModel->select(selection, command);
}
+/*!
+ \reimp
+
+ We have a QListView way of knowing what elements are on the viewport
+ through the intersectingSet function
+*/
+QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ Q_Q(const QListView);
+ QRect &rect = *r;
+ const QRect viewportRect = viewport->rect();
+ QItemViewPaintPairs ret;
+ const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet();
+ for (int i = 0; i < indexes.count(); ++i) {
+ const QModelIndex &index = indexes.at(i);
+ if (visibleIndexes.contains(index)) {
+ const QRect current = q->visualRect(index);
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
+ }
+ rect &= viewportRect;
+ return ret;
+}
/*!
\internal
@@ -925,9 +950,9 @@ void QListView::dragMoveEvent(QDragMoveEvent *e)
QModelIndex index;
if (d->movement == Snap) {
QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize());
- d->intersectingSet(rect);
- index = d->intersectVector.count() > 0
- ? d->intersectVector.last() : QModelIndex();
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
+ index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
} else {
index = indexAt(e->pos());
}
@@ -1100,10 +1125,8 @@ void QListView::paintEvent(QPaintEvent *e)
return;
QStyleOptionViewItemV4 option = d->viewOptionsV4();
QPainter painter(d->viewport);
- QRect area = e->rect();
- d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
- const QVector<QModelIndex> toBeRendered = d->intersectVector;
+ const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
const QModelIndex current = currentIndex();
const QModelIndex hover = d->hover;
@@ -1225,9 +1248,9 @@ QModelIndex QListView::indexAt(const QPoint &p) const
{
Q_D(const QListView);
QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
- d->intersectingSet(rect);
- QModelIndex index = d->intersectVector.count() > 0
- ? d->intersectVector.last() : QModelIndex();
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
if (index.isValid() && visualRect(index).contains(p))
return index;
return QModelIndex();
@@ -1325,38 +1348,38 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
if (d->gridSize().isValid()) rect.setSize(d->gridSize());
QSize contents = d->contentsSize();
- d->intersectVector.clear();
+ QVector<QModelIndex> intersectVector;
switch (cursorAction) {
case MoveLeft:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(-rect.width(), 0);
if (rect.right() <= 0)
return current;
if (rect.left() < 0)
rect.setLeft(0);
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MoveRight:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(rect.width(), 0);
if (rect.left() >= contents.width())
return current;
if (rect.right() > contents.width())
rect.setRight(contents.width());
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MovePageUp:
rect.moveTop(rect.top() - d->viewport->height());
if (rect.top() < rect.height())
rect.moveTop(rect.height());
case MovePrevious:
case MoveUp:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(0, -rect.height());
if (rect.bottom() <= 0) {
#ifdef QT_KEYPAD_NAVIGATION
@@ -1372,17 +1395,17 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
if (rect.top() < 0)
rect.setTop(0);
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MovePageDown:
rect.moveTop(rect.top() + d->viewport->height());
if (rect.bottom() > contents.height() - rect.height())
rect.moveBottom(contents.height() - rect.height());
case MoveNext:
case MoveDown:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(0, rect.height());
if (rect.top() >= contents.height()) {
#ifdef QT_KEYPAD_NAVIGATION
@@ -1399,10 +1422,10 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
if (rect.bottom() > contents.height())
rect.setBottom(contents.height());
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MoveHome:
return d->model->index(0, d->column, d->root);
case MoveEnd:
@@ -1477,10 +1500,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
QItemSelection selection;
if (rect.width() == 1 && rect.height() == 1) {
- d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
QModelIndex tl;
- if (!d->intersectVector.isEmpty())
- tl = d->intersectVector.last(); // special case for mouse press; only select the top item
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last(); // special case for mouse press; only select the top item
if (tl.isValid() && d->isIndexEnabled(tl))
selection.select(tl, tl);
} else {
@@ -1490,14 +1513,14 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
QModelIndex tl, br;
// get the first item
const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1);
- d->intersectingSet(topLeft);
- if (!d->intersectVector.isEmpty())
- tl = d->intersectVector.last();
+ QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft);
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last();
// get the last item
const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1);
- d->intersectingSet(bottomRight);
- if (!d->intersectVector.isEmpty())
- br = d->intersectVector.last();
+ intersectVector = d->intersectingSet(bottomRight);
+ if (!intersectVector.isEmpty())
+ br = intersectVector.last();
// get the ranges
if (tl.isValid() && br.isValid()
@@ -1633,14 +1656,16 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con
QModelIndexList QListView::selectedIndexes() const
{
Q_D(const QListView);
- QModelIndexList viewSelected;
- QModelIndexList modelSelected;
- if (d->selectionModel)
- modelSelected = d->selectionModel->selectedIndexes();
- for (int i = 0; i < modelSelected.count(); ++i) {
- QModelIndex index = modelSelected.at(i);
+ if (!d->selectionModel)
+ return QModelIndexList();
+
+ QModelIndexList viewSelected = d->selectionModel->selectedIndexes();
+ for (int i = 0; i < viewSelected.count(); ++i) {
+ const QModelIndex &index = viewSelected.at(i);
if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column)
- viewSelected.append(index);
+ ++i;
+ else
+ viewSelected.removeAt(i);
}
return viewSelected;
}
@@ -2116,8 +2141,8 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const
{
QItemSelection selection;
QModelIndex tl, br;
- intersectingSet(rect);
- QVector<QModelIndex>::iterator it = intersectVector.begin();
+ const QVector<QModelIndex> intersectVector = intersectingSet(rect);
+ QVector<QModelIndex>::const_iterator it = intersectVector.begin();
for (; it != intersectVector.end(); ++it) {
if (!tl.isValid() && !br.isValid()) {
tl = br = *it;
@@ -2408,9 +2433,9 @@ void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)
Finds the set of items intersecting with \a area.
In this function, itemsize is counted from topleft to the start of the next item.
*/
-void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
+QVector<QModelIndex> QStaticListViewBase::intersectingStaticSet(const QRect &area) const
{
- clearIntersections();
+ QVector<QModelIndex> ret;
int segStartPosition;
int segEndPosition;
int flowStartPosition;
@@ -2427,7 +2452,7 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
flowEndPosition = area.bottom();
}
if (segmentPositions.count() < 2 || flowPositions.isEmpty())
- return;
+ return ret;
// the last segment position is actually the edge of the last segment
const int segLast = segmentPositions.count() - 2;
int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1);
@@ -2442,13 +2467,14 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
continue;
QModelIndex index = modelIndex(row);
if (index.isValid())
- appendToIntersections(index);
+ ret += index;
#if 0 // for debugging
else
qWarning("intersectingStaticSet: row %d was invalid", row);
#endif
}
}
+ return ret;
}
int QStaticListViewBase::itemIndex(const QListViewItem &item) const
@@ -2769,12 +2795,15 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
viewport()->update();
}
-void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
+QVector<QModelIndex> QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
{
- clearIntersections();
- QListViewPrivate *that = const_cast<QListViewPrivate*>(dd);
+ QDynamicListViewBase *that = const_cast<QDynamicListViewBase*>(this);
QBspTree::Data data(static_cast<void*>(that));
- that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
+ QVector<QModelIndex> res;
+ that->interSectingVector = &res;
+ that->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
+ that->interSectingVector = 0;
+ return res;
}
void QDynamicListViewBase::createItems(int to)
@@ -2851,20 +2880,20 @@ int QDynamicListViewBase::itemIndex(const QListViewItem &item) const
}
void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
- uint visited, QBspTree::Data data)
+ uint visited, QBspTree::Data data)
{
QListViewItem *vi;
- QListViewPrivate *_this = static_cast<QListViewPrivate *>(data.ptr);
+ QDynamicListViewBase *_this = static_cast<QDynamicListViewBase *>(data.ptr);
for (int i = 0; i < leaf.count(); ++i) {
int idx = leaf.at(i);
- if (idx < 0 || idx >= _this->dynamicListView->items.count())
+ if (idx < 0 || idx >= _this->items.count())
continue;
- vi = &_this->dynamicListView->items[idx];
+ vi = &_this->items[idx];
Q_ASSERT(vi);
if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
- QModelIndex index = _this->listViewItemToIndex(*vi);
+ QModelIndex index = _this->dd->listViewItemToIndex(*vi);
Q_ASSERT(index.isValid());
- _this->intersectVector.append(index);
+ _this->interSectingVector->append(index);
vi->visited = visited;
}
}