00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "StatusEventItemDelegate.h"
00018 #include "StatusEventItem.h"
00019
00020 #include "Vidalia.h"
00021
00022 #include <QPainter>
00023 #include <QTextLine>
00024 #include <QTextLayout>
00025
00026 StatusEventItemDelegate::StatusEventItemDelegate(QObject *parent)
00027 : QItemDelegate(parent)
00028 {
00029 _helpIcon = QPixmap(":/images/16x16/system-help.png");
00030 }
00031
00032 void
00033 StatusEventItemDelegate::paint(QPainter *painter,
00034 const QStyleOptionViewItem &option,
00035 const QModelIndex &index) const
00036 {
00037 QItemDelegate::paint(painter, option, index);
00038
00039 painter->save();
00040 if (option.state & QStyle::State_Selected)
00041 painter->setPen(option.palette.highlightedText().color());
00042
00043 QPixmap icon = index.data(StatusEventItem::IconRole).value<QPixmap>();
00044 QTime tstamp = index.data(StatusEventItem::TimestampRole).toTime();
00045 QString title = index.data(StatusEventItem::TitleRole).toString();
00046 QString text = index.data(StatusEventItem::DescriptionRole).toString();
00047 QFont font = option.font;
00048 QFontMetrics fm = option.fontMetrics;
00049
00050
00051 QRect iconRect(option.rect.x(),
00052 option.rect.y(),
00053 qMax(fm.width(tstamp.toString()), icon.width()) + 16,
00054 option.rect.height());
00055 QRect textRect(iconRect.topRight(), option.rect.bottomRight());
00056
00057
00058 QPoint center = iconRect.center();
00059 int x = center.x() - qRound(icon.width() / 2.0);
00060 int y = center.y() - qRound((icon.height() + fm.lineSpacing()) / 2.0);
00061 painter->drawPixmap(x, y, icon);
00062
00063
00064 x = iconRect.x();
00065 y = y + icon.height();
00066 painter->drawText(x, y,
00067 iconRect.width(),
00068 fm.lineSpacing(),
00069 Qt::AlignCenter,
00070 tstamp.toString());
00071
00072
00073
00074
00075 font.setBold(true);
00076 painter->setFont(font);
00077 if (! index.data(StatusEventItem::HelpUrlRole).isNull()) {
00078
00079
00080 title = fm.elidedText(title,
00081 Qt::ElideRight,
00082 textRect.width() - _helpIcon.width() - 24);
00083
00084 x = textRect.topRight().x() - _helpIcon.width() - 8;
00085 y = textRect.y() + 8;
00086 painter->drawPixmap(x, y, _helpIcon);
00087 } else {
00088 title = fm.elidedText(title, Qt::ElideRight, textRect.width() - 16);
00089 }
00090 painter->drawText(textRect.x(),
00091 textRect.y() + 8,
00092 textRect.width(),
00093 fm.lineSpacing(),
00094 Qt::AlignVCenter | Qt::AlignLeft, title);
00095
00096
00097
00098
00099 font.setBold(false);
00100 painter->setFont(font);
00101 if (option.state & QStyle::State_Selected)
00102 text = layoutText(text, font, textRect.width(), 6).join("\n");
00103 else
00104 text = layoutText(text, font, textRect.width(), 3).join("\n");
00105
00106 x = textRect.x();
00107 y = textRect.y() + 8 + fm.leading() + fm.lineSpacing();
00108 painter->drawText(x, y,
00109 textRect.width(),
00110 textRect.height() - (y - textRect.y()),
00111 Qt::AlignTop | Qt::AlignLeft, text);
00112
00113 painter->restore();
00114 }
00115
00116 QSize
00117 StatusEventItemDelegate::sizeHint(const QStyleOptionViewItem &option,
00118 const QModelIndex &index) const
00119 {
00120 int iconHeight, iconWidth;
00121 int textWidth, textHeight;
00122 QFontMetrics fontMetrics = option.fontMetrics;
00123
00124 QPixmap icon = index.data(StatusEventItem::IconRole).value<QPixmap>();
00125 QString text = index.data(StatusEventItem::DescriptionRole).toString();
00126 QTime tstamp = index.data(StatusEventItem::TimestampRole).toTime();
00127
00128 iconHeight = icon.height() + fontMetrics.lineSpacing() + 16;
00129 iconWidth = qMax(fontMetrics.width(tstamp.toString()), icon.width()) + 16;
00130 textWidth = option.rect.width() - iconWidth;
00131
00132 if (option.state & QStyle::State_Selected)
00133 layoutText(text, option.font, textWidth, 6, &textHeight);
00134 else
00135 layoutText(text, option.font, textWidth, 3, &textHeight);
00136 textHeight += 8 + fontMetrics.leading() + fontMetrics.lineSpacing();
00137
00138 return QSize(option.rect.width(), qMax(iconHeight, textHeight));
00139 }
00140
00141 QStringList
00142 StatusEventItemDelegate::layoutText(const QString &text,
00143 const QFont &font,
00144 int maxLineWidth,
00145 int maxLines,
00146 int *textHeight)
00147 {
00148 QTextLayout textLayout(text, font);
00149 QFontMetrics fontMetrics(font);
00150 QStringList lines;
00151 qreal height = 0.0;
00152
00153 textLayout.beginLayout();
00154 while (lines.size() < maxLines) {
00155 QTextLine line = textLayout.createLine();
00156 if (! line.isValid())
00157 break;
00158 if (maxLines <= 0 || lines.size() < maxLines-1) {
00159
00160 line.setLineWidth(maxLineWidth);
00161 lines.append(text.mid(line.textStart(), line.textLength()));
00162 } else {
00163
00164
00165
00166 line.setLineWidth(2 * maxLineWidth);
00167 lines.append(fontMetrics.elidedText(text.mid(line.textStart()),
00168 Qt::ElideRight,
00169 maxLineWidth));
00170 }
00171 height += fontMetrics.leading() + line.height();
00172 }
00173 textLayout.endLayout();
00174
00175 if (textHeight)
00176 *textHeight = qRound(height);
00177
00178 return lines;
00179 }
00180