]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kitemlistgroupheader.cpp
Fix selection issue when expanding a tree
[dolphin.git] / src / kitemviews / kitemlistgroupheader.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * Based on the Itemviews NG project from Trolltech Labs: *
5 * http://qt.gitorious.org/qt-labs/itemviews-ng *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
21 ***************************************************************************/
22
23 #include "kitemlistgroupheader.h"
24
25 #include "kitemlistview.h"
26
27 #include <QGraphicsSceneResizeEvent>
28 #include <QPainter>
29 #include <QStyleOptionGraphicsItem>
30 #include <KDebug>
31
32 KItemListGroupHeader::KItemListGroupHeader(QGraphicsWidget* parent) :
33 QGraphicsWidget(parent, 0),
34 m_dirtyCache(true),
35 m_role(),
36 m_data(),
37 m_styleOption(),
38 m_scrollOrientation(Qt::Vertical),
39 m_leftBorderCache(0),
40 m_rightBorderCache(0),
41 m_outlineColor()
42 {
43 }
44
45 KItemListGroupHeader::~KItemListGroupHeader()
46 {
47 deleteCache();
48 }
49
50 void KItemListGroupHeader::setRole(const QByteArray& role)
51 {
52 if (m_role != role) {
53 const QByteArray previous = m_role;
54 m_role = role;
55 update();
56 roleChanged(role, previous);
57 }
58 }
59
60 QByteArray KItemListGroupHeader::role() const
61 {
62 return m_role;
63 }
64
65 void KItemListGroupHeader::setData(const QVariant& data)
66 {
67 if (m_data != data) {
68 const QVariant previous = m_data;
69 m_data = data;
70 update();
71 dataChanged(data, previous);
72 }
73 }
74
75 QVariant KItemListGroupHeader::data() const
76 {
77 return m_data;
78 }
79
80 void KItemListGroupHeader::setStyleOption(const KItemListStyleOption& option)
81 {
82 const KItemListStyleOption previous = m_styleOption;
83 m_styleOption = option;
84 m_dirtyCache = true;
85 styleOptionChanged(option, previous);
86 }
87
88 const KItemListStyleOption& KItemListGroupHeader::styleOption() const
89 {
90 return m_styleOption;
91 }
92
93 void KItemListGroupHeader::setScrollOrientation(Qt::Orientation orientation)
94 {
95 if (m_scrollOrientation != orientation) {
96 const Qt::Orientation previous = m_scrollOrientation;
97 m_scrollOrientation = orientation;
98 if (orientation == Qt::Vertical) {
99 m_dirtyCache = true;
100 } else {
101 deleteCache();
102 }
103 scrollOrientationChanged(orientation, previous);
104 }
105 }
106
107 Qt::Orientation KItemListGroupHeader::scrollOrientation() const
108 {
109 return m_scrollOrientation;
110 }
111
112 void KItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
113 {
114 Q_UNUSED(option);
115 Q_UNUSED(widget);
116
117 if (m_scrollOrientation == Qt::Horizontal) {
118 Q_ASSERT(!m_leftBorderCache);
119 Q_ASSERT(!m_rightBorderCache);
120 return;
121 }
122
123 if (m_dirtyCache) {
124 updateCache();
125 }
126
127 const int leftBorderX = m_leftBorderCache->width() + 1;
128 const int rightBorderX = size().width() - m_rightBorderCache->width() - 2;
129
130 painter->setPen(m_outlineColor);
131 painter->drawLine(leftBorderX, 1, rightBorderX, 1);
132
133 painter->drawPixmap(1, 1, *m_leftBorderCache);
134 painter->drawPixmap(rightBorderX, 1, *m_rightBorderCache);
135 }
136
137 void KItemListGroupHeader::roleChanged(const QByteArray& current, const QByteArray& previous)
138 {
139 Q_UNUSED(current);
140 Q_UNUSED(previous);
141 }
142
143 void KItemListGroupHeader::dataChanged(const QVariant& current, const QVariant& previous)
144 {
145 Q_UNUSED(current);
146 Q_UNUSED(previous);
147 }
148
149 void KItemListGroupHeader::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
150 {
151 Q_UNUSED(current);
152 Q_UNUSED(previous);
153 }
154
155 void KItemListGroupHeader::scrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
156 {
157 Q_UNUSED(current);
158 Q_UNUSED(previous);
159 }
160
161 void KItemListGroupHeader::resizeEvent(QGraphicsSceneResizeEvent* event)
162 {
163 QGraphicsWidget::resizeEvent(event);
164 if (event->oldSize().height() != event->newSize().height()) {
165 m_dirtyCache = true;
166 }
167 }
168
169 void KItemListGroupHeader::updateCache()
170 {
171 Q_ASSERT(m_dirtyCache);
172
173 deleteCache();
174
175 const int length = qMax(int(size().height() - 1), 1);
176 m_leftBorderCache = new QPixmap(length, length);
177 m_leftBorderCache->fill(Qt::transparent);
178
179 m_rightBorderCache = new QPixmap(length, length);
180 m_rightBorderCache->fill(Qt::transparent);
181
182 // Calculate the outline color. No alphablending is used for
183 // performance reasons.
184 const QColor c1 = m_styleOption.palette.text().color();
185 const QColor c2 = m_styleOption.palette.background().color();
186 const int p1 = 35;
187 const int p2 = 100 - p1;
188 m_outlineColor = QColor((c1.red() * p1 + c2.red() * p2) / 100,
189 (c1.green() * p1 + c2.green() * p2) / 100,
190 (c1.blue() * p1 + c2.blue() * p2) / 100);
191
192 // The drawing code is based on the code of DolphinCategoryDrawer from Dolphin 1.7
193 // Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
194 {
195 // Cache the left border as pixmap
196 QPainter painter(m_leftBorderCache);
197 painter.setPen(m_outlineColor);
198
199 // 1. Draw top horizontal line
200 painter.drawLine(3, 0, length, 0);
201
202 // 2. Draw vertical line with gradient
203 const QPoint start(0, 3);
204 QLinearGradient gradient(start, QPoint(0, length));
205 gradient.setColorAt(0, m_outlineColor);
206 gradient.setColorAt(1, Qt::transparent);
207 painter.fillRect(QRect(start, QSize(1, length - start.y())), gradient);
208
209 // 3. Draw arc
210 painter.setRenderHint(QPainter::Antialiasing);
211 QRectF arc(QPointF(0, 0), QSizeF(4, 4));
212 arc.translate(0.5, 0.5);
213 painter.drawArc(arc, 1440, 1440);
214 }
215
216 {
217 // Cache the right border as pixmap
218 QPainter painter(m_rightBorderCache);
219 painter.setPen(m_outlineColor);
220
221 // 1. Draw top horizontal line
222 painter.drawLine(0, 0, length - 3, 0);
223
224 // 2. Draw vertical line with gradient
225 const int right = length - 1;
226 const QPoint start(right, 3);
227 QLinearGradient gradient(start, QPoint(right, length));
228 gradient.setColorAt(0, m_outlineColor);
229 gradient.setColorAt(1, Qt::transparent);
230 painter.fillRect(QRect(start, QSize(1, length - start.y())), gradient);
231
232 // 3. Draw arc
233 painter.setRenderHint(QPainter::Antialiasing);
234 QRectF arc(QPointF(length - 5, 0), QSizeF(4, 4));
235 arc.translate(0.5, 0.5);
236 painter.drawArc(arc, 0, 1440);
237 }
238
239 m_dirtyCache = false;
240 }
241
242 void KItemListGroupHeader::deleteCache()
243 {
244 delete m_leftBorderCache;
245 m_leftBorderCache = 0;
246
247 delete m_rightBorderCache;
248 m_rightBorderCache = 0;
249 }
250
251 #include "kitemlistgroupheader.moc"