]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphincategorydrawer.cpp
move statusbar code into the directory "statusbar"
[dolphin.git] / src / dolphincategorydrawer.cpp
index 4bb408babffaf54add1d0b7999f91a3cc6a3401f..7e6ed16edd769bc1784555d88d17d980adb34b56 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
   * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@gmail.com>
+  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Library General Public
 
 #include "dolphincategorydrawer.h"
 
+#include <config-nepomuk.h>
+
 #include <QPainter>
 #include <QFile>
 #include <QDir>
+#include <QApplication>
+#include <QStyleOption>
+
+#ifdef HAVE_NEPOMUK
+#include <nepomuk/kratingpainter.h>
+#endif
 
 #include <kiconloader.h>
 #include <kcategorizedsortfilterproxymodel.h>
-#include <kpixmapeffect.h>
+#include <qimageblitz.h>
 #include <kuser.h>
 
-#include <config-nepomuk.h>
-#ifdef HAVE_NEPOMUK
-#include <nepomuk/global.h>
-#include <nepomuk/resource.h>
-#include <nepomuk/tag.h>
-#endif
-
 #include "dolphinview.h"
 #include "dolphinmodel.h"
 
+#define HORIZONTAL_HINT 3
+
 DolphinCategoryDrawer::DolphinCategoryDrawer()
+        : KCategoryDrawer()
 {
 }
 
@@ -50,285 +54,163 @@ DolphinCategoryDrawer::~DolphinCategoryDrawer()
 void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
                                          const QStyleOption &option, QPainter *painter) const
 {
-    QRect starRect = option.rect;
-
-    int iconSize = KIconLoader::global()->currentSize(K3Icon::Small);
-    QVariant categoryVariant = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryRole);
-
-    if (!categoryVariant.isValid())
-    {
-        return;
-    }
+    Q_UNUSED(sortRole);
+    painter->setRenderHint(QPainter::Antialiasing);
 
-    const QString category = categoryVariant.toString();
+    const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
+    const QRect optRect = option.rect;
+    QFont font(QApplication::font());
+    font.setBold(true);
+    const QFontMetrics fontMetrics = QFontMetrics(font);
 
-    QColor color;
+    QColor outlineColor = option.palette.text().color();
+    outlineColor.setAlphaF(0.35);
 
-    if (option.state & QStyle::State_Selected)
-    {
-        color = option.palette.color(QPalette::HighlightedText);
-    }
-    else
+    //BEGIN: top left corner
     {
-        color = option.palette.color(QPalette::Text);
+        painter->save();
+        painter->setPen(outlineColor);
+        const QPointF topLeft(optRect.topLeft());
+        QRectF arc(topLeft, QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter->drawArc(arc, 1440, 1440);
+        painter->restore();
     }
+    //END: top left corner
 
-    painter->save();
-    painter->setRenderHint(QPainter::Antialiasing);
-
-    QStyleOptionButton opt;
-
-    opt.rect = option.rect;
-    opt.palette = option.palette;
-    opt.direction = option.direction;
-    opt.text = category;
-
-    if (option.state & QStyle::State_Selected)
+    //BEGIN: left vertical line
     {
-        QColor selected = option.palette.color(QPalette::Highlight);
-
-        QLinearGradient gradient(option.rect.topLeft(),
-                                 option.rect.bottomRight());
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                                : 1, selected);
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                                : 0, Qt::transparent);
-
-        painter->fillRect(option.rect, gradient);
+        QPoint start(optRect.topLeft());
+        start.ry() += 3;
+        QPoint verticalGradBottom(optRect.topLeft());
+        verticalGradBottom.ry() += fontMetrics.height() + 5;
+        QLinearGradient gradient(start, verticalGradBottom);
+        gradient.setColorAt(0, outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
     }
