File indexing completed on 2024-05-12 05:56:49

0001 /*
0002   SPDX-FileCopyrightText: 2008 Eike Hein <hein@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "skinlistdelegate.h"
0008 #include "appearancesettings.h"
0009 
0010 #include <KLocalizedString>
0011 
0012 #include <QApplication>
0013 #include <QModelIndex>
0014 #include <QPainter>
0015 
0016 #define MARGIN 3
0017 #define ICON 32
0018 #define KNS_ICON_SIZE (ICON / 2)
0019 
0020 SkinListDelegate::SkinListDelegate(QObject *parent)
0021     : QAbstractItemDelegate(parent)
0022 {
0023 }
0024 
0025 SkinListDelegate::~SkinListDelegate()
0026 {
0027 }
0028 
0029 void SkinListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0030 {
0031     painter->save();
0032 
0033     paintBackground(painter, option);
0034 
0035     paintIcon(painter, option, index);
0036 
0037     paintText(painter, option, index);
0038 
0039     painter->restore();
0040 }
0041 
0042 void SkinListDelegate::paintBackground(QPainter *painter, const QStyleOptionViewItem &option) const
0043 {
0044     QStyleOptionViewItem opt = option;
0045     QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0046     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
0047 }
0048 
0049 void SkinListDelegate::paintIcon(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0050 {
0051     QVariant value;
0052 
0053     value = index.data(AppearanceSettings::SkinIcon);
0054 
0055     if (value.isValid() && value.type() == QVariant::Icon) {
0056         int x = option.rect.x() + MARGIN;
0057         int y = option.rect.y() + (option.rect.height() / 2) - (ICON / 2);
0058 
0059         if (option.direction == Qt::RightToLeft)
0060             x = option.rect.right() - ICON - MARGIN;
0061 
0062         qvariant_cast<QIcon>(value).paint(painter, x, y, ICON, ICON);
0063     }
0064 }
0065 
0066 void SkinListDelegate::paintText(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0067 {
0068     QFont font = option.font;
0069     int initialY = option.rect.y();
0070     int x = option.rect.x() + ICON + (3 * MARGIN);
0071     int y = initialY;
0072     int width = option.rect.width() - ICON - (3 * MARGIN);
0073 
0074     if (option.state & QStyle::State_Selected)
0075         painter->setPen(option.palette.color(QPalette::HighlightedText));
0076 
0077     QVariant value;
0078 
0079     value = index.data(AppearanceSettings::SkinName);
0080 
0081     if (value.isValid()) {
0082         font.setBold(true);
0083         painter->setFont(font);
0084         QFontMetrics fontMetrics(font);
0085 
0086         QRect textRect = fontMetrics.boundingRect(value.toString());
0087         int textWidth = textRect.width();
0088 
0089         if (option.direction == Qt::RightToLeft) {
0090             if (width < textWidth)
0091                 x = option.rect.x() + MARGIN;
0092             else
0093                 x = option.rect.right() - ICON - (3 * MARGIN) - textWidth;
0094         }
0095 
0096         y += textRect.height();
0097 
0098         painter->drawText(x, y, fontMetrics.elidedText(value.toString(), option.textElideMode, width));
0099 
0100         value = index.data(AppearanceSettings::SkinInstalledWithKns);
0101 
0102         if (value.isValid() && value.toBool()) {
0103             QIcon ghnsIcon(QStringLiteral("get-hot-new-stuff"));
0104             int knsIconX = x;
0105             int iconSize = qMin(textRect.height(), KNS_ICON_SIZE);
0106 
0107             if (option.direction == Qt::RightToLeft)
0108                 // In RTL mode we have to correct our position
0109                 // so there's room for the icon and enough space
0110                 // between the text and the icon.
0111                 knsIconX -= (iconSize + MARGIN);
0112             else
0113                 // Otherwise we just have to make sure that we
0114                 // start painting after the text and add some margin.
0115                 knsIconX += textWidth + MARGIN;
0116 
0117             ghnsIcon.paint(painter, knsIconX, initialY + MARGIN, iconSize, iconSize);
0118         }
0119     }
0120 
0121     value = index.data(AppearanceSettings::SkinAuthor);
0122 
0123     if (value.isValid()) {
0124         QString skinAuthor = xi18nc("@item:intext", "by %1", value.toString());
0125 
0126         font.setBold(false);
0127         painter->setFont(font);
0128         QFontMetrics fontMetrics(font);
0129 
0130         QRect textRect = fontMetrics.boundingRect(skinAuthor);
0131 
0132         if (option.direction == Qt::RightToLeft) {
0133             if (width < textRect.width())
0134                 x = option.rect.x() + MARGIN;
0135             else
0136                 x = option.rect.right() - ICON - (3 * MARGIN) - textRect.width();
0137         }
0138 
0139         y += textRect.height();
0140 
0141         painter->drawText(x, y, fontMetrics.elidedText(skinAuthor, option.textElideMode, width));
0142     }
0143 }
0144 
0145 QSize SkinListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0146 {
0147     QFont font = option.font;
0148     QRect name, author;
0149     int width, height;
0150 
0151     QVariant value;
0152 
0153     value = index.data(AppearanceSettings::SkinName);
0154 
0155     if (value.isValid()) {
0156         font.setBold(true);
0157         QFontMetrics fontMetrics(font);
0158         name = fontMetrics.boundingRect(value.toString());
0159     }
0160 
0161     value = index.data(Qt::UserRole + 1);
0162 
0163     if (value.isValid()) {
0164         QString skinAuthor = xi18nc("@item:intext", "by %1", value.toString());
0165 
0166         font.setBold(false);
0167         QFontMetrics fontMetrics(font);
0168         author = fontMetrics.boundingRect(skinAuthor);
0169     }
0170 
0171     width = qMax(name.width(), author.width());
0172     QRect textRect(0, 0, width, name.height() + author.height());
0173 
0174     width = ICON + (3 * MARGIN) + textRect.width() + MARGIN;
0175     height = qMax(ICON + (2 * MARGIN), textRect.height() + (2 * MARGIN));
0176 
0177     return QSize(width, height);
0178 }