/ src / qt / bitcoingui.h
bitcoingui.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_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