diff options
Diffstat (limited to 'src/graphwidget.h')
-rw-r--r-- | src/graphwidget.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/graphwidget.h b/src/graphwidget.h new file mode 100644 index 0000000..119ddbb --- /dev/null +++ b/src/graphwidget.h @@ -0,0 +1,213 @@ +/*************************************************************************** + * + * 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 <qcanvas.h> +#include <qpopupmenu.h> +#include <qdict.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 QCanvasView 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 QCanvasView +{ + Q_OBJECT + +public: + GraphWidget(QWidget* 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. */ + QString m_sCaller; + + /** The name of the called function. */ + QString m_sCallee; + + /** Path of the file in which the call appears. */ + QString m_sFile; + + /** The line number of the call. */ + QString m_sLine; + + /** The call's text. */ + QString m_sText; + }; + + /** Graph orientation values. */ + enum Orientation { Portrait, Landscape }; + + void setRoot(const QString&); + GraphNode* addNode(const QString&, bool bMultiCall = false); + void addCall(const CallData&); + void addMultiCall(const QString&, bool); + void draw(); + void save(FILE*); + void save(const QString&); + void zoom(bool); + void setZoom(double); + void rotate(); + QString getTip(const QPoint&, QRect&); + + void resize(int, int); + void drawNode(const QString&, const QRect&); + void drawEdge(const QString&, const QString&, const QPointArray&); + + /** + * 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 QString& sPath, uint nLine); + +protected: + virtual void drawContents(QPainter*, int, int, int, int); + virtual void contentsMousePressEvent(QMouseEvent*); + +private: + /** The graph is stored as a map of nodes indexed by their names. + Each node holds a list of outgoing edges. */ + QDict<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. */ + QString 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. */ + QCanvasPolygonalItem* m_pMenuItem; + + /** A popup menu that appears when a node is right-clicked. */ + QPopupMenu* m_pNodePopup; + + /** A popup menu that appears when a node is right-clicked. */ + QPopupMenu* m_pMultiCallPopup; + + /** A popup menu that appears when an edge is right-clicked. */ + QPopupMenu* 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. */ + QString m_sDrawFilePath; + + /** Allows lengthy drawing operations to be cancelled. */ + ProgressDlg* m_pProgressDlg; + + void write(QTextStream&, const QString&, const QString&, bool); + void removeEdges(GraphNode*, bool); + void removeDisconnected(GraphNode*); + void showNodeMenu(GraphNode*, const QPoint&); + void showEdgeMenu(GraphEdge*, const QPoint&); + +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 |