]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphincategorydrawer.cpp
Use the "new" bug dialog opening bugs.kde.org that will also check for already report...
[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 QRect starRect = option.rect;
54
55 int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
56 QVariant categoryVariant = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
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);
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.bottom() - (iconSize / 4));
171 KUser user(category);
172 QString faceIconPath = user.faceIconPath();
173
174 if (!faceIconPath.isEmpty())
175 {
176 icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(option.fontMetrics.height(), Qt::SmoothTransformation));
177 }
178 else
179 {
180 icon = KIconLoader::global()->loadIcon("user", KIconLoader::NoGroup, option.fontMetrics.height());
181 }
182
183 opt.rect.setTop(opt.rect.top() - icon.height());
184
185 break;
186 }
187
188 case KDirModel::Group:
189 paintIcon = false;
190 break;
191
192 case KDirModel::Type: {
193 opt.rect.setTop(option.rect.bottom() - (iconSize / 4));
194 const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
195 const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
196 KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
197 // This is the only way of getting the icon right. Others will fail on corner
198 // cases like the item representing this group has been set a different icon,
199 // so the group icon drawn is that one particularly. This way assures the drawn
200 // icon is the one of the mimetype of the group itself. (ereslibre)
201 icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(),
202 KIconLoader::NoGroup, option.fontMetrics.height());
203
204 opt.rect.setTop(opt.rect.top() - icon.height());
205
206 break;
207 }
208
209 #ifdef HAVE_NEPOMUK
210 case DolphinModel::Rating: {
211 paintText = false;
212 paintIcon = false;
213
214 painter->setLayoutDirection( option.direction );
215 QRect ratingRect( option.rect );
216 ratingRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
217 ratingRect.setHeight( iconSize );
218 Nepomuk::RatingPainter::drawRating( painter, ratingRect, Qt::AlignLeft, category.toInt() );
219 break;
220 }
221
222 case DolphinModel::Tags:
223 paintIcon = false;
224 break;
225 #endif
226 }
227
228 if (paintIcon) {
229 painter->drawPixmap(QRect(option.direction == Qt::LeftToRight ? opt.rect.left()
230 : opt.rect.right() - icon.width() + (iconSize / 4), opt.rect.top(), icon.width(), icon.height()), icon);
231
232 if (option.direction == Qt::LeftToRight)
233 {
234 opt.rect.setLeft(opt.rect.left() + icon.width() + (iconSize / 4));
235 }
236 else
237 {
238 opt.rect.setRight(opt.rect.right() + (iconSize / 4));
239 }
240 }
241
242 if (paintText) {
243 opt.rect.setTop(option.rect.top() + (iconSize / 4));
244 opt.rect.setBottom(opt.rect.bottom() - 2);
245 painter->setPen(color);
246
247 QRect textRect = opt.rect;
248
249 if (option.direction == Qt::RightToLeft)
250 {
251 textRect.setWidth(textRect.width() - (paintIcon ? icon.width() + (iconSize / 2)
252 : -(iconSize / 4)));
253 }
254
255 painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
256 metrics.elidedText(category, Qt::ElideRight, textRect.width()));
257 }
258
259 painter->restore();
260 }
261
262 int DolphinCategoryDrawer::categoryHeight(const QStyleOption &option) const
263 {
264 int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
265
266 return qMax(option.fontMetrics.height() + (iconSize / 4) * 2 + 2, iconSize + (iconSize / 4) * 2 + 2) /* 2 gradient */;
267 }