Falkon Develop
Cross-platform Qt-based web browser
gm_settingslistdelegate.cpp
Go to the documentation of this file.
1/* ============================================================
2* GreaseMonkey plugin for Falkon
3* Copyright (C) 2012-2017 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program 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
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
19#include "gm_script.h"
20
21#include "iconprovider.h"
22
23#include <QPainter>
24#include <QListWidget>
25#include <QApplication>
26#include <QtGuiVersion>
27
29 : QStyledItemDelegate(parent)
30 , m_rowHeight(0)
31 , m_padding(0)
32{
33 m_removePixmap = IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(16);
34 m_updateIcon = IconProvider::standardIcon(QStyle::SP_BrowserReload);
35}
36
38{
39 return m_padding;
40}
41
42void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
43{
44 GM_Script *script = static_cast<GM_Script*>(index.data(Qt::UserRole + 10).value<void*>());
45 if (!script)
46 return;
47
48 QStyleOptionViewItem opt = option;
49 initStyleOption(&opt, index);
50
51 const QWidget* w = opt.widget;
52 const QStyle* style = w ? w->style() : QApplication::style();
53 const int height = opt.rect.height();
54 const int center = height / 2 + opt.rect.top();
55
56 // forced to LTR, see issue#967
57 painter->setLayoutDirection(Qt::LeftToRight);
58
59 // Prepare title font
60 QFont titleFont = opt.font;
61 titleFont.setBold(true);
62 titleFont.setPointSize(titleFont.pointSize() + 1);
63
64 const QFontMetrics titleMetrics(titleFont);
65 const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text;
66
67 QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
68 if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
69 cg = QPalette::Inactive;
70 }
71
72#ifdef Q_OS_WIN
73 opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text));
74 opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108));
75#endif
76
77 QPalette textPalette = opt.palette;
78 textPalette.setCurrentColorGroup(cg);
79
80 int leftPosition = m_padding;
81 int rightPosition = opt.rect.right() - m_padding - 16; // 16 for remove button
82 if (!script->downloadUrl().isEmpty())
83 rightPosition -= m_padding + 16; // 16 for update button
84
85 // Draw background
86 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
87
88 // Draw checkbox
89 const int checkboxSize = 18;
90 const int checkboxYPos = center - (checkboxSize / 2);
91 QStyleOptionViewItem opt2 = opt;
92 opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off;
93 QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt2, w);
94 opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height());
95 style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt2, painter, w);
96 leftPosition = opt2.rect.right() + m_padding;
97
98 // Draw icon
99 const int iconSize = 32;
100 const int iconYPos = center - (iconSize / 2);
101 QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
102 QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize);
103 if (!pixmap.isNull()) {
104 painter->drawPixmap(iconRect, pixmap);
105 leftPosition = iconRect.right() + m_padding;
106 } else {
107 leftPosition += m_padding;
108 }
109
110 // Draw script name
111 const QString name = index.data(Qt::DisplayRole).toString();
112 const int leftTitleEdge = leftPosition + 2;
113 const int rightTitleEdge = rightPosition - m_padding;
114 const int leftPosForVersion = titleMetrics.horizontalAdvance(name) + m_padding;
115 QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height());
116 painter->setFont(titleFont);
117 style->drawItemText(painter, nameRect, Qt::AlignLeft, textPalette, true, name, colorRole);
118
119 // Draw version
120 QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height());
121 QFont versionFont = titleFont;
122 versionFont.setBold(false);
123 painter->setFont(versionFont);
124 style->drawItemText(painter, versionRect, Qt::AlignLeft, textPalette, true, script->version(), colorRole);
125
126 // Draw description
127 const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading();
128 QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height());
129 const QString info = opt.fontMetrics.elidedText(script->description(), Qt::ElideRight, infoRect.width());
130 painter->setFont(opt.font);
131 style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, info, colorRole);
132
133 // Draw update button
134 if (!script->downloadUrl().isEmpty()) {
135 const int updateIconSize = 16;
136 const int updateIconYPos = center - (updateIconSize / 2);
137 const QPixmap updatePixmap = m_updateIcon.pixmap(16, script->isUpdating() ? QIcon::Disabled : QIcon::Normal);
138 QRect updateIconRect(rightPosition, updateIconYPos, updateIconSize, updateIconSize);
139 painter->drawPixmap(updateIconRect, updatePixmap);
140 rightPosition += m_padding + 16;
141 }
142
143 // Draw remove button
144 const int removeIconSize = 16;
145 const int removeIconYPos = center - (removeIconSize / 2);
146 QRect removeIconRect(rightPosition, removeIconYPos, removeIconSize, removeIconSize);
147 painter->drawPixmap(removeIconRect, m_removePixmap);
148}
149
150QSize GM_SettingsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
151{
152 Q_UNUSED(index)
153
154 if (!m_rowHeight) {
155 QStyleOptionViewItem opt(option);
156 initStyleOption(&opt, index);
157
158 const QWidget* w = opt.widget;
159 const QStyle* style = w ? w->style() : QApplication::style();
160 const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1;
161
162 QFont titleFont = opt.font;
163 titleFont.setBold(true);
164 titleFont.setPointSize(titleFont.pointSize() + 1);
165
166 m_padding = padding > 5 ? padding : 5;
167
168 const QFontMetrics titleMetrics(titleFont);
169
170 m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height();
171 }
172
173 return QSize(200, m_rowHeight);
174}
QUrl downloadUrl() const
Definition: gm_script.cpp:92
bool isUpdating()
Definition: gm_script.cpp:152
QString version() const
Definition: gm_script.cpp:77
QString description() const
Definition: gm_script.cpp:72
GM_SettingsListDelegate(QObject *parent=nullptr)
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
static QIcon standardIcon(QStyle::StandardPixmap icon)