]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinitemcategorizer.cpp
remove kde4_automoc()
[dolphin.git] / src / dolphinitemcategorizer.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 "dolphinitemcategorizer.h"
22
23 #include "dolphinview.h"
24 #include "dolphinsortfilterproxymodel.h"
25
26 #ifdef HAVE_NEPOMUK
27 #include <config-nepomuk.h>
28 #include <nepomuk/global.h>
29 #include <nepomuk/resource.h>
30 #endif
31
32 #include <kdatetime.h>
33 #include <kdirmodel.h>
34 #include <kfileitem.h>
35 #include <kiconloader.h>
36 #include <klocale.h>
37 #include <kurl.h>
38 #include <kuser.h>
39 #include <kmimetype.h>
40 #include <kstandarddirs.h>
41 #include <kpixmapeffect.h>
42
43 #include <QList>
44 #include <QSortFilterProxyModel>
45 #include <QPainter>
46 #include <QDir>
47
48 DolphinItemCategorizer::DolphinItemCategorizer() :
49 KItemCategorizer()
50 {
51 }
52
53 DolphinItemCategorizer::~DolphinItemCategorizer()
54 {
55 }
56
57 QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index,
58 int sortRole) const
59 {
60 QString retString;
61
62 if (!index.isValid())
63 {
64 return retString;
65 }
66
67 const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
68 KFileItem *item = dirModel->itemForIndex(index);
69
70 switch (sortRole)
71 {
72 case DolphinView::SortByName:
73 {
74 // KDirModel checks columns to know to which role are
75 // we talking about
76 QModelIndex theIndex = index.model()->index(index.row(),
77 KDirModel::Name,
78 index.parent());
79
80 if (!theIndex.isValid()) {
81 return retString;
82 }
83
84 QVariant data = theIndex.model()->data(theIndex, Qt::DisplayRole);
85 if (data.toString().size())
86 {
87 if (!item->isHidden() && data.toString().at(0).isLetter())
88 retString = data.toString().toUpper().at(0);
89 else if (item->isHidden() && data.toString().at(0) == '.' &&
90 data.toString().at(1).isLetter())
91 retString = data.toString().toUpper().at(1);
92 else if (item->isHidden() && data.toString().at(0) == '.' &&
93 !data.toString().at(1).isLetter())
94 retString = i18nc("@title:group Name", "Others");
95 else if (item->isHidden() && data.toString().at(0) != '.')
96 retString = data.toString().toUpper().at(0);
97 else if (item->isHidden())
98 retString = data.toString().toUpper().at(0);
99 else
100 {
101 bool validCategory = false;
102
103 const QString str(data.toString().toUpper());
104 const QChar* currA = str.unicode();
105 while (!currA->isNull() && !validCategory) {
106 if (currA->isLetter())
107 validCategory = true;
108 else if (currA->isDigit())
109 return i18nc("@title:group", "Others");
110 else
111 ++currA;
112 }
113
114 if (!validCategory)
115 retString = i18nc("@title:group Name", "Others");
116 else
117 retString = *currA;
118 }
119 }
120 break;
121 }
122
123 case DolphinView::SortByDate:
124 {
125 KDateTime modifiedTime;
126 modifiedTime.setTime_t(item->time(KIO::UDS_MODIFICATION_TIME));
127 modifiedTime = modifiedTime.toLocalZone();
128
129 if (modifiedTime.daysTo(KDateTime::currentLocalDateTime()) == 0)
130 retString = i18nc("@title:group Date", "Today");
131 else if (modifiedTime.daysTo(KDateTime::currentLocalDateTime()) == 1)
132 retString = i18nc("@title:group Date", "Yesterday");
133 else if (modifiedTime.daysTo(KDateTime::currentLocalDateTime()) < 7)
134 retString = i18nc("@title:group Date", "Less than a week");
135 else if (modifiedTime.daysTo(KDateTime::currentLocalDateTime()) < 31)
136 retString = i18nc("@title:group Date", "Less than a month");
137 else if (modifiedTime.daysTo(KDateTime::currentLocalDateTime()) < 365)
138 retString = i18nc("@title:group Date", "Less than a year");
139 else
140 retString = i18nc("@title:group Date", "More than a year");
141 break;
142 }
143
144 case DolphinView::SortByPermissions:
145 retString = item->permissionsString();
146 break;
147
148 case DolphinView::SortByOwner:
149 retString = item->user();
150 break;
151
152 case DolphinView::SortByGroup:
153 retString = item->group();
154 break;
155
156 case DolphinView::SortBySize: {
157 const int fileSize = item ? item->size() : -1;
158 if (item && item->isDir()) {
159 retString = i18nc("@title:group Size", "Folders");
160 } else if (fileSize < 5242880) {
161 retString = i18nc("@title:group Size", "Small");
162 } else if (fileSize < 10485760) {
163 retString = i18nc("@title:group Size", "Medium");
164 } else {
165 retString = i18nc("@title:group Size", "Big");
166 }
167 break;
168 }
169
170 case DolphinView::SortByType:
171 retString = item->mimeComment();
172 break;
173
174 #ifdef HAVE_NEPOMUK
175 case DolphinView::SortByRating: {
176 const quint32 rating = DolphinSortFilterProxyModel::ratingForIndex(index);
177
178 retString = QString::number(rating);
179 break;
180 }
181
182 case DolphinView::SortByTags: {
183 retString = DolphinSortFilterProxyModel::tagsForIndex(index);
184
185 if (retString.isEmpty())
186 retString = i18nc("@title:group Tags", "Not yet tagged");
187
188 break;
189 }
190 #endif
191 }
192
193 return retString;
194 }
195
196 void DolphinItemCategorizer::drawCategory(const QModelIndex &index,
197 int sortRole,
198 const QStyleOption &option,
199 QPainter *painter) const
200 {
201 QRect starRect = option.rect;
202 int iconSize = KIconLoader::global()->theme()->defaultSize(K3Icon::Small);
203
204 const QString category = categoryForItem(index, sortRole);
205
206 QColor color = option.palette.color(QPalette::Text);
207
208 painter->save();
209 painter->setRenderHint(QPainter::Antialiasing);
210
211 QStyleOptionButton opt;
212
213 opt.rect = option.rect;
214 opt.palette = option.palette;
215 opt.direction = option.direction;
216 opt.text = category;
217
218 if (option.state & QStyle::State_MouseOver)
219 {
220 const QPalette::ColorGroup group =
221 option.state & QStyle::State_Enabled ?
222 QPalette::Normal : QPalette::Disabled;
223
224 QLinearGradient gradient(option.rect.topLeft(),
225 option.rect.bottomRight());
226 gradient.setColorAt(0,
227 option.palette.color(group,
228 QPalette::Highlight).light());
229 gradient.setColorAt(1, Qt::transparent);
230
231 painter->fillRect(option.rect, gradient);
232 }
233
234 QFont painterFont = painter->font();
235 painterFont.setWeight(QFont::Bold);
236 QFontMetrics metrics(painterFont);
237 painter->setFont(painterFont);
238
239 QPainterPath path;
240 path.addRect(option.rect.left(),
241 option.rect.bottom() - 2,
242 option.rect.width(),
243 2);
244
245 QLinearGradient gradient(option.rect.topLeft(),
246 option.rect.bottomRight());
247 gradient.setColorAt(0, color);
248 gradient.setColorAt(1, Qt::transparent);
249
250 painter->setBrush(gradient);
251 painter->fillPath(path, gradient);
252
253 opt.rect.setLeft(opt.rect.left() + (iconSize / 4));
254 starRect.setLeft(starRect.left() + (iconSize / 4));
255 starRect.setRight(starRect.right() + (iconSize / 4));
256
257 bool paintIcon = true;
258 bool paintText = true;
259
260 QPixmap icon;
261 switch (sortRole) {
262 case DolphinView::SortByName:
263 paintIcon = false;
264 break;
265
266 case DolphinView::SortByDate:
267 paintIcon = false;
268 break;
269
270 case DolphinView::SortByPermissions:
271 paintIcon = false; // FIXME: let's think about how to represent permissions
272 break;
273
274 case DolphinView::SortByOwner: {
275 opt.rect.setTop(option.rect.top() + (iconSize / 4));
276 KUser user(category);
277 if (QFile::exists(user.homeDir() + QDir::separator() + ".face.icon"))
278 {
279 icon = QPixmap::fromImage(QImage(user.homeDir() + QDir::separator() + ".face.icon")).scaled(iconSize, iconSize);
280 }
281 else
282 {
283 icon = KIconLoader::global()->loadIcon("user", K3Icon::Small);
284 }
285 break;
286 }
287
288 case DolphinView::SortByGroup:
289 paintIcon = false;
290 break;
291
292 case DolphinView::SortBySize:
293 paintIcon = false;
294 break;
295
296 case DolphinView::SortByType: {
297 opt.rect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
298 const KDirModel *model = static_cast<const KDirModel*>(index.model());
299 KFileItem *item = model->itemForIndex(index);
300 icon = KIconLoader::global()->loadIcon(KMimeType::iconNameForUrl(item->url()),
301 K3Icon::Small);
302 break;
303 }
304
305 #ifdef HAVE_NEPOMUK
306 case DolphinView::SortByRating: {
307 paintText = false;
308 paintIcon = false;
309
310 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
311 starRect.setSize(QSize(iconSize, iconSize));
312
313 QPixmap pixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
314 QPixmap smallPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::NoGroup, iconSize / 2);
315 QPixmap disabledPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
316
317 KPixmapEffect::toGray(disabledPixmap, false);
318
319 int rating = category.toInt();
320
321 for (int i = 0; i < rating - (rating % 2); i += 2) {
322 painter->drawPixmap(starRect, pixmap);
323 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4) /* separator between stars */);
324 }
325
326 if (rating && rating % 2) {
327 starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 4));
328 starRect.setSize(QSize(iconSize / 2, iconSize / 2));
329 painter->drawPixmap(starRect, smallPixmap);
330 starRect.setTop(opt.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
331 starRect.setSize(QSize(iconSize / 2, iconSize / 2));
332 starRect.setLeft(starRect.left() + (iconSize / 2) + (iconSize / 4));
333 starRect.setSize(QSize(iconSize, iconSize));
334 }
335
336 for (int i = rating; i < 9; i += 2) {
337 painter->drawPixmap(starRect, disabledPixmap);
338 starRect.setLeft(starRect.left() + iconSize + (iconSize / 4));
339 }
340
341 break;
342 }
343
344 case DolphinView::SortByTags:
345 paintIcon = false;
346 break;
347 #endif
348 }
349
350 if (paintIcon) {
351 painter->drawPixmap(QRect(opt.rect.left(), opt.rect.top(), iconSize, iconSize), icon);
352 opt.rect.setLeft(opt.rect.left() + iconSize + (iconSize / 4));
353 }
354
355 if (paintText) {
356 opt.rect.setTop(option.rect.top() + (iconSize / 4));
357 opt.rect.setBottom(opt.rect.bottom() - 2);
358 painter->setPen(color);
359
360 painter->drawText(opt.rect, Qt::AlignVCenter | Qt::AlignLeft,
361 metrics.elidedText(category, Qt::ElideRight, opt.rect.width()));
362 }
363
364 painter->restore();
365 }
366
367 int DolphinItemCategorizer::categoryHeight(const QStyleOption &option) const
368 {
369 int iconSize = KIconLoader::global()->theme()->defaultSize(K3Icon::Small);
370
371 return qMax(option.fontMetrics.height() + (iconSize / 4) * 2 + 2, iconSize + (iconSize / 4) * 2 + 2) /* 2 gradient */;
372 }