~ubuntu-branches/debian/sid/kde-baseapps/sid

« back to all changes in this revision

Viewing changes to dolphin/src/views/dolphincategorydrawer.cpp

  • Committer: Package Import Robot
  • Author(s): Modestas Vainius, Eshat Cakar, Pino Toscano
  • Date: 2012-06-09 22:18:08 UTC
  • mfrom: (4.2.1) (6.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20120609221808-h1l0ekd5qmb8nefr
Tags: 4:4.8.4-1
* New upstream release.

[ Eshat Cakar ]
* Add watch file.
* Bump kde-sc-dev-latest build dependency to version 4:4.8.4.
* Update installed files.

[ Pino Toscano ]
* Move files of the konqueror documentation from kde-baseapps-data to
  konqueror itself.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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>
33
 
#endif
34
 
 
35
 
#include <KIconLoader>
36
 
#include <KIconEffect>
37
 
#include <KCategorizedSortFilterProxyModel>
38
 
#include <KUser>
39
 
#include <KCategorizedView>
40
 
 
41
 
#include "dolphinview.h"
42
 
#include "dolphinmodel.h"
43
 
 
44
 
#define HORIZONTAL_HINT 3
45
 
 
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))
55
 
{
56
 
}
57
 
 
58
 
DolphinCategoryDrawer::~DolphinCategoryDrawer()
59
 
{
60
 
}
61
 
 
62
 
bool DolphinCategoryDrawer::allCategorySelected(const QString &category) const
63
 
{
64
 
    const QModelIndexList list = view()->block(category);
65
 
    foreach (const QModelIndex &index, list) {
66
 
        if (!view()->selectionModel()->isSelected(index)) {
67
 
            return false;
68
 
        }
69
 
    }
70
 
    return true;
71
 
}
72
 
 
73
 
bool DolphinCategoryDrawer::someCategorySelected(const QString &category) const
74
 
{
75
 
    const QModelIndexList list = view()->block(category);
76
 
    foreach (const QModelIndex &index, list) {
77
 
        if (view()->selectionModel()->isSelected(index)) {
78
 
            return true;
79
 
        }
80
 
    }
81
 
    return false;
82
 
}
83
 
 
84
 
void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
85
 
                                         const QStyleOption &option, QPainter *painter) const
86
 
{
87
 
    Q_UNUSED(sortRole);
88
 
    painter->setRenderHint(QPainter::Antialiasing);
89
 
 
90
 
    if (!index.isValid()) {
91
 
        return;
92
 
    }
93
 
 
94
 
    const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
95
 
    const QRect optRect = option.rect;
96
 
    QFont font(QApplication::font());
97
 
    font.setBold(true);
98
 
    const QFontMetrics fontMetrics = QFontMetrics(font);
99
 
 
100
 
    QColor outlineColor = option.palette.text().color();
101
 
    outlineColor.setAlphaF(0.35);
102
 
 
103
 
    //BEGIN: top left corner
104
 
    {
105
 
        painter->save();
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);
111
 
        painter->restore();
112
 
    }
113
 
    //END: top left corner
114
 
 
115
 
    //BEGIN: left vertical line
116
 
    {
117
 
        QPoint start(optRect.topLeft());
118
 
        start.ry() += 3;
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);
125
 
    }
126
 
    //END: left vertical line
127
 
 
128
 
    //BEGIN: horizontal line
129
 
    {
130
 
        QPoint start(optRect.topLeft());
131
 
        start.rx() += 3;
132
 
        QPoint horizontalGradTop(optRect.topLeft());
133
 
        horizontalGradTop.rx() += optRect.width() - 6;
134
 
        painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
135
 
    }
136
 
    //END: horizontal line
137
 
 
138
 
    //BEGIN: top right corner
139
 
    {
140
 
        painter->save();
141
 
        painter->setPen(outlineColor);
142
 
        QPointF topRight(optRect.topRight());
143
 
        topRight.rx() -= 4;
144
 
        QRectF arc(topRight, QSizeF(4, 4));
145
 
        arc.translate(0.5, 0.5);
146
 
        painter->drawArc(arc, 0, 1440);
147
 
        painter->restore();
148
 
    }
149
 
    //END: top right corner
150
 
 
151
 
    //BEGIN: right vertical line
152
 
    {
153
 
        QPoint start(optRect.topRight());
154
 
        start.ry() += 3;
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);
161
 
    }
162
 
    //END: right vertical line
163
 
 
164
 
    const int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
165
 
 
166
 
    //BEGIN: select/unselect all
167
 
    {
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);
176
 
                } else {
177
 
                    painter->drawPixmap(iconAllRect, selectAll);
178
 
                }
179
 
            } else {
180
 
                painter->drawPixmap(iconAllRect, selectAllDisabled);
181
 
            }
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);
189
 
                } else {
190
 
                    painter->drawPixmap(iconNoneRect, unselectAll);
191
 
                }
