1 /*
2  * Copyright Johannes Sixt
3  * This file is licensed under the GNU General Public License Version 2.
4  * See the file COPYING in the toplevel directory of the source directory.
5  */
6 
7 #ifndef SOURCEWND_H
8 #define SOURCEWND_H
9 
10 #include <QPixmap>
11 #include <QPlainTextEdit>
12 #include <QSyntaxHighlighter>
13 #include <vector>
14 #include "dbgdriver.h"
15 
16 // forward declarations
17 class KDebugger;
18 struct DbgAddr;
19 class LineInfoArea;
20 class HighlightCpp;
21 
22 class SourceWindow : public QPlainTextEdit
23 {
24     Q_OBJECT
25 public:
26     SourceWindow(const QString& fileName, QWidget* parent);
27     ~SourceWindow();
28 
29     bool loadFile();
30     void reloadFile();
31     bool fileNameMatches(const QString& other);
32     void scrollTo(int lineNo, const DbgAddr& address);
fileName()33     const QString& fileName() const { return m_fileName; }
34     void updateLineItems(const KDebugger* dbg);
35     void setPC(bool set, int lineNo, const DbgAddr& address, int frameNo);
36     enum FindDirection { findForward = 1, findBackward = -1 };
37     void find(const QString& text, bool caseSensitive, FindDirection dir);
38     bool wordAtPoint(const QPoint& p, QString& word, QRect& r);
39     /**
40      * Translates row number (zero-based) to zero-based source line number.
41      * If sourceRow is non-zero, it is filled with the source code row
42      * belonging to the line number.
43      */
44     int rowToLine(int row, int* sourceRow = 0);
45     /** Translates zero-based source line number to row number (zero-based) */
46     int lineToRow(int line);
47     /** Is the row disassembled? */
48     bool isRowExpanded(int row);
49     /** Does the row show disassembled code? */
50     bool isRowDisassCode(int row);
51 
52     /** lineNo is zero-based */
53     void disassembled(int lineNo, const std::list<DisassembledCode>& disass);
54 
55     void activeLine(int& lineNo, DbgAddr& address);
56 
57     static QString extendExpr(const QString &plainText,
58                               int            wordStart,
59                               int            wordEnd);
60 protected:
61     void drawLineInfoArea(QPainter* p, QPaintEvent* event);
62     void infoMousePress(QMouseEvent* ev);
63     virtual void resizeEvent(QResizeEvent* e);
64     virtual void contextMenuEvent(QContextMenuEvent* e);
65     virtual void keyPressEvent(QKeyEvent* ev);
66     virtual void changeEvent(QEvent* ev);
67     void expandRow(int row);
68     void collapseRow(int row);
69     void scrollToRow(int row);
70     /** translates (0-based) line number plus a code address into a row number */
71     int lineToRow(int row, const DbgAddr& address);
72     int lineInfoAreaWidth() const;
73 
74     void actionExpandRow(int row);
75     void actionCollapseRow(int row);
76 
77 signals:
78     void clickedLeft(const QString&, int, const DbgAddr& address, bool);
79     void clickedMid(const QString&, int, const DbgAddr& address);
80     void disassemble(const QString&, int);
81     void expanded(int lineNo);		/* source lineNo has been expanded */
82     void collapsed(int lineNo);		/* source lineNo has been collapsed */
83 public slots:
84     void setTabWidth(int numChars);
85     void cursorChanged();
86 
87 protected:
88     QString m_fileName;
89     enum LineItem { liPC = 1, liPCup = 2,
90 	liBP = 4, liBPdisabled = 8, liBPtemporary = 16,
91 	liBPconditional = 32, liBPorphan = 64,
92 	liBPany = liBP|liBPdisabled|liBPtemporary|liBPconditional|liBPorphan
93     };
94 
95     struct SourceLine {
96 	std::vector<QString> disass;		/* its disassembled code */
97 	std::vector<DbgAddr> disassAddr;	/* the addresses thereof */
98 	bool canDisass;			/* if line can be disassembled */
SourceLineSourceLine99 	SourceLine() : canDisass(true) { }
100 	int findAddressRowOffset(const DbgAddr& address) const;
101     };
102     std::vector<SourceLine> m_sourceCode;
103     HighlightCpp* m_highlighter;
104 
105     std::vector<int> m_rowToLine;	//!< The source line number for each row
106     std::vector<uchar> m_lineItems;	//!< Icons displayed on the line
107     QPixmap m_pcinner;			/* PC at innermost frame */
108     QPixmap m_pcup;			/* PC at frame up the stack */
109     QPixmap m_brkena;			/* enabled breakpoint */
110     QPixmap m_brkdis;			/* disabled breakpoint */
111     QPixmap m_brktmp;			/* temporary breakpoint marker */
112     QPixmap m_brkcond;			/* conditional breakpoint marker */
113     QPixmap m_brkorph;			/* orphaned breakpoint marker */
114     QFont m_lineNoFont;			//!< The font used to draw line numbers
115     int m_widthItems;			//!< The width of the item column
116     int m_widthPlus;			//!< The width of the expander column
117     int m_widthLineNo;			//!< The width of the line number columns
118     LineInfoArea* m_lineInfoArea;
119 
120     friend class LineInfoArea;
121 };
122 
123 class LineInfoArea : public QWidget
124 {
125 public:
LineInfoArea(QWidget * parent)126     LineInfoArea(QWidget* parent) : QWidget(parent) { }
127     virtual void paintEvent(QPaintEvent* e);
128     virtual void mousePressEvent(QMouseEvent* ev);
129     virtual void contextMenuEvent(QContextMenuEvent* e);
130 };
131 
132 class HighlightCpp : public QSyntaxHighlighter
133 {
134     SourceWindow* m_srcWnd;
135 
136 public:
137     HighlightCpp(SourceWindow* srcWnd);
138     virtual void highlightBlock(const QString& text);
139     int highlight(const QString& text, int state);
140 
141     static bool isCppKeyword(const QString& word);
142 };
143 
144 #endif // SOURCEWND_H
145