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/graphwidget.h

214 lines
6.9 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.
*
***************************************************************************/
#ifndef GRAPHWIDGET_H
#define GRAPHWIDGET_H
#include <tqcanvas.h>
#include <tqpopupmenu.h>
#include <tqdict.h>
#include "cscopefrontend.h"
#include "graphnode.h"
#include "dotfrontend.h"
class ProgressDlg;
/**
* A widget that displays call tree graphs generated by graphviz.
* This class is based on a TQCanvasView widget, and displays two types of
* canvas items: GraphNode, which draws the name of a function inside a
* polygon, and ArrowEdge, which is a directed graph edge shaped like an
* arrow.
* The call tree graph is populated using the addNode() method. The first
* call creates a root node. Subsequent calls add nodes which represent either
* functions called by a previously inserted node, or that are calling such
* a node. A directed edge is created to depict the relationship between a
* node and its parent.
* Drawing is done through the embedded Agraph_t object (a graph, as defined
* by the graphviz libraray). When the draw() method is called, the graph is
* layed out in memory. The class then uses the CodeGenerator class to
* obtain a set of instructions on how to actually draw the graph. These
* instructions are used to create the appropriate canvas items.
* An application _must_ call GraphWidget::init() before attempting to use
* this class. It should also call GraphWidget::fini() when it no longer needs
* any of these widgets.
* @author Elad Lahav
*/
class GraphWidget : public TQCanvasView
{
Q_OBJECT
public:
GraphWidget(TQWidget* pParent = 0, const char* szName = 0);
~GraphWidget();
/**
* Information on a function call, as produced by a Cscope query.
* This structure is used for adding calls to the graph.
* @see addCall()
*/
struct CallData
{
/** The name of the calling function. */
TQString m_sCaller;
/** The name of the called function. */
TQString m_sCallee;
/** Path of the file in which the call appears. */
TQString m_sFile;
/** The line number of the call. */
TQString m_sLine;
/** The call's text. */
TQString m_sText;
};
/** Graph orientation values. */
enum Orientation { Portrait, Landscape };
void setRoot(const TQString&);
GraphNode* addNode(const TQString&, bool bMultiCall = false);
void addCall(const CallData&);
void addMultiCall(const TQString&, bool);
void draw();
void save(FILE*);
void save(const TQString&);
void zoom(bool);
void setZoom(double);
void rotate();
TQString getTip(const TQPoint&, TQRect&);
void resize(int, int);
void drawNode(const TQString&, const TQRect&);
void drawEdge(const TQString&, const TQString&, const TQPointArray&);
/**
* Adjusts the maximal number of calling/called functions shown for
* every node (@see m_nMaxNodeDegree).
* @param nMaxNodeDegree The new value to set
*/
void setMaxNodeDegree(int nMaxNodeDegree) { m_nMaxNodeDegree =
nMaxNodeDegree; }
static void setArrowInfo(int, int);
signals:
/**
* Emitted when the user makes a request to view the contents of a
* location in the source code.
* This can be the location of a call, the definition of a function,
* etc.
* @param sPath The full path of the file to show
* @param nLine The line number in this file
*/
void lineRequested(const TQString& sPath, uint nLine);
protected:
virtual void drawContents(TQPainter*, int, int, int, int);
virtual void contentsMousePressEvent(TQMouseEvent*);
private:
/** The graph is stored as a map of nodes indexed by their names.
Each node holds a list of outgoing edges. */
TQDict<GraphNode> m_dictNodes;
/** A Cscope process to use for running queries. */
CscopeFrontend* m_pCscope;
/** Displays query progress information. */
CscopeProgress m_progress;
/** A Dot process used to draw the graph. */
DotFrontend m_dot;
/** Remembers the function the was last queried for calling/called
functions. */
TQString m_sQueriedFunc;
/** Remembers whether the last query was for calling or called
functions. */
bool m_bCalled;
/** The node over which the popup menu has been invoked. */
TQCanvasPolygonalItem* m_pMenuItem;
/** A popup menu that appears when a node is right-clicked. */
TQPopupMenu* m_pNodePopup;
/** A popup menu that appears when a node is right-clicked. */
TQPopupMenu* m_pMultiCallPopup;
/** A popup menu that appears when an edge is right-clicked. */
TQPopupMenu* m_pEdgePopup;
/** The zoom factor for the graph. */
double m_dZoom;
/** Maximal number of in/out edges per node. If this number is exceeded,
the graph shows a single "multi-call" node. */
int m_nMaxNodeDegree;
/** Holds information used to draw arrow heads. */
static ArrowInfo s_ai;
/** Used for generating unique names for multi-call nodes. */
uint m_nMultiCallNum;
/** Holds the path of the temporary dot file used for drawing the graph. */
TQString m_sDrawFilePath;
/** Allows lengthy drawing operations to be cancelled. */
ProgressDlg* m_pProgressDlg;
void write(TQTextStream&, const TQString&, const TQString&, bool);
void removeEdges(GraphNode*, bool);
void removeDisconnected(GraphNode*);
void showNodeMenu(GraphNode*, const TQPoint&);
void showEdgeMenu(GraphEdge*, const TQPoint&);
private slots:
void slotDotFinished();
void slotDataReady(FrontendToken*);
void slotProgress(int, int);
void slotFinished(uint);
void slotAborted();
void slotShowCalled();
void slotListCalled();
void slotHideCalled();
void slotShowCalling();
void slotListCalling();
void slotHideCalling();
void slotFindDef();
void slotRemoveNode();
void slotMultiCallDetails();
void slotOpenCall();
};
#endif