]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphincategorydrawer.cpp
Restore the root URL when navigating through the history (this is important for views...
[dolphin.git] / src / dolphincategorydrawer.cpp
1 /**
2 * This file is part of the KDE project
3 * Copyright (C) 2007 Rafael Fernández López <ereslibre@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "dolphincategorydrawer.h"
22
23 #include <QPainter>
24 #include <QFile>
25 #include <QDir>
26
27 #include <kiconloader.h>
28 #include <kcategorizedsortfilterproxymodel.h>
29 #include <kpixmapeffect.h>
30 #include <kuser.h>
31
32 #include <config-nepomuk.h>
33 #ifdef HAVE_NEPOMUK
34 #include <nepomuk/global.h>
35 #include <nepomuk/resource.h>
36 #include <nepomuk/tag.h>
37 #endif
38
39 #include "dolphinview.h"
40 #include "dolphinmodel.h"
41
42 DolphinCategoryDrawer::DolphinCategoryDrawer()
43 {
44 }
45
46 DolphinCategoryDrawer::~DolphinCategoryDrawer()
47 {
48 }
49
50 void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
51 const QStyleOption &option, QPainter *painter) const
52 {
53 QRect starRect = option.rect;
54
55 int iconSize = KIconLoader::global()->currentSize(K3Icon::Small);
56 QVariant categoryVariant = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryRole);
57
58 if (!categoryVariant.isValid())
59 {
60 return;
61 }
62
63 const QString category = categoryVariant.toString();
64
65 QColor color;
66
67 if (option.state & QStyle::State_Selected)
68 {
69 color = option.palette.color(QPalette::HighlightedText);
70 }
71 else
72 {
73 color = option.palette.color(QPalette::Text);
74 }
75
76 painter->save();
77 painter->setRenderHint(QPainter::Antialiasing);
78
79 QStyleOptionButton opt;
80
81 opt.rect = option.rect;
82 opt.palette = option.palette;
83 opt.direction = option.direction;
84 opt.text = category;
85
86 if (option.state & QStyle::State_Selected)
87 {
88 QColor selected = option.palette.color(QPalette::Highlight);
89
90 QLinearGradient gradient(option.rect.topLeft(),
91 option.rect.bottomRight());
92 gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
93 : 1, selected);
94 gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
95 : 0, Qt::transparent);
96
97 painter->fillRect(option.rect, gradient);
98 }
99 else if (option.state & QStyle::State_MouseOver)
100 {
101 QColor hover = option.palette.color(QPalette::Highlight).light();
102 hover.setAlpha(88);
103
104 QLinearGradient gradient(option.rect.topLeft(),
105 option.rect.bottomRight());
106 gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
107 : 1, hover);
108 gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
109 : 0, Qt::transparent);
110
111 painter->fillRect(option.rect, gradient);
112 }
113
114 QFont painterFont = painter->font();
115 painterFont.setWeight(QFont::Bold);
116 QFontMetrics metrics(painterFont);
117 painter->setFont(painterFont);
118
119 QPainterPath path;
120 path.addRect(option.rect.left(),
121 option.rect.bottom() - 2,
122 option.rect.width(),
123 2);
124
125 QLinearGradient gradient(option.rect.topLeft(),
126 option.rect.bottomRight());
127 gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
128 : 1, color);
129 gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
130 : 0, Qt::transparent);
131
132 painter->setBrush(gradient);
133 painter->fillPath(path, gradient);
134
135 if (option.direction == Qt::LeftToRight)
136 {
137 opt.rect.setLeft(opt.rect.left() + (iconSize / 4));
138 starRect.setLeft(starRect.left() + (iconSize / 4));
139 starRect.setRight(starRect.right() + (iconSize / 4));
140 }
141 else
142 {
143 opt.rect.setRight(opt.rect.width() - (iconSize / 4));
144 starRect.setLeft(starRect.width() - iconSize);
145 starRect.setRight(starRect.width() - (iconSize / 4));
146 }
147
148 bool paintIcon = true;
149 bool paintText = true;
150
151 QPixmap icon;
152 switch (index.column()) {
153 case KDirModel::Name:
154 paintIcon = false;
155 break;
156
157 case KDirModel::Size:
158 paintIcon = false;
159 break;
160
161 case KDirModel::ModifiedTime:
162 paintIcon = false;
163 break;
164
165 case KDirModel::Permissions:
166 paintIcon = false; // TODO: let's think about how to represent permissions
167 break;
168
169 case KDirModel::Owner: {
170 opt.rect.setTop(option.rect.top() + (iconSize / 4));
171 KUser user(category);
172 if (QFile::exists(user.homeDir() + QDir::separator() + ".face.icon"))
173 {
174 icon = QPixmap::fromImage(QImage(user.homeDir() + QDir::separator() + ".face.icon")).scaled(iconSize, iconSize);
175 }
176 else
177 {
178 icon = KIconLoader::global()->loadIcon("user", K3Icon::Small);
179 }
180 break;
181 }
182
183 case KDirModel::Group:
184 paintIcon = false;
185 break;
186
187 case KDirModel::Type: {
188 opt.rect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
189 const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
190 const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
191 KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
192 // This is the only way of getting the icon right. Others will fail on corner
193 // cases like the item representing this group has been set a different icon,
194 // so the group icon drawn is that one particularly. This way assures the drawn
195 // icon is the one of the mimetype of the group itself. (ereslibre)
196 icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(),
197 K3Icon::Small);
198 break;
199 }
200
201 #ifdef HAVE_NEPOMUK
202 case DolphinModel::Rating: {
203 paintText = false;
204 paintIcon = false;
205
206 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
207 starRect.setSize(QSize(iconSize, iconSize));
208
209 QPixmap pixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
210 QPixmap smallPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::NoGroup, iconSize / 2);
211 QPixmap disabledPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
212
213 KPixmapEffect::toGray(disabledPixmap, false);
214
215 int rating = category.toInt();
216
217 for (int i = 0; i < rating - (rating % 2); i += 2) {
218 painter->drawPixmap(starRect, pixmap);
219
220 if (option.direction == Qt::LeftToRight)
221 {
222 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4) /* separator between stars */);
223 starRect.setRight(starRect.right() + iconSize + (iconSize / 4) /* separator between stars */);
224 }
225 else
226 {
227 starRect.setLeft(starRect.left() - iconSize - (iconSize / 4) /* separator between stars */);
228 starRect.setRight(starRect.right() - iconSize - (iconSize / 4) /* separator between stars */);
229 }
230 }
231
232 if (rating && rating % 2) {
233 if (option.direction == Qt::RightToLeft)
234 {
235 starRect.setLeft(starRect.left() + (iconSize / 2) /* separator between stars */);
236 }
237
238 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 4));
239 starRect.setSize(QSize(iconSize / 2, iconSize / 2));
240 painter->drawPixmap(starRect, smallPixmap);
241 starRect.setTop(opt.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
242
243 if (option.direction == Qt::LeftToRight)
244 {
245 starRect.setLeft(starRect.left() + (iconSize / 2) + (iconSize / 4));
246 starRect.setRight(starRect.right() + (iconSize / 2) + (iconSize / 4));
247 }
248 else
249 {
250 starRect.setLeft(starRect.left() - (iconSize / 2) - (iconSize / 4));
251 starRect.setRight(starRect.right() - (iconSize / 2) - (iconSize / 4));
252 }
253
254 if (option.direction == Qt::RightToLeft)
255 {
256 starRect.setLeft(starRect.left() - (iconSize / 2));
257 starRect.setRight(starRect.right() - (iconSize / 2));
258 }
259
260 starRect.setSize(QSize(iconSize, iconSize));
261 }
262
263 for (int i = rating; i < 9; i += 2) {
264 painter->drawPixmap(starRect, disabledPixmap);
265
266 if (option.direction == Qt::LeftToRight)
267 {
268 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4));
269 starRect.setRight(starRect.right() + iconSize + (iconSize / 4));
270 }
271 else
272 {
273 starRect.setLeft(starRect.left() - iconSize - (iconSize / 4));
274 starRect.setRight(starRect.right() - iconSize - (iconSize / 4));
275 }
276 }
277
278 break;
279 }
280
281 case DolphinModel::Tags:
282 paintIcon = false;
283 break;
284 #endif
285 }
286
287 if (paintIcon) {
288 painter->drawPixmap(QRect(option.direction == Qt::LeftToRight ? opt.rect.left()
289 : opt.rect.right() - iconSize + (iconSize / 4), opt.rect.top(), iconSize, iconSize), icon);
290
291 if (option.direction == Qt::LeftToRight)
292 {
293 opt.rect.setLeft(opt.rect.left() + iconSize + (iconSize / 4));
294 }
295 else
296 {
297 opt.rect.setRight(opt.rect.right() + (iconSize / 4));
298 }
299 }
300
301 if (paintText) {
302 opt.rect.setTop(option.rect.top() + (iconSize / 4));
303 opt.rect.setBottom(opt.rect.bottom() - 2);
304 painter->setPen(color);
305
306 QRect textRect = opt.rect;
307
308 if (option.direction == Qt::RightToLeft)
309 {
310 textRect.setWidth(textRect.width() - (paintIcon ? iconSize + (iconSize / 2)
311 : -(iconSize / 4)));
312 }
313
314 painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
315 metrics.elidedText(category, Qt::ElideRight, textRect.width()));
316 }
317
318 painter->restore();
319 }
320
321 int DolphinCategoryDrawer::categoryHeight(const QStyleOption &option) const
322 {
323 int iconSize = KIconLoader::global()->currentSize(K3Icon::Small);
324
325 return qMax(option.fontMetrics.height() + (iconSize / 4) * 2 + 2, iconSize + (iconSize / 4) * 2 + 2) /* 2 gradient */;
326 }