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