diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index fc15435c..4374b9d7 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -150,6 +150,39 @@ void GraphController::handleMessage(MessageGraphNodeExpand* message) DummyNode* node = getDummyGraphNodeById(message->tokenId); if (node) { + if (!node->active && message->expand) + { + for (size_t i = 0, l = m_dummyEdges.size(); i < l; i++) + { + std::shared_ptr edge = m_dummyEdges[i]; + + if (edge && edge->data && edge->data->isType(Edge::EDGE_AGGREGATION) && + (edge->targetId == node->tokenId || edge->ownerId == node->tokenId)) + { + std::vector aggregationIds = + utility::toVector(edge->data->getComponent()->getAggregationIds()); + + if (m_graph->getEdgeById(aggregationIds[0]) != nullptr) + { + break; + } + + std::shared_ptr graph = m_storageAccess->getGraphForActiveTokenIds(aggregationIds); + + graph->forEachEdge( + [this](Edge* e) + { + if (!e->isType(Edge::EDGE_MEMBER)) + { + m_dummyEdges.push_back(std::make_shared( + e->getFrom()->getId(), e->getTo()->getId(), m_graph->addEdgeAsPlainCopy(e))); + } + } + ); + } + } + } + node->expanded = message->expand; setActiveAndVisibility(utility::concat(m_activeNodeIds, m_activeEdgeIds)); diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index b4d1d608..aa17d4b1 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -799,7 +799,8 @@ std::shared_ptr PersistentStorage::getGraphForActiveTokenIds(const std::v continue; } - if ((nodeType & Node::NODE_USEABLE_TYPE) && (edgeType & Edge::EDGE_TYPE_USAGE)) + if ((nodeType & Node::NODE_USEABLE_TYPE) && (edgeType & Edge::EDGE_TYPE_USAGE) && + m_hierarchyCache.isChildOfVisibleNodeOrInvisible(edge.sourceNodeId)) { edgesToAggregate.push_back(edge); } @@ -1661,13 +1662,10 @@ void PersistentStorage::addAggregationEdgesToGraph( componentAggregation->addAggregationId(edgeInfo.edgeId, edgeInfo.forward); } - Edge* edge = graph->createEdge( - *componentAggregation->getAggregationIds().begin(), - Edge::EDGE_AGGREGATION, - sourceNode, - targetNode - ); + // Set first bit to 1 to avoid collisions + Id aggregationId = ~(~size_t(0) >> 1) + *componentAggregation->getAggregationIds().begin(); + Edge* edge = graph->createEdge(aggregationId, Edge::EDGE_AGGREGATION, sourceNode, targetNode); edge->addComponentAggregation(componentAggregation); } } diff --git a/src/lib_gui/qt/view/QtGraphView.cpp b/src/lib_gui/qt/view/QtGraphView.cpp index 4fdb0dc5..a1e84b1c 100644 --- a/src/lib_gui/qt/view/QtGraphView.cpp +++ b/src/lib_gui/qt/view/QtGraphView.cpp @@ -253,14 +253,23 @@ void QtGraphView::doRebuildGraph( } m_edges.clear(); - for (unsigned int i = 0; i < edges.size(); i++) + + std::set visibleEdgeIds; + for (std::shared_ptr edge : edges) { - std::shared_ptr edge = createEdge(view, edges[i].get()); - if (edge) + if (!edge->data || !edge->data->isType(Edge::EDGE_AGGREGATION)) { - m_edges.push_back(edge); + createEdge(view, edge.get(), &visibleEdgeIds); } } + for (std::shared_ptr edge : edges) + { + if (edge->data && edge->data->isType(Edge::EDGE_AGGREGATION)) + { + createAggregationEdge(view, edge.get(), &visibleEdgeIds); + } + } + if (graph) { @@ -341,7 +350,8 @@ std::shared_ptr QtGraphView::createNodeRecursive( std::shared_ptr newNode; if (node->isGraphNode()) { - newNode = std::make_shared(node->data, node->name, node->hasParent, node->childVisible, node->hasQualifier); + newNode = std::make_shared( + node->data, node->name, node->hasParent, node->childVisible, node->hasQualifier); } else if (node->isAccessNode()) { @@ -397,7 +407,8 @@ std::shared_ptr QtGraphView::createNodeRecursive( return newNode; } -std::shared_ptr QtGraphView::createEdge(QGraphicsView* view, const DummyEdge* edge) +std::shared_ptr QtGraphView::createEdge( + QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds) { if (!edge->visible) { @@ -417,12 +428,46 @@ std::shared_ptr QtGraphView::createEdge(QGraphicsView* view, const view->scene()->addItem(qtEdge.get()); + if (edge->data) + { + visibleEdgeIds->insert(edge->data->getId()); + } + + m_edges.push_back(qtEdge); + return qtEdge; } return NULL; } +std::shared_ptr QtGraphView::createAggregationEdge( + QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds) +{ + if (!edge->visible) + { + return NULL; + } + + bool allVisible = true; + std::set aggregationIds = edge->data->getComponent()->getAggregationIds(); + for (Id edgeId : aggregationIds) + { + if (visibleEdgeIds->find(edgeId) == visibleEdgeIds->end()) + { + allVisible = false; + break; + } + } + + if (allVisible) + { + return NULL; + } + + return createEdge(view, edge, visibleEdgeIds); +} + QRectF QtGraphView::itemsBoundingRect(const std::list>& items) const { QRectF boundingRect; @@ -459,7 +504,8 @@ void QtGraphView::compareNodesRecursive( ((*it)->isBundleNode() && (*it2)->isBundleNode() && (*it)->getTokenId() == (*it2)->getTokenId())) { remainingNodes->push_back(std::pair((*it).get(), (*it2).get())); - compareNodesRecursive((*it)->getSubNodes(), (*it2)->getSubNodes(), appearingNodes, vanishingNodes, remainingNodes); + compareNodesRecursive( + (*it)->getSubNodes(), (*it2)->getSubNodes(), appearingNodes, vanishingNodes, remainingNodes); oldSubNodes.erase(it2); remains = true; diff --git a/src/lib_gui/qt/view/QtGraphView.h b/src/lib_gui/qt/view/QtGraphView.h index d9b0b5a6..99fe4362 100644 --- a/src/lib_gui/qt/view/QtGraphView.h +++ b/src/lib_gui/qt/view/QtGraphView.h @@ -1,6 +1,8 @@ #ifndef QT_GRAPH_VIEW_H #define QT_GRAPH_VIEW_H +#include + #include #include @@ -72,7 +74,9 @@ private: std::shared_ptr createNodeRecursive( QGraphicsView* view, std::shared_ptr parentNode, const DummyNode* node, bool multipleActive); - std::shared_ptr createEdge(QGraphicsView* view, const DummyEdge* edge); + std::shared_ptr createEdge(QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds); + std::shared_ptr createAggregationEdge( + QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds); QRectF itemsBoundingRect(const std::list>& items) const; QRectF getSceneRect(const std::list>& items) const;