diff options
| author | Peter Penz <[email protected]> | 2008-12-06 20:06:04 +0000 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2008-12-06 20:06:04 +0000 |
| commit | 53bdec9b58131014dcec9d6bc7d48e1aa01be979 (patch) | |
| tree | 2d8b1b193c5828c6937586f780a3d28dbec417b7 /src/dolphinviewautoscroller.cpp | |
| parent | d2e8f27200727a7a8d12932176f21c1e81dcad93 (diff) | |
Fixed serious usability issue: QAbstractItemView::setAutoScroll() is not usable when trying to select items outside the visible view area (reported to Qt Software with bug ID #214542) -> implemented custom auto scrolling algorithm.
BUG: 165531
svn path=/trunk/KDE/kdebase/apps/; revision=893546
Diffstat (limited to 'src/dolphinviewautoscroller.cpp')
| -rw-r--r-- | src/dolphinviewautoscroller.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/dolphinviewautoscroller.cpp b/src/dolphinviewautoscroller.cpp new file mode 100644 index 000000000..ce10f92cd --- /dev/null +++ b/src/dolphinviewautoscroller.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[email protected]> * + * * + * 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" |
