]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Select items when using the rubberband
authorPeter Penz <peter.penz19@gmail.com>
Sat, 20 Aug 2011 20:52:45 +0000 (22:52 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 20 Aug 2011 20:53:19 +0000 (22:53 +0200)
src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistcontroller.h
src/kitemviews/kitemlistview.h

index a8fe36c08c18acd9a6e6444c6617b18cf05f18e1..4fc3307efd1cd1ad8654af32924292d30fe23d5b 100644 (file)
@@ -86,9 +86,7 @@ void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsIte
 {
     KItemListWidget::paint(painter, option, widget);
 
-    if (m_dirtyContent || m_dirtyLayout) {
-        const_cast<KFileItemListWidget*>(this)->updateCache();
-    }
+    const_cast<KFileItemListWidget*>(this)->updateCache();
 
     // Draw expansion toggle '>' or 'V'
     if (m_isDir && !m_expansionArea.isEmpty()) {
@@ -135,6 +133,8 @@ void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsIte
 
 QRectF KFileItemListWidget::iconBoundingRect() const
 {
+    const_cast<KFileItemListWidget*>(this)->updateCache();
+
     QRectF bounds = m_hoverPixmapRect;
     const qreal margin = styleOption().margin;
     bounds.adjust(-margin, -margin, margin, margin);
@@ -143,11 +143,13 @@ QRectF KFileItemListWidget::iconBoundingRect() const
 
 QRectF KFileItemListWidget::textBoundingRect() const
 {
+    const_cast<KFileItemListWidget*>(this)->updateCache();
     return m_textBoundingRect;
 }
 
 QRectF KFileItemListWidget::expansionToggleRect() const
 {
+    const_cast<KFileItemListWidget*>(this)->updateCache();
     return m_isDir ? m_expansionArea : QRectF();
 }
 
@@ -242,7 +244,7 @@ void KFileItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
 
 void KFileItemListWidget::updateCache()
 {
-    if (index() < 0) {
+    if ((!m_dirtyContent && !m_dirtyLayout) || index() < 0) {
         return;
     }
 
index 7331131a94f8a638566806d107ac030cb195f0cc..31a1cfc2f0c2a4b253cdd2d0761742a506083057 100644 (file)
@@ -291,6 +291,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
         rubberBand->setStartPosition(startPos);
         rubberBand->setEndPosition(startPos);
         rubberBand->setActive(true);
+        connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
     }
 
     return false;
@@ -322,7 +323,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 +548,68 @@ 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<int> 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);
+}
+
 #include "kitemlistcontroller.moc"
index c4406a972c7da829c7fa6679a573c2b6e7a67ad0..49442c643ff74de9107c73704d79fa091ae37780 100644 (file)
@@ -28,7 +28,6 @@
 #include <QObject>
 
 class KItemModelBase;
-class KItemListRubberBandManager;
 class KItemListSelectionManager;
 class KItemListView;
 class QGraphicsSceneHoverEvent;
@@ -123,6 +122,12 @@ signals:
 private slots:
     void slotViewOffsetChanged(qreal current, qreal previous);
 
+    /**
+     * Is invoked when the rubberband boundaries have been changed and will select
+     * all items that are touched by the rubberband.
+     */
+    void slotRubberBandChanged();
+
 private:
     SelectionBehavior m_selectionBehavior;
     KItemModelBase* m_model;
index 1ff56babd2638e4e0fade47d4838930b9490261c..3f877d2360a668be7900a8a6a6a3f5f62c2d9dbe 100644 (file)
@@ -136,7 +136,19 @@ public:
     virtual QSizeF itemSizeHint(int index) const;
     virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
 
+    /**
+     * @return The bounding rectangle of the item relative to the top/left of
+     *         the currently visible area (see KItemListView::offset()).
+     */
     QRectF itemBoundingRect(int index) const;
+
+    /**
+     * @return The number of items that can be shown in parallel for one offset.
+     *         Assuming the scrolldirection is vertical then a value of 4 means
+     *         that 4 columns for items are available. Assuming the scrolldirection
+     *         is horizontal then a value of 4 means that 4 lines for items are
+     *         available.
+     */
     int itemsPerOffset() const;
 
     void beginTransaction();