After making some other task I decided to reimplement item delegate. I modified StarDelegate example and finally got this:
qtlenrosteritemdelegate.hpp
#ifndef QTLENROSTERITEMDELEGATE_HPP
#define QTLENROSTERITEMDELEGATE_HPP
#include <QtGui>
#include "qtlenrosteritem.hpp"
class QTlenRosterItemDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
QTlenRosterItemDelegate
(QWidget *parent
= 0) : QStyledItemDelegate
(parent
) {}
};
#endif // QTLENROSTERITEMDELEGATE_HPP
#ifndef QTLENROSTERITEMDELEGATE_HPP
#define QTLENROSTERITEMDELEGATE_HPP
#include <QtGui>
#include "qtlenrosteritem.hpp"
class QTlenRosterItemDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
QTlenRosterItemDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
#endif // QTLENROSTERITEMDELEGATE_HPP
To copy to clipboard, switch view to plain text mode
qtlenrosteritemdelegate.cpp
{
if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
bool checked = false;
if (option.
state & QStyle::State_Selected) {
painter->fillRect(option.rect, option.palette.highlight());
checked = true;
}
rosterItem.setHeight(rosterItem.paint(painter, option.rect, option.palette, checked));
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
{
if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
return rosterItem.sizeHint(option);
} else {
return QStyledItemDelegate::sizeHint(option, index);
}
}
void QTlenRosterItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
bool checked = false;
if (option.state & QStyle::State_Selected)
{
painter->fillRect(option.rect, option.palette.highlight());
checked = true;
}
rosterItem.setHeight(rosterItem.paint(painter, option.rect, option.palette, checked));
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
QSize QTlenRosterItemDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
return rosterItem.sizeHint(option);
} else {
return QStyledItemDelegate::sizeHint(option, index);
}
}
To copy to clipboard, switch view to plain text mode
qtlenrosteritem.hpp
#ifndef QTLENROSTERITEM_HPP
#define QTLENROSTERITEM_HPP
#include "defines.h"
#include <QtGui>
class QTlenRosterItem
{
public:
const QPalette &palette,
bool checked
) const;
int height;
void setHeight(int);
private:
};
Q_DECLARE_METATYPE(QTlenRosterItem)
#endif // QTLENROSTERITEM_HPP
#ifndef QTLENROSTERITEM_HPP
#define QTLENROSTERITEM_HPP
#include "defines.h"
#include <QtGui>
class QTlenRosterItem
{
public:
QTlenRosterItem(QString name = "", QTlenPresence type = Offline, QString desc="", QString jid="", QPixmap pxAvatar=QPixmap());
int paint(QPainter *painter, const QRect &rect,
const QPalette &palette, bool checked) const;
QSize sizeHint(const QStyleOptionViewItem &option) const;
int height;
void setHeight(int);
private:
QString name;
QPixmap presence;
QString desc;
QString jid;
QPixmap avatar;
};
Q_DECLARE_METATYPE(QTlenRosterItem)
#endif // QTLENROSTERITEM_HPP
To copy to clipboard, switch view to plain text mode
qtlenrosteritem.cpp
#include "qtlenrosteritem.hpp"
{
this->name = name;
this->desc = desc;
this->jid = jid;
this->avatar = pxAvatar;
height = 68;
switch (type)
{
case Online:
presence
=QPixmap(QString::fromUtf8(":/icons/icons/16x16/online.png"));
break;
case Chatty:
presence
=QPixmap(QString::fromUtf8(":/icons/icons/16x16/chatty.png"));
break;
case Away:
break;
case XA:
break;
case DND:
break;
case Offline:
presence
=QPixmap(QString::fromUtf8(":/icons/icons/16x16/offline.png"));
break;
}
}
int QTlenRosterItem
::paint(QPainter *painter,
const QRect &rect,
const QPalette &palette,
bool checked
) const {
painter->save();
painter
->setRenderHint
(QPainter::Antialiasing,
true);
if (checked) painter->setBrush(palette.highlightedText());
else
painter->setBrush(palette.foreground());
//name
nameRect.setLeft(rect.left()+20);
nameRect.setRight(rect.right()-68);
nameRect.setTop(rect.top()+2);
nameRect.setBottom(rect.bottom()-2);
nameFont.setBold(true);
painter->setFont(nameFont);
painter->drawText(nameRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), name, nameBR);
//jid
jidRect.setLeft(rect.left()+20);
jidRect.setRight(rect.right()-68);
jidRect.setTop(nameBR->bottom()+2);
jidRect.setBottom(nameBR->bottom()+18);
nameFont.setBold(false);
painter->setFont(nameFont);
painter->drawText(jidRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), jid, jidBR);
//desc
descRect.setLeft(rect.left()+20);
descRect.setRight(rect.right()-68);
descRect.setTop(jidBR->bottom()+2);
descRect.setBottom(rect.bottom()-2);
descFont.setPointSize(7);
descFont.setItalic(true);
painter->setFont(descFont);
painter->drawText(descRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), desc, descBR);
int textHeight = nameBR->height() + jidBR->height() + descBR->height()+8;
int theight;
if (textHeight > 68)
theight = textHeight;
else
theight = 68;
//setHeight(68);
painter->drawPixmap(rect.left()+2, rect.top()-8+rect.height()/2,16, 16, presence);
painter->drawPixmap(rect.right()-66, rect.top()+2, 64, 64, avatar);
painter->restore();
return theight;
}
{
descFont.setPointSize(7);
descFont.setItalic(true);
QRect rect
= fm.
boundingRect(0,
0,
80,
160,
(int)(Qt
::AlignLeft | Qt
::TextWordWrap), desc
);
int h = rect.height();
if ((h + 30) < 68)
}
void QTlenRosterItem::setHeight(int h)
{
height = h;
}
#include "qtlenrosteritem.hpp"
QTlenRosterItem::QTlenRosterItem(QString name, QTlenPresence type, QString desc, QString jid, QPixmap pxAvatar)
{
this->name = name;
this->desc = desc;
this->jid = jid;
this->avatar = pxAvatar;
height = 68;
switch (type)
{
case Online:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/online.png"));
break;
case Chatty:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/chatty.png"));
break;
case Away:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/away.png"));
break;
case XA:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/xa.png"));
break;
case DND:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/dnd.png"));
break;
case Offline:
presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/offline.png"));
break;
}
}
int QTlenRosterItem::paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool checked) const
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
if (checked) painter->setBrush(palette.highlightedText());
else
painter->setBrush(palette.foreground());
//name
QRect nameRect;
nameRect.setLeft(rect.left()+20);
nameRect.setRight(rect.right()-68);
nameRect.setTop(rect.top()+2);
nameRect.setBottom(rect.bottom()-2);
QRect *nameBR = new QRect;
QFont nameFont;
nameFont.setBold(true);
painter->setFont(nameFont);
painter->drawText(nameRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), name, nameBR);
//jid
QRect jidRect;
jidRect.setLeft(rect.left()+20);
jidRect.setRight(rect.right()-68);
jidRect.setTop(nameBR->bottom()+2);
jidRect.setBottom(nameBR->bottom()+18);
QRect *jidBR = new QRect;
nameFont.setBold(false);
painter->setFont(nameFont);
painter->drawText(jidRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), jid, jidBR);
//desc
QRect descRect;
descRect.setLeft(rect.left()+20);
descRect.setRight(rect.right()-68);
descRect.setTop(jidBR->bottom()+2);
descRect.setBottom(rect.bottom()-2);
QRect *descBR = new QRect;
QFont descFont;
descFont.setPointSize(7);
descFont.setItalic(true);
painter->setFont(descFont);
painter->drawText(descRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), desc, descBR);
int textHeight = nameBR->height() + jidBR->height() + descBR->height()+8;
int theight;
if (textHeight > 68)
theight = textHeight;
else
theight = 68;
//setHeight(68);
painter->drawPixmap(rect.left()+2, rect.top()-8+rect.height()/2,16, 16, presence);
painter->drawPixmap(rect.right()-66, rect.top()+2, 64, 64, avatar);
painter->restore();
return theight;
}
QSize QTlenRosterItem::sizeHint(const QStyleOptionViewItem &option) const
{
qDebug(QByteArray::number(option.rect.right()));
QFont descFont;
descFont.setPointSize(7);
descFont.setItalic(true);
QFontMetrics fm(descFont);
QRect rect = fm.boundingRect(0,0,80,160, (int)(Qt::AlignLeft | Qt::TextWordWrap), desc);
int h = rect.height();
if ((h + 30) < 68)
return QSize(160, 68);
return QSize(160, h+30);
}
void QTlenRosterItem::setHeight(int h)
{
height = h;
}
To copy to clipboard, switch view to plain text mode
What I found, that in calculating SizeHint option.rect is not providing width, so I cannot calculate width of text blocks properly. This results in improper calculated height (only few pixels fortunately). Other thing, that is strange for me (maybe I'm misunderstanding docs) is that painter->setBrush(palette.highlightedText()); doesn't work as expected - text is still black (as if I used painter->setBrush(palette.foreground()) while for selected items should be white (or other colour derived from style). Any ideas? Thanks in advance.
Bookmarks