From 5f0556536ece408972f6aa6b18aad9e80c378d86 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 8 Sep 2023 16:14:06 +0200 Subject: [PATCH] QmlDesigner: Cleanup PropertyTreeModel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Some cleanup * Add cache * Strip full qualified name from PropertyNameRole * Hide nodes without children if filtering Change-Id: Ibd368174f5a56d6be33b6e55dc7a8099bbe2d119 Reviewed-by: Henning Gründl --- .../connectioneditor/propertytreemodel.cpp | 84 ++++++++----------- .../connectioneditor/propertytreemodel.h | 7 +- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp index 759d47037ae..ece4d1d927a 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp @@ -141,10 +141,23 @@ void PropertyTreeModel::resetModel() m_indexCount = 0; m_nodeList = allModelNodesWithIdsSortedByDisplayName(); + if (!m_filter.isEmpty()) { //This could be a bit slow for large projects, but we have to check everynode to "hide" it. + m_nodeList = Utils::filtered(m_nodeList, [this](const ModelNode &node) { + return node.displayName().contains(m_filter) + || !sortedAndFilteredPropertyNamesSignalsSlots(node).empty(); + }); + } + + m_sortedAndFilteredPropertyNamesSignalsSlots.clear(); + endResetModel(); testModel(); } +QString stripQualification(const QString &string) +{ + return string.split(".").last(); +} QVariant PropertyTreeModel::data(const QModelIndex &index, int role) const { int internalId = index.internalId(); @@ -161,7 +174,7 @@ QVariant PropertyTreeModel::data(const QModelIndex &index, int role) const return {}; if (internalId < 0) - return {}; + return "--root item--"; QTC_ASSERT(internalId < m_indexCount, return {"assert"}); @@ -175,7 +188,7 @@ QVariant PropertyTreeModel::data(const QModelIndex &index, int role) const if (role == PropertyNameRole) { if (!item.propertyName.isEmpty()) - return QString::fromUtf8(item.propertyName); + return stripQualification(QString::fromUtf8(item.propertyName)); else return item.modelNode.displayName(); } @@ -188,53 +201,14 @@ QVariant PropertyTreeModel::data(const QModelIndex &index, int role) const if (std::find(dynamic.begin(), dynamic.end(), item.propertyName) != dynamic.end()) return true; // dynamic properties have priority - if (item.propertyName.isEmpty()) { //node - //if (role == PropertyNameRole) - // return item.modelNode.displayName(); - + if (item.propertyName.isEmpty()) { return true; // nodes are always shown } return false; } - // can be removed later since we only use the two roles above in QML - // just for testing - - if (!(role == Qt::DisplayRole || role == Qt::FontRole)) - return {}; - - if (!index.isValid()) - return {}; - - if (internalId < 0) - return {}; - - QTC_ASSERT(internalId < m_indexCount, return {"assert"}); - - DataCacheItem item = m_indexHash[index.internalId()]; - - if (item.propertyName.isEmpty()) { - const QString name = item.modelNode.displayName(); - if (role == Qt::DisplayRole) - return name; - QFont f; - f.setBold(true); - return f; - } - - if (role == Qt::DisplayRole) - return QString::fromUtf8(item.propertyName); - - QFont f; - auto priority = properityLists(); - if (std::find(priority.begin(), priority.end(), item.propertyName) != priority.end()) - f.setBold(true); - auto dynamic = getDynamicProperties(item.modelNode); - if (std::find(dynamic.begin(), dynamic.end(), item.propertyName) != dynamic.end()) - f.setBold(true); - - return f; + return {}; } Qt::ItemFlags PropertyTreeModel::flags(const QModelIndex &) const @@ -248,14 +222,14 @@ QModelIndex PropertyTreeModel::index(int row, int column, const QModelIndex &par if (!m_connectionView->isAttached()) return {}; - if (!hasIndex(row, column, parent)) - return {}; - const int rootId = -1; if (!parent.isValid()) return createIndex(0, 0, rootId); + if (!hasIndex(row, column, parent)) + return {}; + if (internalId == rootId) { //root level model node const ModelNode modelNode = m_nodeList[row]; return ensureModelIndex(modelNode, row); @@ -290,7 +264,7 @@ QModelIndex PropertyTreeModel::parent(const QModelIndex &index) const int internalId = index.internalId(); - if (internalId == -1) + if (internalId == m_internalRootIndex) return {}; QTC_ASSERT(internalId < m_indexCount, return {}); @@ -471,6 +445,12 @@ const std::vector PropertyTreeModel::sortedAndFilteredPropertyName const ModelNode &modelNode) const { std::vector returnValue; + + returnValue = m_sortedAndFilteredPropertyNamesSignalsSlots.value(modelNode); + + if (!returnValue.empty()) + return returnValue; + if (m_type == SignalType) { returnValue = sortedAndFilteredSignalNames(modelNode.metaInfo()); } else if (m_type == SlotType) { @@ -484,9 +464,13 @@ const std::vector PropertyTreeModel::sortedAndFilteredPropertyName if (m_filter.isEmpty() || modelNode.displayName().contains(m_filter)) return returnValue; - return Utils::filtered(returnValue, [this](const PropertyName &name) { + const auto filtered = Utils::filtered(returnValue, [this](const PropertyName &name) { return name.contains(m_filter.toUtf8()) || name == m_filter.toUtf8(); }); + + m_sortedAndFilteredPropertyNamesSignalsSlots.insert(modelNode, filtered); + + return filtered; } const std::vector PropertyTreeModel::getDynamicProperties( @@ -852,6 +836,10 @@ void PropertyListProxyModel::goInto(int row) void PropertyListProxyModel::goUp() { qDebug() << Q_FUNC_INFO; + + if (m_parentIndex.internalId() == -1) + return; + m_parentIndex = m_treeModel->parent(m_parentIndex); resetModel(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.h b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.h index 9c1c876b466..241cd53e528 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.h +++ b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.h @@ -28,8 +28,8 @@ class PropertyTreeModel : public QAbstractItemModel Q_OBJECT public: enum UserRoles { - PropertyNameRole = Qt::UserRole + 1, - PropertyPriorityRole, + PropertyNameRole = Qt::DisplayRole, + PropertyPriorityRole = Qt::UserRole + 1, ExpressionRole, ChildCountRole, RowRole, @@ -122,6 +122,8 @@ private: QList m_nodeList; PropertyTypes m_type = AllTypes; QString m_filter; + mutable QHash> m_sortedAndFilteredPropertyNamesSignalsSlots; + int m_internalRootIndex = -1; }; class PropertyListProxyModel : public QAbstractListModel @@ -158,6 +160,7 @@ private: PropertyTreeModel *m_treeModel = nullptr; }; + inline bool operator==(const PropertyTreeModel::DataCacheItem &lhs, const PropertyTreeModel::DataCacheItem &rhs) {