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