Commit 2d612a25 authored by Aurindam Jana's avatar Aurindam Jana Committed by Kai Koehne
Browse files

QtMessageLogView: Optimize performance



Performance is hit when rendering a large number of messages.
Show text contents that fits a line and expands to show the
complete text when clicked.

Change-Id: I803a8b2da12830172f9e75f86546adf121799a67
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent af6da38d
......@@ -1314,9 +1314,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
QtMessageLogItem *item = new QtMessageLogItem(parent);
if (result.type() == QVariant::Map) {
if (key.isEmpty())
item->text = _("Object");
item->setText(_("Object"));
else
item->text = QString(_("%1: Object")).arg(key);
item->setText(key + _(" : Object"));
QMapIterator<QString, QVariant> i(result.toMap());
while (i.hasNext()) {
......@@ -1328,9 +1328,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
}
} else if (result.type() == QVariant::List) {
if (key.isEmpty())
item->text = _("List");
item->setText(_("List"));
else
item->text = QString(_("[%1] : List")).arg(key);
item->setText(QString(_("[%1] : List")).arg(key));
QVariantList resultList = result.toList();
for (int i = 0; i < resultList.count(); i++) {
QtMessageLogItem *child = constructLogItemTree(item, resultList.at(i),
......@@ -1339,9 +1339,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
item->insertChild(child);
}
} else if (result.canConvert(QVariant::String)) {
item->text = result.toString();
item->setText(result.toString());
} else {
item->text = _("Unknown Value");
item->setText(_("Unknown Value"));
}
return item;
......
......@@ -50,11 +50,11 @@ namespace Internal {
QtMessageLogItem::QtMessageLogItem(QtMessageLogItem *parent,
QtMessageLogHandler::ItemType itemType, const QString &text)
: m_parentItem(parent),
text(text),
itemType(itemType),
line(-1)
{
setText(text);
}
QtMessageLogItem::~QtMessageLogItem()
......@@ -105,7 +105,7 @@ void QtMessageLogItem::insertChild(QtMessageLogItem *item)
int i = 0;
for (; i < m_childItems.count(); i++) {
if (item->text < m_childItems[i]->text) {
if (item->m_text < m_childItems[i]->m_text) {
break;
}
}
......@@ -148,6 +148,20 @@ bool QtMessageLogItem::detachChild(int position)
return true;
}
void QtMessageLogItem::setText(const QString &text)
{
m_text = text;
for (int i = 0; i < m_text.length(); ++i) {
if (m_text.at(i).isPunct())
m_text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE
}
}
const QString &QtMessageLogItem::text() const
{
return m_text;
}
///////////////////////////////////////////////////////////////////////
//
// QtMessageLogHandler
......@@ -171,8 +185,8 @@ void QtMessageLogHandler::clear()
{
beginResetModel();
reset();
qDeleteAll(m_rootItem->m_childItems);
m_rootItem->m_childItems.clear();
delete m_rootItem;
m_rootItem = new QtMessageLogItem(0);
endResetModel();
if (m_hasEditableRow)
......@@ -262,7 +276,7 @@ QVariant QtMessageLogHandler::data(const QModelIndex &index, int role) const
QtMessageLogItem *item = getItem(index);
if (role == Qt::DisplayRole )
return item->text;
return item->text();
else if (role == QtMessageLogHandler::TypeRole)
return int(item->itemType);
else if (role == QtMessageLogHandler::FileRole)
......@@ -338,7 +352,7 @@ bool QtMessageLogHandler::setData(const QModelIndex &index, const QVariant &valu
QtMessageLogItem *item = getItem(index);
bool result = false;
if (role == Qt::DisplayRole) {
item->text = value.toString();
item->setText(value.toString());
result = true;
} else if (role == QtMessageLogHandler::TypeRole) {
item->itemType = (QtMessageLogHandler::ItemType)value.toInt();
......
......@@ -132,19 +132,18 @@ public:
bool removeChildren(int position, int count);
bool detachChild(int position);
int childNumber() const;
void setText(const QString &text);
const QString &text() const;
private:
QtMessageLogItem *m_parentItem;
QList<QtMessageLogItem *> m_childItems;
QString m_text;
public:
QString text;
QtMessageLogHandler::ItemType itemType;
QString file;
int line;
private:
friend class QtMessageLogHandler;
};
} //Internal
......
......@@ -73,7 +73,8 @@ QtMessageLogItemDelegate::QtMessageLogItemDelegate(QObject *parent) :
m_expandIcon(QLatin1String(":/debugger/images/expand.png")),
m_collapseIcon(QLatin1String(":/debugger/images/collapse.png")),
m_prompt(QLatin1String(":/debugger/images/prompt.png")),
m_itemModel(0)
m_itemModel(0),
m_cachedHeight(0)
{
}
......@@ -189,12 +190,18 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt
// Paint TextArea:
// Layout the description
QString str = index.data(Qt::DisplayRole).toString();
formatTextForWidth(str);
QTextLayout tl(str, opt.font);
bool showFileLineInfo = true;
// show complete text if selected
if (view->selectionModel()->currentIndex() == index) {
QTextLayout tl(str, opt.font);
layoutText(tl, positions.textAreaWidth(), &showFileLineInfo);
tl.draw(painter, QPoint(positions.textAreaLeft(), positions.adjustedTop()));
} else {
QFontMetrics fm(opt.font);
painter->drawText(positions.textArea(),
fm.elidedText(str, Qt::ElideRight,
positions.textAreaWidth()));
}
//skip if area is editable
if (showExpandableIcon) {
// Paint ExpandableIconArea:
......@@ -267,6 +274,10 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option,
if (index.flags() & Qt::ItemIsEditable)
return QSize(width, view->height() * 1/2);
const bool selected = (view->selectionModel()->currentIndex() == index);
if (!selected && option.font == m_cachedFont && m_cachedHeight > 0)
return QSize(width, m_cachedHeight);
QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data(
QtMessageLogHandler::TypeRole).toInt();
bool showTypeIcon = index.parent() == QModelIndex();
......@@ -277,14 +288,25 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option,
showTypeIcon, showExpandableIcon, m_itemModel);
QFontMetrics fm(option.font);
qreal height = fm.height();
if (selected) {
QString str = index.data(Qt::DisplayRole).toString();
formatTextForWidth(str);
QTextLayout tl(str, option.font);
qreal height = layoutText(tl, positions.textAreaWidth());
height = layoutText(tl, positions.textAreaWidth());
}
height += 2 * ConsoleItemPositions::ITEM_PADDING;
if (height < positions.minimumHeight())
height = positions.minimumHeight();
if (!selected) {
m_cachedHeight = height;
m_cachedFont = option.font;
}
return QSize(width, height);
}
......@@ -359,13 +381,6 @@ qreal QtMessageLogItemDelegate::layoutText(QTextLayout &tl, int width,
return height;
}
void QtMessageLogItemDelegate::formatTextForWidth(QString &text) const
{
for (int i = 0; i < text.length(); ++i) {
if (text.at(i).isPunct())
text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE
}
}
void QtMessageLogItemDelegate::setItemModel(QtMessageLogHandler *model)
{
m_itemModel = model;
......
......@@ -76,7 +76,6 @@ private slots:
private:
qreal layoutText(QTextLayout &tl, int width, bool *success = 0) const;
void formatTextForWidth(QString &text) const;
private:
const QIcon m_logIcon;
......@@ -86,6 +85,8 @@ private:
const QIcon m_collapseIcon;
const QIcon m_prompt;
QtMessageLogHandler *m_itemModel;
mutable int m_cachedHeight;
mutable QFont m_cachedFont;
};
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment