bitcoingui.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_BITCOINGUI_H
   6  #define BITCOIN_QT_BITCOINGUI_H
   7  
   8  #include <bitcoin-build-config.h> // IWYU pragma: keep
   9  
  10  #include <qt/bitcoinunits.h>
  11  #include <qt/clientmodel.h>
  12  #include <qt/guiutil.h>
  13  #include <qt/optionsdialog.h>
  14  
  15  #include <consensus/amount.h>
  16  
  17  #include <QLabel>
  18  #include <QMainWindow>
  19  #include <QMap>
  20  #include <QMenu>
  21  #include <QPoint>
  22  #include <QSystemTrayIcon>
  23  
  24  #ifdef Q_OS_MACOS
  25  #include <qt/macos_appnap.h>
  26  #endif
  27  
  28  #include <memory>
  29  
  30  class NetworkStyle;
  31  class Notificator;
  32  class OptionsModel;
  33  class PlatformStyle;
  34  class RPCConsole;
  35  class SendCoinsRecipient;
  36  class UnitDisplayStatusBarControl;
  37  class WalletController;
  38  class WalletFrame;
  39  class WalletModel;
  40  class HelpMessageDialog;
  41  class ModalOverlay;
  42  enum class SynchronizationState;
  43  
  44  namespace interfaces {
  45  class Handler;
  46  class Node;
  47  struct BlockAndHeaderTipInfo;
  48  }
  49  
  50  QT_BEGIN_NAMESPACE
  51  class QAction;
  52  class QComboBox;
  53  class QDateTime;
  54  class QProgressBar;
  55  class QProgressDialog;
  56  QT_END_NAMESPACE
  57  
  58  namespace GUIUtil {
  59  class ClickableLabel;
  60  class ClickableProgressBar;
  61  }
  62  
  63  /**
  64    Bitcoin GUI main class. This class represents the main window of the Bitcoin UI. It communicates with both the client and
  65    wallet models to give the user an up-to-date view of the current core state.
  66  */
  67  class BitcoinGUI : public QMainWindow
  68  {
  69      Q_OBJECT
  70  
  71  public:
  72      static const std::string DEFAULT_UIPLATFORM;
  73  
  74      explicit BitcoinGUI(interfaces::Node& node, const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = nullptr);
  75      ~BitcoinGUI();
  76  
  77      /** Set the client model.
  78          The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
  79      */
  80      void setClientModel(ClientModel *clientModel = nullptr, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr);
  81  #ifdef ENABLE_WALLET
  82      void setWalletController(WalletController* wallet_controller, bool show_loading_minimized);
  83      WalletController* getWalletController();
  84  #endif
  85  
  86  #ifdef ENABLE_WALLET
  87      /** Set the wallet model.
  88          The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
  89          functionality.
  90      */
  91      void addWallet(WalletModel* walletModel);
  92      void removeWallet(WalletModel* walletModel);
  93      void removeAllWallets();
  94  #endif // ENABLE_WALLET
  95      bool enableWallet = false;
  96  
  97      /** Get the tray icon status.
  98          Some systems have not "system tray" or "notification area" available.
  99      */
 100      bool hasTrayIcon() const { return trayIcon; }
 101  
 102      /** Disconnect core signals from GUI client */
 103      void unsubscribeFromCoreSignals();
 104  
 105      bool isPrivacyModeActivated() const;
 106  
 107  protected:
 108      void changeEvent(QEvent *e) override;
 109      void closeEvent(QCloseEvent *event) override;
 110      void showEvent(QShowEvent *event) override;
 111      void dragEnterEvent(QDragEnterEvent *event) override;
 112      void dropEvent(QDropEvent *event) override;
 113      bool eventFilter(QObject *object, QEvent *event) override;
 114  
 115  private:
 116      interfaces::Node& m_node;
 117      WalletController* m_wallet_controller{nullptr};
 118      std::unique_ptr<interfaces::Handler> m_handler_message_box;
 119      std::unique_ptr<interfaces::Handler> m_handler_question;
 120      ClientModel* clientModel = nullptr;
 121      WalletFrame* walletFrame = nullptr;
 122  
 123      UnitDisplayStatusBarControl* unitDisplayControl = nullptr;
 124      GUIUtil::ThemedLabel* labelWalletEncryptionIcon = nullptr;
 125      GUIUtil::ThemedLabel* labelWalletHDStatusIcon = nullptr;
 126      GUIUtil::ClickableLabel* labelProxyIcon = nullptr;
 127      GUIUtil::ClickableLabel* connectionsControl = nullptr;
 128      GUIUtil::ClickableLabel* labelBlocksIcon = nullptr;
 129      QLabel* progressBarLabel = nullptr;
 130      GUIUtil::ClickableProgressBar* progressBar = nullptr;
 131      QProgressDialog* progressDialog = nullptr;
 132  
 133      QMenuBar* appMenuBar = nullptr;
 134      QToolBar* appToolBar = nullptr;
 135      QAction* overviewAction = nullptr;
 136      QAction* historyAction = nullptr;
 137      QAction* quitAction = nullptr;
 138      QAction* sendCoinsAction = nullptr;
 139      QAction* usedSendingAddressesAction = nullptr;
 140      QAction* usedReceivingAddressesAction = nullptr;
 141      QAction* signMessageAction = nullptr;
 142      QAction* verifyMessageAction = nullptr;
 143      QAction* m_load_psbt_action = nullptr;
 144      QAction* m_load_psbt_clipboard_action = nullptr;
 145      QAction* aboutAction = nullptr;
 146      QAction* receiveCoinsAction = nullptr;
 147      QAction* optionsAction = nullptr;
 148      QAction* encryptWalletAction = nullptr;
 149      QAction* backupWalletAction = nullptr;
 150      QAction* changePassphraseAction = nullptr;
 151      QAction* aboutQtAction = nullptr;
 152      QAction* openRPCConsoleAction = nullptr;
 153      QAction* openAction = nullptr;
 154      QAction* showHelpMessageAction = nullptr;
 155      QAction* m_create_wallet_action{nullptr};
 156      QAction* m_open_wallet_action{nullptr};
 157      QMenu* m_open_wallet_menu{nullptr};
 158      QAction* m_restore_wallet_action{nullptr};
 159      QAction* m_close_wallet_action{nullptr};
 160      QAction* m_close_all_wallets_action{nullptr};
 161      QAction* m_wallet_selector_label_action = nullptr;
 162      QAction* m_wallet_selector_action = nullptr;
 163      QAction* m_mask_values_action{nullptr};
 164      QAction* m_migrate_wallet_action{nullptr};
 165      QMenu* m_migrate_wallet_menu{nullptr};
 166  
 167      QLabel *m_wallet_selector_label = nullptr;
 168      QComboBox* m_wallet_selector = nullptr;
 169  
 170      QSystemTrayIcon* trayIcon = nullptr;
 171      const std::unique_ptr<QMenu> trayIconMenu;
 172      Notificator* notificator = nullptr;
 173      RPCConsole* rpcConsole = nullptr;
 174      HelpMessageDialog* helpMessageDialog = nullptr;
 175      ModalOverlay* modalOverlay = nullptr;
 176  
 177      QMenu* m_network_context_menu = new QMenu(this);
 178  
 179  #ifdef Q_OS_MACOS
 180      CAppNapInhibitor* m_app_nap_inhibitor = nullptr;
 181  #endif
 182  
 183      /** Keep track of previous number of blocks, to detect progress */
 184      int prevBlocks = 0;
 185      int spinnerFrame = 0;
 186  
 187      const PlatformStyle *platformStyle;
 188      const NetworkStyle* const m_network_style;
 189  
 190      /** Create the main UI actions. */
 191      void createActions();
 192      /** Create the menu bar and sub-menus. */
 193      void createMenuBar();
 194      /** Create the toolbars */
 195      void createToolBars();
 196      /** Create system tray icon and notification */
 197      void createTrayIcon();
 198      /** Create system tray menu (or setup the dock menu) */
 199      void createTrayIconMenu();
 200  
 201      /** Enable or disable all wallet-related actions */
 202      void setWalletActionsEnabled(bool enabled);
 203  
 204      /** Connect core signals to GUI client */
 205      void subscribeToCoreSignals();
 206  
 207      /** Update UI with latest network info from model. */
 208      void updateNetworkState();
 209  
 210      void updateHeadersSyncProgressLabel();
 211      void updateHeadersPresyncProgressLabel(int64_t height, const QDateTime& blockDate);
 212  
 213      /** Open the OptionsDialog on the specified tab index */
 214      void openOptionsDialogWithTab(OptionsDialog::Tab tab);
 215  
 216  Q_SIGNALS:
 217      void quitRequested();
 218      /** Signal raised when a URI was entered or dragged to the GUI */
 219      void receivedURI(const QString &uri);
 220      /** Signal raised when RPC console shown */
 221      void consoleShown(RPCConsole* console);
 222      void setPrivacy(bool privacy);
 223  
 224  public Q_SLOTS:
 225      /** Set number of connections shown in the UI */
 226      void setNumConnections(int count);
 227      /** Set network state shown in the UI */
 228      void setNetworkActive(bool network_active);
 229      /** Set number of blocks and last block date shown in the UI */
 230      void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state);
 231      /** Launch the wallet creation modal (no-op if wallet is not compiled) **/
 232      void createWallet();
 233  
 234      /** Notify the user of an event from the core network or transaction handling code.
 235         @param[in] title             the message box / notification title
 236         @param[in] message           the displayed text
 237         @param[in] style             modality and style definitions (icon and used buttons - buttons only for message boxes)
 238                                      @see CClientUIInterface::MessageBoxFlags
 239         @param[in] ret               pointer to a bool that will be modified to whether Ok was clicked (modal only)
 240         @param[in] detailed_message  the text to be displayed in the details area
 241      */
 242      void message(const QString& title, QString message, unsigned int style, bool* ret = nullptr, const QString& detailed_message = QString());
 243  
 244  #ifdef ENABLE_WALLET
 245      void setCurrentWallet(WalletModel* wallet_model);
 246      void setCurrentWalletBySelectorIndex(int index);
 247      /** Set the UI status indicators based on the currently selected wallet.
 248      */
 249      void updateWalletStatus();
 250  
 251  private:
 252      /** Set the encryption status as shown in the UI.
 253         @param[in] status            current encryption status
 254         @see WalletModel::EncryptionStatus
 255      */
 256      void setEncryptionStatus(int status);
 257  
 258      /** Set the hd-enabled status as shown in the UI.
 259       @param[in] hdEnabled         current hd enabled status
 260       @see WalletModel::EncryptionStatus
 261       */
 262      void setHDStatus(bool privkeyDisabled, int hdEnabled);
 263  
 264  public Q_SLOTS:
 265      bool handlePaymentRequest(const SendCoinsRecipient& recipient);
 266  
 267      /** Show incoming transaction notification for new transactions. */
 268      void incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
 269  #endif // ENABLE_WALLET
 270  
 271  private:
 272      /** Set the proxy-enabled icon as shown in the UI. */
 273      void updateProxyIcon();
 274      void updateWindowTitle();
 275  
 276  public Q_SLOTS:
 277  #ifdef ENABLE_WALLET
 278      /** Switch to overview (home) page */
 279      void gotoOverviewPage();
 280      /** Switch to history (transactions) page */
 281      void gotoHistoryPage();
 282      /** Switch to receive coins page */
 283      void gotoReceiveCoinsPage();
 284      /** Switch to send coins page */
 285      void gotoSendCoinsPage(QString addr = "");
 286  
 287      /** Show Sign/Verify Message dialog and switch to sign message tab */
 288      void gotoSignMessageTab(QString addr = "");
 289      /** Show Sign/Verify Message dialog and switch to verify message tab */
 290      void gotoVerifyMessageTab(QString addr = "");
 291      /** Load Partially Signed Bitcoin Transaction from file or clipboard */
 292      void gotoLoadPSBT(bool from_clipboard = false);
 293      /** Enable history action when privacy is changed */
 294      void enableHistoryAction(bool privacy);
 295  
 296      /** Show open dialog */
 297      void openClicked();
 298  #endif // ENABLE_WALLET
 299      /** Show configuration dialog */
 300      void optionsClicked();
 301      /** Show about dialog */
 302      void aboutClicked();
 303      /** Show debug window */
 304      void showDebugWindow();
 305      /** Show debug window and set focus to the console */
 306      void showDebugWindowActivateConsole();
 307      /** Show help message dialog */
 308      void showHelpMessageClicked();
 309  
 310      /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
 311      void showNormalIfMinimized() { showNormalIfMinimized(false); }
 312      void showNormalIfMinimized(bool fToggleHidden);
 313      /** Simply calls showNormalIfMinimized(true) */
 314      void toggleHidden();
 315  
 316      /** called by a timer to check if shutdown has been requested */
 317      void detectShutdown();
 318  
 319      /** Show progress dialog e.g. for verifychain */
 320      void showProgress(const QString &title, int nProgress);
 321  
 322      void showModalOverlay();
 323  };
 324  
 325  class UnitDisplayStatusBarControl : public QLabel
 326  {
 327      Q_OBJECT
 328  
 329  public:
 330      explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle);
 331      /** Lets the control know about the Options Model (and its signals) */
 332      void setOptionsModel(OptionsModel *optionsModel);
 333  
 334  protected:
 335      /** So that it responds to left-button clicks */
 336      void mousePressEvent(QMouseEvent *event) override;
 337      void changeEvent(QEvent* e) override;
 338  
 339  private:
 340      OptionsModel* optionsModel{nullptr};
 341      QMenu* menu{nullptr};
 342      const PlatformStyle* m_platform_style;
 343  
 344      /** Shows context menu with Display Unit options by the mouse coordinates */
 345      void onDisplayUnitsClicked(const QPoint& point);
 346      /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
 347      void createContextMenu();
 348  
 349  private Q_SLOTS:
 350      /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
 351      void updateDisplayUnit(BitcoinUnit newUnits);
 352      /** Tells underlying optionsModel to update its current display unit. */
 353      void onMenuSelection(QAction* action);
 354  };
 355  
 356  #endif // BITCOIN_QT_BITCOINGUI_H
 357