From: Peter Penz Date: Thu, 8 May 2008 20:44:26 +0000 (+0000) Subject: * If one item is selected and the item is (at least partly) visible, assure that... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/fc97fa250d89c620a99d58d0a787a648d680fb31?ds=inline * If one item is selected and the item is (at least partly) visible, assure that an automatic horizontal scrolling is done so that the item gets fully visible. * Use QTimeLine instead of QTimer + value CCMAIL: haraldhv@stud.ntnu.no svn path=/trunk/KDE/kdebase/apps/; revision=805596 --- diff --git a/src/ktreeview.cpp b/src/ktreeview.cpp index 7448614f9..687bfe1e3 100644 --- a/src/ktreeview.cpp +++ b/src/ktreeview.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2008 by * + * Copyright (C) 2008 by * * * * 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 * @@ -17,151 +18,124 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include - -#include -#include - #include "ktreeview.h" #include "ktreeview_p.h" -KTreeView::KTreeViewPrivate::KTreeViewPrivate(KTreeView *parent) - : parent(parent), - autoHorizontalScroll(true), - scrollTowards(0), - scrollPixels(5), - scrollDelay(50), - leftSideMargin(30), - considerDelay(500), - topLeftPoint(QPoint(10,10)) -{ - Q_ASSERT(parent->verticalScrollBar()); - - considerDelayTimer.setInterval(considerDelay); - - connect( &considerDelayTimer, - SIGNAL(timeout()), - this, - SLOT(considerAutoScroll()) - ); - - connect( parent->verticalScrollBar(), - SIGNAL(rangeChanged(int, int)), - &considerDelayTimer, - SLOT(start()) - ); - - connect( parent->verticalScrollBar(), - SIGNAL(valueChanged(int)), - &considerDelayTimer, - SLOT(start()) - ); - - connect( parent, - SIGNAL( collapsed ( const QModelIndex &)), - &considerDelayTimer, - SLOT(start()) - ); - - connect( parent, - SIGNAL( expanded ( const QModelIndex &)), - &considerDelayTimer, - SLOT(start()) - ); +#include +#include +#include +#include +#include + +KTreeView::KTreeViewPrivate::KTreeViewPrivate(KTreeView *parent) : + parent(parent), + autoHorizontalScroll(false), + timeLine(0), + startScrollTimer(0) +{ + startScrollTimer = new QTimer(this); + startScrollTimer->setSingleShot(true); + startScrollTimer->setInterval(50); + connect(startScrollTimer, SIGNAL(timeout()), + this, SLOT(startScrolling())); + + timeLine = new QTimeLine(300, this); + connect(timeLine, SIGNAL(frameChanged(int)), + this, SLOT(updateVerticalScrollBar(int))); + + connect(parent->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), + startScrollTimer, SLOT(start())); + connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), + startScrollTimer, SLOT(start())); + connect(parent, SIGNAL(collapsed(const QModelIndex&)), + startScrollTimer, SLOT(start())); + connect(parent, SIGNAL(expanded(const QModelIndex&)), + startScrollTimer, SLOT(start())); } -void KTreeView::KTreeViewPrivate::considerAutoScroll() +KTreeView::~KTreeView() { - qDebug() << "Considering auto scroll"; - - QModelIndex i = parent->indexAt(topLeftPoint); - int smallest = parent->width(); - - while (i.isValid()) - { - QRect r = parent->visualRect(i); - if (r.top() > parent->height()) - break; - - int leftSide = r.left(); - - smallest = qMin(smallest, leftSide); - i = parent->indexBelow(i); - } - - int currentScroll = parent->horizontalScrollBar()->value(); - - setScrollTowards(smallest + currentScroll - leftSideMargin); - - considerDelayTimer.stop(); - } -void KTreeView::KTreeViewPrivate::autoScrollTimeout() +void KTreeView::KTreeViewPrivate::startScrolling() { - - Q_ASSERT(parent); - - QScrollBar *scrollBar = parent->horizontalScrollBar(); - if (scrollBar == NULL) - { - qDebug() << "Warning: no scrollbar present, but told to scroll."; - scrollTimer.stop(); - return; - } - - int currentScroll = scrollBar->value(); - - int difference = currentScroll - scrollTowards; - - if (qAbs(difference) < scrollPixels) - { - scrollBar->setValue(scrollTowards); - scrollTimer.stop(); - return; - } - - if (difference < 0) - { - scrollBar->setValue(currentScroll + scrollPixels); - } - else - { - scrollBar->setValue(currentScroll - scrollPixels); - } + QModelIndex index; + + const int viewportHeight = parent->viewport()->height(); + + // check whether there is a selected index which is partly visible + const QModelIndexList selectedIndexes = parent->selectionModel()->selectedIndexes(); + if (selectedIndexes.count() == 1) { + QModelIndex selectedIndex = selectedIndexes.first(); + const QRect rect = parent->visualRect(selectedIndex); + if ((rect.bottom() >= 0) && (rect.top() <= viewportHeight)) { + // the selected index is (at least partly) visible, use it as + // scroll target + index = selectedIndex; + } + } + + if (!index.isValid()) { + // no partly selected index is visible, determine the most left visual index + QModelIndex visibleIndex = parent->indexAt(QPoint(0, 0)); + if (!visibleIndex.isValid()) { + return; + } + + index = visibleIndex; + int minimum = parent->width(); + do { + const QRect rect = parent->visualRect(visibleIndex); + if (rect.top() > viewportHeight) { + // the current index and all successors are not visible anymore + break; + } + if (rect.left() < minimum) { + minimum = rect.left(); + index = visibleIndex; + } + visibleIndex = parent->indexBelow(visibleIndex); + } while (visibleIndex.isValid()); + } + + // start the horizontal scrolling to assure that the item indicated by 'index' gets fully visible + Q_ASSERT(index.isValid()); + const QRect rect = parent->visualRect(index); + + QScrollBar *scrollBar = parent->horizontalScrollBar(); + const int oldScrollBarPos = scrollBar->value(); + + const int itemRight = oldScrollBarPos + rect.left() + rect.width() - 1; + const int availableWidth = parent->viewport()->width(); + int scrollBarPos = itemRight - availableWidth; + const int scrollBarPosMax = oldScrollBarPos + rect.left() - parent->indentation(); + if (scrollBarPos > scrollBarPosMax) { + scrollBarPos = scrollBarPosMax; + } + + if (scrollBarPos != oldScrollBarPos) { + timeLine->setFrameRange(oldScrollBarPos, scrollBarPos); + timeLine->start(); + } } -void KTreeView::KTreeViewPrivate::setScrollTowards( int scrollTowards ) +void KTreeView::KTreeViewPrivate::updateVerticalScrollBar(int value) { - if (scrollTowards < 0) - scrollTowards = 0; - this->scrollTowards = scrollTowards; - scrollTimer.start(scrollDelay); + QScrollBar *scrollBar = parent->horizontalScrollBar(); + scrollBar->setValue(value); + startScrollTimer->stop(); } -//************************************************ +// ************************************************ -KTreeView::KTreeView(QWidget *parent) - : QTreeView(parent) - , d(new KTreeViewPrivate(this)) +KTreeView::KTreeView(QWidget *parent) : + QTreeView(parent), + d(new KTreeViewPrivate(this)) { - /* The graphicEffectsLevel was not available in the 4.0.3 version of - * the libs I was compiling with, so this is left out for now and - * enabled by default... - */ - //if (KGlobalSettings::graphicEffectsLevel() >= - //KGlobalSettings::SimpleAnimationEffects) - //{ - setAutoHorizontalScroll(true); - //} - connect( - &d->scrollTimer, - SIGNAL(timeout()), - d, - SLOT(autoScrollTimeout()) - ); - + if (KGlobalSettings::graphicEffectsLevel() >= KGlobalSettings::SimpleAnimationEffects) { + setAutoHorizontalScroll(true); + } } void KTreeView::setAutoHorizontalScroll(bool value) @@ -169,10 +143,18 @@ void KTreeView::setAutoHorizontalScroll(bool value) d->autoHorizontalScroll = value; } -bool KTreeView::autoHorizontalScroll( void ) +bool KTreeView::autoHorizontalScroll() const { return d->autoHorizontalScroll; } +void KTreeView::setSelectionModel(QItemSelectionModel *selectionModel) +{ + QTreeView::setSelectionModel(selectionModel); + connect(selectionModel, + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + d->startScrollTimer, SLOT(start())); +} + #include "ktreeview.moc" #include "ktreeview_p.moc" diff --git a/src/ktreeview.h b/src/ktreeview.h index 93b4b892e..4a6262621 100644 --- a/src/ktreeview.h +++ b/src/ktreeview.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2008 by * + * Copyright (C) 2008 by * * * * 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 * @@ -17,26 +18,27 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef _KTREEVIEW_H_ -#define _KTREEVIEW_H_ +#ifndef KTREEVIEW_H +#define KTREEVIEW_H #include class KTreeView : public QTreeView { + Q_OBJECT - Q_OBJECT +public: + KTreeView(QWidget *parent = 0); + virtual ~KTreeView(); - public: - KTreeView(QWidget *parent = NULL); + void setAutoHorizontalScroll(bool value); + bool autoHorizontalScroll() const; - void setAutoHorizontalScroll(bool value); - bool autoHorizontalScroll( void ); - - private: - class KTreeViewPrivate; - KTreeViewPrivate *d; + virtual void setSelectionModel(QItemSelectionModel *selectionModel); +private: + class KTreeViewPrivate; + KTreeViewPrivate *d; }; -#endif /* ifndef _KTREEVIEW_H_ */ +#endif /* ifndef KTREEVIEW_H */ diff --git a/src/ktreeview_p.h b/src/ktreeview_p.h index eb71999f7..1cfa463cd 100644 --- a/src/ktreeview_p.h +++ b/src/ktreeview_p.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2008 by * + * Copyright (C) 2008 by * * * * 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 * @@ -17,47 +18,32 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef _KTREEVIEW_P_H_ -#define _KTREEVIEW_P_H_ +#ifndef KTREEVIEW_P_H +#define KTREEVIEW_P_H -#include #include #include "ktreeview.h" +class QTimer; +class QTimeLine; + class KTreeView::KTreeViewPrivate : public QObject { - Q_OBJECT - - - - public Q_SLOTS: - void autoScrollTimeout(); - void considerAutoScroll(); - - public: - - KTreeViewPrivate(KTreeView *parent); - //~KTreeViewPrivate(); - KTreeView *parent; - - //Function for start scrolling towards a certain position - void setScrollTowards( int scrollTowards ); - - //Privates for doing the scrolling - QTimer scrollTimer; - QTimer considerDelayTimer; - bool autoHorizontalScroll; - int scrollTowards; + Q_OBJECT - //Constants - const int scrollPixels; - const int scrollDelay; - const int leftSideMargin; - const int considerDelay; - const QPoint topLeftPoint; +public Q_SLOTS: + void startScrolling(); + void updateVerticalScrollBar(int value); +public: + KTreeViewPrivate(KTreeView *parent); + KTreeView *parent; + void setScrollTowards( int scrollTowards ); + bool autoHorizontalScroll; + QTimeLine *timeLine; + QTimer *startScrollTimer; }; -#endif /* ifndef _KTREEVIEW_P_H_ */ +#endif /* ifndef KTREEVIEW_P_H */ diff --git a/src/treeviewsidebarpage.cpp b/src/treeviewsidebarpage.cpp index c4a793cbd..6c89e762b 100644 --- a/src/treeviewsidebarpage.cpp +++ b/src/treeviewsidebarpage.cpp @@ -41,7 +41,6 @@ TreeViewSidebarPage::TreeViewSidebarPage(QWidget* parent) : SidebarPage(parent), m_setLeafVisible(false), - m_horizontalPos(0), m_dirLister(0), m_dolphinModel(0), m_proxyModel(0), @@ -211,8 +210,6 @@ void TreeViewSidebarPage::expandToLeafDir() void TreeViewSidebarPage::loadSubTree() { - m_treeView->selectionModel()->clearSelection(); - if (m_leafDir.isParentOf(m_dirLister->url())) { // The leaf directory is not a child of the base URL, hence // no sub directory must be loaded or selected. @@ -244,8 +241,6 @@ void TreeViewSidebarPage::loadTree(const KUrl& url) Q_ASSERT(m_dirLister != 0); m_leafDir = url; - m_horizontalPos = m_treeView->horizontalScrollBar()->value(); - KUrl baseUrl = url; if (url.isLocalFile()) { // use the root directory as base for local URLs @@ -283,8 +278,6 @@ void TreeViewSidebarPage::selectLeafDirectory() QItemSelectionModel* selModel = m_treeView->selectionModel(); selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select); - - m_treeView->horizontalScrollBar()->setValue(m_horizontalPos); } #include "treeviewsidebarpage.moc" diff --git a/src/treeviewsidebarpage.h b/src/treeviewsidebarpage.h index 624b6dc53..336d2a6ca 100644 --- a/src/treeviewsidebarpage.h +++ b/src/treeviewsidebarpage.h @@ -124,7 +124,6 @@ private: private: bool m_setLeafVisible; - int m_horizontalPos; KDirLister* m_dirLister; DolphinModel* m_dolphinModel; DolphinSortFilterProxyModel* m_proxyModel;