forked from Vector35/binaryninja-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtokenizedtextwidget.h
254 lines (210 loc) · 8.8 KB
/
tokenizedtextwidget.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#pragma once
#include <QtWidgets/QAbstractScrollArea>
#include <QtCore/QTimer>
#include <optional>
#include "binaryninjaapi.h"
#include "viewframe.h"
#include "render.h"
#include "commentdialog.h"
#include "menus.h"
#include "uicontext.h"
/*!
\defgroup tokenizedtextwidget TokenizedTextWidget
\ingroup uiapi
*/
/*!
\ingroup tokenizedtextwidget
*/
enum BINARYNINJAUIAPI TokenizedTextWidgetSelectionStyle
{
NoSelection = 1 << 0,
SelectLines = 1 << 1,
SelectOneToken = 1 << 2,
SelectTokens = 1 << 3,
SelectCharacters = 1 << 4,
AllStyles = NoSelection | SelectLines | SelectOneToken | SelectTokens | SelectCharacters,
};
/*!
\ingroup tokenizedtextwidget
*/
struct BINARYNINJAUIAPI TokenizedTextWidgetCursorPosition
{
/// Index of line in widget
size_t lineIndex = BN_INVALID_OPERAND;
/// Index of token in current line
size_t tokenIndex = BN_INVALID_OPERAND;
/// Index of character in current token
size_t characterIndex = BN_INVALID_OPERAND;
// Directly from QMouseEvent, not used in comparator
int cursorX;
int cursorY;
bool isValid() const { return lineIndex != BN_INVALID_OPERAND; }
bool operator==(const TokenizedTextWidgetCursorPosition& other) const;
bool operator!=(const TokenizedTextWidgetCursorPosition& other) const { return !(*this == other); }
bool operator<(const TokenizedTextWidgetCursorPosition& other) const;
};
/*!
QWidget that displays lines of InstructionTextTokens with the ability to make selections
\ingroup tokenizedtextwidget
*/
class BINARYNINJAUIAPI TokenizedTextWidget :
public QAbstractScrollArea
{
protected:
struct LineMetadata
{
size_t charWidth;
int copyStyles;
LineMetadata():
charWidth(0),
copyStyles(TokenizedTextWidgetSelectionStyle::AllStyles)
{}
};
struct TokenMetadata
{
size_t charOffset;
int copyStyles;
bool selectLineTarget;
TokenMetadata():
charOffset(0),
copyStyles(TokenizedTextWidgetSelectionStyle::AllStyles),
selectLineTarget(false)
{}
};
private:
Q_OBJECT
UIActionHandler m_actionHandler;
ContextMenuManager* m_contextMenuManager;
Menu m_contextMenu;
RenderContext m_render;
int m_cols, m_rows;
int m_contentsCols, m_contentsRows;
int m_verticalWheelDelta, m_horizontalWheelDelta;
bool m_updatingScrollBar;
bool m_autoScrollHorizontal, m_autoScrollVertical;
TokenizedTextWidgetCursorPosition m_cursorPos, m_selectionStartPos, m_hoverPos;
TokenizedTextWidgetSelectionStyle m_selectionMode;
size_t m_hoverLine;
bool m_selectionStartedPastWidth;
bool m_selectionStartedPastHeight;
bool m_cursorKeys;
bool m_forceLineSelect;
std::vector<BinaryNinja::LinearDisassemblyLine> m_lines;
std::vector<LineMetadata> m_lineMetadata;
std::vector<std::vector<TokenMetadata>> m_tokenMetadata;
DisassemblySettingsRef m_settings;
void adjustSize(int width, int height);
void clampCursorPosition(TokenizedTextWidgetCursorPosition& pos);
void clampSelectionToValid();
protected:
virtual void updateMetadata(const std::vector<BinaryNinja::LinearDisassemblyLine>& lines, int& width, int& height);
private Q_SLOTS:
void verticalScrollBarMoved(int value);
void verticalScrollBarAction(int action);
void horizontalScrollBarMoved(int value);
void horizontalScrollBarAction(int action);
public:
explicit TokenizedTextWidget(QWidget* parent,
const std::vector<BinaryNinja::LinearDisassemblyLine>& lines =
std::vector<BinaryNinja::LinearDisassemblyLine>());
virtual ~TokenizedTextWidget();
void bindActions();
QFont font() const;
void setFont(const QFont& font);
DisassemblySettingsRef settings() { return m_settings; }
const DisassemblySettingsRef& settings() const { return m_settings; }
int topLineIndex() const;
int leftmostCharIndex() const;
int visibleColumnCount() const { return m_cols; }
int visibleRowCount() const { return m_rows; }
int contentsColumnCount() const { return m_contentsCols; }
int contentsRowCount() const { return m_contentsRows; }
bool hasSelection() const;
// Lines vs Tokens vs Characters vs NoSelection
TokenizedTextWidgetSelectionStyle selectionStyle() const;
// Lower bound of selection
TokenizedTextWidgetCursorPosition selectionBegin() const;
// Upper bound of selection
TokenizedTextWidgetCursorPosition selectionEnd() const;
// Originally highlighted selection base
TokenizedTextWidgetCursorPosition selectionBase() const;
// Position of cursor for movement operations
TokenizedTextWidgetCursorPosition cursorPosition() const;
bool forceLineSelect() const { return m_forceLineSelect; }
void setForceLineSelect(bool value) { m_forceLineSelect = value; }
void setSelection(TokenizedTextWidgetCursorPosition base, TokenizedTextWidgetCursorPosition cursor, TokenizedTextWidgetSelectionStyle mode);
void setCursorPosition(TokenizedTextWidgetCursorPosition newPosition, bool selecting, bool cursorKeys, bool evenIfNoChange);
void moveCursorHorizontal(int count, bool allTheWay, bool selecting, bool cursorKeys);
void moveCursorVertical(int count, bool allTheWay, bool selecting, bool cursorKeys);
bool autoScrollHorizontal() const { return m_autoScrollHorizontal; }
void setAutoScrollHorizontal(bool value) { m_autoScrollHorizontal = value; }
bool autoScrollVertical() const { return m_autoScrollVertical; }
void setAutoScrollVertical(bool value) { m_autoScrollVertical = value; }
HighlightTokenState highlightTokenState();
UIActionHandler* actionHandler() { return &m_actionHandler; }
virtual UIActionContext actionContext();
Menu& contextMenu() { return m_contextMenu; }
void showContextMenu();
void left(size_t count, bool selecting);
void right(size_t count, bool selecting);
void leftToWord(bool selecting);
void rightToWord(bool selecting);
void up(bool selecting);
void down(bool selecting);
void pageUp(bool selecting);
void pageDown(bool selecting);
void moveToStartOfLine(bool selecting);
void moveToEndOfLine(bool selecting);
void moveToStartOfView(bool selecting);
void moveToEndOfView(bool selecting);
void selectAll();
void selectNone();
void scrollLines(int count);
void scrollLineToVisible(int lineIndex);
void scrollLineToTop(int lineIndex);
void scrollChars(int count);
void scrollCharToVisible(int charIndex);
void scrollCharToLeftmost(int charIndex);
void copy() const;
std::string selectedText() const;
const std::vector<BinaryNinja::LinearDisassemblyLine>& lines() const { return m_lines; }
std::optional<std::reference_wrapper<const BinaryNinja::LinearDisassemblyLine>> lineAtPosition(const TokenizedTextWidgetCursorPosition& position) const;
std::optional<std::reference_wrapper<const BinaryNinja::InstructionTextToken>> tokenAtPosition(const TokenizedTextWidgetCursorPosition& position) const;
std::optional<char> charAtPosition(const TokenizedTextWidgetCursorPosition& position) const;
void clearLines();
void setLines(const std::vector<BinaryNinja::LinearDisassemblyLine>& lines, bool resetScroll = true);
void setLines(const std::vector<BinaryNinja::DisassemblyTextLine>& lines, bool resetScroll = true);
void setLines(const std::vector<BinaryNinja::TypeDefinitionLine>& lines, bool resetScroll = true);
int lineCopyStyles(size_t lineIndex) const;
void setLineCopyStyles(size_t lineIndex, int styles);
int tokenCopyStyles(size_t lineIndex, size_t tokenIndex) const;
void setTokenCopyStyles(size_t lineIndex, size_t tokenIndex, int styles);
bool tokenSelectLineTarget(size_t lineIndex, size_t tokenIndex) const;
void setTokenSelectLineTarget(size_t lineIndex, size_t tokenIndex, bool selectLineTarget);
Q_SIGNALS:
void sizeChanged(int cols, int rows);
void visibleChanged(int leftCol, int topRow);
void linesChanged();
void selectionChanged(const TokenizedTextWidgetCursorPosition& begin, const TokenizedTextWidgetCursorPosition& end);
void tokenLeftClicked(const TokenizedTextWidgetCursorPosition& position);
void tokenRightClicked(const TokenizedTextWidgetCursorPosition& position);
void tokenDoubleClicked(const TokenizedTextWidgetCursorPosition& position);
void tokenOtherClicked(const TokenizedTextWidgetCursorPosition& position, Qt::MouseButton button);
void tokenHovered(const TokenizedTextWidgetCursorPosition& position);
void lineLeftClicked(size_t lineIndex);
void lineRightClicked(size_t lineIndex);
void lineDoubleClicked(size_t lineIndex);
void lineOtherClicked(size_t lineIndex, Qt::MouseButton button);
void lineHovered(size_t lineIndex);
protected:
virtual void resizeEvent(QResizeEvent* event) override;
virtual void paintEvent(QPaintEvent* event) override;
virtual void wheelEvent(QWheelEvent* event) override;
virtual void mousePressEvent(QMouseEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
virtual void leaveEvent(QEvent* event) override;
virtual void focusInEvent(QFocusEvent* event) override;
virtual void focusOutEvent(QFocusEvent* event) override;
virtual void contextMenuEvent(QContextMenuEvent* event) override;
};