]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphincategorydrawer.cpp
Create the new architecture for KCategorizedView. Now DolphinModel is created, inheri...
[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 = option.palette.color(QPalette::Text);
66
67 painter->save();
68 painter->setRenderHint(QPainter::Antialiasing);
69
70 QStyleOptionButton opt;
71
72 opt.rect = option.rect;
73 opt.palette = option.palette;
74 opt.direction = option.direction;
75 opt.text = category;
76
77 if (option.state & QStyle::State_MouseOver)
78 {
79 QColor hover = option.palette.color(QPalette::Highlight).light();
80 hover.setAlpha(88);
81
82 QLinearGradient gradient(option.rect.topLeft(),
83 option.rect.bottomRight());
84 gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
85 : 1, hover);
86 gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
87 : 0, Qt::transparent);
88
89 painter->fillRect(option.rect, gradient);
90 }
91
92 QFont painterFont = painter->font();
93 painterFont.setWeight(QFont::Bold);
94 QFontMetrics metrics(painterFont);
95 painter->setFont(painterFont);
96
97 QPainterPath path;
98 path.addRect(option.rect.left(),
99 option.rect.bottom() - 2,
100 option.rect.width(),
101 2);
102
103 QLinearGradient gradient(option.rect.topLeft(),
104 option.rect.bottomRight());
105 gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
106 : 1, color);
107 gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
108 : 0, Qt::transparent);
109
110 painter->setBrush(gradient);
111 painter->fillPath(path, gradient);
112
113 if (option.direction == Qt::LeftToRight)
114 {
115 opt.rect.setLeft(opt.rect.left() + (iconSize / 4));
116 starRect.setLeft(starRect.left() + (iconSize / 4));
117 starRect.setRight(starRect.right() + (iconSize / 4));
118 }
119 else
120 {
121 opt.rect.setRight(opt.rect.width() - (iconSize / 4));
122 starRect.setLeft(starRect.width() - iconSize);
123 starRect.setRight(starRect.width() - (iconSize / 4));
124 }
125
126 bool paintIcon = true;
127 bool paintText = true;
128
129 QPixmap icon;
130 switch (index.column()) {
131 case KDirModel::Name:
132 paintIcon = false;
133 break;
134
135 case KDirModel::Size:
136 paintIcon = false;
137 break;
138
139 case KDirModel::ModifiedTime:
140 paintIcon = false;
141 break;
142
143 case KDirModel::Permissions:
144 paintIcon = false; // TODO: let's think about how to represent permissions
145 break;
146
147 case KDirModel::Owner: {
148 opt.rect.setTop(option.rect.top() + (iconSize / 4));
149 KUser user(category);
150 if (QFile::exists(user.homeDir() + QDir::separator() + ".face.icon"))
151 {
152 icon = QPixmap::fromImage(QImage(user.homeDir() + QDir::separator() + ".face.icon")).scaled(iconSize, iconSize);
153 }
154 else
155 {
156 icon = KIconLoader::global()->loadIcon("user", K3Icon::Small);
157 }
158 break;
159 }
160
161 case KDirModel::Group:
162 paintIcon = false;
163 break;
164
165 case KDirModel::Type: {
166 opt.rect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
167 const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
168 const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
169 KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
170 // This is the only way of getting the icon right. Others will fail on corner
171 // cases like the item representing this group has been set a different icon,
172 // so the group icon drawn is that one particularly. This way assures the drawn
173 // icon is the one of the mimetype of the group itself. (ereslibre)
174 icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(),
175 K3Icon::Small);
176 break;
177 }
178
179 #ifdef HAVE_NEPOMUK
180 case DolphinModel::Rating: {
181 paintText = false;
182 paintIcon = false;
183
184 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
185 starRect.setSize(QSize(iconSize, iconSize));
186
187 QPixmap pixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
188 QPixmap smallPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::NoGroup, iconSize / 2);
189 QPixmap disabledPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
190
191 KPixmapEffect::toGray(disabledPixmap, false);
192
193 int rating = category.toInt();
194
195 for (int i = 0; i < rating - (rating % 2); i += 2) {
196 painter->drawPixmap(starRect, pixmap);
197
198 if (option.direction == Qt::LeftToRight)
199 {
200 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4) /* separator between stars */);
201 starRect.setRight(starRect.right() + iconSize + (iconSize / 4) /* separator between stars */);
202 }
203 else
204 {
205 starRect.setLeft(starRect.left() - iconSize - (iconSize / 4) /* separator between stars */);
206 starRect.setRight(starRect.right() - iconSize - (iconSize / 4) /* separator between stars */);
207 }
208 }
209
210 if (rating && rating % 2) {
211 if (option.direction == Qt::RightToLeft)
212 {
213 starRect.setLeft(starRect.left() + (iconSize / 2) /* separator between stars */);
214 //starRect.setRight(starRect.right() + (iconSize / 2) /* separator between stars */);
215 }
216
217 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 4));
218 starRect.setSize(QSize(iconSize / 2, iconSize / 2));
219 painter->drawPixmap(starRect, smallPixmap);
220 starRect.setTop(opt.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
221 //starRect.setSize(QSize(iconSize / 2, iconSize / 2));
222
223 if (option.direction == Qt::LeftToRight)
224 {
225 starRect.setLeft(starRect.left() + (iconSize / 2) + (iconSize / 4));
226 starRect.setRight(starRect.right() + (iconSize / 2) + (iconSize / 4));
227 }
228 else
229 {
230 starRect.setLeft(starRect.left() - (iconSize / 2) - (iconSize / 4));
231 starRect.setRight(starRect.right() - (iconSize / 2) - (iconSize / 4));
232 }
233
234 if (option.direction == Qt::RightToLeft)
235 {
236 starRect.setLeft(starRect.left() - (iconSize / 2));
237 starRect.setRight(starRect.right() - (iconSize / 2));
238 }
239
240 starRect.setSize(QSize(iconSize, iconSize));
241 }
242
243 for (int i = rating; i < 9; i += 2) {
244 painter->drawPixmap(starRect, disabledPixmap);
245
246 if (option.direction == Qt::LeftToRight)
247 {
248 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4));
249 starRect.setRight(starRect.right() + iconSize + (iconSize / 4));
250 }
251 else
252 {
253 starRect.setLeft(starRect.left() - iconSize - (iconSize / 4));
254 starRect.setRight(starRect.right() - iconSize - (iconSize / 4));
255 }
256 }
257
258 break;
259 }
260
261 case DolphinModel::Tags:
262 paintIcon = false;
263 break;
264 #endif
265 }
266
267 if (paintIcon) {
268 painter->drawPixmap(QRect(option.direction == Qt::LeftToRight ? opt.rect.left()
269 : opt.rect.right() - iconSize, opt.rect.top(), iconSize, iconSize), icon);
270
271 if (option.direction == Qt::LeftToRight)
272 {
273 opt.rect.setLeft(opt.rect.left() + iconSize + (iconSize / 4));
274 }
275 }
276
277 if (paintText) {
278 opt.rect.setTop(option.rect.top() + (iconSize / 4));
279 opt.rect.setBottom(opt.rect.bottom() - 2);
280 painter->setPen(color);
281
282 QRect textRect = opt.rect;
283
284 if (option.direction == Qt::RightToLeft)
285 {
286 textRect.setWidth(textRect.width() - (paintIcon ? iconSize + (iconSize / 4)
287 : (iconSize / 4)));
288 }
289
290 painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
291 metrics.elidedText(category, Qt::ElideRight, textRect.width()));
292 }
293
294 painter->restore();
295 }
296
297 int DolphinCategoryDrawer::categoryHeight(const QStyleOption &option) const
298 {
299 int iconSize = KIconLoader::global()->currentSize(K3Icon::Small);
300
301 return qMax(option.fontMetrics.height() + (iconSize / 4) * 2 + 2, iconSize + (iconSize / 4) * 2 + 2) /* 2 gradient */;
302 }