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