rpcconsole.h raw

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