From ff5506f3b95bd64036d45aa4a206d31d57c8aab9 Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@nokia.com> Date: Fri, 16 Jul 2010 11:03:42 +0200 Subject: [PATCH] QmlJSOutline: Optimize performance of QmlOutlineModel Previously we're setting the properties of the items one by one, each time potentially triggering an update of the view. Actually this uncovered an error in the Filter, which was only reacting to the first change and therefore didn't take the item type into account on first load. Instead, we now use our own QStandardItem class which can be used to assign all values at once. --- src/plugins/qmljseditor/qmloutlinemodel.cpp | 92 +++++++++++---------- src/plugins/qmljseditor/qmloutlinemodel.h | 9 +- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp index 7e38084d459..cfb2e6c1c91 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.cpp +++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp @@ -18,6 +18,13 @@ enum { namespace QmlJSEditor { namespace Internal { +QmlOutlineItem &QmlOutlineItem::copyValues(const QmlOutlineItem &other) +{ + *this = other; + emitDataChanged(); + return *this; +} + class QmlOutlineModelSync : protected AST::Visitor { public: @@ -201,22 +208,6 @@ private: int indent; }; -class OutlineItem : public QStandardItem -{ - int type() const - { - return QStandardItem::UserType + 1; - } - - QVariant data(int role = Qt::UserRole + 1) const - { - if (role == Qt::ToolTipRole) { - - } - return QStandardItem::data(role); - } -}; - QmlOutlineModel::QmlOutlineModel(QObject *parent) : QStandardItemModel(parent) { @@ -246,16 +237,19 @@ void QmlOutlineModel::update(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &sn QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id, const QIcon &icon, const AST::SourceLocation &sourceLocation) { - QStandardItem *item = enterNode(sourceLocation); + QmlOutlineItem prototype; + if (!id.isEmpty()) { - item->setText(id); + prototype.setText(id); } else { - item->setText(type); + prototype.setText(type); } - item->setIcon(icon); - item->setToolTip(type); - item->setData(ElementType, ItemTypeRole); - return item->index(); + prototype.setIcon(icon); + prototype.setToolTip(type); + prototype.setData(ElementType, ItemTypeRole); + prototype.setData(QVariant::fromValue(sourceLocation), SourceLocationRole); + + return enterNode(prototype); } void QmlOutlineModel::leaveElement() @@ -265,15 +259,18 @@ void QmlOutlineModel::leaveElement() QModelIndex QmlOutlineModel::enterProperty(const QString &name, bool isCustomProperty, const AST::SourceLocation &sourceLocation) { - QStandardItem *item = enterNode(sourceLocation); - item->setText(name); + QmlOutlineItem prototype; + + prototype.setText(name); if (isCustomProperty) { - item->setIcon(m_icons->publicMemberIcon()); + prototype.setIcon(m_icons->publicMemberIcon()); } else { - item->setIcon(m_icons->scriptBindingIcon()); + prototype.setIcon(m_icons->scriptBindingIcon()); } - item->setData(PropertyType, ItemTypeRole); - return item->index(); + prototype.setData(PropertyType, ItemTypeRole); + prototype.setData(QVariant::fromValue(sourceLocation), SourceLocationRole); + + return enterNode(prototype); } void QmlOutlineModel::leaveProperty() @@ -281,40 +278,49 @@ void QmlOutlineModel::leaveProperty() leaveNode(); } -QStandardItem *QmlOutlineModel::enterNode(const QmlJS::AST::SourceLocation &location) +QModelIndex QmlOutlineModel::enterNode(const QmlOutlineItem &prototype) { int siblingIndex = m_treePos.last(); if (siblingIndex == 0) { // first child if (!m_currentItem->hasChildren()) { - QStandardItem *parentItem = m_currentItem; - m_currentItem = new QStandardItem; - m_currentItem->setEditable(false); - parentItem->appendRow(m_currentItem); if (debug) - qDebug() << "QmlOutlineModel - Adding" << "element to" << parentItem->text(); + qDebug() << "QmlOutlineModel - Adding" << "element to" << m_currentItem->text(); + + QmlOutlineItem *newItem = new QmlOutlineItem; + newItem->copyValues(prototype); + newItem->setEditable(false); + m_currentItem->appendRow(newItem); + + m_currentItem = newItem; } else { m_currentItem = m_currentItem->child(0); + + QmlOutlineItem *existingItem = static_cast<QmlOutlineItem*>(m_currentItem); + existingItem->copyValues(prototype); } } else { // sibling if (m_currentItem->rowCount() <= siblingIndex) { - // attach - QStandardItem *oldItem = m_currentItem; - m_currentItem = new QStandardItem; - m_currentItem->setEditable(false); - oldItem->appendRow(m_currentItem); if (debug) - qDebug() << "QmlOutlineModel - Adding" << "element to" << oldItem->text(); + qDebug() << "QmlOutlineModel - Adding" << "element to" << m_currentItem->text(); + + QmlOutlineItem *newItem = new QmlOutlineItem; + newItem->copyValues(prototype); + newItem->setEditable(false); + m_currentItem->appendRow(newItem); + m_currentItem = newItem; } else { m_currentItem = m_currentItem->child(siblingIndex); + + QmlOutlineItem *existingItem = static_cast<QmlOutlineItem*>(m_currentItem); + existingItem->copyValues(prototype); } } m_treePos.append(0); - m_currentItem->setData(QVariant::fromValue(location), SourceLocationRole); - return m_currentItem; + return m_currentItem->index(); } void QmlOutlineModel::leaveNode() diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h index 1363ef9b27e..38fb36284eb 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.h +++ b/src/plugins/qmljseditor/qmloutlinemodel.h @@ -9,10 +9,17 @@ namespace QmlJSEditor { namespace Internal { +class QmlOutlineItem : public QStandardItem +{ +public: + QmlOutlineItem ©Values(const QmlOutlineItem &other); // so that we can assign all values at once +}; + class QmlOutlineModel : public QStandardItemModel { Q_OBJECT public: + enum CustomRoles { SourceLocationRole = Qt::UserRole + 1, ItemTypeRole = SourceLocationRole + 1 @@ -40,7 +47,7 @@ signals: void updated(); private: - QStandardItem *enterNode(const QmlJS::AST::SourceLocation &location); + QModelIndex enterNode(const QmlOutlineItem &prototype); void leaveNode(); QStandardItem *parentItem(); -- GitLab