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