-    else if (option.state & QStyle::State_MouseOver)
-    {
-        QColor hover = option.palette.color(QPalette::Highlight).light();
-        hover.setAlpha(88);
+    //END: left vertical line
 
-        QLinearGradient gradient(option.rect.topLeft(),
-                                 option.rect.bottomRight());
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                                : 1, hover);
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                                : 0, Qt::transparent);
-
-        painter->fillRect(option.rect, gradient);
+    //BEGIN: horizontal line
+    {
+        QPoint start(optRect.topLeft());
+        start.rx() += 3;
+        QPoint horizontalGradTop(optRect.topLeft());
+        horizontalGradTop.rx() += optRect.width() - 6;
+        painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
     }
+    //END: horizontal line
 
-    QFont painterFont = painter->font();
-    painterFont.setWeight(QFont::Bold);
-    QFontMetrics metrics(painterFont);
-    painter->setFont(painterFont);
-
-    QPainterPath path;
-    path.addRect(option.rect.left(),
-                 option.rect.bottom() - 2,
-                 option.rect.width(),
-                 2);
-
-    QLinearGradient gradient(option.rect.topLeft(),
-                             option.rect.bottomRight());
-    gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                            : 1, color);
-    gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                            : 0, Qt::transparent);
-
-    painter->setBrush(gradient);
-    painter->fillPath(path, gradient);
-
-    if (option.direction == Qt::LeftToRight)
+    //BEGIN: top right corner
     {
-        opt.rect.setLeft(opt.rect.left() + (iconSize / 4));
-        starRect.setLeft(starRect.left() + (iconSize / 4));
-        starRect.setRight(starRect.right() + (iconSize / 4));
+        painter->save();
+        painter->setPen(outlineColor);
+        QPointF topRight(optRect.topRight());
+        topRight.rx() -= 4;
+        QRectF arc(topRight, QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter->drawArc(arc, 0, 1440);
+        painter->restore();
     }
-    else
+    //END: top right corner
+
+    //BEGIN: right vertical line
     {
-        opt.rect.setRight(opt.rect.width() - (iconSize / 4));
-        starRect.setLeft(starRect.width() - iconSize);
-        starRect.setRight(starRect.width() - (iconSize / 4));
+        QPoint start(optRect.topRight());
+        start.ry() += 3;
+        QPoint verticalGradBottom(optRect.topRight());
+        verticalGradBottom.ry() += fontMetrics.height() + 5;
+        QLinearGradient gradient(start, verticalGradBottom);
+        gradient.setColorAt(0, outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
     }
+    //END: right vertical line
 
-    bool paintIcon = true;
-    bool paintText = true;
-
-    QPixmap icon;
-    switch (index.column()) {
-        case KDirModel::Name:
-            paintIcon = false;
-            break;
-
-        case KDirModel::Size:
-            paintIcon = false;
-            break;
-
-        case KDirModel::ModifiedTime:
-            paintIcon = false;
-            break;
-
-        case KDirModel::Permissions:
-            paintIcon = false; // TODO: let's think about how to represent permissions
-            break;
-
-        case KDirModel::Owner: {
-            opt.rect.setTop(option.rect.bottom() - (iconSize / 4));
-            KUser user(category);
-            QString faceIconPath = user.faceIconPath();
-
-            if (!faceIconPath.isEmpty())
-            {
-                icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(KIconLoader::global()->currentSize(K3Icon::MainToolbar), Qt::SmoothTransformation));
-            }
-            else
-            {
-                icon = KIconLoader::global()->loadIcon("user", K3Icon::MainToolbar, option.fontMetrics.height());
-            }
-
-            opt.rect.setTop(opt.rect.top() - icon.height());
-
-            break;
-        }
-
-        case KDirModel::Group:
-            paintIcon = false;
-            break;
-
-        case KDirModel::Type: {
-            opt.rect.setTop(option.rect.bottom() - (iconSize / 4));
-            const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
-            const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
-            KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
-            // This is the only way of getting the icon right. Others will fail on corner
-            // cases like the item representing this group has been set a different icon,
-            // so the group icon drawn is that one particularly. This way assures the drawn
-            // icon is the one of the mimetype of the group itself. (ereslibre)
-            icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(),
-                                                           K3Icon::MainToolbar);
-
-            opt.rect.setTop(opt.rect.top() - icon.height());
-
-            break;
-        }
-
-#ifdef HAVE_NEPOMUK
-        case DolphinModel::Rating: {
-            paintText = false;
-            paintIcon = false;
-
-            starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
-            starRect.setSize(QSize(iconSize, iconSize));
-
-            QPixmap pixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
-            QPixmap smallPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::NoGroup, iconSize / 2);
-            QPixmap disabledPixmap = KIconLoader::global()->loadIcon("rating", K3Icon::Small);
-
-            KPixmapEffect::toGray(disabledPixmap, false);
-
-            int rating = category.toInt();
-
-            for (int i = 0; i < rating - (rating % 2); i += 2) {
-                painter->drawPixmap(starRect, pixmap);
-
-                if (option.direction == Qt::LeftToRight)
-                {
-                    starRect.setLeft(starRect.left() + iconSize + (iconSize / 4) /* separator between stars */);
-                    starRect.setRight(starRect.right() + iconSize + (iconSize / 4) /* separator between stars */);
-                }
-                else
-                {
-                    starRect.setLeft(starRect.left() - iconSize - (iconSize / 4) /* separator between stars */);
-                    starRect.setRight(starRect.right() - iconSize - (iconSize / 4) /* separator between stars */);
-                }
-            }
-
-            if (rating && rating % 2) {
-                if (option.direction == Qt::RightToLeft)
-                {
-                    starRect.setLeft(starRect.left() + (iconSize / 2) /* separator between stars */);
-                }
-
-                starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 4));
-                starRect.setSize(QSize(iconSize / 2, iconSize / 2));
-                painter->drawPixmap(starRect, smallPixmap);
-                starRect.setTop(opt.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
-
-                if (option.direction == Qt::LeftToRight)
-                {
-                    starRect.setLeft(starRect.left() + (iconSize / 2) + (iconSize / 4));
-                    starRect.setRight(starRect.right() + (iconSize / 2) + (iconSize / 4));
-                }
-                else
-                {
-                    starRect.setLeft(starRect.left() - (iconSize / 2) - (iconSize / 4));
-                    starRect.setRight(starRect.right() - (iconSize / 2) - (iconSize / 4));
-                }
-
-                if (option.direction == Qt::RightToLeft)
-                {
-                    starRect.setLeft(starRect.left() - (iconSize / 2));
-                    starRect.setRight(starRect.right() - (iconSize / 2));
-                }
-
-                starRect.setSize(QSize(iconSize, iconSize));
-            }
-
-            for (int i = rating; i < 9; i += 2) {
-                painter->drawPixmap(starRect, disabledPixmap);
-
-                if (option.direction == Qt::LeftToRight)
-                {
-                    starRect.setLeft(starRect.left() + iconSize + (iconSize / 4));
-                    starRect.setRight(starRect.right() + iconSize + (iconSize / 4));
-                }
-                else
-                {
-                    starRect.setLeft(starRect.left() - iconSize - (iconSize / 4));
-                    starRect.setRight(starRect.right() - iconSize - (iconSize / 4));
-                }
-            }
-
-            break;
+    //BEGIN: category information
+    {
+        const int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
+
+        bool paintIcon;
+        QPixmap icon;
+        switch (index.column()) {
+             case KDirModel::Owner: {
+                     paintIcon = true;
+                     KUser user(category);
+                     const QString faceIconPath = user.faceIconPath();
+                     if (faceIconPath.isEmpty()) {
+                         icon = KIconLoader::global()->loadIcon("user-identity", KIconLoader::NoGroup, iconSize);
+                     } else {
+                         icon = QPixmap::fromImage(QImage(faceIconPath).scaledToHeight(iconSize, Qt::SmoothTransformation));
+                     }
+                 }
+                 break;
+             case KDirModel::Type: {
+                     paintIcon = true;
+                     const KCategorizedSortFilterProxyModel *proxyModel = static_cast<const KCategorizedSortFilterProxyModel*>(index.model());
+                     const DolphinModel *model = static_cast<const DolphinModel*>(proxyModel->sourceModel());
+                     KFileItem item = model->itemForIndex(proxyModel->mapToSource(index));
+                     // This is the only way of getting the icon right. Others will fail on corner
+                     // cases like the item representing this group has been set a different icon,
+                     // so the group icon drawn is that one particularly. This way assures the drawn
+                     // icon is the one of the mimetype of the group itself. (ereslibre)
+                     icon = KIconLoader::global()->loadMimeTypeIcon(item.mimeTypePtr()->iconName(), KIconLoader::NoGroup, iconSize);
+                 }
+                 break;
+             default:
+                 paintIcon = false;
+             }
+
+        if (paintIcon) {
+            QRect iconRect(option.rect);
+            iconRect.setTop(iconRect.top() + 4);
+            iconRect.setLeft(iconRect.left() + 7);
+            iconRect.setSize(QSize(iconSize, iconSize));
+
+            painter->drawPixmap(iconRect, icon);
         }
 
-        case DolphinModel::Tags:
-            paintIcon = false;
-            break;
-#endif
-    }
-
-    if (paintIcon) {
-        painter->drawPixmap(QRect(option.direction == Qt::LeftToRight ? opt.rect.left()
-                                                                      : opt.rect.right() - icon.width() + (iconSize / 4), opt.rect.top(), icon.width(), icon.height()), icon);
-
-        if (option.direction == Qt::LeftToRight)
-        {
-            opt.rect.setLeft(opt.rect.left() + icon.width() + (iconSize / 4));
-        }
-        else
+        //BEGIN: text
         {
-            opt.rect.setRight(opt.rect.right() + (iconSize / 4));
+            QRect textRect(option.rect);
+            textRect.setTop(textRect.top() + 7);
+            textRect.setLeft(textRect.left() + 7 + (paintIcon ? (iconSize + 6) : 0));
+            textRect.setHeight(qMax(fontMetrics.height(), iconSize));
+            textRect.setRight(textRect.right() - 7);
+            textRect.setBottom(textRect.bottom() - 5); // only one pixel separation here (no gradient)
+
+            painter->save();
+            painter->setFont(font);
+            QColor penColor(option.palette.text().color());
+            penColor.setAlphaF(0.6);
+            painter->setPen(penColor);
+            painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, category);
+            painter->restore();
         }
