summaryrefslogtreecommitdiff
path: root/ui/scriptingconsole.h
blob: 4059df2a62501d994c891a72330b12633a38e9d3 (plain)
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
#pragma once

#include <QtCore/QTimer>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QWidget>
#include <mutex>
#include <string>
#include <utility>
#include <vector>
#include "binaryninjaapi.h"
#include "action.h"
#include "dockhandler.h"
#include "uitypes.h"

#define SCRIPT_OUTPUT_UPDATE_INTERVAL 100
#define SCRIPT_HISTORY_LENGTH 100

class ScriptingConsole;

class BINARYNINJAUIAPI ScriptingConsoleEdit: public QTextEdit
{
	Q_OBJECT

	ScriptingConsole* m_console;
	int m_charHeight;
	bool m_continuation;

public:
	ScriptingConsoleEdit(ScriptingConsole* parent);
	void setCharHeight(int height);
	void setContinutation(bool cont);

protected:
	virtual void keyPressEvent(QKeyEvent* event) override;
};

class BINARYNINJAUIAPI ScriptingConsoleOutput: public QTextEdit
{
	Q_OBJECT

	ScriptingConsole* m_console;
	QAction* m_outputActionClear;

public:
	ScriptingConsoleOutput(ScriptingConsole* parent);

protected:
	virtual void contextMenuEvent(QContextMenuEvent *event) override;
};

class ScriptingConsoleWidget;

class BINARYNINJAUIAPI ScriptingConsole: public QWidget, public DockContextHandler, BinaryNinja::ScriptingOutputListener
{
	Q_OBJECT

	struct ScriptOutput
	{
		std::string text;
		bool isError;
	};

	QString m_providerName;
	QString m_instanceName;
	ScriptingInstanceRef m_instance;
	ScriptingConsoleOutput* m_output;
	ScriptingConsoleEdit* m_input;
	QLabel* m_prompt;
	QPushButton* m_button;
	QTimer* m_runTimer;

	std::mutex m_mutex;
	std::vector<ScriptOutput> m_pendingOutput;
	QTimer* m_updateTimer;

	BNScriptingProviderInputReadyState m_currentState;

	QStringList m_history;
	QString m_inputOutsideHistory;
	int m_currentHistoryEntry;

	static int m_stateUpdatedEventType;

private Q_SLOTS:
	void updateTimerEvent();
	void cancel();
	void showCancelButton();

protected:
	void customEvent(QEvent* event) override;
	void focusInput() override;
	void updateFonts() override;

public:
	ScriptingConsole(QWidget* parent, const QString& providerName, const QString& instanceName, ScriptingInstanceRef instance);
	virtual ~ScriptingConsole();

	QString getProviderName() const { return m_providerName; }
	QString getInstanceName() const { return m_instanceName; }
	ScriptingInstanceRef getInstance() { return m_instance; }

	void clearConsole();
	void hideConsole();

	void addInput(const std::string& text);

	virtual void NotifyOutput(const std::string& text) override;
	virtual void NotifyError(const std::string& text) override;
	virtual void NotifyInputReadyStateChanged(BNScriptingProviderInputReadyState state) override;

	void moveUpInHistory();
	void moveDownInHistory();
};