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 }