File indexing completed on 2025-01-05 04:35:04
0001 /* ============================================================ 0002 * GreaseMonkey plugin for Falkon 0003 * Copyright (C) 2012-2017 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "gm_settingslistdelegate.h" 0019 #include "gm_script.h" 0020 0021 #include "iconprovider.h" 0022 0023 #include <QPainter> 0024 #include <QListWidget> 0025 #include <QApplication> 0026 #include <QtGuiVersion> 0027 0028 GM_SettingsListDelegate::GM_SettingsListDelegate(QObject* parent) 0029 : QStyledItemDelegate(parent) 0030 , m_rowHeight(0) 0031 , m_padding(0) 0032 { 0033 m_removePixmap = IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(16); 0034 m_updateIcon = IconProvider::standardIcon(QStyle::SP_BrowserReload); 0035 } 0036 0037 int GM_SettingsListDelegate::padding() const 0038 { 0039 return m_padding; 0040 } 0041 0042 void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 0043 { 0044 GM_Script *script = static_cast<GM_Script*>(index.data(Qt::UserRole + 10).value<void*>()); 0045 if (!script) 0046 return; 0047 0048 QStyleOptionViewItem opt = option; 0049 initStyleOption(&opt, index); 0050 0051 const QWidget* w = opt.widget; 0052 const QStyle* style = w ? w->style() : QApplication::style(); 0053 const int height = opt.rect.height(); 0054 const int center = height / 2 + opt.rect.top(); 0055 0056 // forced to LTR, see issue#967 0057 painter->setLayoutDirection(Qt::LeftToRight); 0058 0059 // Prepare title font 0060 QFont titleFont = opt.font; 0061 titleFont.setBold(true); 0062 titleFont.setPointSize(titleFont.pointSize() + 1); 0063 0064 const QFontMetrics titleMetrics(titleFont); 0065 const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; 0066 0067 QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; 0068 if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { 0069 cg = QPalette::Inactive; 0070 } 0071 0072 #ifdef Q_OS_WIN 0073 opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); 0074 opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); 0075 #endif 0076 0077 QPalette textPalette = opt.palette; 0078 textPalette.setCurrentColorGroup(cg); 0079 0080 int leftPosition = m_padding; 0081 int rightPosition = opt.rect.right() - m_padding - 16; // 16 for remove button 0082 if (!script->downloadUrl().isEmpty()) 0083 rightPosition -= m_padding + 16; // 16 for update button 0084 0085 // Draw background 0086 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); 0087 0088 // Draw checkbox 0089 const int checkboxSize = 18; 0090 const int checkboxYPos = center - (checkboxSize / 2); 0091 QStyleOptionViewItem opt2 = opt; 0092 opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off; 0093 QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt2, w); 0094 opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height()); 0095 style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt2, painter, w); 0096 leftPosition = opt2.rect.right() + m_padding; 0097 0098 // Draw icon 0099 const int iconSize = 32; 0100 const int iconYPos = center - (iconSize / 2); 0101 QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); 0102 QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize); 0103 if (!pixmap.isNull()) { 0104 painter->drawPixmap(iconRect, pixmap); 0105 leftPosition = iconRect.right() + m_padding; 0106 } else { 0107 leftPosition += m_padding; 0108 } 0109 0110 // Draw script name 0111 const QString name = index.data(Qt::DisplayRole).toString(); 0112 const int leftTitleEdge = leftPosition + 2; 0113 const int rightTitleEdge = rightPosition - m_padding; 0114 const int leftPosForVersion = titleMetrics.horizontalAdvance(name) + m_padding; 0115 QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height()); 0116 painter->setFont(titleFont); 0117 style->drawItemText(painter, nameRect, Qt::AlignLeft, textPalette, true, name, colorRole); 0118 0119 // Draw version 0120 QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height()); 0121 QFont versionFont = titleFont; 0122 versionFont.setBold(false); 0123 painter->setFont(versionFont); 0124 style->drawItemText(painter, versionRect, Qt::AlignLeft, textPalette, true, script->version(), colorRole); 0125 0126 // Draw description 0127 const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading(); 0128 QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height()); 0129 const QString info = opt.fontMetrics.elidedText(script->description(), Qt::ElideRight, infoRect.width()); 0130 painter->setFont(opt.font); 0131 style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, info, colorRole); 0132 0133 // Draw update button 0134 if (!script->downloadUrl().isEmpty()) { 0135 const int updateIconSize = 16; 0136 const int updateIconYPos = center - (updateIconSize / 2); 0137 const QPixmap updatePixmap = m_updateIcon.pixmap(16, script->isUpdating() ? QIcon::Disabled : QIcon::Normal); 0138 QRect updateIconRect(rightPosition, updateIconYPos, updateIconSize, updateIconSize); 0139 painter->drawPixmap(updateIconRect, updatePixmap); 0140 rightPosition += m_padding + 16; 0141 } 0142 0143 // Draw remove button 0144 const int removeIconSize = 16; 0145 const int removeIconYPos = center - (removeIconSize / 2); 0146 QRect removeIconRect(rightPosition, removeIconYPos, removeIconSize, removeIconSize); 0147 painter->drawPixmap(removeIconRect, m_removePixmap); 0148 } 0149 0150 QSize GM_SettingsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 0151 { 0152 Q_UNUSED(index) 0153 0154 if (!m_rowHeight) { 0155 QStyleOptionViewItem opt(option); 0156 initStyleOption(&opt, index); 0157 0158 const QWidget* w = opt.widget; 0159 const QStyle* style = w ? w->style() : QApplication::style(); 0160 const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1; 0161 0162 QFont titleFont = opt.font; 0163 titleFont.setBold(true); 0164 titleFont.setPointSize(titleFont.pointSize() + 1); 0165 0166 m_padding = padding > 5 ? padding : 5; 0167 0168 const QFontMetrics titleMetrics(titleFont); 0169 0170 m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height(); 0171 } 0172 0173 return QSize(200, m_rowHeight); 0174 }