From 30f97be3b15be5f73ffa6fa80b42c411b6444394 Mon Sep 17 00:00:00 2001 From: nowrep Date: Thu, 19 Apr 2012 18:07:00 +0200 Subject: [PATCH] Plugin list is now painted with QStyledItemDelegate. --- src/lib/preferences/pluginlistdelegate.cpp | 118 ++++++++++++++------- src/lib/preferences/pluginlistdelegate.h | 9 +- src/lib/preferences/pluginslist.cpp | 13 ++- src/lib/preferences/pluginslist.ui | 6 ++ src/lib/tools/focusselectlineedit.cpp | 6 +- src/lib/tools/focusselectlineedit.h | 10 +- 6 files changed, 108 insertions(+), 54 deletions(-) diff --git a/src/lib/preferences/pluginlistdelegate.cpp b/src/lib/preferences/pluginlistdelegate.cpp index 3342d2317..500552503 100644 --- a/src/lib/preferences/pluginlistdelegate.cpp +++ b/src/lib/preferences/pluginlistdelegate.cpp @@ -26,65 +26,105 @@ #include PluginListDelegate::PluginListDelegate(QListWidget* parent) - : QItemDelegate(parent) - , m_listWidget(parent) + : QStyledItemDelegate(parent) + , m_rowHeight(0) { } -void PluginListDelegate::drawDisplay(QPainter* painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const +void PluginListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); - if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) { - cg = QPalette::Inactive; - } + const QWidget* w = opt.widget; + const QStyle* style = w ? w->style() : QApplication::style(); + const int height = opt.rect.height(); + const int center = height / 2 + opt.rect.top(); - if (option.state & QStyle::State_Selected) { - painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight)); - painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); - } - else { - painter->setPen(option.palette.color(cg, QPalette::Text)); - } + // Prepare title font + QFont titleFont = opt.font; + titleFont.setBold(true); + titleFont.setPointSize(titleFont.pointSize() + 1); - QTextDocument textDocument; - textDocument.setHtml(text); + const QFontMetrics titleMetrics(titleFont); + const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; - QTextLayout textLayout(textDocument.begin()); - textLayout.setFont(option.font); + int leftPosition = m_padding; + int rightPosition = opt.rect.right() - m_padding; - const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; - QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding + // Draw background + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); - textLayout.beginLayout(); - qreal height = 0; - QTextLine line = textLayout.createLine(); + // Draw checkbox + const int checkboxSize = 18; + const int checkboxYPos = center - (checkboxSize / 2); + QStyleOptionViewItemV4 opt2 = opt; + opt2.rect = QRect(leftPosition, checkboxYPos, checkboxSize, checkboxSize); + opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off; + style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w); + leftPosition = opt2.rect.right() + m_padding; - while (line.isValid()) { - line.setLineWidth(textRect.width()); - height += 3; - line.setPosition(QPoint(0, height)); - height += line.height(); + // Draw icon + const int iconSize = 32; + const int iconYPos = center - (iconSize / 2); + QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); + QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(iconSize); + painter->drawPixmap(iconRect, pixmap); + leftPosition = iconRect.right() + m_padding; - line = textLayout.createLine(); - } + // Draw plugin name + const QString &name = index.data(Qt::DisplayRole).toString(); + const int leftTitleEdge = leftPosition + 2; + const int rightTitleEdge = rightPosition - m_padding; + const int leftPosForVersion = titleMetrics.width(name) + m_padding; + QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height()); + painter->setFont(titleFont); + style->drawItemText(painter, nameRect, Qt::AlignLeft, opt.palette, true, name, colorRole); - textLayout.endLayout(); - textLayout.draw(painter, QPointF(textRect.left(), textRect.top())); + // Draw version + const QString &version = index.data(Qt::UserRole).toString(); + QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height()); + QFont versionFont = titleFont; + versionFont.setBold(false); + painter->setFont(versionFont); + style->drawItemText(painter, versionRect, Qt::AlignLeft, opt.palette, true, version, colorRole); + + // Draw info + const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading(); + QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height()); + const QString &info = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 1).toString(), Qt::ElideRight, infoRect.width()); + painter->setFont(opt.font); + style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, info, colorRole); + + // Draw description + const int descriptionYPos = infoRect.bottom() + opt.fontMetrics.leading(); + QRect descriptionRect(infoRect.x(), descriptionYPos, infoRect.width(), opt.fontMetrics.height()); + const QString &description = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 2).toString(), Qt::ElideRight, descriptionRect.width()); + style->drawItemText(painter, descriptionRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, description, colorRole); } QSize PluginListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) - const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; - const int scrollBarSize = m_listWidget->verticalScrollBar()->isVisible() ? m_listWidget->verticalScrollBar()->width() : 0; + if (!m_rowHeight) { + QStyleOptionViewItemV4 opt(option); + initStyleOption(&opt, index); - QSize size; - size.setWidth(m_listWidget->width() - 10 - scrollBarSize); + const QWidget* w = opt.widget; + const QStyle* style = w ? w->style() : QApplication::style(); + const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; - // ( height of font * 3 = 3 lines ) + ( text margins ) + ( 2 free lines = every line is 3px ) - size.setHeight((option.fontMetrics.height() * 3) + (textMargin * 2) + (2 * 3)); + QFont titleFont = opt.font; + titleFont.setBold(true); + titleFont.setPointSize(titleFont.pointSize() + 1); - return size; + m_padding = padding > 5 ? padding : 5; + + const QFontMetrics titleMetrics(titleFont); + + m_rowHeight = 2 * m_padding + 2 * opt.fontMetrics.leading() + 2 * opt.fontMetrics.height() + titleMetrics.height(); + } + + return QSize(200, m_rowHeight); } diff --git a/src/lib/preferences/pluginlistdelegate.h b/src/lib/preferences/pluginlistdelegate.h index 4eaa70357..7d4ef7b22 100644 --- a/src/lib/preferences/pluginlistdelegate.h +++ b/src/lib/preferences/pluginlistdelegate.h @@ -18,22 +18,23 @@ #ifndef PLUGINLISTDELEGATE_H #define PLUGINLISTDELEGATE_H -#include +#include #include "qz_namespace.h" class QListWidget; -class QT_QUPZILLA_EXPORT PluginListDelegate : public QItemDelegate +class QT_QUPZILLA_EXPORT PluginListDelegate : public QStyledItemDelegate { public: PluginListDelegate(QListWidget* parent); - void drawDisplay(QPainter* painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const; + void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: - QListWidget* m_listWidget; + mutable int m_rowHeight; + mutable int m_padding; }; #endif // PLUGINLISTDELEGATE_H diff --git a/src/lib/preferences/pluginslist.cpp b/src/lib/preferences/pluginslist.cpp index a319ba895..643965b6d 100644 --- a/src/lib/preferences/pluginslist.cpp +++ b/src/lib/preferences/pluginslist.cpp @@ -24,6 +24,7 @@ #include "settings.h" #include +#include #include #include @@ -156,16 +157,20 @@ void PluginsList::refresh() PluginSpec spec = plugin.pluginSpec; QListWidgetItem* item = new QListWidgetItem(ui->list); - QString pluginInfo = QString("%1 %2 (%3)
\n%4
\n%5\n").arg(spec.name, spec.version, spec.author, spec.info, spec.description); - item->setText(pluginInfo); - - QIcon icon = QIcon(spec.icon); if (icon.isNull()) { icon = QIcon(":/icons/preferences/extension.png"); } item->setIcon(icon); + QString pluginInfo = QString("%1 %2
%3
%4").arg(spec.name, spec.version, Qt::escape(spec.author), spec.info); + item->setToolTip(pluginInfo); + + item->setText(spec.name); + item->setData(Qt::UserRole, spec.version); + item->setData(Qt::UserRole + 1, spec.info); + item->setData(Qt::UserRole + 2, spec.description); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(plugin.isLoaded() ? Qt::Checked : Qt::Unchecked); item->setData(Qt::UserRole + 10, qVariantFromValue(plugin)); diff --git a/src/lib/preferences/pluginslist.ui b/src/lib/preferences/pluginslist.ui index af8354dc5..d8674cbe1 100644 --- a/src/lib/preferences/pluginslist.ui +++ b/src/lib/preferences/pluginslist.ui @@ -14,6 +14,9 @@ + + 0 + @@ -34,6 +37,9 @@ + + 0 + diff --git a/src/lib/tools/focusselectlineedit.cpp b/src/lib/tools/focusselectlineedit.cpp index 5e26d585c..93dda6965 100644 --- a/src/lib/tools/focusselectlineedit.cpp +++ b/src/lib/tools/focusselectlineedit.cpp @@ -19,7 +19,7 @@ #include -FocusSelectLineEdit::FocusSelectLineEdit(QWidget *parent) +FocusSelectLineEdit::FocusSelectLineEdit(QWidget* parent) : QLineEdit(parent) , m_mouseFocusReason(false) { @@ -32,7 +32,7 @@ void FocusSelectLineEdit::setFocus() QLineEdit::setFocus(); } -void FocusSelectLineEdit::focusInEvent(QFocusEvent *event) +void FocusSelectLineEdit::focusInEvent(QFocusEvent* event) { m_mouseFocusReason = event->reason() == Qt::MouseFocusReason; selectAll(); @@ -40,7 +40,7 @@ void FocusSelectLineEdit::focusInEvent(QFocusEvent *event) QLineEdit::focusInEvent(event); } -void FocusSelectLineEdit::mousePressEvent(QMouseEvent *event) +void FocusSelectLineEdit::mousePressEvent(QMouseEvent* event) { if (m_mouseFocusReason) { m_mouseFocusReason = false; diff --git a/src/lib/tools/focusselectlineedit.h b/src/lib/tools/focusselectlineedit.h index 0ceb1a3a0..e01d93102 100644 --- a/src/lib/tools/focusselectlineedit.h +++ b/src/lib/tools/focusselectlineedit.h @@ -20,18 +20,20 @@ #include -class FocusSelectLineEdit : public QLineEdit +#include "qz_namespace.h" + +class QT_QUPZILLA_EXPORT FocusSelectLineEdit : public QLineEdit { Q_OBJECT public: - explicit FocusSelectLineEdit(QWidget *parent = 0); + explicit FocusSelectLineEdit(QWidget* parent = 0); public slots: void setFocus(); protected: - void focusInEvent(QFocusEvent *event); - void mousePressEvent(QMouseEvent *event); + void focusInEvent(QFocusEvent* event); + void mousePressEvent(QMouseEvent* event); bool m_mouseFocusReason;