X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/dbe2152912cc58f1d2bfba187175ec0e4b3e4761..2f0ceedae088158b8af24a5e94500a7d1c0edecb:/src/kitemviews/kitemlistcontroller.cpp diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 7331131a9..92a14b23d 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -26,6 +26,7 @@ #include "kitemlistrubberband_p.h" #include "kitemlistselectionmanager.h" +#include #include #include @@ -285,12 +286,18 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const QPointF startPos = pos; if (m_view->scrollOrientation() == Qt::Vertical) { startPos.ry() += m_view->offset(); + if (m_view->itemSize().width() < 0) { + // Use a special rubberband for views that have only one column and + // expand the rubberband to use the whole width of the view. + startPos.setX(0); + } } else { startPos.rx() += m_view->offset(); } rubberBand->setStartPosition(startPos); rubberBand->setEndPosition(startPos); rubberBand->setActive(true); + connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged())); } return false; @@ -307,6 +314,11 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QPointF endPos = transform.map(event->pos()); if (m_view->scrollOrientation() == Qt::Vertical) { endPos.ry() += m_view->offset(); + if (m_view->itemSize().width() < 0) { + // Use a special rubberband for views that have only one column and + // expand the rubberband to use the whole width of the view. + endPos.setX(m_view->size().width()); + } } else { endPos.rx() += m_view->offset(); } @@ -322,7 +334,13 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con return false; } - m_view->rubberBand()->setActive(false); + KItemListRubberBand* rubberBand = m_view->rubberBand(); + if (rubberBand->isActive()) { + disconnect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged())); + rubberBand->setActive(false); + m_pressedIndex = -1; + return false; + } const QPointF pos = transform.map(event->pos()); const int index = m_view->itemAt(pos); @@ -541,4 +559,79 @@ void KItemListController::slotViewOffsetChanged(qreal current, qreal previous) } } +void KItemListController::slotRubberBandChanged() +{ + if (!m_view || !m_model || m_model->count() <= 0) { + return; + } + + const KItemListRubberBand* rubberBand = m_view->rubberBand(); + const QPointF startPos = rubberBand->startPosition(); + const QPointF endPos = rubberBand->endPosition(); + QRectF rubberBandRect = QRectF(startPos, endPos).normalized(); + + const bool scrollVertical = (m_view->scrollOrientation() == Qt::Vertical); + if (scrollVertical) { + rubberBandRect.translate(0, -m_view->offset()); + } else { + rubberBandRect.translate(-m_view->offset(), 0); + } + + QSet previousSelectedItems; + if (m_selectionManager->hasSelection()) { + // Don't clear the current selection in case if the user pressed the + // Shift- or Control-key during the rubberband selection + const bool shiftOrControlPressed = QApplication::keyboardModifiers() & Qt::ShiftModifier || + QApplication::keyboardModifiers() & Qt::ControlModifier; + if (shiftOrControlPressed) { + previousSelectedItems = m_selectionManager->selectedItems(); + } + } + + QSet selectedItems; + + // Select all visible items that intersect with the rubberband + foreach (const KItemListWidget* widget, m_view->visibleItemListWidgets()) { + const int index = widget->index(); + + const QRectF widgetRect = m_view->itemBoundingRect(index); + if (widgetRect.intersects(rubberBandRect)) { + const QRectF iconRect = widget->iconBoundingRect().translated(widgetRect.topLeft()); + const QRectF textRect = widget->textBoundingRect().translated(widgetRect.topLeft()); + if (iconRect.intersects(rubberBandRect) || textRect.intersects(rubberBandRect)) { + selectedItems.insert(index); + } + } + } + + // Select all invisible items that intersect with the rubberband. Instead of + // iterating all items only the area which might be touched by the rubberband + // will be checked. + const bool increaseIndex = scrollVertical ? + startPos.y() > endPos.y(): startPos.x() > endPos.x(); + + int index = increaseIndex ? m_view->lastVisibleIndex() + 1 : m_view->firstVisibleIndex() - 1; + bool selectionFinished = false; + do { + const QRectF widgetRect = m_view->itemBoundingRect(index); + if (widgetRect.intersects(rubberBandRect)) { + selectedItems.insert(index); + } + + if (increaseIndex) { + ++index; + selectionFinished = (index >= m_model->count()) || + ( scrollVertical && widgetRect.top() > rubberBandRect.bottom()) || + (!scrollVertical && widgetRect.left() > rubberBandRect.right()); + } else { + --index; + selectionFinished = (index < 0) || + ( scrollVertical && widgetRect.bottom() < rubberBandRect.top()) || + (!scrollVertical && widgetRect.right() < rubberBandRect.left()); + } + } while (!selectionFinished); + + m_selectionManager->setSelectedItems(selectedItems + previousSelectedItems); +} + #include "kitemlistcontroller.moc"