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