From 3af5832abe7c802a384cd58d34f7cc4433595ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Mon, 7 Oct 2013 23:28:24 +0200 Subject: Initial import of kscope 1.6.2 --- src/graphnode.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/graphnode.cpp (limited to 'src/graphnode.cpp') diff --git a/src/graphnode.cpp b/src/graphnode.cpp new file mode 100644 index 0000000..28a219d --- /dev/null +++ b/src/graphnode.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#include +#include +#include "graphnode.h" + +int GraphNode::RTTI = 1001; + +/** + * Class constructor. + * @param pCanvas The owner canvas + * @param sFunc The node's function + * @param bMultiCall Whether this node represents multiple calls + */ +GraphNode::GraphNode(QCanvas* pCanvas, const QString& sFunc, bool bMultiCall) : + QCanvasPolygon(pCanvas), + m_sFunc(sFunc), + m_bMultiCall(bMultiCall), + m_bDfsFlag(false) +{ + // Every node deletes its out-edges only + m_dictOutEdges.setAutoDelete(true); +} + +/** + * Class destructor. + */ +GraphNode::~GraphNode() +{ +} + +/** + * Finds an edge leaving this node and reaching the given node. + * If such an edge does not exist, a new one is created. + * @param pTail The destination node + * @return The edge that ends at the given node + */ +GraphEdge* GraphNode::addOutEdge(GraphNode* pTail) +{ + GraphEdge* pEdge; + + // Look for the edge + if ((pEdge = m_dictOutEdges.find(pTail->getFunc())) == NULL) { + // Create a new edge + pEdge = new GraphEdge(canvas(), this, pTail); + m_dictOutEdges.insert(pTail->getFunc(), pEdge); + pTail->m_dictInEdges.replace(m_sFunc, pEdge); + } + + // Return the new/constructed edge + return pEdge; +} + +/** + * Performs a weak depth-first-search on the graph. + * The search continues along all edges, both incoming and outgoing. + */ +void GraphNode::dfs() +{ + // Stop if this node is already marked + if (m_bDfsFlag) + return; + + // Mark the node as visited + m_bDfsFlag = true; + + // Continue along outgoing edges + QDictIterator itrOut(m_dictOutEdges); + for (; itrOut.current(); ++itrOut) + (*itrOut)->getTail()->dfs(); + + // Continue along incoming edges + QDictIterator itrIn(m_dictInEdges); + for (; itrIn.current(); ++itrIn) + (*itrIn)->getHead()->dfs(); +} + +/** + * Deletes all outgoing edges. + * Uses the auto-delete property of the dictionary. + */ +void GraphNode::removeOutEdges() +{ + m_dictOutEdges.clear(); +} + +/** + * Deletes all incoming edges. + * To avoid double deletions, the function lets the head node of the edge remove + * it. + */ +void GraphNode::removeInEdges() +{ + QDictIterator itr(m_dictInEdges); + + // Delete edges through their head nodes + for (; itr.current(); ++itr) + (*itr)->getHead()->m_dictOutEdges.remove(m_sFunc); + + // remove edges from the local dictionary (will not delete them) + m_dictInEdges.clear(); +} + +/** + * Returns the first found node connected to this one. + * This function is used with multi-call nodes for retrieving the parent node. + * @param pNode + * @param bCalled + */ +void GraphNode::getFirstNeighbour(GraphNode*& pNode, bool& bCalled) +{ + QDictIterator itrIn(m_dictInEdges); + QDictIterator itrOut(m_dictOutEdges); + + if (itrIn.current()) { + pNode = itrIn.current()->getHead(); + bCalled = false; + } + else if (itrOut.current()) { + pNode = itrOut.current()->getTail(); + bCalled = true; + } + else { + pNode = NULL; + } +} + +/** + * Modifies the bounding rectangle of the node. + * @param rect The new coordinates to set + */ +void GraphNode::setRect(const QRect& rect) +{ + QPointArray arr(4); + + m_rect = rect; + + arr.setPoint(0, m_rect.topLeft()); + arr.setPoint(1, m_rect.topRight()); + arr.setPoint(2, m_rect.bottomRight()); + arr.setPoint(3, m_rect.bottomLeft()); + setPoints(arr); +} + +/** + * Draws the node. + * @param painter Used for drawing the item on the canvas view + */ +void GraphNode::drawShape(QPainter& painter) +{ + const QPen& pen = painter.pen(); + const QFont& font = painter.font(); + + // Draw the rectangle + painter.setPen(QPen(Qt::black)); + painter.drawRect(m_rect); + + // Draw the text + painter.setPen(pen); + painter.setFont(m_font); + if (m_bMultiCall) + painter.drawText(m_rect, Qt::AlignCenter, "..."); + else + painter.drawText(m_rect, Qt::AlignCenter, m_sFunc); + + painter.setFont(font); +} -- cgit v1.2.1