192
 
            } else {
193
 
                painter->drawPixmap(iconNoneRect, unselectAllDisabled);
194
 
            }
195
 
        }
196
 
    }
197
 
    //END: select/unselect all
198
 
 
199
 
    //BEGIN: category information
200
 
    {
201
 
        bool paintIcon;
202
 
        QPixmap icon;
203
 
        switch (index.column()) {
204
 
             case KDirModel::Owner: {
205
 
                     paintIcon = true;
206
 
                     KUser user(category);
207
 
                     const QString faceIconPath = user.faceIconPath();
208
 
                     if (faceIconPath.isEmpty()) {
209
 
                         icon = KIconLoader::global()->loadIcon("user-identity", KIconLoader::NoGroup, iconSize);
210
 
                     } else {
211
 
                         icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(iconSize, Qt::SmoothTransformation));
212
 
                     }
213
 
                 }
214
 
                 break;
215
 
             case KDirModel::Type: {
216
 
                     paintIcon = true;
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);
225
 
                 }
226
 
                 break;
227
 
             default:
228
 
                 paintIcon = false;
229
 
             }
230
 
 
231
 
        if (paintIcon) {
232
 
            QRect iconRect(option.rect);
233
 
            iconRect.setTop(iconRect.top() + 4);
234
 
            iconRect.setLeft(iconRect.left() + 7);
235
 
            iconRect.setSize(QSize(iconSize, iconSize));
236
 
 
237
 
            painter->drawPixmap(iconRect, icon);
238
 
        }
239
 
 
240
 
        //BEGIN: text
241
 
        {
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)
248
 
 
249
 
            painter->save();
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);
255
 
            painter->restore();
256
 
        }
257
 
        //END: text
258
 
    }
259
 
    //BEGIN: category information
260
 
}
261
 
 
262
 
int DolphinCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &) const
263
 
{
264
 
    int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
265
 
    QFont font(QApplication::font());
266
 
    font.setBold(true);
267
 
    const QFontMetrics fontMetrics = QFontMetrics(font);
268
 
    int heightWithoutIcon = fontMetrics.height() + (iconSize / 4) * 2 + 1; /* 1 pixel-width gradient */
269
 
    bool paintIcon;
270
 
 
271
 
    switch (index.column()) {
272
 
    case KDirModel::Owner:
273
 
    case KDirModel::Type:
274
 
        paintIcon = true;
275
 
        break;
276
 
    default:
277
 
        paintIcon = false;
278
 
    }
279
 
 
280
 
    if (paintIcon) {
281
 
        return qMax(heightWithoutIcon + 5, iconSize + 1 /* 1 pixel-width gradient */
282
 
                    + 5 /* top and bottom separation */);
283
 
    }
284
 
 
285
 
    return heightWithoutIcon + 5;
286
 
}
287
 
 
288
 
void DolphinCategoryDrawer::mouseButtonPressed(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
289
 
{
290
 
    if (!index.isValid()) {
291
 
        event->ignore();
292
 
        return;
293
 
    }
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)) {
302
 
            event->accept();
303
 
            hotSpotPressed = SelectAllHotSpot;
304
 
            categoryPressed = index;
305
 
            return;
306
 
        }
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)) {
312
 
            event->accept();
313
 
            hotSpotPressed = UnselectAllHotSpot;
314
 
            categoryPressed = index;
315
 
            return;
316
 
        }
317
 
    }
318
 
    event->ignore();
319
 
}
320
 
 
321
 
void DolphinCategoryDrawer::mouseButtonReleased(const QModelIndex &index, const QRect &blockRect, QMouseEvent *event)
322
 
{
323
 
    if (!index.isValid() || hotSpotPressed == NoneHotSpot || categoryPressed != index) {
324
 
        event->ignore();
325
 
        return;
326
 
    }
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) {
337
 
                event->accept();
338
 
                emit actionRequested(SelectAll, index);
339
 
            } else {
340
 
                event->ignore();
341
 
                hotSpotPressed = NoneHotSpot;
342
 
            }
343
 
            return;
344
 
        }
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) {
351
 
                event->accept();
352
 
                emit actionRequested(UnselectAll, index);
353
 
            } else {
354
 
                event->ignore();
355
 
                hotSpotPressed = NoneHotSpot;
356
 
            }
357
 
            return;
358
 
        }
359
 
    }
360
 
    event->ignore();
361
 
}
362
 
 
363
 
void DolphinCategoryDrawer::mouseMoved(const QModelIndex &index, const QRect &, QMouseEvent *event)
364
 
{
365
 
    event->ignore();
366
 
    if (!index.isValid()) {
367
 
        return;
368
 
    }
369
 
    pos = event->pos();
370
 
    category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
371
 
}
372
 
 
373
 
void DolphinCategoryDrawer::mouseLeft(const QModelIndex &, const QRect &)
374
 
{
375
 
    pos = QPoint();
376
 
    category.clear();
377
 
}