/ src / qt / rpcconsole.h
rpcconsole.h
  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      /** Helper for the output of a time duration field. Inputs are UNIX epoch times. */
186      QString TimeDurationField(std::chrono::seconds time_now, std::chrono::seconds time_at_event) const
187      {
188          return time_at_event.count() ? GUIUtil::formatDurationStr(time_now - time_at_event) : tr("Never");
189      }
190  
191      void updateWindowTitle();
192  
193  private Q_SLOTS:
194      void updateAlerts(const QString& warnings);
195  };
196  
197  /**
198   * A version of QTextEdit that only populates plaintext mime data from a
199   * selection, this avoids some bad behavior in QT's HTML->Markdown conversion.
200   */
201  class PlainCopyTextEdit : public QTextEdit {
202      Q_OBJECT
203  public:
204      using QTextEdit::QTextEdit;
205  protected:
206      QMimeData* createMimeDataFromSelection() const override {
207          auto md = new QMimeData();
208          md->setText(textCursor().selection().toPlainText());
209          return md;
210      }
211  };
212  
213  #endif // BITCOIN_QT_RPCCONSOLE_H