You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kscope/src/graphnode.cpp

193 lines
5.2 KiB

/***************************************************************************
*
* 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 <tqpainter.h>
#include <tqfontmetrics.h>
#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(TQCanvas* pCanvas, const TQString& sFunc, bool bMultiCall) :
TQCanvasPolygon(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
TQDictIterator<GraphEdge> itrOut(m_dictOutEdges);
for (; itrOut.current(); ++itrOut)
(*itrOut)->getTail()->dfs();
// Continue along incoming edges
TQDictIterator<GraphEdge> 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()
{
TQDictIterator<GraphEdge> 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)
{
TQDictIterator<GraphEdge> itrIn(m_dictInEdges);
TQDictIterator<GraphEdge> 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 TQRect& rect)
{
TQPointArray 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(TQPainter& painter)
{
const TQPen& pen = painter.pen();
const TQFont& font = painter.font();
// Draw the rectangle
painter.setPen(TQPen(TQt::black));
painter.drawRect(m_rect);
// Draw the text
painter.setPen(pen);
painter.setFont(m_font);
if (m_bMultiCall)
painter.drawText(m_rect, TQt::AlignCenter, "...");
else
painter.drawText(m_rect, TQt::AlignCenter, m_sFunc);
painter.setFont(font);
}