+        //END: text
     }
+    //BEGIN: category information
+}
 
-    if (paintText) {
-        opt.rect.setTop(option.rect.top() + (iconSize / 4));
-        opt.rect.setBottom(opt.rect.bottom() - 2);
-        painter->setPen(color);
-
-        QRect textRect = opt.rect;
-
-        if (option.direction == Qt::RightToLeft)
-        {
-            textRect.setWidth(textRect.width() - (paintIcon ? icon.width() + (iconSize / 2)
-                                                            : -(iconSize / 4)));
-        }
+int DolphinCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const
+{
+    int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
+    int heightWithoutIcon = option.fontMetrics.height() + (iconSize / 4) * 2 + 1; /* 1 pixel-width gradient */
+    bool paintIcon;
 
-        painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
-        metrics.elidedText(category, Qt::ElideRight, textRect.width()));
+    switch (index.column()) {
+    case KDirModel::Owner:
+    case KDirModel::Type:
+        paintIcon = true;
+        break;
+    default:
+        paintIcon = false;
     }
 
-    painter->restore();
-}
-
-int DolphinCategoryDrawer::categoryHeight(const QStyleOption &option) const
-{
-    int iconSize = KIconLoader::global()->currentSize(K3Icon::Small);
+    if (paintIcon) {
+        return qMax(heightWithoutIcon + 5, iconSize + 1 /* 1 pixel-width gradient */
+                    + 5 /* top and bottom separation */);
+    }
 
-    return qMax(option.fontMetrics.height() + (iconSize / 4) * 2 + 2, iconSize + (iconSize / 4) * 2 + 2) /* 2 gradient */;
+    return heightWithoutIcon + 5;
 }