]> cloud.milkyroute.net Git - dolphin.git/blob - src/views/dolphincategorydrawer.cpp
Fix spelling errors reported by crazy
[dolphin.git] / src / views / 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
23 #include <config-nepomuk.h>
24
25 #include <QPainter>
26 #include <QFile>
27 #include <QDir>
28 #include <QApplication>
29 #include <QStyleOption>
30
31 #ifdef HAVE_NEPOMUK
32 #include <nepomuk/kratingpainter.h>
33 #endif
34
35 #include <kiconloader.h>
36 #include <kiconeffect.h>
37 #include <kcategorizedsortfilterproxymodel.h>
38 #include <qimageblitz.h>
39 #include <kuser.h>
40 #include <kcategorizedview.h>
41
42 #include "dolphinview.h"
43 #include "dolphinmodel.h"
44
45 #define HORIZONTAL_HINT 3
46
47 DolphinCategoryDrawer::DolphinCategoryDrawer(KCategorizedView *view)
48 : KCategoryDrawerV3(view)
49 , hotSpotPressed(NoneHotSpot)
50 , selectAll(KIconLoader::global()->loadIcon("list-add", KIconLoader::Desktop, 16))
51 , selectAllHovered(KIconLoader::global()->iconEffect()->apply(selectAll, KIconLoader::Desktop, KIconLoader::ActiveState))
52 , selectAllDisabled(KIconLoader::global()->iconEffect()->apply(selectAll, KIconLoader::Desktop, KIconLoader::DisabledState))
53 , unselectAll(KIconLoader::global()->loadIcon("list-remove", KIconLoader::Desktop, 16))
54 , unselectAllHovered(KIconLoader::global()->iconEffect()->apply(unselectAll, KIconLoader::Desktop, KIconLoader::ActiveState))
55 , unselectAllDisabled(KIconLoader::global()->iconEffect()->apply(unselectAll, KIconLoader::Desktop, KIconLoader::DisabledState))
56 {
57 }
58
59 DolphinCategoryDrawer::~DolphinCategoryDrawer()
60 {
61 }
62
63 bool DolphinCategoryDrawer::allCategorySelected(const QString &category) const
64 {
65 const QModelIndexList list = view()->block(category);
66 foreach (const QModelIndex &index, list) {
67 if (!view()->selectionModel()->isSelected(index)) {
68 return false;
69 }
70 }
71 return true;
72 }
73
74 bool DolphinCategoryDrawer::someCategorySelected(const QString &category) const
75 {
76 const QModelIndexList list = view()->block(category);
77 foreach (const QModelIndex &index, list) {
78 if (view()->selectionModel()->isSelected(index)) {
79 return true;
80 }
81 }
82 return false;
83 }
84
85 void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
86 const QStyleOption &option, QPainter *painter) const
87 {
88 Q_UNUSED(sortRole);
89 painter->setRenderHint(QPainter::Antialiasing);
90
91 if (!index.isValid()) {
92 return;
93 }
94
95 const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
96 const QRect optRect = option.rect;
97 QFont font(QApplication::font());
98 font.setBold(true);
99 const QFontMetrics fontMetrics = QFontMetrics(font);
100
101 QColor outlineColor = option.palette.text().color();
102 outlineColor.setAlphaF(0.35);
103
104 //BEGIN: top left corner
105 {
106 painter->save();
107 painter->setPen(outlineColor);
108 const QPointF topLeft(optRect.topLeft());
109 QRectF arc(topLeft, QSizeF(4, 4));
110 arc.translate(0.5, 0.5);
111 painter->drawArc(arc, 1440, 1440);
112 painter->restore();
113 }
114 //END: top left corner
115
116 //BEGIN: left vertical line
117 {
118 QPoint start(optRect.topLeft());
119 start.ry() += 3;
120 QPoint verticalGradBottom(optRect.topLeft());
121 verticalGradBottom.ry() += fontMetrics.height() + 5;
122 QLinearGradient gradient(start, verticalGradBottom);
123 gradient.setColorAt(0, outlineColor);
124 gradient.setColorAt(1, Qt::transparent);
125 painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
126 }
127 //END: left vertical line
128
129 //BEGIN: horizontal line
130 {
131 QPoint start(optRect.topLeft());
132 start.rx() += 3;
133 QPoint horizontalGradTop(optRect.topLeft());
134 horizontalGradTop.rx() += optRect.width() - 6;
135 painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
136 }
137 //END: horizontal line
138
139 //BEGIN: top right corner
140 {
141 painter->save();
142 painter->setPen(outlineColor);
143 QPointF topRight(optRect.topRight());
144 topRight.rx() -= 4;
145 QRectF arc(topRight, QSizeF(4, 4));
146 arc.translate(0.5, 0.5);
147 painter->drawArc(arc, 0, 1440);
148 painter->restore();
149 }
150 //END: top right corner
151
152 //BEGIN: right vertical line
153 {
154 QPoint start(optRect.topRight());
155 start.ry() += 3;
156 QPoint verticalGradBottom(optRect.topRight());
157 verticalGradBottom.ry() += fontMetrics.height() + 5;
158 QLinearGradient gradient(start, verticalGradBottom);
159 gradient.setColorAt(0, outlineColor);
160 gradient.setColorAt(1, Qt::transparent);
161 painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
162 }
163 //END: right vertical line
164
165 const int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
166
167 //BEGIN: select/unselect all
168 {
169 if (this->category == category) {
170 QRect iconAllRect(option.rect);
171 iconAllRect.setTop(iconAllRect.top() + 4);
172 iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
173 iconAllRect.setSize(QSize(iconSize, iconSize));
174 if (!allCategorySelected(category)) {
175 if (iconAllRect.contains(pos)) {
176 painter->drawPixmap(iconAllRect, selectAllHovered);
177 } else {
178 painter->drawPixmap(iconAllRect, selectAll);
179 }
180 } else {
181 painter->drawPixmap(iconAllRect, selectAllDisabled);
182 }
183 QRect iconNoneRect(option.rect);
184 iconNoneRect.setTop(iconNoneRect.top() + 4);
185 iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
186 iconNoneRect.setSize(QSize(iconSize, iconSize));
187 if (someCategorySelected(category)) {
188 if (iconNoneRect.contains(pos)) {
189 painter->drawPixmap(iconNoneRect, unselectAllHovered);
190 } else {
191 painter->drawPixmap(iconNoneRect, unselectAll);
192 }
193 } else {
194 painter->drawPixmap(iconNoneRect, unselectAllDisabled);
195 }
196 }
197 }
198 //END: select/unselect all
199
200 //BEGIN: category information
201 {
202 bool paintIcon;
203 QPixmap icon;
204 switch (index.column()) {
205 case KDirModel::Owner: {
206 paintIcon = true;
207 KUser user(category);
208 const QString faceIconPath = user.faceIconPath();
209 if (faceIconPath.isEmpty()) {
210 icon = KIconLoader::global()->loadIcon("user-identity", KIconLoader::NoGroup, iconSize);
211 } else {
212 icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(iconSize, Qt::SmoothTransformation));
213 }
214 }
215 break;
216 case KDirModel::Type: {
217 paintIcon = true;
218 const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
219 const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
220 KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
221 // This is the only way of getting the icon right. Others will fail on corner
222 // cases like the item representing this group has been set a different icon,
223 // so the group icon drawn is that one particularly. This way assures the drawn
224 // icon is the one of the mimetype of the group itself. (ereslibre)
225 icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(), KIconLoader::NoGroup, iconSize);
226 }
227 break;
228 default:
229 paintIcon = false;
230 }
231
232 if (paintIcon) {
233 QRect iconRect(option.rect);
234 iconRect.setTop(iconRect.top() + 4);
235 iconRect.setLeft(iconRect.left() + 7);
236 iconRect.setSize(QSize(iconSize, iconSize));
237
238 painter->drawPixmap(iconRect, icon);
239 }
240
241 //BEGIN: text
242 {
243 QRect textRect(option.rect);
244 textRect.setTop(textRect.top() + 7);
245 textRect.setLeft(textRect.left() + 7 + (paintIcon ? (iconSize + 6) : 0));
246 textRect.setHeight(qMax(fontMetrics.height(), iconSize));
247 textRect.setRight(textRect.right() - 7);
248 textRect.setBottom(textRect.bottom() - 5); // only one pixel separation here (no gradient)
249
250 painter->save();
251 painter->setFont(font);
252 QColor penColor(option.palette.text().color());
253 penColor.setAlphaF(0.6);
254 painter->setPen(penColor);
255 painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, category);
256 painter->restore();
257 }
258 //END: text
259 }
260 //BEGIN: category information
261 }
262
263 int DolphinCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &) const
264 {
265 int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
266 QFont font(QApplication::font());
267 font.setBold(true);
268 const QFontMetrics fontMetrics = QFontMetrics(font);
269 int heightWithoutIcon = fontMetrics.height() + (iconSize / 4) * 2 + 1; /* 1 pixel-width gradient */
270 bool paintIcon;
271
272 switch (index.column()) {
273 case KDirModel::Owner:
274 case KDirModel::Type:
275 paintIcon = true;
276 break;
277 default:
278 paintIcon = false;
279 }
280
281 if (paintIcon) {
282 return qMax(heightWithoutIcon + 5, iconSize + 1 /* 1 pixel-width gradient */
283 + 5 /* top and bottom separation */);
284 }
285
286 return heightWithoutIcon + 5;
287 }
288
289 void DolphinCategoryDrawer::mouseButtonPressed(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
290 {
291 if (!index.isValid()) {
292 event->ignore();
293 return;
294 }
295 const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
296 int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
297 if (this->category == category) {
298 QRect iconAllRect(blockRect);
299 iconAllRect.setTop(iconAllRect.top() + 4);
300 iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
301 iconAllRect.setSize(QSize(iconSize, iconSize));
302 if (iconAllRect.contains(pos)) {
303 event->accept();
304 hotSpotPressed = SelectAllHotSpot;
305 categoryPressed = index;
306 return;
307 }
308 QRect iconNoneRect(blockRect);
309 iconNoneRect.setTop(iconNoneRect.top() + 4);
310 iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
311 iconNoneRect.setSize(QSize(iconSize, iconSize));
312 if (iconNoneRect.contains(pos)) {
313 event->accept();
314 hotSpotPressed = UnselectAllHotSpot;
315 categoryPressed = index;
316 return;
317 }
318 }
319 event->ignore();
320 }
321
322 void DolphinCategoryDrawer::mouseButtonReleased(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
323 {
324 if (!index.isValid() || hotSpotPressed == NoneHotSpot || categoryPressed != index) {
325 event->ignore();
326 return;
327 }
328 categoryPressed = QModelIndex();
329 const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
330 int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
331 if (this->category == category) {
332 QRect iconAllRect(blockRect);
333 iconAllRect.setTop(iconAllRect.top() + 4);
334 iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
335 iconAllRect.setSize(QSize(iconSize, iconSize));
336 if (iconAllRect.contains(pos)) {
337 if (hotSpotPressed == SelectAllHotSpot) {
338 event->accept();
339 emit actionRequested(SelectAll, index);
340 } else {
341 event->ignore();
342 hotSpotPressed = NoneHotSpot;
343 }
344 return;
345 }
346 QRect iconNoneRect(blockRect);
347 iconNoneRect.setTop(iconNoneRect.top() + 4);
348 iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
349 iconNoneRect.setSize(QSize(iconSize, iconSize));
350 if (iconNoneRect.contains(pos)) {
351 if (hotSpotPressed == UnselectAllHotSpot) {
352 event->accept();
353 emit actionRequested(UnselectAll, index);
354 } else {
355 event->ignore();
356 hotSpotPressed = NoneHotSpot;
357 }
358 return;
359 }
360 }
361 event->ignore();
362 }
363
364 void DolphinCategoryDrawer::mouseMoved(const QModelIndex &index, const QRect &, QMouseEvent *event)
365 {
366 event->ignore();
367 if (!index.isValid()) {
368 return;
369 }
370 pos = event->pos();
371 category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
372 }
373
374 void DolphinCategoryDrawer::mouseLeft(const QModelIndex &, const QRect &)
375 {
376 pos = QPoint();
377 category.clear();
378 }