File indexing completed on 2024-05-12 04:58:19

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-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 "pluginlistdelegate.h"
0019 
0020 #include <QPainter>
0021 #include <QListWidget>
0022 #include <QApplication>
0023 
0024 PluginListDelegate::PluginListDelegate(QListWidget* parent)
0025     : QStyledItemDelegate(parent)
0026     , m_rowHeight(0)
0027     , m_padding(0)
0028 {
0029 }
0030 
0031 void PluginListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0032 {
0033     QStyleOptionViewItem opt = option;
0034     initStyleOption(&opt, index);
0035 
0036     const QWidget* w = opt.widget;
0037     const QStyle* style = w ? w->style() : QApplication::style();
0038     const int height = opt.rect.height();
0039     const int center = height / 2 + opt.rect.top();
0040 
0041     painter->setLayoutDirection(Qt::LeftToRight);
0042 
0043     // Prepare title font
0044     QFont titleFont = opt.font;
0045     titleFont.setBold(true);
0046     titleFont.setPointSize(titleFont.pointSize() + 1);
0047 
0048     const QFontMetrics titleMetrics(titleFont);
0049     const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text;
0050 
0051     QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
0052     if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
0053         cg = QPalette::Inactive;
0054     }
0055 
0056 #ifdef Q_OS_WIN
0057     opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text));
0058     opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108));
0059 #endif
0060 
0061     QPalette textPalette = opt.palette;
0062     textPalette.setCurrentColorGroup(cg);
0063 
0064     int leftPosition = m_padding;
0065     int rightPosition = opt.rect.right() - m_padding;
0066 
0067     // Draw background
0068     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
0069 
0070     // Draw checkbox
0071     const int checkboxSize = 18;
0072     const int checkboxYPos = center - (checkboxSize / 2);
0073     QStyleOptionViewItem opt2 = opt;
0074     opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off;
0075     QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt2, w);
0076     opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height());
0077     style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt2, painter, w);
0078     leftPosition = opt2.rect.right() + m_padding;
0079 
0080     // Draw icon
0081     const int iconSize = 32;
0082     const int iconYPos = center - (iconSize / 2);
0083     QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
0084     QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize);
0085     painter->drawPixmap(iconRect, pixmap);
0086     leftPosition = iconRect.right() + m_padding;
0087 
0088     // Draw plugin name
0089     const QString name = index.data(Qt::DisplayRole).toString();
0090     const int leftTitleEdge = leftPosition + 2;
0091     const int rightTitleEdge = rightPosition - m_padding;
0092     QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height());
0093     painter->setFont(titleFont);
0094     style->drawItemText(painter, nameRect, Qt::AlignLeft, textPalette, true, name, colorRole);
0095 
0096     // Draw description
0097     const int descriptionYPos = nameRect.bottom() + opt.fontMetrics.leading();
0098     QRect descriptionRect(nameRect.x(), descriptionYPos, nameRect.width(), opt.fontMetrics.height());
0099     const QString description = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 2).toString(), Qt::ElideRight, descriptionRect.width());
0100     painter->setFont(opt.font);
0101     style->drawItemText(painter, descriptionRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, description, colorRole);
0102 }
0103 
0104 QSize PluginListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0105 {
0106     Q_UNUSED(index)
0107 
0108     if (!m_rowHeight) {
0109         QStyleOptionViewItem opt(option);
0110         initStyleOption(&opt, index);
0111 
0112         const QWidget* w = opt.widget;
0113         const QStyle* style = w ? w->style() : QApplication::style();
0114         const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1;
0115 
0116         QFont titleFont = opt.font;
0117         titleFont.setBold(true);
0118         titleFont.setPointSize(titleFont.pointSize() + 1);
0119 
0120         m_padding = padding > 5 ? padding : 5;
0121 
0122         const QFontMetrics titleMetrics(titleFont);
0123 
0124         m_rowHeight = 2 * m_padding + 2 * opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height();
0125     }
0126 
0127     return QSize(200, m_rowHeight);
0128 }