Commit 2c3fae73 authored by Rafael Fernández López's avatar Rafael Fernández López
Browse files

Faster selections

svn path=/trunk/KDE/kdebase/apps/; revision=680550
parent f680748b
......@@ -80,6 +80,7 @@ KListView::Private::Private(KListView *listView)
, itemCategorizer(0)
, mouseButtonPressed(false)
, isDragging(false)
, dragLeftViewport(false)
, proxyModel(0)
, lastIndex(QModelIndex())
{
......@@ -658,7 +659,7 @@ void KListView::paintEvent(QPaintEvent *event)
painter.restore();
}
if (d->isDragging)
if (d->isDragging && !d->dragLeftViewport)
d->drawDraggedItems(&painter);
painter.restore();
......@@ -691,96 +692,75 @@ void KListView::setSelection(const QRect &rect,
return;
}
if (!flags)
return;
selectionModel()->clear();
if (flags & QItemSelectionModel::Clear)
{
selectionModel()->clear();
d->isIndexSelected.clear();
d->isTemporarySelected.clear();
d->lastSelection = QItemSelection();
}
QItemSelection selection;
QItemSelection deselect;
QModelIndexList dirtyIndexes = d->intersectionSet(rect);
foreach (const QModelIndex &index, dirtyIndexes)
QItemSelection selection;
if (!dirtyIndexes.count())
{
if (!d->mouseButtonPressed && rect.intersects(visualRect(index)))
if (d->lastSelection.count())
{
if (d->isIndexSelected.contains(index))
{
if (!d->isIndexSelected[index])
{
selection.select(index, index);
d->isIndexSelected[index] = true;
}
else
{
deselect.select(index, index);
d->isIndexSelected[index] = false;
}
}
else
{
d->isIndexSelected.insert(index, true);
selection.select(index, index);
}
selectionModel()->select(d->lastSelection, flags);
}
else if (d->mouseButtonPressed) // selection cache
return;
}
if (!d->mouseButtonPressed)
{
selection = QItemSelection(dirtyIndexes[0], dirtyIndexes[0]);
}
else
{
QModelIndex first = dirtyIndexes[0];
QModelIndex last;
foreach (const QModelIndex &index, dirtyIndexes)
{
if (!d->isIndexSelected.contains(index) ||
(d->isIndexSelected.contains(index) && !d->isIndexSelected[index]))
if (last.isValid() && last.row() + 1 != index.row())
{
if (d->isTemporarySelected.contains(index))
{
d->isTemporarySelected[index] = true;
}
else
{
d->isTemporarySelected.insert(index, true);
}
}
QItemSelectionRange range(first, last);
if (d->isIndexSelected.contains(index))
{
if (!d->isIndexSelected[index])
selection.select(index, index);
selection << range;
d->isIndexSelected[index] = true;
}
else
{
d->isIndexSelected.insert(index, true);
selection.select(index, index);
first = index;
}
last = index;
}
if (last.isValid())
selection << QItemSelectionRange(first, last);
}
foreach (const QModelIndex &index, d->isIndexSelected.keys())
if (d->lastSelection.count() && !d->mouseButtonPressed)
{
if (!rect.intersects(visualRect(index)))
{
if (d->isTemporarySelected.contains(index) &&
d->isTemporarySelected[index])
{
deselect.select(index, index);
d->isTemporarySelected[index] = false;
d->isIndexSelected[index] = false;
}
}
selection.merge(d->lastSelection, flags);
}
else if (d->lastSelection.count())
{
selection.merge(d->lastSelection, QItemSelectionModel::Select);
}
if (selection.count())
selectionModel()->select(selection, QItemSelectionModel::Select);
selectionModel()->select(selection, flags);
if (deselect.count())
selectionModel()->select(deselect, QItemSelectionModel::Deselect);
viewport()->update();
}
void KListView::mouseMoveEvent(QMouseEvent *event)
{
QListView::mouseMoveEvent(event);
d->mousePosition = event->pos();
QListView::mouseMoveEvent(event);
if ((viewMode() != KListView::IconMode) || !d->proxyModel ||
!d->itemCategorizer)
{
......@@ -804,6 +784,8 @@ void KListView::mousePressEvent(QMouseEvent *event)
event->accept();
d->dragLeftViewport = false;
if (event->button() == Qt::LeftButton)
{
d->mouseButtonPressed = true;
......@@ -822,8 +804,6 @@ void KListView::mouseReleaseEvent(QMouseEvent *event)
{
QListView::mouseReleaseEvent(event);
d->mouseButtonPressed = false;
if ((viewMode() != KListView::IconMode) || !d->proxyModel ||
!d->itemCategorizer)
{
......@@ -832,7 +812,8 @@ void KListView::mouseReleaseEvent(QMouseEvent *event)
event->accept();
d->isTemporarySelected.clear(); // selection cache
d->mouseButtonPressed = false;
d->lastSelection = selectionModel()->selection();
QPoint initialPressPosition = viewport()->mapFromGlobal(QCursor::pos());
initialPressPosition.setY(initialPressPosition.y() + verticalOffset());
......@@ -921,6 +902,25 @@ void KListView::dragMoveEvent(QDragMoveEvent *event)
d->isDragging = false;
}
d->dragLeftViewport = false;
event->accept();
viewport()->update();
}
void KListView::dragLeaveEvent(QDragLeaveEvent *event)
{
QListView::dragLeaveEvent(event);
if ((viewMode() != KListView::IconMode) || !d->proxyModel ||
!d->itemCategorizer)
{
return;
}
d->dragLeftViewport = true;
event->accept();
viewport()->update();
......
......@@ -70,6 +70,8 @@ protected:
virtual void dragMoveEvent(QDragMoveEvent *event);
virtual void dragLeaveEvent(QDragLeaveEvent *event);
protected Q_SLOTS:
virtual void rowsInserted(const QModelIndex &parent,
int start,
......
......@@ -119,9 +119,11 @@ public:
// Behavior data
bool mouseButtonPressed;
bool isDragging;
bool dragLeftViewport;
QModelIndex hovered;
QPoint initialPressPosition;
QPoint mousePosition;
QItemSelection lastSelection;
// Cache data
// We cannot merge some of them into structs because it would affect
......@@ -134,7 +136,6 @@ public:
QStringList categories;
QModelIndexList intersectedIndexes;
QHash<QModelIndex, bool> isIndexSelected; // selection cache
QHash<QModelIndex, bool> isTemporarySelected; // selection cache
// Attributes for speed reasons
KSortFilterProxyModel *proxyModel;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment