2
* This file is part of the KDE project
3
* Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
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.
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.
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.
21
#include "dolphincategorydrawer.h"
23
#include <config-nepomuk.h>
28
#include <QApplication>
29
#include <QStyleOption>
32
#include <Nepomuk/KRatingPainter>
35
#include <KIconLoader>
36
#include <KIconEffect>
37
#include <KCategorizedSortFilterProxyModel>
39
#include <KCategorizedView>
41
#include "dolphinview.h"
42
#include "dolphinmodel.h"
44
#define HORIZONTAL_HINT 3
46
DolphinCategoryDrawer::DolphinCategoryDrawer(KCategorizedView *view)
47
: KCategoryDrawerV3(view)
48
, hotSpotPressed(NoneHotSpot)
49
, selectAll(KIconLoader::global()->loadIcon("list-add", KIconLoader::Desktop, 16))
50
, selectAllHovered(KIconLoader::global()->iconEffect()->apply(selectAll, KIconLoader::Desktop, KIconLoader::ActiveState))
51
, selectAllDisabled(KIconLoader::global()->iconEffect()->apply(selectAll, KIconLoader::Desktop, KIconLoader::DisabledState))
52
, unselectAll(KIconLoader::global()->loadIcon("list-remove", KIconLoader::Desktop, 16))
53
, unselectAllHovered(KIconLoader::global()->iconEffect()->apply(unselectAll, KIconLoader::Desktop, KIconLoader::ActiveState))
54
, unselectAllDisabled(KIconLoader::global()->iconEffect()->apply(unselectAll, KIconLoader::Desktop, KIconLoader::DisabledState))
58
DolphinCategoryDrawer::~DolphinCategoryDrawer()
62
bool DolphinCategoryDrawer::allCategorySelected(const QString &category) const
64
const QModelIndexList list = view()->block(category);
65
foreach (const QModelIndex &index, list) {
66
if (!view()->selectionModel()->isSelected(index)) {
73
bool DolphinCategoryDrawer::someCategorySelected(const QString &category) const
75
const QModelIndexList list = view()->block(category);
76
foreach (const QModelIndex &index, list) {
77
if (view()->selectionModel()->isSelected(index)) {
84
void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
85
const QStyleOption &option, QPainter *painter) const
88
painter->setRenderHint(QPainter::Antialiasing);
90
if (!index.isValid()) {
94
const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
95
const QRect optRect = option.rect;
96
QFont font(QApplication::font());
98
const QFontMetrics fontMetrics = QFontMetrics(font);
100
QColor outlineColor = option.palette.text().color();
101
outlineColor.setAlphaF(0.35);
103
//BEGIN: top left corner
106
painter->setPen(outlineColor);
107
const QPointF topLeft(optRect.topLeft());
108
QRectF arc(topLeft, QSizeF(4, 4));
109
arc.translate(0.5, 0.5);
110
painter->drawArc(arc, 1440, 1440);
113
//END: top left corner
115
//BEGIN: left vertical line
117
QPoint start(optRect.topLeft());
119
QPoint verticalGradBottom(optRect.topLeft());
120
verticalGradBottom.ry() += fontMetrics.height() + 5;
121
QLinearGradient gradient(start, verticalGradBottom);
122
gradient.setColorAt(0, outlineColor);
123
gradient.setColorAt(1, Qt::transparent);
124
painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
126
//END: left vertical line
128
//BEGIN: horizontal line
130
QPoint start(optRect.topLeft());
132
QPoint horizontalGradTop(optRect.topLeft());
133
horizontalGradTop.rx() += optRect.width() - 6;
134
painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
136
//END: horizontal line
138
//BEGIN: top right corner
141
painter->setPen(outlineColor);
142
QPointF topRight(optRect.topRight());
144
QRectF arc(topRight, QSizeF(4, 4));
145
arc.translate(0.5, 0.5);
146
painter->drawArc(arc, 0, 1440);
149
//END: top right corner
151
//BEGIN: right vertical line
153
QPoint start(optRect.topRight());
155
QPoint verticalGradBottom(optRect.topRight());
156
verticalGradBottom.ry() += fontMetrics.height() + 5;
157
QLinearGradient gradient(start, verticalGradBottom);
158
gradient.setColorAt(0, outlineColor);
159
gradient.setColorAt(1, Qt::transparent);
160
painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
162
//END: right vertical line
164
const int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
166
//BEGIN: select/unselect all
168
if (this->category == category) {
169
QRect iconAllRect(option.rect);
170
iconAllRect.setTop(iconAllRect.top() + 4);
171
iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
172
iconAllRect.setSize(QSize(iconSize, iconSize));
173
if (!allCategorySelected(category)) {
174
if (iconAllRect.contains(pos)) {
175
painter->drawPixmap(iconAllRect, selectAllHovered);
177
painter->drawPixmap(iconAllRect, selectAll);
180
painter->drawPixmap(iconAllRect, selectAllDisabled);
182
QRect iconNoneRect(option.rect);
183
iconNoneRect.setTop(iconNoneRect.top() + 4);
184
iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
185
iconNoneRect.setSize(QSize(iconSize, iconSize));
186
if (someCategorySelected(category)) {
187
if (iconNoneRect.contains(pos)) {
188
painter->drawPixmap(iconNoneRect, unselectAllHovered);
190
painter->drawPixmap(iconNoneRect, unselectAll);
193
painter->drawPixmap(iconNoneRect, unselectAllDisabled);
197
//END: select/unselect all
199
//BEGIN: category information
203
switch (index.column()) {
204
case KDirModel::Owner: {
206
KUser user(category);
207
const QString faceIconPath = user.faceIconPath();
208
if (faceIconPath.isEmpty()) {
209
icon = KIconLoader::global()->loadIcon("user-identity", KIconLoader::NoGroup, iconSize);
211
icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(iconSize, Qt::SmoothTransformation));
215
case KDirModel::Type: {
217
const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
218
const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
219
KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
220
// This is the only way of getting the icon right. Others will fail on corner
221
// cases like the item representing this group has been set a different icon,
222
// so the group icon drawn is that one particularly. This way assures the drawn
223
// icon is the one of the mimetype of the group itself. (ereslibre)
224
icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(), KIconLoader::NoGroup, iconSize);
232
QRect iconRect(option.rect);
233
iconRect.setTop(iconRect.top() + 4);
234
iconRect.setLeft(iconRect.left() + 7);
235
iconRect.setSize(QSize(iconSize, iconSize));
237
painter->drawPixmap(iconRect, icon);
242
QRect textRect(option.rect);
243
textRect.setTop(textRect.top() + 7);
244
textRect.setLeft(textRect.left() + 7 + (paintIcon ? (iconSize + 6) : 0));
245
textRect.setHeight(qMax(fontMetrics.height(), iconSize));
246
textRect.setRight(textRect.right() - 7);
247
textRect.setBottom(textRect.bottom() - 5); // only one pixel separation here (no gradient)
250
painter->setFont(font);
251
QColor penColor(option.palette.text().color());
252
penColor.setAlphaF(0.6);
253
painter->setPen(penColor);
254
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, category);
259
//BEGIN: category information
262
int DolphinCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &) const
264
int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
265
QFont font(QApplication::font());
267
const QFontMetrics fontMetrics = QFontMetrics(font);
268
int heightWithoutIcon = fontMetrics.height() + (iconSize / 4) * 2 + 1; /* 1 pixel-width gradient */
271
switch (index.column()) {
272
case KDirModel::Owner:
273
case KDirModel::Type:
281
return qMax(heightWithoutIcon + 5, iconSize + 1 /* 1 pixel-width gradient */
282
+ 5 /* top and bottom separation */);
285
return heightWithoutIcon + 5;
288
void DolphinCategoryDrawer::mouseButtonPressed(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
290
if (!index.isValid()) {
294
const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
295
int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
296
if (this->category == category) {
297
QRect iconAllRect(blockRect);
298
iconAllRect.setTop(iconAllRect.top() + 4);
299
iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
300
iconAllRect.setSize(QSize(iconSize, iconSize));
301
if (iconAllRect.contains(pos)) {
303
hotSpotPressed = SelectAllHotSpot;
304
categoryPressed = index;
307
QRect iconNoneRect(blockRect);
308
iconNoneRect.setTop(iconNoneRect.top() + 4);
309
iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
310
iconNoneRect.setSize(QSize(iconSize, iconSize));
311
if (iconNoneRect.contains(pos)) {
313
hotSpotPressed = UnselectAllHotSpot;
314
categoryPressed = index;
321
void DolphinCategoryDrawer::mouseButtonReleased(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
323
if (!index.isValid() || hotSpotPressed == NoneHotSpot || categoryPressed != index) {
327
categoryPressed = QModelIndex();
328
const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
329
int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
330
if (this->category == category) {
331
QRect iconAllRect(blockRect);
332
iconAllRect.setTop(iconAllRect.top() + 4);
333
iconAllRect.setLeft(iconAllRect.right() - 16 - 7);
334
iconAllRect.setSize(QSize(iconSize, iconSize));
335
if (iconAllRect.contains(pos)) {
336
if (hotSpotPressed == SelectAllHotSpot) {
338
emit actionRequested(SelectAll, index);
341
hotSpotPressed = NoneHotSpot;
345
QRect iconNoneRect(blockRect);
346
iconNoneRect.setTop(iconNoneRect.top() + 4);
347
iconNoneRect.setLeft(iconNoneRect.right() - 16 * 2 - 7 * 2);
348
iconNoneRect.setSize(QSize(iconSize, iconSize));
349
if (iconNoneRect.contains(pos)) {
350
if (hotSpotPressed == UnselectAllHotSpot) {
352
emit actionRequested(UnselectAll, index);
355
hotSpotPressed = NoneHotSpot;
363
void DolphinCategoryDrawer::mouseMoved(const QModelIndex &index, const QRect &, QMouseEvent *event)
366
if (!index.isValid()) {
370
category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
373
void DolphinCategoryDrawer::mouseLeft(const QModelIndex &, const QRect &)