rpcconsole.h raw
1 // Copyright (c) 2011-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #ifndef BITCOIN_QT_RPCCONSOLE_H
6 #define BITCOIN_QT_RPCCONSOLE_H
7
8 #include <bitcoin-build-config.h> // IWYU pragma: keep
9
10 #include <qt/clientmodel.h>
11 #include <qt/guiutil.h>
12 #include <qt/peertablemodel.h>
13
14 #include <net.h>
15
16 #include <QByteArray>
17 #include <QCompleter>
18 #include <QMimeData>
19 #include <QTextDocumentFragment>
20 #include <QTextEdit>
21 #include <QThread>
22 #include <QWidget>
23
24 class PlatformStyle;
25 class RPCExecutor;
26 class WalletModel;
27
28 namespace interfaces {
29 class Node;
30 }
31
32 namespace Ui {
33 class RPCConsole;
34 }
35
36 QT_BEGIN_NAMESPACE
37 class QDateTime;
38 class QMenu;
39 class QItemSelection;
40 QT_END_NAMESPACE
41
42 /** Local Bitcoin RPC console. */
43 class RPCConsole: public QWidget
44 {
45 Q_OBJECT
46
47 public:
48 explicit RPCConsole(interfaces::Node& node, const PlatformStyle *platformStyle, QWidget *parent);
49 ~RPCConsole();
50
51 static bool RPCParseCommandLine(interfaces::Node* node, std::string& strResult, const std::string& strCommand, bool fExecute, std::string* pstrFilteredOut = nullptr, const QString& wallet_name = {});
52 static bool RPCExecuteCommandLine(interfaces::Node& node, std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const QString& wallet_name = {}) {
53 return RPCParseCommandLine(&node, strResult, strCommand, true, pstrFilteredOut, wallet_name);
54 }
55
56 void setClientModel(ClientModel *model = nullptr, int bestblock_height = 0, int64_t bestblock_date = 0, double verification_progress = 0.0);
57
58 #ifdef ENABLE_WALLET
59 void addWallet(WalletModel* walletModel);
60 void removeWallet(WalletModel* walletModel);
61 #endif // ENABLE_WALLET
62
63 enum MessageClass {
64 MC_ERROR,
65 MC_DEBUG,
66 CMD_REQUEST,
67 CMD_REPLY,
68 CMD_ERROR
69 };
70
71 enum class TabTypes {
72 INFO,
73 CONSOLE,
74 GRAPH,
75 PEERS
76 };
77
78 std::vector<TabTypes> tabs() const { return {TabTypes::INFO, TabTypes::CONSOLE, TabTypes::GRAPH, TabTypes::PEERS}; }
79
80 QString tabTitle(TabTypes tab_type) const;
81 QKeySequence tabShortcut(TabTypes tab_type) const;
82
83 protected:
84 virtual bool eventFilter(QObject* obj, QEvent *event) override;
85 void keyPressEvent(QKeyEvent *) override;
86 void changeEvent(QEvent* e) override;
87
88 private Q_SLOTS:
89 void on_lineEdit_returnPressed();
90 void on_tabWidget_currentChanged(int index);
91 /** open the debug.log from the current datadir */
92 void on_openDebugLogfileButton_clicked();
93 /** change the time range of the network traffic graph */
94 void on_sldGraphRange_valueChanged(int value);
95 /** update traffic statistics */
96 void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut);
97 void resizeEvent(QResizeEvent *event) override;
98 void showEvent(QShowEvent *event) override;
99 void hideEvent(QHideEvent *event) override;
100 /** Show custom context menu on Peers tab */
101 void showPeersTableContextMenu(const QPoint& point);
102 /** Show custom context menu on Bans tab */
103 void showBanTableContextMenu(const QPoint& point);
104 /** Hides ban table if no bans are present */
105 void showOrHideBanTableIfRequired();
106 /** clear the selected node */
107 void clearSelectedNode();
108 /** show detailed information on ui about selected node */
109 void updateDetailWidget();
110
111 public Q_SLOTS:
112 void clear(bool keep_prompt = false);
113 void fontBigger();
114 void fontSmaller();
115 void setFontSize(int newSize);
116 /** Append the message to the message widget */
117 void message(int category, const QString &msg) { message(category, msg, false); }
118 void message(int category, const QString &message, bool html);
119 /** Set number of connections shown in the UI */
120 void setNumConnections(int count);
121 /** Set network state shown in the UI */
122 void setNetworkActive(bool networkActive);
123 /** Set number of blocks and last block date shown in the UI */
124 void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype);
125 /** Set size (number of transactions and memory usage) of the mempool in the UI */
126 void setMempoolSize(long numberOfTxs, size_t dynUsage, size_t maxUsage);
127 /** Go forward or back in history */
128 void browseHistory(int offset);
129 /** Scroll console view to end */
130 void scrollToEnd();
131 /** Disconnect a selected node on the Peers tab */
132 void disconnectSelectedNode();
133 /** Ban a selected node on the Peers tab */
134 void banSelectedNode(int bantime);
135 /** Unban a selected node on the Bans tab */
136 void unbanSelectedNode();
137 /** set which tab has the focus (is visible) */
138 void setTabFocus(enum TabTypes tabType);
139 #ifdef ENABLE_WALLET
140 /** Set the current (ie - active) wallet */
141 void setCurrentWallet(WalletModel* wallet_model);
142 #endif // ENABLE_WALLET
143
144 private:
145 struct TranslatedStrings {
146 const QString yes{tr("Yes")}, no{tr("No")}, to{tr("To")}, from{tr("From")},
147 ban_for{tr("Ban for")}, na{tr("N/A")}, unknown{tr("Unknown")};
148 } const ts;
149
150 void startExecutor();
151 void setTrafficGraphRange(int mins);
152
153 enum ColumnWidths
154 {
155 ADDRESS_COLUMN_WIDTH = 200,
156 SUBVERSION_COLUMN_WIDTH = 150,
157 PING_COLUMN_WIDTH = 80,
158 BANSUBNET_COLUMN_WIDTH = 200,
159 BANTIME_COLUMN_WIDTH = 250
160
161 };
162
163 interfaces::Node& m_node;
164 Ui::RPCConsole* const ui;
165 ClientModel *clientModel = nullptr;
166 QStringList history;
167 int historyPtr = 0;
168 QString cmdBeforeBrowsing;
169 QList<NodeId> cachedNodeids;
170 const PlatformStyle* const platformStyle;
171 QMenu *peersTableContextMenu = nullptr;
172 QMenu *banTableContextMenu = nullptr;
173 int consoleFontSize = 0;
174 QCompleter *autoCompleter = nullptr;
175 QThread thread;
176 RPCExecutor* m_executor{nullptr};
177 WalletModel* m_last_wallet_model{nullptr};
178 bool m_is_executing{false};
179 QByteArray m_peer_widget_header_state;
180 QByteArray m_banlist_widget_header_state;
181
182 /** Update UI with latest network info from model. */
183 void updateNetworkState();
184
185 /// Format the duration between now and event as a string.
186 QString TimeDurationField(NodeClock::time_point now, NodeClock::time_point event) const
187 {
188 return event > NodeClock::epoch ? GUIUtil::formatDurationStr(now - event) : tr("Never");
189 }
190 /// DEPRECATED: Helper for the output of a time duration field. Inputs are UNIX epoch times.
191 QString TimeDurationField(std::chrono::seconds time_now, std::chrono::seconds time_at_event) const
192 {
193 return time_at_event.count() ? GUIUtil::formatDurationStr(time_now - time_at_event) : tr("Never");
194 }
195
196 void updateWindowTitle();
197
198 private Q_SLOTS:
199 void updateAlerts(const QString& warnings);
200 };
201
202 /**
203 * A version of QTextEdit that only populates plaintext mime data from a
204 * selection, this avoids some bad behavior in QT's HTML->Markdown conversion.
205 */
206 class PlainCopyTextEdit : public QTextEdit {
207 Q_OBJECT
208 public:
209 using QTextEdit::QTextEdit;
210 protected:
211 QMimeData* createMimeDataFromSelection() const override {
212 auto md = new QMimeData();
213 md->setText(textCursor().selection().toPlainText());
214 return md;
215 }
216 };
217
218 #endif // BITCOIN_QT_RPCCONSOLE_H
219