]> cloud.milkyroute.net Git - dolphin.git/blob - src/ktreeview.cpp
The space info widget now inherits KCapacityBar. Two things to check:
[dolphin.git] / src / ktreeview.cpp
1 /***************************************************************************
2 * Copyright (C) 2008 by <haraldhv (at) stud.ntnu.no> *
3 * Copyright (C) 2008 by <peter.penz@gmx.at> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include "ktreeview.h"
22 #include "ktreeview_p.h"
23
24 #include <KGlobalSettings>
25
26 #include <QItemSelectionModel>
27 #include <QScrollBar>
28 #include <QTimer>
29 #include <QTimeLine>
30
31 KTreeView::KTreeViewPrivate::KTreeViewPrivate(KTreeView *parent) :
32 parent(parent),
33 autoHorizontalScroll(false),
34 timeLine(0),
35 startScrollTimer(0)
36 {
37 startScrollTimer = new QTimer(this);
38 startScrollTimer->setSingleShot(true);
39 startScrollTimer->setInterval(300);
40 connect(startScrollTimer, SIGNAL(timeout()),
41 this, SLOT(startScrolling()));
42
43 timeLine = new QTimeLine(300, this);
44 connect(timeLine, SIGNAL(frameChanged(int)),
45 this, SLOT(updateVerticalScrollBar(int)));
46
47 connect(parent->verticalScrollBar(), SIGNAL(rangeChanged(int, int)),
48 startScrollTimer, SLOT(start()));
49 connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)),
50 startScrollTimer, SLOT(start()));
51 connect(parent, SIGNAL(collapsed(const QModelIndex&)),
52 startScrollTimer, SLOT(start()));
53 connect(parent, SIGNAL(expanded(const QModelIndex&)),
54 startScrollTimer, SLOT(start()));
55 }
56
57 KTreeView::~KTreeView()
58 {
59 }
60
61 void KTreeView::KTreeViewPrivate::startScrolling()
62 {
63 QModelIndex index;
64
65 const int viewportHeight = parent->viewport()->height();
66
67 // check whether there is a selected index which is partly visible
68 const QModelIndexList selectedIndexes = parent->selectionModel()->selectedIndexes();
69 if (selectedIndexes.count() == 1) {
70 QModelIndex selectedIndex = selectedIndexes.first();
71 const QRect rect = parent->visualRect(selectedIndex);
72 if ((rect.bottom() >= 0) && (rect.top() <= viewportHeight)) {
73 // the selected index is (at least partly) visible, use it as
74 // scroll target
75 index = selectedIndex;
76 }
77 }
78
79 if (!index.isValid()) {
80 // no partly selected index is visible, determine the most left visual index
81 QModelIndex visibleIndex = parent->indexAt(QPoint(0, 0));
82 if (!visibleIndex.isValid()) {
83 return;
84 }
85
86 index = visibleIndex;
87 int minimum = parent->width();
88 do {
89 const QRect rect = parent->visualRect(visibleIndex);
90 if (rect.top() > viewportHeight) {
91 // the current index and all successors are not visible anymore
92 break;
93 }
94 if (rect.left() < minimum) {
95 minimum = rect.left();
96 index = visibleIndex;
97 }
98 visibleIndex = parent->indexBelow(visibleIndex);
99 } while (visibleIndex.isValid());
100 }
101
102 // start the horizontal scrolling to assure that the item indicated by 'index' gets fully visible
103 Q_ASSERT(index.isValid());
104 const QRect rect = parent->visualRect(index);
105
106 QScrollBar *scrollBar = parent->horizontalScrollBar();
107 const int oldScrollBarPos = scrollBar->value();
108
109 const int itemRight = oldScrollBarPos + rect.left() + rect.width() - 1;
110 const int availableWidth = parent->viewport()->width();
111 int scrollBarPos = itemRight - availableWidth;
112 const int scrollBarPosMax = oldScrollBarPos + rect.left() - parent->indentation();
113 if (scrollBarPos > scrollBarPosMax) {
114 scrollBarPos = scrollBarPosMax;
115 }
116
117 if (scrollBarPos != oldScrollBarPos) {
118 timeLine->setFrameRange(oldScrollBarPos, scrollBarPos);
119 timeLine->start();
120 }
121 }
122
123 void KTreeView::KTreeViewPrivate::updateVerticalScrollBar(int value)
124 {
125 QScrollBar *scrollBar = parent->horizontalScrollBar();
126 scrollBar->setValue(value);
127 startScrollTimer->stop();
128 }
129
130 // ************************************************
131
132 KTreeView::KTreeView(QWidget *parent) :
133 QTreeView(parent),
134 d(new KTreeViewPrivate(this))
135 {
136 if (KGlobalSettings::graphicEffectsLevel() >= KGlobalSettings::SimpleAnimationEffects) {
137 setAutoHorizontalScroll(true);
138 }
139 }
140
141 void KTreeView::setAutoHorizontalScroll(bool value)
142 {
143 d->autoHorizontalScroll = value;
144 }
145
146 bool KTreeView::autoHorizontalScroll() const
147 {
148 return d->autoHorizontalScroll;
149 }
150
151 void KTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
152 {
153 QTreeView::setSelectionModel(selectionModel);
154 connect(selectionModel,
155 SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
156 d->startScrollTimer, SLOT(start()));
157 }
158
159 void KTreeView::scrollTo(const QModelIndex& index, ScrollHint hint)
160 {
161 if (d->autoHorizontalScroll) {
162 // assure that the value of the horizontal scrollbar stays on its current value,
163 // KTreeView will adjust the value manually
164 const int value = horizontalScrollBar()->value();
165 QTreeView::scrollTo(index, hint);
166 horizontalScrollBar()->setValue(value);
167 } else {
168 QTreeView::scrollTo(index, hint);
169 }
170 }
171
172 #include "ktreeview.moc"
173 #include "ktreeview_p.moc"