class ComboUpDownDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
static const int SESSION_DATA_ROLE;
static const int ICON1_ROLE;
static const int ICON2_ROLE;
static const int ICON3_ROLE;
static const char* COMBO_TYPE;
static const QString COMBO_ICON_TEXT;
static const QString COMBO_ICON_TEXT_ICONS;
static const QString COMBO_ICON_RICHTEXT_COUNTER;
public:
ComboUpDownDelegate
(QObject* parent
);
~ComboUpDownDelegate();
virtual bool eventFilter
(QObject *object,
QEvent *event
) override;
void setTitle(const QString& title);
virtual QWidget* createEditor
(QWidget* parent,
const QStyleOptionViewItem
& option,
const QModelIndex
& index
) const override
{ return nullptr;
}
protected:
void drawIconRichTextCounter
(QPainter* painter,
const CUDSession
& data,
const QPoint
& topLeft,
int row,
int width
) const;
private:
};
class ComboUpDownDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
static const int SESSION_DATA_ROLE;
static const int ICON1_ROLE;
static const int ICON2_ROLE;
static const int ICON3_ROLE;
static const char* COMBO_TYPE;
static const QString COMBO_ICON_TEXT;
static const QString COMBO_ICON_TEXT_ICONS;
static const QString COMBO_ICON_RICHTEXT_COUNTER;
public:
ComboUpDownDelegate(QObject* parent);
~ComboUpDownDelegate();
void initCombo(QComboBox* combo);
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const override;
virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
virtual bool eventFilter(QObject *object, QEvent *event) override;
void setTitle(const QString& title);
QString title() const;
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override {
return nullptr;
}
protected:
void drawIconRichTextCounter(QPainter* painter, const CUDSession& data, const QPoint& topLeft, int row, int width) const;
private:
QString m_title;
QPixmap m_icon1, m_icon2, m_icon3;
};
To copy to clipboard, switch view to plain text mode
namespace {
QPoint drawText
(QPainter* painter,
const QPoint
& point,
const QString
& text,
const QFont
& font
) { painter->setFont(font);
const int w = fm.width(text);
painter->drawText(point, text);
return QPoint(point.
x() + w, point.
y());
}
}
const int ComboUpDownDelegate::SESSION_DATA_ROLE = Qt::UserRole + 1;
const int ComboUpDownDelegate::ICON1_ROLE = Qt::UserRole + 1;
const int ComboUpDownDelegate::ICON2_ROLE = Qt::UserRole + 2;
const int ComboUpDownDelegate::ICON3_ROLE = Qt::UserRole + 3;
const char* ComboUpDownDelegate::COMBO_TYPE = "combo_type";
const QString ComboUpDownDelegate
::COMBO_ICON_TEXT = "icon_text";
const QString ComboUpDownDelegate
::COMBO_ICON_TEXT_ICONS = "icon_text_icons";
const QString ComboUpDownDelegate
::COMBO_ICON_RICHTEXT_COUNTER = "icon_richtext_counter";
ComboUpDownDelegate
::ComboUpDownDelegate(QObject* parent
) : QStyledItemDelegate(parent) {
initCombo(qobject_cast<QComboBox*>(parent));
// Icons
m_icon1
= Customisation
::getImage("time",
QSize(16,
16),
QColor("#C8C8C8"));
m_icon2
= Customisation
::getImage("warning",
QSize(16,
16),
QColor("#C8C8C8"));
m_icon3
= Customisation
::getImage("warning",
QSize(16,
16),
QColor("#FF0000"));
}
ComboUpDownDelegate::~ComboUpDownDelegate() {
}
void ComboUpDownDelegate
::initCombo(QComboBox* combo
) { if (combo != nullptr) {
combo->installEventFilter(this);
}
}
auto combo = static_cast<QComboBox*>(this->parent());
const auto text = index.data(Qt::DisplayRole).toString();
opt.text = text;
opt.rect = option.rect;
opt.icon = index.data(Qt::DecorationRole).value<QIcon>();
if (combo != nullptr) {
opt.iconSize = combo->iconSize();
}
return style
->sizeFromContents
(QStyle::CT_CheckBox,
&opt,
QSize());
//return style->sizeFromContents(QStyle::CT_PushButton, &opt, QSize());
}
QComboBox* combo
= static_cast<QComboBox
*>
(this
->parent
());
// Basic style
QStyleOptionViewItemV4 modifiedOption(option);
modifiedOption.text.clear();
modifiedOption.
icon = QIcon();
const auto topLeft = option.rect.topLeft();
const int margin = 3;
const int fontHeight
= QFontMetrics(painter
->font
()).
height();
painter
->setPen
(combo
->palette
().
color(QPalette::Text));
if (combo->property(COMBO_TYPE) == COMBO_ICON_TEXT)
{
const bool state1 = index.data(ICON1_ROLE).toBool();
QPixmap icon1
(state1 ? m_icon1
: m_icon2
);
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
const QString text
= index.
data(Qt
::DisplayRole).
toString();
painter->drawText(icon1.width() + 2 * margin, topLeft.y() + fontHeight + 3, text);
const bool state2 = index.data(ICON2_ROLE).toBool();
QPixmap icon2
(state2 ? m_icon1
: m_icon2
);
int w = option.rect.width() - icon2.width() - margin;
painter->drawPixmap(w, topLeft.y() + margin, icon2);
}
else if (combo->property(COMBO_TYPE) == COMBO_ICON_TEXT_ICONS)
{
const bool state1 = index.data(ICON1_ROLE).toBool();
QPixmap icon1
(state1 ? m_icon1
: m_icon2
);
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
const QString text
= index.
data(Qt
::DisplayRole).
toString();
painter->drawText(icon1.width() + 2 * margin, topLeft.y() + fontHeight + 3, text);
const bool state3 = index.data(ICON3_ROLE).toBool();
QPixmap icon3
(state3 ? m_icon1
: m_icon2
);
int w = option.rect.width() - icon3.width() - margin;
painter->drawPixmap(w, topLeft.y() + margin, icon3);
const bool state2 = index.data(ICON2_ROLE).toBool();
QPixmap icon2
(state2 ? m_icon1
: m_icon2
);
w -= icon2.width();
painter->drawPixmap(w, topLeft.y() + margin, icon2);
}
else if (combo->property(COMBO_TYPE) == COMBO_ICON_RICHTEXT_COUNTER)
{
const CUDSession data = index.data(SESSION_DATA_ROLE).value<CUDSession>();
drawIconRichTextCounter(painter, data, topLeft, index.row(), option.rect.width());
}
}
void ComboUpDownDelegate
::drawIconRichTextCounter(QPainter* painter,
const CUDSession
& data,
const QPoint
& topLeft,
int row,
int width
) const { const int margin = 15;
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
QFont normalFont
(painter
->font
());
QFont boldFont
(normalFont
);
boldFont.setBold(true);
QPoint p
(topLeft
+ QPoint(icon1.
width() + 1.5 * margin, fm.
height() + 11));
if (row == 0)
{
p
= drawText
(painter, p,
QString("ALL SESSIONS"), boldFont
);
}
else
{
if(strRow.length() < 2)
{
strRow = "0" + strRow;
}
p
= drawText
(painter, p,
QString("SESSION %1").
arg(strRow
), boldFont
);
painter
->setPen
(QColor("#C8C8C8"));
p
= drawText
(painter, p,
QString(" | "), normalFont
);
p
= drawText
(painter, p,
QString("START:"), boldFont
);
p
= drawText
(painter, p,
QString(" %1 - ").
arg(data.
StartStr()), normalFont
);
p
= drawText
(painter, p,
QString("END:"), boldFont
);
if(data.End().isValid())
{
p
= drawText
(painter, p,
QString(" %1").
arg(data.
EndStr()), normalFont
);
}
else
{
p
= drawText
(painter, p,
QString(" %1").
arg(tr
("Running")), normalFont
);
}
p.setX(width - fm.width("888") - margin);
painter->drawText(p, errorCounter);
QPixmap icon2
(data.
Errors() >
0 ? m_icon3
: m_icon2
);
painter->drawPixmap(p.x() - icon2.width() - 3, topLeft.y() + margin, icon2);
}
}
bool ComboUpDownDelegate
::eventFilter(QObject *object,
QEvent *event
) { auto combo = static_cast<QComboBox*>(object);
if (combo
!= nullptr
&& object
== this
->parent
() && event
->type
() == QEvent::Paint) {
painter.
setPen(combo
->palette
().
color(QPalette::Text));
opt.initFrom(combo);
opt.editable = combo->isEditable();
opt.frame = combo->hasFrame();
if (combo->hasFocus() && !opt.editable) {
opt.
state |
= QStyle::State_Selected;
}
opt.
subControls = QStyle::SC_All;
if (m_title.isEmpty()) {
opt.currentText = combo->currentText();
} else {
opt.currentText = m_title.arg(combo->count());
}
painter.
drawComplexControl(QStyle::CC_ComboBox, opt
);
painter.
drawControl(QStyle::CE_ComboBoxLabel, opt
);
if (combo->property(COMBO_TYPE) == COMBO_ICON_RICHTEXT_COUNTER) {
drawIconRichTextCounter(&painter, combo->currentData(SESSION_DATA_ROLE).value<CUDSession>(),
QPoint(0,
0), combo
->currentIndex
(), combo
->width
() - 16);
}
return true;
}
return QStyledItemDelegate::eventFilter(object, event);
}
void ComboUpDownDelegate::setTitle(const QString& title) {
m_title = title;
}
QString ComboUpDownDelegate
::title() const { return m_title;
}
namespace {
QPoint drawText(QPainter* painter, const QPoint& point, const QString& text, const QFont& font) {
painter->setFont(font);
QFontMetrics fm(font);
const int w = fm.width(text);
painter->drawText(point, text);
return QPoint(point.x() + w, point.y());
}
}
const int ComboUpDownDelegate::SESSION_DATA_ROLE = Qt::UserRole + 1;
const int ComboUpDownDelegate::ICON1_ROLE = Qt::UserRole + 1;
const int ComboUpDownDelegate::ICON2_ROLE = Qt::UserRole + 2;
const int ComboUpDownDelegate::ICON3_ROLE = Qt::UserRole + 3;
const char* ComboUpDownDelegate::COMBO_TYPE = "combo_type";
const QString ComboUpDownDelegate::COMBO_ICON_TEXT = "icon_text";
const QString ComboUpDownDelegate::COMBO_ICON_TEXT_ICONS = "icon_text_icons";
const QString ComboUpDownDelegate::COMBO_ICON_RICHTEXT_COUNTER = "icon_richtext_counter";
ComboUpDownDelegate::ComboUpDownDelegate(QObject* parent)
: QStyledItemDelegate(parent) {
initCombo(qobject_cast<QComboBox*>(parent));
// Icons
m_icon1 = Customisation::getImage("time", QSize(16, 16), QColor("#C8C8C8"));
m_icon2 = Customisation::getImage("warning", QSize(16, 16), QColor("#C8C8C8"));
m_icon3 = Customisation::getImage("warning", QSize(16, 16), QColor("#FF0000"));
}
ComboUpDownDelegate::~ComboUpDownDelegate() {
}
void ComboUpDownDelegate::initCombo(QComboBox* combo) {
if (combo != nullptr) {
combo->view()->setEditTriggers(QAbstractItemView::CurrentChanged);
combo->installEventFilter(this);
}
}
QSize ComboUpDownDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {
auto combo = static_cast<QComboBox*>(this->parent());
const auto text = index.data(Qt::DisplayRole).toString();
const auto style = QApplication::style();
QStyleOptionButton opt;
opt.text = text;
opt.rect = option.rect;
opt.icon = index.data(Qt::DecorationRole).value<QIcon>();
if (combo != nullptr) {
opt.iconSize = combo->iconSize();
}
return style->sizeFromContents(QStyle::CT_CheckBox, &opt, QSize());
//return style->sizeFromContents(QStyle::CT_PushButton, &opt, QSize());
}
void ComboUpDownDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QComboBox* combo = static_cast<QComboBox*>(this->parent());
// Basic style
QStyleOptionViewItemV4 modifiedOption(option);
modifiedOption.text.clear();
modifiedOption.icon = QIcon();
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &modifiedOption, painter);
const auto topLeft = option.rect.topLeft();
const int margin = 3;
const int fontHeight = QFontMetrics(painter->font()).height();
painter->setPen(combo->palette().color(QPalette::Text));
if (combo->property(COMBO_TYPE) == COMBO_ICON_TEXT)
{
const bool state1 = index.data(ICON1_ROLE).toBool();
QPixmap icon1(state1 ? m_icon1 : m_icon2);
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
const QString text = index.data(Qt::DisplayRole).toString();
painter->drawText(icon1.width() + 2 * margin, topLeft.y() + fontHeight + 3, text);
const bool state2 = index.data(ICON2_ROLE).toBool();
QPixmap icon2(state2 ? m_icon1 : m_icon2);
int w = option.rect.width() - icon2.width() - margin;
painter->drawPixmap(w, topLeft.y() + margin, icon2);
}
else if (combo->property(COMBO_TYPE) == COMBO_ICON_TEXT_ICONS)
{
const bool state1 = index.data(ICON1_ROLE).toBool();
QPixmap icon1(state1 ? m_icon1 : m_icon2);
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
const QString text = index.data(Qt::DisplayRole).toString();
painter->drawText(icon1.width() + 2 * margin, topLeft.y() + fontHeight + 3, text);
const bool state3 = index.data(ICON3_ROLE).toBool();
QPixmap icon3(state3 ? m_icon1 : m_icon2);
int w = option.rect.width() - icon3.width() - margin;
painter->drawPixmap(w, topLeft.y() + margin, icon3);
const bool state2 = index.data(ICON2_ROLE).toBool();
QPixmap icon2(state2 ? m_icon1 : m_icon2);
w -= icon2.width();
painter->drawPixmap(w, topLeft.y() + margin, icon2);
}
else if (combo->property(COMBO_TYPE) == COMBO_ICON_RICHTEXT_COUNTER)
{
const CUDSession data = index.data(SESSION_DATA_ROLE).value<CUDSession>();
drawIconRichTextCounter(painter, data, topLeft, index.row(), option.rect.width());
}
}
void ComboUpDownDelegate::drawIconRichTextCounter(QPainter* painter, const CUDSession& data, const QPoint& topLeft, int row, int width) const {
const int margin = 15;
QPixmap icon1(m_icon1);
painter->drawPixmap(margin, topLeft.y() + margin, icon1);
QFont normalFont(painter->font());
QFont boldFont(normalFont);
boldFont.setBold(true);
QFontMetrics fm(normalFont);
QPoint p(topLeft + QPoint(icon1.width() + 1.5 * margin, fm.height() + 11));
if (row == 0)
{
p = drawText(painter, p, QString("ALL SESSIONS"), boldFont);
}
else
{
QString strRow = QString::number(row);
if(strRow.length() < 2)
{
strRow = "0" + strRow;
}
p = drawText(painter, p, QString("SESSION %1").arg(strRow), boldFont);
painter->setPen(QColor("#C8C8C8"));
p = drawText(painter, p, QString(" | "), normalFont);
p = drawText(painter, p, QString("START:"), boldFont);
p = drawText(painter, p, QString(" %1 - ").arg(data.StartStr()), normalFont);
p = drawText(painter, p, QString("END:"), boldFont);
if(data.End().isValid())
{
p = drawText(painter, p, QString(" %1").arg(data.EndStr()), normalFont);
}
else
{
p = drawText(painter, p, QString(" %1").arg(tr("Running")), normalFont);
}
const QString errorCounter(QString::number(data.Errors()));
p.setX(width - fm.width("888") - margin);
painter->drawText(p, errorCounter);
QPixmap icon2(data.Errors() > 0 ? m_icon3 : m_icon2);
painter->drawPixmap(p.x() - icon2.width() - 3, topLeft.y() + margin, icon2);
}
}
bool ComboUpDownDelegate::eventFilter(QObject *object, QEvent *event) {
auto combo = static_cast<QComboBox*>(object);
if (combo != nullptr && object == this->parent() && event->type() == QEvent::Paint) {
QStylePainter painter(combo);
painter.setPen(combo->palette().color(QPalette::Text));
QStyleOptionComboBox opt;
opt.initFrom(combo);
opt.editable = combo->isEditable();
opt.frame = combo->hasFrame();
if (combo->hasFocus() && !opt.editable) {
opt.state |= QStyle::State_Selected;
}
opt.subControls = QStyle::SC_All;
if (m_title.isEmpty()) {
opt.currentText = combo->currentText();
} else {
opt.currentText = m_title.arg(combo->count());
}
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
if (combo->property(COMBO_TYPE) == COMBO_ICON_RICHTEXT_COUNTER) {
drawIconRichTextCounter(&painter, combo->currentData(SESSION_DATA_ROLE).value<CUDSession>(),
QPoint(0, 0), combo->currentIndex(), combo->width() - 16);
}
return true;
}
return QStyledItemDelegate::eventFilter(object, event);
}
void ComboUpDownDelegate::setTitle(const QString& title) {
m_title = title;
}
QString ComboUpDownDelegate::title() const {
return m_title;
}
To copy to clipboard, switch view to plain text mode
Bookmarks