forked from qt-creator/qt-creator
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.
This commit is contained in:
@@ -18,6 +18,13 @@ enum {
|
|||||||
namespace QmlJSEditor {
|
namespace QmlJSEditor {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
QmlOutlineItem &QmlOutlineItem::copyValues(const QmlOutlineItem &other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
emitDataChanged();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
class QmlOutlineModelSync : protected AST::Visitor
|
class QmlOutlineModelSync : protected AST::Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -201,22 +208,6 @@ private:
|
|||||||
int indent;
|
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) :
|
QmlOutlineModel::QmlOutlineModel(QObject *parent) :
|
||||||
QStandardItemModel(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)
|
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()) {
|
if (!id.isEmpty()) {
|
||||||
item->setText(id);
|
prototype.setText(id);
|
||||||
} else {
|
} else {
|
||||||
item->setText(type);
|
prototype.setText(type);
|
||||||
}
|
}
|
||||||
item->setIcon(icon);
|
prototype.setIcon(icon);
|
||||||
item->setToolTip(type);
|
prototype.setToolTip(type);
|
||||||
item->setData(ElementType, ItemTypeRole);
|
prototype.setData(ElementType, ItemTypeRole);
|
||||||
return item->index();
|
prototype.setData(QVariant::fromValue(sourceLocation), SourceLocationRole);
|
||||||
|
|
||||||
|
return enterNode(prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlOutlineModel::leaveElement()
|
void QmlOutlineModel::leaveElement()
|
||||||
@@ -265,15 +259,18 @@ void QmlOutlineModel::leaveElement()
|
|||||||
|
|
||||||
QModelIndex QmlOutlineModel::enterProperty(const QString &name, bool isCustomProperty, const AST::SourceLocation &sourceLocation)
|
QModelIndex QmlOutlineModel::enterProperty(const QString &name, bool isCustomProperty, const AST::SourceLocation &sourceLocation)
|
||||||
{
|
{
|
||||||
QStandardItem *item = enterNode(sourceLocation);
|
QmlOutlineItem prototype;
|
||||||
item->setText(name);
|
|
||||||
|
prototype.setText(name);
|
||||||
if (isCustomProperty) {
|
if (isCustomProperty) {
|
||||||
item->setIcon(m_icons->publicMemberIcon());
|
prototype.setIcon(m_icons->publicMemberIcon());
|
||||||
} else {
|
} else {
|
||||||
item->setIcon(m_icons->scriptBindingIcon());
|
prototype.setIcon(m_icons->scriptBindingIcon());
|
||||||
}
|
}
|
||||||
item->setData(PropertyType, ItemTypeRole);
|
prototype.setData(PropertyType, ItemTypeRole);
|
||||||
return item->index();
|
prototype.setData(QVariant::fromValue(sourceLocation), SourceLocationRole);
|
||||||
|
|
||||||
|
return enterNode(prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlOutlineModel::leaveProperty()
|
void QmlOutlineModel::leaveProperty()
|
||||||
@@ -281,40 +278,49 @@ void QmlOutlineModel::leaveProperty()
|
|||||||
leaveNode();
|
leaveNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStandardItem *QmlOutlineModel::enterNode(const QmlJS::AST::SourceLocation &location)
|
QModelIndex QmlOutlineModel::enterNode(const QmlOutlineItem &prototype)
|
||||||
{
|
{
|
||||||
int siblingIndex = m_treePos.last();
|
int siblingIndex = m_treePos.last();
|
||||||
if (siblingIndex == 0) {
|
if (siblingIndex == 0) {
|
||||||
// first child
|
// first child
|
||||||
if (!m_currentItem->hasChildren()) {
|
if (!m_currentItem->hasChildren()) {
|
||||||
QStandardItem *parentItem = m_currentItem;
|
|
||||||
m_currentItem = new QStandardItem;
|
|
||||||
m_currentItem->setEditable(false);
|
|
||||||
parentItem->appendRow(m_currentItem);
|
|
||||||
if (debug)
|
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 {
|
} else {
|
||||||
m_currentItem = m_currentItem->child(0);
|
m_currentItem = m_currentItem->child(0);
|
||||||
|
|
||||||
|
QmlOutlineItem *existingItem = static_cast<QmlOutlineItem*>(m_currentItem);
|
||||||
|
existingItem->copyValues(prototype);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// sibling
|
// sibling
|
||||||
if (m_currentItem->rowCount() <= siblingIndex) {
|
if (m_currentItem->rowCount() <= siblingIndex) {
|
||||||
// attach
|
|
||||||
QStandardItem *oldItem = m_currentItem;
|
|
||||||
m_currentItem = new QStandardItem;
|
|
||||||
m_currentItem->setEditable(false);
|
|
||||||
oldItem->appendRow(m_currentItem);
|
|
||||||
if (debug)
|
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 {
|
} else {
|
||||||
m_currentItem = m_currentItem->child(siblingIndex);
|
m_currentItem = m_currentItem->child(siblingIndex);
|
||||||
|
|
||||||
|
QmlOutlineItem *existingItem = static_cast<QmlOutlineItem*>(m_currentItem);
|
||||||
|
existingItem->copyValues(prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_treePos.append(0);
|
m_treePos.append(0);
|
||||||
m_currentItem->setData(QVariant::fromValue(location), SourceLocationRole);
|
|
||||||
|
|
||||||
return m_currentItem;
|
return m_currentItem->index();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlOutlineModel::leaveNode()
|
void QmlOutlineModel::leaveNode()
|
||||||
|
|||||||
@@ -9,10 +9,17 @@
|
|||||||
namespace QmlJSEditor {
|
namespace QmlJSEditor {
|
||||||
namespace Internal {
|
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
|
class QmlOutlineModel : public QStandardItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum CustomRoles {
|
enum CustomRoles {
|
||||||
SourceLocationRole = Qt::UserRole + 1,
|
SourceLocationRole = Qt::UserRole + 1,
|
||||||
ItemTypeRole = SourceLocationRole + 1
|
ItemTypeRole = SourceLocationRole + 1
|
||||||
@@ -40,7 +47,7 @@ signals:
|
|||||||
void updated();
|
void updated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStandardItem *enterNode(const QmlJS::AST::SourceLocation &location);
|
QModelIndex enterNode(const QmlOutlineItem &prototype);
|
||||||
void leaveNode();
|
void leaveNode();
|
||||||
|
|
||||||
QStandardItem *parentItem();
|
QStandardItem *parentItem();
|
||||||
|
|||||||
Reference in New Issue
Block a user