1
0
Fork 0
x64dbg/src/gui/Src/Gui/RichTextItemDelegate.cpp

102 lines
3.4 KiB
C++

#include "RichTextItemDelegate.h"
#include <QTextDocument>
#include <QPainter>
#include <QAbstractTextDocumentLayout>
#include <QApplication>
RichTextItemDelegate::RichTextItemDelegate(QObject* parent)
: QStyledItemDelegate(parent)
{
}
void RichTextItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem & inOption, const QModelIndex & index) const
{
QStyleOptionViewItem option = inOption;
initStyleOption(&option, index);
if(option.text.isEmpty())
{
// This is nothing this function is supposed to handle
QStyledItemDelegate::paint(painter, inOption, index);
return;
}
QStyle* style = option.widget ? option.widget->style() : QApplication::style();
QTextOption textOption;
textOption.setWrapMode(option.features & QStyleOptionViewItem::WrapText ? QTextOption::WordWrap
: QTextOption::ManualWrap);
textOption.setTextDirection(option.direction);
QTextDocument doc;
doc.setDefaultTextOption(textOption);
doc.setHtml(option.text);
doc.setDefaultFont(option.font);
doc.setDocumentMargin(0);
doc.setTextWidth(option.rect.width());
doc.adjustSize();
if(doc.size().width() > option.rect.width())
{
// Elide text
QTextCursor cursor(&doc);
cursor.movePosition(QTextCursor::End);
const QString elidedPostfix = "...";
QFontMetrics metric(option.font);
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
int postfixWidth = metric.horizontalAdvance(elidedPostfix);
#else
int postfixWidth = metric.width(elidedPostfix);
#endif
while(doc.size().width() > option.rect.width() - postfixWidth)
{
cursor.deletePreviousChar();
doc.adjustSize();
}
cursor.insertText(elidedPostfix);
}
// Painting item without text (this takes care of painting e.g. the highlighted for selected
// or hovered over items in an ItemView)
option.text = QString();
style->drawControl(QStyle::CE_ItemViewItem, &option, painter, inOption.widget);
// Figure out where to render the text in order to follow the requested alignment
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option);
QSize documentSize(doc.size().width(), doc.size().height()); // Convert QSizeF to QSize
QRect layoutRect = QStyle::alignedRect(Qt::LayoutDirectionAuto, option.displayAlignment, documentSize, textRect);
painter->save();
// Translate the painter to the origin of the layout rectangle in order for the text to be
// rendered at the correct position
painter->translate(layoutRect.topLeft());
doc.drawContents(painter, textRect.translated(-textRect.topLeft()));
painter->restore();
}
QSize RichTextItemDelegate::sizeHint(const QStyleOptionViewItem & inOption, const QModelIndex & index) const
{
QStyleOptionViewItem option = inOption;
initStyleOption(&option, index);
if(option.text.isEmpty())
{
// This is nothing this function is supposed to handle
return QStyledItemDelegate::sizeHint(inOption, index);
}
QTextDocument doc;
doc.setHtml(option.text);
doc.setTextWidth(option.rect.width());
doc.setDefaultFont(option.font);
doc.setDocumentMargin(0);
return QSize(doc.idealWidth(), doc.size().height());
}