┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemlistwidget.cpp10
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp73
-rw-r--r--src/kitemviews/kitemlistcontroller.h7
-rw-r--r--src/kitemviews/kitemlistview.h12
4 files changed, 96 insertions, 6 deletions
diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp
index a8fe36c08..4fc3307ef 100644
--- a/src/kitemviews/kfileitemlistwidget.cpp
+++ b/src/kitemviews/kfileitemlistwidget.cpp
@@ -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;
}
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index 7331131a9..31a1cfc2f 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -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"
diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h
index c4406a972..49442c643 100644
--- a/src/kitemviews/kitemlistcontroller.h
+++ b/src/kitemviews/kitemlistcontroller.h
@@ -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;
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index 1ff56babd..3f877d236 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -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();