forked from qt-creator/qt-creator
QmlDesigner: Fix performance bottleneck in navigator
NavigatorTreeModel::filteredList is relativly slow and it is frequently called by ::index and ::rowCount. We introduce the cache and also improve appendForcedNodes to avoid quadratic blow up by using a set. Task-number: QDS-6110 Change-Id: I83b860158ad2cdc1c83a9e8a72b2d13781e91f86 Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
@@ -304,24 +304,28 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
|||||||
|
|
||||||
void static appendForcedNodes(const NodeListProperty &property, QList<ModelNode> &list)
|
void static appendForcedNodes(const NodeListProperty &property, QList<ModelNode> &list)
|
||||||
{
|
{
|
||||||
const QStringList visibleProperties = NodeHints::fromModelNode(property.parentModelNode()).visibleNonDefaultProperties();
|
const QSet<ModelNode> set = QSet<ModelNode>(list.constBegin(), list.constEnd());
|
||||||
for (const ModelNode &node : property.parentModelNode().directSubModelNodes()) {
|
for (const ModelNode &node : property.parentModelNode().directSubModelNodes()) {
|
||||||
if (!list.contains(node) && visibleProperties.contains(QString::fromUtf8(node.parentProperty().name())))
|
if (!set.contains(node)) {
|
||||||
|
const QStringList visibleProperties = NodeHints::fromModelNode(property.parentModelNode()).visibleNonDefaultProperties();
|
||||||
|
if (visibleProperties.contains(QString::fromUtf8(node.parentProperty().name())))
|
||||||
list.append(node);
|
list.append(node);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, bool reverseOrder)
|
QList<ModelNode> NavigatorTreeModel::filteredList(const NodeListProperty &property, bool filter, bool reverseOrder) const
|
||||||
{
|
{
|
||||||
|
auto it = m_rowCache.find(property.parentModelNode());
|
||||||
|
|
||||||
|
if (it != m_rowCache.end())
|
||||||
|
return it.value();
|
||||||
|
|
||||||
QList<ModelNode> list;
|
QList<ModelNode> list;
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
|
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
|
||||||
const char auxProp[] = "showInNavigator@Internal";
|
|
||||||
if (arg.hasAuxiliaryData(auxProp))
|
|
||||||
return arg.auxiliaryData(auxProp).toBool();
|
|
||||||
const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
|
const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
|
||||||
arg.setAuxiliaryDataWithoutLock(auxProp, value);
|
|
||||||
return value;
|
return value;
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
@@ -333,6 +337,7 @@ QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, boo
|
|||||||
if (reverseOrder)
|
if (reverseOrder)
|
||||||
std::reverse(list.begin(), list.end());
|
std::reverse(list.begin(), list.end());
|
||||||
|
|
||||||
|
m_rowCache.insert(property.parentModelNode(), list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,6 +1142,7 @@ QList<QPersistentModelIndex> NavigatorTreeModel::nodesToPersistentIndex(const QL
|
|||||||
|
|
||||||
void NavigatorTreeModel::notifyModelNodesRemoved(const QList<ModelNode> &modelNodes)
|
void NavigatorTreeModel::notifyModelNodesRemoved(const QList<ModelNode> &modelNodes)
|
||||||
{
|
{
|
||||||
|
m_rowCache.clear();
|
||||||
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
||||||
emit layoutAboutToBeChanged(indexes);
|
emit layoutAboutToBeChanged(indexes);
|
||||||
emit layoutChanged(indexes);
|
emit layoutChanged(indexes);
|
||||||
@@ -1144,6 +1150,7 @@ void NavigatorTreeModel::notifyModelNodesRemoved(const QList<ModelNode> &modelNo
|
|||||||
|
|
||||||
void NavigatorTreeModel::notifyModelNodesInserted(const QList<ModelNode> &modelNodes)
|
void NavigatorTreeModel::notifyModelNodesInserted(const QList<ModelNode> &modelNodes)
|
||||||
{
|
{
|
||||||
|
m_rowCache.clear();
|
||||||
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
||||||
emit layoutAboutToBeChanged(indexes);
|
emit layoutAboutToBeChanged(indexes);
|
||||||
emit layoutChanged(indexes);
|
emit layoutChanged(indexes);
|
||||||
@@ -1151,6 +1158,7 @@ void NavigatorTreeModel::notifyModelNodesInserted(const QList<ModelNode> &modelN
|
|||||||
|
|
||||||
void NavigatorTreeModel::notifyModelNodesMoved(const QList<ModelNode> &modelNodes)
|
void NavigatorTreeModel::notifyModelNodesMoved(const QList<ModelNode> &modelNodes)
|
||||||
{
|
{
|
||||||
|
m_rowCache.clear();
|
||||||
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
QList<QPersistentModelIndex> indexes = nodesToPersistentIndex(collectParents(modelNodes));
|
||||||
emit layoutAboutToBeChanged(indexes);
|
emit layoutAboutToBeChanged(indexes);
|
||||||
emit layoutChanged(indexes);
|
emit layoutChanged(indexes);
|
||||||
@@ -1164,18 +1172,21 @@ void NavigatorTreeModel::notifyIconsChanged()
|
|||||||
void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
||||||
{
|
{
|
||||||
m_showOnlyVisibleItems = showOnlyVisibleItems;
|
m_showOnlyVisibleItems = showOnlyVisibleItems;
|
||||||
|
m_rowCache.clear();
|
||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorTreeModel::setOrder(bool reverseItemOrder)
|
void NavigatorTreeModel::setOrder(bool reverseItemOrder)
|
||||||
{
|
{
|
||||||
m_reverseItemOrder = reverseItemOrder;
|
m_reverseItemOrder = reverseItemOrder;
|
||||||
|
m_rowCache.clear();
|
||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorTreeModel::resetModel()
|
void NavigatorTreeModel::resetModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
m_rowCache.clear();
|
||||||
m_nodeIndexHash.clear();
|
m_nodeIndexHash.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
@@ -129,9 +129,11 @@ private:
|
|||||||
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
||||||
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
||||||
void addImport(const QString &importName);
|
void addImport(const QString &importName);
|
||||||
|
QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, bool reverseOrder) const;
|
||||||
|
|
||||||
QPointer<NavigatorView> m_view;
|
QPointer<NavigatorView> m_view;
|
||||||
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
||||||
|
mutable QHash<ModelNode, QList<ModelNode> > m_rowCache;
|
||||||
bool m_showOnlyVisibleItems = true;
|
bool m_showOnlyVisibleItems = true;
|
||||||
bool m_reverseItemOrder = false;
|
bool m_reverseItemOrder = false;
|
||||||
DesignerActionManager *m_actionManager = nullptr;
|
DesignerActionManager *m_actionManager = nullptr;
|
||||||
|
Reference in New Issue
Block a user