]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Fixed serious usability issue: QAbstractItemView::setAutoScroll() is not usable when...
authorPeter Penz <peter.penz19@gmail.com>
Sat, 6 Dec 2008 20:06:04 +0000 (20:06 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 6 Dec 2008 20:06:04 +0000 (20:06 +0000)
BUG: 165531

svn path=/trunk/KDE/kdebase/apps/; revision=893546

src/CMakeLists.txt
src/dolphincolumnwidget.cpp
src/dolphindetailsview.cpp
src/dolphiniconsview.cpp
src/dolphinviewautoscroller.cpp [new file with mode: 0644]
src/dolphinviewautoscroller.h [new file with mode: 0644]

index 196577fc83bccbf6707adca0bd247d8ce542a352..9cd091045a0d1a50d91d50dce53672b158c1b05a 100644 (file)
@@ -34,6 +34,7 @@ set(dolphinprivate_LIB_SRCS
     dolphincategorydrawer.cpp
     dolphinview.cpp
     dolphinviewactionhandler.cpp
+    dolphinviewautoscroller.cpp
     draganddrophelper.cpp
     folderexpander.cpp
     ktooltip.cpp
index 86ab88207c8f88ff4e52fe773d0aa18185b880bc..8edcf9a803ce00886a78de7d08a27fabc91eaa85 100644 (file)
@@ -25,6 +25,7 @@
 #include "dolphindirlister.h"
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphinsettings.h"
+#include "dolphinviewautoscroller.h"
 #include "dolphin_columnmodesettings.h"
 #include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
@@ -75,6 +76,8 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
 
     setVerticalScrollMode(QListView::ScrollPerPixel);
     setHorizontalScrollMode(QListView::ScrollPerPixel);
+    
+    new DolphinViewAutoScroller(this);
 
     // apply the column mode settings to the widget
     const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
index c4f54cec4da13e9af8bc9c41ae5efd6dfd136b0f..32deb873b22233a93e04a77984c5fa4fdfb099a1 100644 (file)
@@ -25,6 +25,7 @@
 #include "dolphinfileitemdelegate.h"
 #include "dolphinsettings.h"
 #include "dolphinsortfilterproxymodel.h"
+#include "dolphinviewautoscroller.h"
 #include "draganddrophelper.h"
 #include "selectionmanager.h"
 #include "viewproperties.h"
@@ -75,6 +76,7 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     setEditTriggers(QAbstractItemView::NoEditTriggers);
 
     setMouseTracking(true);
+    new DolphinViewAutoScroller(this);
 
     const ViewProperties props(controller->url());
     setSortIndicatorSection(props.sorting());
index 6a54bd5c39da9bb59befbf57efa21e2a9e608351..54c6ede8c239bbc760b13a49d0502f823c7fc412 100644 (file)
@@ -22,6 +22,7 @@
 #include "dolphincategorydrawer.h"
 #include "dolphincontroller.h"
 #include "dolphinsettings.h"
+#include "dolphinviewautoscroller.h"
 #include "dolphin_iconsmodesettings.h"
 #include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
@@ -61,6 +62,7 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle
     viewport()->setAcceptDrops(true);
 
     setMouseTracking(true);
+    new DolphinViewAutoScroller(this);
 
     connect(this, SIGNAL(clicked(const QModelIndex&)),
             controller, SLOT(requestTab(const QModelIndex&)));
diff --git a/src/dolphinviewautoscroller.cpp b/src/dolphinviewautoscroller.cpp
new file mode 100644 (file)
index 0000000..ce10f92
--- /dev/null
@@ -0,0 +1,150 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "dolphinviewautoscroller.h"
+
+#include <QAbstractItemView>
+#include <QCoreApplication>
+#include <QCursor>
+#include <QEvent>
+#include <QMouseEvent>
+#include <QScrollBar>
+#include <QTimer>
+
+DolphinViewAutoScroller::DolphinViewAutoScroller(QAbstractItemView* parent) :
+    QObject(parent),
+    m_rubberBandSelection(false),
+    m_scrollInc(0),
+    m_itemView(parent),
+    m_timer()
+{
+    m_itemView->setAutoScroll(false);
+    m_itemView->viewport()->installEventFilter(this);
+    
+    m_timer = new QTimer(this);
+    m_timer->setSingleShot(false);
+    m_timer->setInterval(1000 / 25); // 25 frames per second
+    connect(m_timer, SIGNAL(timeout()), this, SLOT(scrollViewport()));
+}
+
+DolphinViewAutoScroller::~DolphinViewAutoScroller()
+{
+}
+
+bool DolphinViewAutoScroller::eventFilter(QObject* watched, QEvent* event)
+{
+    if (watched == m_itemView->viewport()) {
+        switch (event->type()) {
+        case QEvent::MouseButtonPress:
+            m_rubberBandSelection = true;
+            break;
+            
+        case QEvent::MouseMove:
+            if (m_rubberBandSelection) {
+                triggerAutoScroll();
+            }
+            break;
+            
+        case QEvent::MouseButtonRelease:
+            m_rubberBandSelection = false;
+            stopAutoScroll();
+            break;
+            
+        case QEvent::DragEnter:
+        case QEvent::DragMove:
+            triggerAutoScroll();
+            break;
+            
+        case QEvent::DragLeave:
+            stopAutoScroll();
+            break;
+            
+        default:
+            break;
+        }
+    }
+
+    return QObject::eventFilter(watched, event);
+}
+
+void DolphinViewAutoScroller::scrollViewport()
+{
+    // TODO: implement horizontal scrolling
+    QScrollBar* verticalScrollBar = m_itemView->verticalScrollBar();
+    if (verticalScrollBar != 0) {
+        const int value = verticalScrollBar->value();
+        verticalScrollBar->setValue(value + m_scrollInc);
+        
+        if (m_rubberBandSelection) {
+            // The scrolling does not lead to an update of the rubberband
+            // selection. Fake a mouse move event to let the QAbstractItemView
+            // update the rubberband.
+            QWidget* viewport = m_itemView->viewport();
+            const QPoint pos = viewport->mapFromGlobal(QCursor::pos());
+            QMouseEvent event(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+            QCoreApplication::sendEvent(viewport, &event);
+        }
+    }
+}
+
+void DolphinViewAutoScroller::triggerAutoScroll()
+{
+    // TODO: implement horizontal scrolling
+    
+    const int startSpeed = 2;
+    const int speedLimiter = 8;
+    const int scrollIncMax = 32;
+    
+    const int autoScrollBorder = 32;
+    
+    QWidget* viewport = m_itemView->viewport();
+    const QPoint pos = viewport->mapFromGlobal(QCursor::pos());
+    if (pos.y() < autoScrollBorder) {
+        // scroll up
+        m_scrollInc = -startSpeed + (pos.y() - autoScrollBorder) / speedLimiter;
+        if (m_scrollInc < -scrollIncMax) {
+            m_scrollInc = -scrollIncMax;
+        }
+    } else if (pos.y() > viewport->height() - autoScrollBorder) {
+        // scroll down
+        m_scrollInc = startSpeed + (pos.y() - viewport->height() + autoScrollBorder) / speedLimiter;
+        if (m_scrollInc > scrollIncMax) {
+            m_scrollInc = scrollIncMax;
+        }
+    } else {
+        // no scrolling
+        m_scrollInc = 0;
+    }
+    
+    if (m_timer->isActive()) {
+        if (m_scrollInc == 0) {
+            m_timer->stop();
+        }
+    } else if (m_scrollInc != 0) {
+        m_timer->start();
+    }
+}
+
+void DolphinViewAutoScroller::stopAutoScroll()
+{
+    m_timer->stop();
+    m_scrollInc = 0;
+}
+
+#include "dolphinviewautoscroller.moc"
diff --git a/src/dolphinviewautoscroller.h b/src/dolphinviewautoscroller.h
new file mode 100644 (file)
index 0000000..c02112b
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef DOLPHINVIEWAUTOSCROLLER_H
+#define DOLPHINVIEWAUTOSCROLLER_H
+
+#include <QObject>
+
+class QAbstractItemView;
+class QTimer;
+
+/**
+ * @brief Assures that an autoscrolling is done for item views.
+ *
+ * This is a workaround as QAbstractItemView::setAutoScroll() is not usable
+ * when selecting items (see Qt issue #214542).
+ */
+class DolphinViewAutoScroller : public QObject
+{
+    Q_OBJECT
+
+public:
+    DolphinViewAutoScroller(QAbstractItemView* parent);
+    virtual ~DolphinViewAutoScroller();
+    
+protected:
+    virtual bool eventFilter(QObject* watched, QEvent* event);
+
+private slots:
+    void scrollViewport();
+    
+private:
+    void triggerAutoScroll();
+    void stopAutoScroll();
+    
+private:
+    bool m_rubberBandSelection;
+    int m_scrollInc;
+    QAbstractItemView* m_itemView;
+    QTimer* m_timer;
+};
+
+#endif