From 3a540285a3613028d230dfeec859930a23544103 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Fri, 10 Feb 2017 14:49:26 +0100 Subject: [PATCH] logic: Show non-indexed nodes within their parents and their childs * Added support for access nodes without title --- .../component/controller/GraphController.cpp | 56 +++++++-------- .../component/controller/helper/DummyNode.h | 4 +- src/lib/component/view/GraphViewStyle.cpp | 1 + src/lib/data/HierarchyCache.cpp | 69 +++++++++++++++++-- src/lib/data/HierarchyCache.h | 17 ++++- src/lib/data/PersistentStorage.cpp | 68 +++++++++++------- src/lib/data/graph/Node.cpp | 2 +- 7 files changed, 156 insertions(+), 61 deletions(-) diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index fe057169..0d12b4e7 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -325,7 +325,7 @@ void GraphController::createDummyGraphForTokenIds(const std::vector& tokenId { node->hasParent = false; - if (node->data->isType(Node::NODE_NON_INDEXED | Node::NODE_NAMESPACE | Node::NODE_PACKAGE)) + if (node->data->isType(Node::NODE_NAMESPACE | Node::NODE_PACKAGE)) { node->name = node->data->getFullName(); } @@ -380,33 +380,32 @@ std::shared_ptr GraphController::createDummyNodeTopDown(Node* node, I [node, &parentId, &result, this](Node* child) { DummyNode* parent = nullptr; + AccessKind accessKind = ACCESS_NONE; TokenComponentAccess* access = child->getComponent(); - - if (access && access->getAccess() != ACCESS_NONE) + if (access) { - AccessKind accessKind = access->getAccess(); - for (std::shared_ptr dummy : result->subNodes) - { - if (dummy->accessKind == accessKind) - { - parent = dummy.get(); - break; - } - } + accessKind = access->getAccess(); + } - if (!parent) + for (std::shared_ptr dummy : result->subNodes) + { + if (dummy->accessKind == accessKind) { - std::shared_ptr accessNode = std::make_shared(); - accessNode->accessKind = accessKind; - result->subNodes.push_back(accessNode); - parent = accessNode.get(); + parent = dummy.get(); + break; } } - else + + if (!parent) { - parent = result.get(); + std::shared_ptr accessNode = std::make_shared(); + accessNode->accessKind = accessKind; + accessNode->isAccess = true; + result->subNodes.push_back(accessNode); + parent = accessNode.get(); } + parent->subNodes.push_back(createDummyNodeTopDown(child, parentId)); } ); @@ -604,7 +603,11 @@ bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode* node, bool n } } - if (noActive || node->active || node->connected || node->childVisible) + if (node->isAccessNode() && node->accessKind == ACCESS_NONE && node->childVisible) + { + node->visible = true; + } + else if (noActive || node->active || node->connected || node->childVisible) { setNodeVisibilityRecursiveTopDown(node, false); } @@ -616,9 +619,13 @@ void GraphController::setNodeVisibilityRecursiveTopDown(DummyNode* node, bool pa { node->visible = true; + if (node->isGraphNode() && node->data->getType() == Node::NODE_ENUM && !node->isExpanded()) + { + return; + } + if ((node->isGraphNode() && node->isExpanded()) || - (node->isAccessNode() && parentExpanded) || - (node->isGraphNode() && parentExpanded && node->data->isType(Node::NODE_ENUM_CONSTANT))) + (node->isAccessNode() && (node->accessKind == ACCESS_NONE || parentExpanded))) { for (std::shared_ptr subNode : node->subNodes) { @@ -1285,11 +1292,6 @@ void GraphController::addExpandToggleNode(DummyNode* node) const i--; continue; } - else if (subNode->isGraphNode() && subNode->data->isType(Node::NODE_ENUM_CONSTANT) && !subNode->visible) - { - expandNode->invisibleSubNodeCount++; - continue; - } for (std::shared_ptr subSubNode : subNode->subNodes) { diff --git a/src/lib/component/controller/helper/DummyNode.h b/src/lib/component/controller/helper/DummyNode.h index 26ad55aa..c1dd048f 100644 --- a/src/lib/component/controller/helper/DummyNode.h +++ b/src/lib/component/controller/helper/DummyNode.h @@ -63,6 +63,7 @@ public: , hasParent(true) , hasQualifier(false) , accessKind(ACCESS_NONE) + , isAccess(false) , invisibleSubNodeCount(0) , bundleId(0) , layoutBucket(0, 0) @@ -79,7 +80,7 @@ public: bool isAccessNode() const { - return accessKind != ACCESS_NONE; + return isAccess; } bool isExpandToggleNode() const @@ -261,6 +262,7 @@ public: // AccessNode AccessKind accessKind; + bool isAccess; // ExpandToggleNode size_t invisibleSubNodeCount; diff --git a/src/lib/component/view/GraphViewStyle.cpp b/src/lib/component/view/GraphViewStyle.cpp index 064d511e..245d724c 100644 --- a/src/lib/component/view/GraphViewStyle.cpp +++ b/src/lib/component/view/GraphViewStyle.cpp @@ -330,6 +330,7 @@ GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfAccessNode(AccessKind ac switch (access) { case ACCESS_NONE: + margins.top = 10; margins.minWidth = 30; break; case ACCESS_PUBLIC: diff --git a/src/lib/data/HierarchyCache.cpp b/src/lib/data/HierarchyCache.cpp index 356969cc..1f20a46a 100644 --- a/src/lib/data/HierarchyCache.cpp +++ b/src/lib/data/HierarchyCache.cpp @@ -5,6 +5,7 @@ HierarchyCache::HierarchyNode::HierarchyNode(Id nodeId) , m_edgeId(0) , m_parent(nullptr) , m_isVisible(true) + , m_isIndexed(true) { } @@ -51,12 +52,21 @@ void HierarchyCache::HierarchyNode::addChildIds(std::vector* nodeIds) const } } -void HierarchyCache::HierarchyNode::addChildIdsRecursive(std::vector* nodeIds, std::vector* edgeIds) const +void HierarchyCache::HierarchyNode::addChildIds(std::set* nodeIds, std::set* edgeIds) const { for (const HierarchyNode* child : m_children) { - nodeIds->push_back(child->getNodeId()); - edgeIds->push_back(child->getEdgeId()); + nodeIds->insert(child->getNodeId()); + edgeIds->insert(child->getEdgeId()); + } +} + +void HierarchyCache::HierarchyNode::addChildIdsRecursive(std::set* nodeIds, std::set* edgeIds) const +{ + for (const HierarchyNode* child : m_children) + { + nodeIds->insert(child->getNodeId()); + edgeIds->insert(child->getEdgeId()); child->addChildIdsRecursive(nodeIds, edgeIds); } @@ -87,13 +97,23 @@ void HierarchyCache::HierarchyNode::setIsVisible(bool isVisible) m_isVisible = isVisible; } +bool HierarchyCache::HierarchyNode::isIndexed() const +{ + return m_isIndexed; +} + +void HierarchyCache::HierarchyNode::setIsIndexed(bool isIndexed) +{ + m_isIndexed = isIndexed; +} + void HierarchyCache::clear() { m_nodes.clear(); } -void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool fromVisible) +void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool sourceIndexed, bool targetIndexed) { HierarchyNode* from = createNode(fromId); HierarchyNode* to = createNode(toId); @@ -101,8 +121,11 @@ void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool fromVi from->addChild(to); to->setParent(from); + from->setIsVisible(sourceVisible); + from->setIsIndexed(sourceIndexed); + to->setEdgeId(edgeId); - from->setIsVisible(fromVisible); + to->setIsIndexed(targetIndexed); } Id HierarchyCache::getLastVisibleParentNodeId(Id nodeId) const @@ -147,7 +170,7 @@ size_t HierarchyCache::getIndexOfLastVisibleParentNode(Id nodeId) const return idx; } -void HierarchyCache::addAllChildIdsForNodeId(Id nodeId, std::vector* nodeIds, std::vector* edgeIds) const +void HierarchyCache::addAllChildIdsForNodeId(Id nodeId, std::set* nodeIds, std::set* edgeIds) const { HierarchyNode* node = getNode(nodeId); if (node) @@ -156,6 +179,29 @@ void HierarchyCache::addAllChildIdsForNodeId(Id nodeId, std::vector* nodeIds } } +void HierarchyCache::addAllVisibleParentsAndChildIdsForNodeId(Id nodeId, std::set* nodeIds, std::set* edgeIds) const +{ + HierarchyNode* node = getNode(nodeId); + if (node) + { + node->addChildIds(nodeIds, edgeIds); + } + + Id edgeId = 0; + while (node && node->isVisible()) + { + if (edgeId) + { + edgeIds->insert(edgeId); + } + + nodeIds->insert(node->getNodeId()); + edgeId = node->getEdgeId(); + + node = node->getParent(); + } +} + void HierarchyCache::addFirstChildIdsForNodeId(Id nodeId, std::vector* nodeIds) const { HierarchyNode* node = getNode(nodeId); @@ -203,6 +249,17 @@ bool HierarchyCache::isChildOfVisibleNodeOrInvisible(Id nodeId) const return false; } +bool HierarchyCache::isIndexed(Id nodeId) const +{ + HierarchyNode* node = getNode(nodeId); + if (!node) + { + return true; + } + + return node->isIndexed(); +} + bool HierarchyCache::nodeHasChildren(Id nodeId) const { HierarchyNode* node = getNode(nodeId); diff --git a/src/lib/data/HierarchyCache.h b/src/lib/data/HierarchyCache.h index 37278aab..60da8d6c 100644 --- a/src/lib/data/HierarchyCache.h +++ b/src/lib/data/HierarchyCache.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "utility/types.h" @@ -12,16 +13,21 @@ class HierarchyCache public: void clear(); - void createConnection(Id edgeId, Id fromId, Id toId, bool fromVisible); + void createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool sourceIndexed, bool targetIndexed); Id getLastVisibleParentNodeId(Id nodeId) const; size_t getIndexOfLastVisibleParentNode(Id nodeId) const; - void addAllChildIdsForNodeId(Id nodeId, std::vector* nodeIds, std::vector* edgeIds) const; + void addAllChildIdsForNodeId(Id nodeId, std::set* nodeIds, std::set* edgeIds) const; + void addAllVisibleParentsAndChildIdsForNodeId(Id nodeId, std::set* nodeIds, std::set* edgeIds) const; + void addAllVisibleParentsRecursive(Id nodeId, std::set* nodeIds, std::set* edgeIds) const; + void addFirstChildIdsForNodeId(Id nodeId, std::vector* nodeIds) const; void addFirstVisibleChildIdsForNodeId(Id nodeId, std::vector* nodeIds) const; bool isChildOfVisibleNodeOrInvisible(Id nodeId) const; + bool isIndexed(Id nodeId) const; + bool nodeHasChildren(Id nodeId) const; private: @@ -42,12 +48,16 @@ private: const std::vector& getChildren() const; void addChildIds(std::vector* nodeIds) const; - void addChildIdsRecursive(std::vector* nodeIds, std::vector* edgeIds) const; + void addChildIds(std::set* nodeIds, std::set* edgeIds) const; + void addChildIdsRecursive(std::set* nodeIds, std::set* edgeIds) const; void addVisibleNodeIdsRecursive(std::vector* nodeIds) const; bool isVisible() const; void setIsVisible(bool isVisible); + bool isIndexed() const; + void setIsIndexed(bool isIndexed); + private: const Id m_nodeId; Id m_edgeId; @@ -56,6 +66,7 @@ private: std::vector m_children; bool m_isVisible; + bool m_isIndexed; }; HierarchyNode* getNode(Id nodeId) const; diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index 27c3409d..8b5c3586 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -843,11 +843,6 @@ std::shared_ptr PersistentStorage::getGraphForActiveTokenIds(const std::v if (!isNamespace) { - for (const StorageFile& file : m_sqliteStorage.getAllByIds(ids)) - { - nodeIds.push_back(file.id); - } - if (nodeIds.size() != ids.size()) { std::vector edges = m_sqliteStorage.getAllByIds(ids); @@ -1453,12 +1448,12 @@ Id PersistentStorage::getLastVisibleParentNodeId(const Id nodeId) const std::vector PersistentStorage::getAllChildNodeIds(const Id nodeId) const { - std::vector childNodeIds; - std::vector edgeIds; + std::set childNodeIds; + std::set edgeIds; m_hierarchyCache.addAllChildIdsForNodeId(nodeId, &childNodeIds, &edgeIds); - return childNodeIds; + return utility::toVector(childNodeIds); } void PersistentStorage::addNodesToGraph(const std::vector& nodeIds, Graph* graph) const @@ -1563,33 +1558,47 @@ void PersistentStorage::addNodesWithChildrenAndEdgesToGraph( { TRACE(); - std::set parentNodeIds; - - for (Id nodeId : nodeIds) - { - parentNodeIds.insert(getLastVisibleParentNodeId(nodeId)); - } - + std::vector nodeIdsFull = nodeIds; if (edgeIds.size() > 0) { for (const StorageEdge& storageEdge : m_sqliteStorage.getAllByIds(edgeIds)) { - parentNodeIds.insert(getLastVisibleParentNodeId(storageEdge.sourceNodeId)); - parentNodeIds.insert(getLastVisibleParentNodeId(storageEdge.targetNodeId)); + nodeIdsFull.push_back(storageEdge.sourceNodeId); + nodeIdsFull.push_back(storageEdge.targetNodeId); } } - std::vector allNodeIds; - std::vector allEdgeIds = edgeIds; + std::set parentNodeIds; + std::set nonIndexedNodeIds; + + for (Id nodeId : nodeIdsFull) + { + if (m_hierarchyCache.isIndexed(nodeId)) + { + parentNodeIds.insert(getLastVisibleParentNodeId(nodeId)); + } + else + { + nonIndexedNodeIds.insert(nodeId); + } + } + + std::set allNodeIds; + std::set allEdgeIds(edgeIds.begin(), edgeIds.end()); for (Id parentNodeId : parentNodeIds) { - allNodeIds.push_back(parentNodeId); + allNodeIds.insert(parentNodeId); m_hierarchyCache.addAllChildIdsForNodeId(parentNodeId, &allNodeIds, &allEdgeIds); } - addNodesToGraph(allNodeIds, graph); - addEdgesToGraph(allEdgeIds, graph); + for (Id nonIndexedNodeId : nonIndexedNodeIds) + { + m_hierarchyCache.addAllVisibleParentsAndChildIdsForNodeId(nonIndexedNodeId, &allNodeIds, &allEdgeIds); + } + + addNodesToGraph(utility::toVector(allNodeIds), graph); + addEdgesToGraph(utility::toVector(allEdgeIds), graph); } void PersistentStorage::addAggregationEdgesToGraph( @@ -1796,10 +1805,23 @@ void PersistentStorage::buildHierarchyCache() return Node::intToType(m_sqliteStorage.getFirstById(id).type); }); + Cache indexedNodeCache([this](Id id){ + StorageSymbol symbol = m_sqliteStorage.getFirstById(id); + if (symbol.id > 0) + { + return intToDefinitionKind(symbol.definitionKind) != DEFINITION_NONE; + } + return false; + }); + for (const StorageEdge& edge : memberEdges) { bool isVisible = !(nodeTypeCache.getValue(edge.sourceNodeId) & Node::NODE_NOT_VISIBLE); - m_hierarchyCache.createConnection(edge.id, edge.sourceNodeId, edge.targetNodeId, isVisible); + bool sourceIsIndexed = indexedNodeCache.getValue(edge.sourceNodeId); + bool targetIsIndexed = indexedNodeCache.getValue(edge.targetNodeId); + + m_hierarchyCache.createConnection( + edge.id, edge.sourceNodeId, edge.targetNodeId, isVisible, sourceIsIndexed, targetIsIndexed); } } diff --git a/src/lib/data/graph/Node.cpp b/src/lib/data/graph/Node.cpp index 33359963..b3ed60e6 100644 --- a/src/lib/data/graph/Node.cpp +++ b/src/lib/data/graph/Node.cpp @@ -12,7 +12,7 @@ #include "data/graph/token_component/TokenComponentFilePath.h" #include "data/graph/token_component/TokenComponentSignature.h" -const Node::NodeTypeMask Node::NODE_NOT_VISIBLE = Node::NODE_NON_INDEXED | Node::NODE_NAMESPACE | Node::NODE_PACKAGE; +const Node::NodeTypeMask Node::NODE_NOT_VISIBLE = Node::NODE_NAMESPACE | Node::NODE_PACKAGE; const Node::NodeTypeMask Node::NODE_USEABLE_TYPE = Node::NODE_NON_INDEXED | Node::NODE_BUILTIN_TYPE | Node::NODE_BUILTIN_TYPE | Node::NODE_STRUCT | Node::NODE_CLASS | Node::NODE_INTERFACE | Node::NODE_TYPEDEF;