]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphindetailsview.cpp
Provide a rubberband for the Details View when selecting items. This assures a consis...
[dolphin.git] / src / dolphindetailsview.cpp
index 4c4102e8bda2f3bec5cf72a23ce76478b205fc19..2bb145cc4c30bdeac6476d6275472923a89d8430 100644 (file)
 #include <kfileitemdelegate.h>
 
 #include <QHeaderView>
+#include <QRubberBand>
+#include <QScrollBar>
 
 DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* controller) :
     QTreeView(parent),
-    m_controller(controller)
+    m_controller(controller),
+    m_rubberBand(0),
+    m_origin()
 {
     Q_ASSERT(controller != 0);
 
@@ -46,6 +50,7 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     setDragDropMode(QAbstractItemView::DragDrop);
     setDropIndicatorShown(false);
 
+    setMouseTracking(true);
     viewport()->setAttribute(Qt::WA_Hover);
 
     const ViewProperties props(controller->url());
@@ -69,7 +74,10 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     }
     connect(this, SIGNAL(activated(const QModelIndex&)),
             controller, SLOT(triggerItem(const QModelIndex&)));
-
+    connect(this, SIGNAL(entered(const QModelIndex&)),
+            this, SLOT(slotEntered(const QModelIndex&)));
+    connect(this, SIGNAL(viewportEntered()),
+            controller, SLOT(emitViewportEntered()));
     connect(controller, SIGNAL(zoomIn()),
             this, SLOT(zoomIn()));
     connect(controller, SIGNAL(zoomOut()),
@@ -90,7 +98,8 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
 }
 
 DolphinDetailsView::~DolphinDetailsView()
-{}
+{
+}
 
 bool DolphinDetailsView::event(QEvent* event)
 {
@@ -141,9 +150,39 @@ void DolphinDetailsView::contextMenuEvent(QContextMenuEvent* event)
     m_controller->triggerContextMenuRequest(event->pos());
 }
 
+void DolphinDetailsView::mousePressEvent(QMouseEvent* event)
+{
+    QTreeView::mousePressEvent(event);
+
+    if (event->button() == Qt::LeftButton) {
+        // initialize rubberband for the selection
+        if (m_rubberBand == 0) {
+            m_rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport());
+        }
+
+        const QPoint pos(contentsPos());
+        m_origin = event->pos();
+        m_origin.setX(m_origin.x() + pos.x());
+        m_origin.setY(m_origin.y() + pos.y());
+        updateRubberBandGeometry();
+        m_rubberBand->show();
+    }
+}
+
+void DolphinDetailsView::mouseMoveEvent(QMouseEvent* event)
+{
+    QTreeView::mouseMoveEvent(event);
+    if (m_rubberBand != 0) {
+        updateRubberBandGeometry();
+    }
+}
+
 void DolphinDetailsView::mouseReleaseEvent(QMouseEvent* event)
 {
     QTreeView::mouseReleaseEvent(event);
+    if (m_rubberBand != 0) {
+        m_rubberBand->hide();
+    }
     m_controller->triggerActivation();
 }
 
@@ -152,6 +191,9 @@ void DolphinDetailsView::dragEnterEvent(QDragEnterEvent* event)
     if (event->mimeData()->hasUrls()) {
         event->acceptProposedAction();
     }
+    if (m_rubberBand != 0) {
+        m_rubberBand->hide();
+    }
 }
 
 void DolphinDetailsView::dropEvent(QDropEvent* event)
@@ -188,6 +230,28 @@ void DolphinDetailsView::synchronizeSortingState(int column)
     m_controller->indicateSortOrderChange(sortOrder);
 }
 
+void DolphinDetailsView::slotEntered(const QModelIndex& index)
+{
+    const QPoint pos = viewport()->mapFromGlobal(QCursor::pos());
+    const int nameColumnWidth = header()->sectionSize(KDirModel::Name);
+    if (pos.x() < nameColumnWidth) {
+        m_controller->emitItemEntered(index);
+    }
+    else {
+        m_controller->emitViewportEntered();
+    }
+}
+
+void DolphinDetailsView::updateRubberBandGeometry()
+{
+    if (m_rubberBand != 0) {
+        const QPoint pos(contentsPos());
+        const QPoint origin(m_origin.x() - pos.x(), m_origin.y() - pos.y());
+        const QPoint dest(viewport()->mapFromGlobal(QCursor::pos()));
+        m_rubberBand->setGeometry(QRect(origin, dest).normalized());
+    }
+}
+
 void DolphinDetailsView::zoomIn()
 {
     if (isZoomInPossible()) {
@@ -240,4 +304,22 @@ void DolphinDetailsView::updateDecorationSize()
     doItemsLayout();
 }
 
+QPoint DolphinDetailsView::contentsPos() const
+{
+    // implementation note: the horizonal position is ignored currently, as no
+    // horizontal scrolling is done anyway during a selection
+    const QScrollBar* scrollbar = verticalScrollBar();
+    Q_ASSERT(scrollbar != 0);
+
+    const int maxHeight = maximumViewportSize().height();
+    const int height = scrollbar->maximum() - scrollbar->minimum() + 1;
+    const int visibleHeight = model()->rowCount() + 1 - height;
+    if (visibleHeight <= 0) {
+        return QPoint(0, 0);
+    }
+
+    const int y = scrollbar->sliderPosition() * maxHeight / visibleHeight;
+    return QPoint(0, y);
+}
+
 #include "dolphindetailsview.moc"