LCOV - code coverage report
Current view: top level - src/qt - bitcoingui.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 2 936 0.2 %
Date: 2020-09-26 01:30:44 Functions: 1 103 1.0 %

          Line data    Source code
       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             : #include <qt/bitcoingui.h>
       6             : 
       7             : #include <qt/bitcoinunits.h>
       8             : #include <qt/clientmodel.h>
       9             : #include <qt/createwalletdialog.h>
      10             : #include <qt/guiconstants.h>
      11             : #include <qt/guiutil.h>
      12             : #include <qt/modaloverlay.h>
      13             : #include <qt/networkstyle.h>
      14             : #include <qt/notificator.h>
      15             : #include <qt/openuridialog.h>
      16             : #include <qt/optionsdialog.h>
      17             : #include <qt/optionsmodel.h>
      18             : #include <qt/platformstyle.h>
      19             : #include <qt/rpcconsole.h>
      20             : #include <qt/utilitydialog.h>
      21             : 
      22             : #ifdef ENABLE_WALLET
      23             : #include <qt/walletcontroller.h>
      24             : #include <qt/walletframe.h>
      25             : #include <qt/walletmodel.h>
      26             : #include <qt/walletview.h>
      27             : #endif // ENABLE_WALLET
      28             : 
      29             : #ifdef Q_OS_MAC
      30             : #include <qt/macdockiconhandler.h>
      31             : #endif
      32             : 
      33             : #include <chain.h>
      34             : #include <chainparams.h>
      35             : #include <interfaces/handler.h>
      36             : #include <interfaces/node.h>
      37             : #include <node/ui_interface.h>
      38             : #include <util/system.h>
      39             : #include <util/translation.h>
      40             : #include <validation.h>
      41             : 
      42             : #include <QAction>
      43             : #include <QApplication>
      44             : #include <QComboBox>
      45             : #include <QDateTime>
      46             : #include <QDragEnterEvent>
      47             : #include <QListWidget>
      48             : #include <QMenu>
      49             : #include <QMenuBar>
      50             : #include <QMessageBox>
      51             : #include <QMimeData>
      52             : #include <QProgressDialog>
      53             : #include <QScreen>
      54             : #include <QSettings>
      55             : #include <QShortcut>
      56             : #include <QStackedWidget>
      57             : #include <QStatusBar>
      58             : #include <QStyle>
      59             : #include <QSystemTrayIcon>
      60             : #include <QTimer>
      61             : #include <QToolBar>
      62             : #include <QUrlQuery>
      63             : #include <QVBoxLayout>
      64             : #include <QWindow>
      65             : 
      66             : 
      67           1 : const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
      68             : #if defined(Q_OS_MAC)
      69           1 :         "macosx"
      70             : #elif defined(Q_OS_WIN)
      71             :         "windows"
      72             : #else
      73             :         "other"
      74             : #endif
      75             :         ;
      76             : 
      77           0 : BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
      78           0 :     QMainWindow(parent),
      79           0 :     m_node(node),
      80           0 :     trayIconMenu{new QMenu()},
      81           0 :     platformStyle(_platformStyle),
      82           0 :     m_network_style(networkStyle)
      83           0 : {
      84           0 :     QSettings settings;
      85           0 :     if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
      86             :         // Restore failed (perhaps missing setting), center the window
      87           0 :         move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
      88           0 :     }
      89             : 
      90             : #ifdef ENABLE_WALLET
      91           0 :     enableWallet = WalletModel::isWalletEnabled();
      92             : #endif // ENABLE_WALLET
      93           0 :     QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
      94           0 :     setWindowIcon(m_network_style->getTrayAndWindowIcon());
      95           0 :     updateWindowTitle();
      96             : 
      97           0 :     rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
      98           0 :     helpMessageDialog = new HelpMessageDialog(this, false);
      99             : #ifdef ENABLE_WALLET
     100           0 :     if(enableWallet)
     101             :     {
     102             :         /** Create wallet frame and make it the central widget */
     103           0 :         walletFrame = new WalletFrame(_platformStyle, this);
     104           0 :         setCentralWidget(walletFrame);
     105             :     } else
     106             : #endif // ENABLE_WALLET
     107             :     {
     108             :         /* When compiled without wallet or -disablewallet is provided,
     109             :          * the central widget is the rpc console.
     110             :          */
     111           0 :         setCentralWidget(rpcConsole);
     112           0 :         Q_EMIT consoleShown(rpcConsole);
     113             :     }
     114             : 
     115           0 :     modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
     116             : 
     117             :     // Accept D&D of URIs
     118           0 :     setAcceptDrops(true);
     119           0 : 
     120             :     // Create actions for the toolbar, menu bar and tray/dock icon
     121           0 :     // Needs walletFrame to be initialized
     122           0 :     createActions();
     123           0 : 
     124           0 :     // Create application menu bar
     125           0 :     createMenuBar();
     126           0 : 
     127           0 :     // Create the toolbars
     128           0 :     createToolBars();
     129           0 : 
     130             :     // Create system tray icon and notification
     131           0 :     if (QSystemTrayIcon::isSystemTrayAvailable()) {
     132           0 :         createTrayIcon();
     133           0 :     }
     134           0 :     notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
     135           0 : 
     136           0 :     // Create status bar
     137           0 :     statusBar();
     138           0 : 
     139           0 :     // Disable size grip because it looks ugly and nobody needs it
     140           0 :     statusBar()->setSizeGripEnabled(false);
     141           0 : 
     142           0 :     // Status bar notification icons
     143           0 :     QFrame *frameBlocks = new QFrame();
     144           0 :     frameBlocks->setContentsMargins(0,0,0,0);
     145           0 :     frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
     146           0 :     QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
     147           0 :     frameBlocksLayout->setContentsMargins(3,0,3,0);
     148           0 :     frameBlocksLayout->setSpacing(3);
     149           0 :     unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
     150           0 :     labelWalletEncryptionIcon = new QLabel();
     151           0 :     labelWalletHDStatusIcon = new QLabel();
     152           0 :     labelProxyIcon = new GUIUtil::ClickableLabel();
     153           0 :     connectionsControl = new GUIUtil::ClickableLabel();
     154           0 :     labelBlocksIcon = new GUIUtil::ClickableLabel();
     155           0 :     if(enableWallet)
     156           0 :     {
     157           0 :         frameBlocksLayout->addStretch();
     158           0 :         frameBlocksLayout->addWidget(unitDisplayControl);
     159           0 :         frameBlocksLayout->addStretch();
     160           0 :         frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
     161           0 :         frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
     162           0 :     }
     163           0 :     frameBlocksLayout->addWidget(labelProxyIcon);
     164           0 :     frameBlocksLayout->addStretch();
     165           0 :     frameBlocksLayout->addWidget(connectionsControl);
     166           0 :     frameBlocksLayout->addStretch();
     167           0 :     frameBlocksLayout->addWidget(labelBlocksIcon);
     168           0 :     frameBlocksLayout->addStretch();
     169             : 
     170           0 :     // Progress bar and label for blocks download
     171           0 :     progressBarLabel = new QLabel();
     172           0 :     progressBarLabel->setVisible(false);
     173           0 :     progressBar = new GUIUtil::ProgressBar();
     174           0 :     progressBar->setAlignment(Qt::AlignCenter);
     175           0 :     progressBar->setVisible(false);
     176           0 : 
     177             :     // Override style sheet for progress bar for styles that have a segmented progress bar,
     178             :     // as they make the text unreadable (workaround for issue #1071)
     179             :     // See https://doc.qt.io/qt-5/gallery.html
     180           0 :     QString curStyle = QApplication::style()->metaObject()->className();
     181           0 :     if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
     182             :     {
     183           0 :         progressBar->setStyleSheet("QProgressBar { background-color: #e8e8e8; border: 1px solid grey; border-radius: 7px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: 7px; margin: 0px; }");
     184           0 :     }
     185             : 
     186           0 :     statusBar()->addWidget(progressBarLabel);
     187           0 :     statusBar()->addWidget(progressBar);
     188           0 :     statusBar()->addPermanentWidget(frameBlocks);
     189             : 
     190             :     // Install event filter to be able to catch status tip events (QEvent::StatusTip)
     191           0 :     this->installEventFilter(this);
     192             : 
     193             :     // Initially wallet actions should be disabled
     194           0 :     setWalletActionsEnabled(false);
     195             : 
     196             :     // Subscribe to notifications from core
     197           0 :     subscribeToCoreSignals();
     198             : 
     199           0 :     connect(connectionsControl, &GUIUtil::ClickableLabel::clicked, [this] {
     200           0 :         m_node.setNetworkActive(!m_node.getNetworkActive());
     201           0 :     });
     202           0 :     connect(labelProxyIcon, &GUIUtil::ClickableLabel::clicked, [this] {
     203           0 :         openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK);
     204           0 :     });
     205             : 
     206           0 :     connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay);
     207           0 :     connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay);
     208             : #ifdef ENABLE_WALLET
     209           0 :     if(enableWallet) {
     210           0 :         connect(walletFrame, &WalletFrame::requestedSyncWarningInfo, this, &BitcoinGUI::showModalOverlay);
     211           0 :     }
     212             : #endif
     213             : 
     214             : #ifdef Q_OS_MAC
     215           0 :     m_app_nap_inhibitor = new CAppNapInhibitor;
     216             : #endif
     217             : 
     218           0 :     GUIUtil::handleCloseWindowShortcut(this);
     219           0 : }
     220             : 
     221           0 : BitcoinGUI::~BitcoinGUI()
     222           0 : {
     223             :     // Unsubscribe from notifications from core
     224           0 :     unsubscribeFromCoreSignals();
     225             : 
     226           0 :     QSettings settings;
     227           0 :     settings.setValue("MainWindowGeometry", saveGeometry());
     228           0 :     if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
     229           0 :         trayIcon->hide();
     230             : #ifdef Q_OS_MAC
     231           0 :     delete m_app_nap_inhibitor;
     232           0 :     delete appMenuBar;
     233           0 :     MacDockIconHandler::cleanup();
     234             : #endif
     235             : 
     236           0 :     delete rpcConsole;
     237           0 : }
     238             : 
     239           0 : void BitcoinGUI::createActions()
     240             : {
     241           0 :     QActionGroup *tabGroup = new QActionGroup(this);
     242           0 :     connect(modalOverlay, &ModalOverlay::triggered, tabGroup, &QActionGroup::setEnabled);
     243             : 
     244           0 :     overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
     245           0 :     overviewAction->setStatusTip(tr("Show general overview of wallet"));
     246           0 :     overviewAction->setToolTip(overviewAction->statusTip());
     247           0 :     overviewAction->setCheckable(true);
     248           0 :     overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
     249           0 :     tabGroup->addAction(overviewAction);
     250             : 
     251           0 :     sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
     252           0 :     sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
     253           0 :     sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
     254           0 :     sendCoinsAction->setCheckable(true);
     255           0 :     sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
     256           0 :     tabGroup->addAction(sendCoinsAction);
     257             : 
     258           0 :     sendCoinsMenuAction = new QAction(sendCoinsAction->text(), this);
     259           0 :     sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
     260           0 :     sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
     261             : 
     262           0 :     receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
     263           0 :     receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
     264           0 :     receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
     265           0 :     receiveCoinsAction->setCheckable(true);
     266           0 :     receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
     267           0 :     tabGroup->addAction(receiveCoinsAction);
     268             : 
     269           0 :     receiveCoinsMenuAction = new QAction(receiveCoinsAction->text(), this);
     270           0 :     receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
     271           0 :     receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
     272             : 
     273           0 :     historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
     274           0 :     historyAction->setStatusTip(tr("Browse transaction history"));
     275           0 :     historyAction->setToolTip(historyAction->statusTip());
     276           0 :     historyAction->setCheckable(true);
     277           0 :     historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
     278           0 :     tabGroup->addAction(historyAction);
     279             : 
     280             : #ifdef ENABLE_WALLET
     281             :     // These showNormalIfMinimized are needed because Send Coins and Receive Coins
     282             :     // can be triggered from the tray menu, and need to show the GUI to be useful.
     283           0 :     connect(overviewAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     284           0 :     connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage);
     285           0 :     connect(sendCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     286           0 :     connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); });
     287           0 :     connect(sendCoinsMenuAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     288           0 :     connect(sendCoinsMenuAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); });
     289           0 :     connect(receiveCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     290           0 :     connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
     291           0 :     connect(receiveCoinsMenuAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     292           0 :     connect(receiveCoinsMenuAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
     293           0 :     connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     294           0 :     connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage);
     295             : #endif // ENABLE_WALLET
     296             : 
     297           0 :     quitAction = new QAction(tr("E&xit"), this);
     298           0 :     quitAction->setStatusTip(tr("Quit application"));
     299           0 :     quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
     300           0 :     quitAction->setMenuRole(QAction::QuitRole);
     301           0 :     aboutAction = new QAction(tr("&About %1").arg(PACKAGE_NAME), this);
     302           0 :     aboutAction->setStatusTip(tr("Show information about %1").arg(PACKAGE_NAME));
     303           0 :     aboutAction->setMenuRole(QAction::AboutRole);
     304           0 :     aboutAction->setEnabled(false);
     305           0 :     aboutQtAction = new QAction(tr("About &Qt"), this);
     306           0 :     aboutQtAction->setStatusTip(tr("Show information about Qt"));
     307           0 :     aboutQtAction->setMenuRole(QAction::AboutQtRole);
     308           0 :     optionsAction = new QAction(tr("&Options..."), this);
     309           0 :     optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(PACKAGE_NAME));
     310           0 :     optionsAction->setMenuRole(QAction::PreferencesRole);
     311           0 :     optionsAction->setEnabled(false);
     312           0 :     toggleHideAction = new QAction(tr("&Show / Hide"), this);
     313           0 :     toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
     314             : 
     315           0 :     encryptWalletAction = new QAction(tr("&Encrypt Wallet..."), this);
     316           0 :     encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
     317           0 :     encryptWalletAction->setCheckable(true);
     318           0 :     backupWalletAction = new QAction(tr("&Backup Wallet..."), this);
     319           0 :     backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
     320           0 :     changePassphraseAction = new QAction(tr("&Change Passphrase..."), this);
     321           0 :     changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
     322           0 :     signMessageAction = new QAction(tr("Sign &message..."), this);
     323           0 :     signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
     324           0 :     verifyMessageAction = new QAction(tr("&Verify message..."), this);
     325           0 :     verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
     326           0 :     m_load_psbt_action = new QAction(tr("&Load PSBT from file..."), this);
     327           0 :     m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
     328           0 :     m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from clipboard..."), this);
     329           0 :     m_load_psbt_clipboard_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction from clipboard"));
     330             : 
     331           0 :     openRPCConsoleAction = new QAction(tr("Node window"), this);
     332           0 :     openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
     333             :     // initially disable the debug window menu item
     334           0 :     openRPCConsoleAction->setEnabled(false);
     335           0 :     openRPCConsoleAction->setObjectName("openRPCConsoleAction");
     336             : 
     337           0 :     usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
     338           0 :     usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
     339           0 :     usedReceivingAddressesAction = new QAction(tr("&Receiving addresses"), this);
     340           0 :     usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
     341             : 
     342           0 :     openAction = new QAction(tr("Open &URI..."), this);
     343           0 :     openAction->setStatusTip(tr("Open a bitcoin: URI"));
     344             : 
     345           0 :     m_open_wallet_action = new QAction(tr("Open Wallet"), this);
     346           0 :     m_open_wallet_action->setEnabled(false);
     347           0 :     m_open_wallet_action->setStatusTip(tr("Open a wallet"));
     348           0 :     m_open_wallet_menu = new QMenu(this);
     349             : 
     350           0 :     m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
     351           0 :     m_close_wallet_action->setStatusTip(tr("Close wallet"));
     352             : 
     353           0 :     m_create_wallet_action = new QAction(tr("Create Wallet..."), this);
     354           0 :     m_create_wallet_action->setEnabled(false);
     355           0 :     m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
     356             : 
     357           0 :     m_close_all_wallets_action = new QAction(tr("Close All Wallets..."), this);
     358           0 :     m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
     359             : 
     360           0 :     showHelpMessageAction = new QAction(tr("&Command-line options"), this);
     361           0 :     showHelpMessageAction->setMenuRole(QAction::NoRole);
     362           0 :     showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(PACKAGE_NAME));
     363             : 
     364           0 :     m_mask_values_action = new QAction(tr("&Mask values"), this);
     365           0 :     m_mask_values_action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M));
     366           0 :     m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab"));
     367           0 :     m_mask_values_action->setCheckable(true);
     368             : 
     369           0 :     connect(quitAction, &QAction::triggered, qApp, QApplication::quit);
     370           0 :     connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
     371           0 :     connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
     372           0 :     connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked);
     373           0 :     connect(toggleHideAction, &QAction::triggered, this, &BitcoinGUI::toggleHidden);
     374           0 :     connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked);
     375           0 :     connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow);
     376             :     // prevents an open debug window from becoming stuck/unusable on client shutdown
     377           0 :     connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
     378             : 
     379             : #ifdef ENABLE_WALLET
     380           0 :     if(walletFrame)
     381             :     {
     382           0 :         connect(encryptWalletAction, &QAction::triggered, walletFrame, &WalletFrame::encryptWallet);
     383           0 :         connect(backupWalletAction, &QAction::triggered, walletFrame, &WalletFrame::backupWallet);
     384           0 :         connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase);
     385           0 :         connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     386           0 :         connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
     387           0 :         connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
     388           0 :         connect(m_load_psbt_clipboard_action, &QAction::triggered, [this]{ gotoLoadPSBT(true); });
     389           0 :         connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
     390           0 :         connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
     391           0 :         connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses);
     392           0 :         connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedReceivingAddresses);
     393           0 :         connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked);
     394           0 :         connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
     395           0 :             m_open_wallet_menu->clear();
     396           0 :             for (const std::pair<const std::string, bool>& i : m_wallet_controller->listWalletDir()) {
     397           0 :                 const std::string& path = i.first;
     398           0 :                 QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path);
     399             :                 // Menu items remove single &. Single & are shown when && is in
     400             :                 // the string, but only the first occurrence. So replace only
     401             :                 // the first & with &&.
     402           0 :                 name.replace(name.indexOf(QChar('&')), 1, QString("&&"));
     403           0 :                 QAction* action = m_open_wallet_menu->addAction(name);
     404             : 
     405           0 :                 if (i.second) {
     406             :                     // This wallet is already loaded
     407           0 :                     action->setEnabled(false);
     408           0 :                     continue;
     409             :                 }
     410             : 
     411           0 :                 connect(action, &QAction::triggered, [this, path] {
     412           0 :                     auto activity = new OpenWalletActivity(m_wallet_controller, this);
     413           0 :                     connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet);
     414           0 :                     connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater);
     415           0 :                     activity->open(path);
     416           0 :                 });
     417           0 :             }
     418           0 :             if (m_open_wallet_menu->isEmpty()) {
     419           0 :                 QAction* action = m_open_wallet_menu->addAction(tr("No wallets available"));
     420           0 :                 action->setEnabled(false);
     421           0 :             }
     422           0 :         });
     423           0 :         connect(m_close_wallet_action, &QAction::triggered, [this] {
     424           0 :             m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
     425           0 :         });
     426           0 :         connect(m_create_wallet_action, &QAction::triggered, [this] {
     427           0 :             auto activity = new CreateWalletActivity(m_wallet_controller, this);
     428           0 :             connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet);
     429           0 :             connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
     430           0 :             activity->create();
     431           0 :         });
     432           0 :         connect(m_close_all_wallets_action, &QAction::triggered, [this] {
     433           0 :             m_wallet_controller->closeAllWallets(this);
     434           0 :         });
     435           0 :         connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::setPrivacy);
     436           0 :     }
     437             : #endif // ENABLE_WALLET
     438             : 
     439           0 :     connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindowActivateConsole);
     440           0 :     connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
     441           0 : }
     442             : 
     443           0 : void BitcoinGUI::createMenuBar()
     444             : {
     445             : #ifdef Q_OS_MAC
     446             :     // Create a decoupled menu bar on Mac which stays even if the window is closed
     447           0 :     appMenuBar = new QMenuBar();
     448             : #else
     449             :     // Get the main window's menu bar on other platforms
     450             :     appMenuBar = menuBar();
     451             : #endif
     452             : 
     453             :     // Configure the menus
     454           0 :     QMenu *file = appMenuBar->addMenu(tr("&File"));
     455           0 :     if(walletFrame)
     456             :     {
     457           0 :         file->addAction(m_create_wallet_action);
     458           0 :         file->addAction(m_open_wallet_action);
     459           0 :         file->addAction(m_close_wallet_action);
     460           0 :         file->addAction(m_close_all_wallets_action);
     461           0 :         file->addSeparator();
     462           0 :         file->addAction(openAction);
     463           0 :         file->addAction(backupWalletAction);
     464           0 :         file->addAction(signMessageAction);
     465           0 :         file->addAction(verifyMessageAction);
     466           0 :         file->addAction(m_load_psbt_action);
     467           0 :         file->addAction(m_load_psbt_clipboard_action);
     468           0 :         file->addSeparator();
     469           0 :     }
     470           0 :     file->addAction(quitAction);
     471             : 
     472           0 :     QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
     473           0 :     if(walletFrame)
     474             :     {
     475           0 :         settings->addAction(encryptWalletAction);
     476           0 :         settings->addAction(changePassphraseAction);
     477           0 :         settings->addSeparator();
     478           0 :         settings->addAction(m_mask_values_action);
     479           0 :         settings->addSeparator();
     480           0 :     }
     481           0 :     settings->addAction(optionsAction);
     482             : 
     483           0 :     QMenu* window_menu = appMenuBar->addMenu(tr("&Window"));
     484             : 
     485           0 :     QAction* minimize_action = window_menu->addAction(tr("Minimize"));
     486           0 :     minimize_action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
     487           0 :     connect(minimize_action, &QAction::triggered, [] {
     488           0 :         QApplication::activeWindow()->showMinimized();
     489           0 :     });
     490           0 :     connect(qApp, &QApplication::focusWindowChanged, [minimize_action] (QWindow* window) {
     491           0 :         minimize_action->setEnabled(window != nullptr && (window->flags() & Qt::Dialog) != Qt::Dialog && window->windowState() != Qt::WindowMinimized);
     492           0 :     });
     493             : 
     494             : #ifdef Q_OS_MAC
     495           0 :     QAction* zoom_action = window_menu->addAction(tr("Zoom"));
     496           0 :     connect(zoom_action, &QAction::triggered, [] {
     497           0 :         QWindow* window = qApp->focusWindow();
     498           0 :         if (window->windowState() != Qt::WindowMaximized) {
     499           0 :             window->showMaximized();
     500           0 :         } else {
     501           0 :             window->showNormal();
     502             :         }
     503           0 :     });
     504             : 
     505           0 :     connect(qApp, &QApplication::focusWindowChanged, [zoom_action] (QWindow* window) {
     506           0 :         zoom_action->setEnabled(window != nullptr);
     507           0 :     });
     508             : #endif
     509             : 
     510           0 :     if (walletFrame) {
     511             : #ifdef Q_OS_MAC
     512           0 :         window_menu->addSeparator();
     513           0 :         QAction* main_window_action = window_menu->addAction(tr("Main Window"));
     514           0 :         connect(main_window_action, &QAction::triggered, [this] {
     515           0 :             GUIUtil::bringToFront(this);
     516           0 :         });
     517             : #endif
     518           0 :         window_menu->addSeparator();
     519           0 :         window_menu->addAction(usedSendingAddressesAction);
     520           0 :         window_menu->addAction(usedReceivingAddressesAction);
     521           0 :     }
     522             : 
     523           0 :     window_menu->addSeparator();
     524           0 :     for (RPCConsole::TabTypes tab_type : rpcConsole->tabs()) {
     525           0 :         QAction* tab_action = window_menu->addAction(rpcConsole->tabTitle(tab_type));
     526           0 :         tab_action->setShortcut(rpcConsole->tabShortcut(tab_type));
     527           0 :         connect(tab_action, &QAction::triggered, [this, tab_type] {
     528           0 :             rpcConsole->setTabFocus(tab_type);
     529           0 :             showDebugWindow();
     530           0 :         });
     531             :     }
     532             : 
     533           0 :     QMenu *help = appMenuBar->addMenu(tr("&Help"));
     534           0 :     help->addAction(showHelpMessageAction);
     535           0 :     help->addSeparator();
     536           0 :     help->addAction(aboutAction);
     537           0 :     help->addAction(aboutQtAction);
     538           0 : }
     539             : 
     540           0 : void BitcoinGUI::createToolBars()
     541             : {
     542           0 :     if(walletFrame)
     543             :     {
     544           0 :         QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
     545           0 :         appToolBar = toolbar;
     546           0 :         toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
     547           0 :         toolbar->setMovable(false);
     548           0 :         toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     549           0 :         toolbar->addAction(overviewAction);
     550           0 :         toolbar->addAction(sendCoinsAction);
     551           0 :         toolbar->addAction(receiveCoinsAction);
     552           0 :         toolbar->addAction(historyAction);
     553           0 :         overviewAction->setChecked(true);
     554             : 
     555             : #ifdef ENABLE_WALLET
     556           0 :         QWidget *spacer = new QWidget();
     557           0 :         spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     558           0 :         toolbar->addWidget(spacer);
     559             : 
     560           0 :         m_wallet_selector = new QComboBox();
     561           0 :         m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
     562           0 :         connect(m_wallet_selector, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
     563             : 
     564           0 :         m_wallet_selector_label = new QLabel();
     565           0 :         m_wallet_selector_label->setText(tr("Wallet:") + " ");
     566           0 :         m_wallet_selector_label->setBuddy(m_wallet_selector);
     567             : 
     568           0 :         m_wallet_selector_label_action = appToolBar->addWidget(m_wallet_selector_label);
     569           0 :         m_wallet_selector_action = appToolBar->addWidget(m_wallet_selector);
     570             : 
     571           0 :         m_wallet_selector_label_action->setVisible(false);
     572           0 :         m_wallet_selector_action->setVisible(false);
     573             : #endif
     574           0 :     }
     575           0 : }
     576             : 
     577           0 : void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndHeaderTipInfo* tip_info)
     578             : {
     579           0 :     this->clientModel = _clientModel;
     580           0 :     if(_clientModel)
     581             :     {
     582             :         // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
     583             :         // while the client has not yet fully loaded
     584           0 :         createTrayIconMenu();
     585             : 
     586             :         // Keep up to date with client
     587           0 :         updateNetworkState();
     588           0 :         connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections);
     589           0 :         connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive);
     590             : 
     591           0 :         modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromTime_t(tip_info->header_time));
     592           0 :         setNumBlocks(tip_info->block_height, QDateTime::fromTime_t(tip_info->block_time), tip_info->verification_progress, false, SynchronizationState::INIT_DOWNLOAD);
     593           0 :         connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks);
     594             : 
     595             :         // Receive and report messages from client model
     596           0 :         connect(_clientModel, &ClientModel::message, [this](const QString &title, const QString &message, unsigned int style){
     597           0 :             this->message(title, message, style);
     598           0 :         });
     599             : 
     600             :         // Show progress dialog
     601           0 :         connect(_clientModel, &ClientModel::showProgress, this, &BitcoinGUI::showProgress);
     602             : 
     603           0 :         rpcConsole->setClientModel(_clientModel, tip_info->block_height, tip_info->block_time, tip_info->verification_progress);
     604             : 
     605           0 :         updateProxyIcon();
     606             : 
     607             : #ifdef ENABLE_WALLET
     608           0 :         if(walletFrame)
     609             :         {
     610           0 :             walletFrame->setClientModel(_clientModel);
     611           0 :         }
     612             : #endif // ENABLE_WALLET
     613           0 :         unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
     614             : 
     615           0 :         OptionsModel* optionsModel = _clientModel->getOptionsModel();
     616           0 :         if (optionsModel && trayIcon) {
     617             :             // be aware of the tray icon disable state change reported by the OptionsModel object.
     618           0 :             connect(optionsModel, &OptionsModel::hideTrayIconChanged, this, &BitcoinGUI::setTrayIconVisible);
     619             : 
     620             :             // initialize the disable state of the tray icon with the current value in the model.
     621           0 :             setTrayIconVisible(optionsModel->getHideTrayIcon());
     622           0 :         }
     623           0 :     } else {
     624             :         // Disable possibility to show main window via action
     625           0 :         toggleHideAction->setEnabled(false);
     626           0 :         if(trayIconMenu)
     627             :         {
     628             :             // Disable context menu on tray icon
     629           0 :             trayIconMenu->clear();
     630           0 :         }
     631             :         // Propagate cleared model to child objects
     632           0 :         rpcConsole->setClientModel(nullptr);
     633             : #ifdef ENABLE_WALLET
     634           0 :         if (walletFrame)
     635             :         {
     636           0 :             walletFrame->setClientModel(nullptr);
     637           0 :         }
     638             : #endif // ENABLE_WALLET
     639           0 :         unitDisplayControl->setOptionsModel(nullptr);
     640             :     }
     641           0 : }
     642             : 
     643             : #ifdef ENABLE_WALLET
     644           0 : void BitcoinGUI::setWalletController(WalletController* wallet_controller)
     645             : {
     646           0 :     assert(!m_wallet_controller);
     647           0 :     assert(wallet_controller);
     648             : 
     649           0 :     m_wallet_controller = wallet_controller;
     650             : 
     651           0 :     m_create_wallet_action->setEnabled(true);
     652           0 :     m_open_wallet_action->setEnabled(true);
     653           0 :     m_open_wallet_action->setMenu(m_open_wallet_menu);
     654             : 
     655           0 :     connect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
     656           0 :     connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
     657             : 
     658           0 :     for (WalletModel* wallet_model : m_wallet_controller->getOpenWallets()) {
     659           0 :         addWallet(wallet_model);
     660             :     }
     661           0 : }
     662             : 
     663           0 : void BitcoinGUI::addWallet(WalletModel* walletModel)
     664             : {
     665           0 :     if (!walletFrame) return;
     666           0 :     if (!walletFrame->addWallet(walletModel)) return;
     667           0 :     const QString display_name = walletModel->getDisplayName();
     668           0 :     setWalletActionsEnabled(true);
     669           0 :     rpcConsole->addWallet(walletModel);
     670           0 :     m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
     671           0 :     if (m_wallet_selector->count() == 2) {
     672           0 :         m_wallet_selector_label_action->setVisible(true);
     673           0 :         m_wallet_selector_action->setVisible(true);
     674             :     }
     675           0 : }
     676             : 
     677           0 : void BitcoinGUI::removeWallet(WalletModel* walletModel)
     678             : {
     679           0 :     if (!walletFrame) return;
     680             : 
     681           0 :     labelWalletHDStatusIcon->hide();
     682           0 :     labelWalletEncryptionIcon->hide();
     683             : 
     684           0 :     int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
     685           0 :     m_wallet_selector->removeItem(index);
     686           0 :     if (m_wallet_selector->count() == 0) {
     687           0 :         setWalletActionsEnabled(false);
     688           0 :         overviewAction->setChecked(true);
     689           0 :     } else if (m_wallet_selector->count() == 1) {
     690           0 :         m_wallet_selector_label_action->setVisible(false);
     691           0 :         m_wallet_selector_action->setVisible(false);
     692           0 :     }
     693           0 :     rpcConsole->removeWallet(walletModel);
     694           0 :     walletFrame->removeWallet(walletModel);
     695           0 :     updateWindowTitle();
     696           0 : }
     697             : 
     698           0 : void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
     699             : {
     700           0 :     if (!walletFrame) return;
     701           0 :     walletFrame->setCurrentWallet(wallet_model);
     702           0 :     for (int index = 0; index < m_wallet_selector->count(); ++index) {
     703           0 :         if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
     704           0 :             m_wallet_selector->setCurrentIndex(index);
     705           0 :             break;
     706             :         }
     707             :     }
     708           0 :     updateWindowTitle();
     709           0 : }
     710             : 
     711           0 : void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
     712             : {
     713           0 :     WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
     714           0 :     if (wallet_model) setCurrentWallet(wallet_model);
     715           0 : }
     716             : 
     717           0 : void BitcoinGUI::removeAllWallets()
     718             : {
     719           0 :     if(!walletFrame)
     720             :         return;
     721           0 :     setWalletActionsEnabled(false);
     722           0 :     walletFrame->removeAllWallets();
     723           0 : }
     724             : #endif // ENABLE_WALLET
     725             : 
     726           0 : void BitcoinGUI::setWalletActionsEnabled(bool enabled)
     727             : {
     728           0 :     overviewAction->setEnabled(enabled);
     729           0 :     sendCoinsAction->setEnabled(enabled);
     730           0 :     sendCoinsMenuAction->setEnabled(enabled);
     731           0 :     receiveCoinsAction->setEnabled(enabled);
     732           0 :     receiveCoinsMenuAction->setEnabled(enabled);
     733           0 :     historyAction->setEnabled(enabled);
     734           0 :     encryptWalletAction->setEnabled(enabled);
     735           0 :     backupWalletAction->setEnabled(enabled);
     736           0 :     changePassphraseAction->setEnabled(enabled);
     737           0 :     signMessageAction->setEnabled(enabled);
     738           0 :     verifyMessageAction->setEnabled(enabled);
     739           0 :     usedSendingAddressesAction->setEnabled(enabled);
     740           0 :     usedReceivingAddressesAction->setEnabled(enabled);
     741           0 :     openAction->setEnabled(enabled);
     742           0 :     m_close_wallet_action->setEnabled(enabled);
     743           0 :     m_close_all_wallets_action->setEnabled(enabled);
     744           0 : }
     745             : 
     746           0 : void BitcoinGUI::createTrayIcon()
     747             : {
     748           0 :     assert(QSystemTrayIcon::isSystemTrayAvailable());
     749             : 
     750             : #ifndef Q_OS_MAC
     751             :     if (QSystemTrayIcon::isSystemTrayAvailable()) {
     752             :         trayIcon = new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
     753             :         QString toolTip = tr("%1 client").arg(PACKAGE_NAME) + " " + m_network_style->getTitleAddText();
     754             :         trayIcon->setToolTip(toolTip);
     755             :     }
     756             : #endif
     757           0 : }
     758             : 
     759           0 : void BitcoinGUI::createTrayIconMenu()
     760             : {
     761             : #ifndef Q_OS_MAC
     762             :     // return if trayIcon is unset (only on non-macOSes)
     763             :     if (!trayIcon)
     764             :         return;
     765             : 
     766             :     trayIcon->setContextMenu(trayIconMenu.get());
     767             :     connect(trayIcon, &QSystemTrayIcon::activated, this, &BitcoinGUI::trayIconActivated);
     768             : #else
     769             :     // Note: On macOS, the Dock icon is used to provide the tray's functionality.
     770           0 :     MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
     771           0 :     connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this, &BitcoinGUI::macosDockIconActivated);
     772           0 :     trayIconMenu->setAsDockMenu();
     773             : #endif
     774             : 
     775             :     // Configuration of the tray icon (or Dock icon) menu
     776             : #ifndef Q_OS_MAC
     777             :     // Note: On macOS, the Dock icon's menu already has Show / Hide action.
     778             :     trayIconMenu->addAction(toggleHideAction);
     779             :     trayIconMenu->addSeparator();
     780             : #endif
     781           0 :     if (enableWallet) {
     782           0 :         trayIconMenu->addAction(sendCoinsMenuAction);
     783           0 :         trayIconMenu->addAction(receiveCoinsMenuAction);
     784           0 :         trayIconMenu->addSeparator();
     785           0 :         trayIconMenu->addAction(signMessageAction);
     786           0 :         trayIconMenu->addAction(verifyMessageAction);
     787           0 :         trayIconMenu->addSeparator();
     788           0 :     }
     789           0 :     trayIconMenu->addAction(optionsAction);
     790           0 :     trayIconMenu->addAction(openRPCConsoleAction);
     791             : #ifndef Q_OS_MAC // This is built-in on macOS
     792             :     trayIconMenu->addSeparator();
     793             :     trayIconMenu->addAction(quitAction);
     794             : #endif
     795           0 : }
     796             : 
     797             : #ifndef Q_OS_MAC
     798             : void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
     799             : {
     800             :     if(reason == QSystemTrayIcon::Trigger)
     801             :     {
     802             :         // Click on system tray icon triggers show/hide of the main window
     803             :         toggleHidden();
     804             :     }
     805             : }
     806             : #else
     807           0 : void BitcoinGUI::macosDockIconActivated()
     808             : {
     809           0 :     show();
     810           0 :     activateWindow();
     811           0 : }
     812             : #endif
     813             : 
     814           0 : void BitcoinGUI::optionsClicked()
     815             : {
     816           0 :     openOptionsDialogWithTab(OptionsDialog::TAB_MAIN);
     817           0 : }
     818             : 
     819           0 : void BitcoinGUI::aboutClicked()
     820             : {
     821           0 :     if(!clientModel)
     822             :         return;
     823             : 
     824           0 :     HelpMessageDialog dlg(this, true);
     825           0 :     dlg.exec();
     826           0 : }
     827             : 
     828           0 : void BitcoinGUI::showDebugWindow()
     829             : {
     830           0 :     GUIUtil::bringToFront(rpcConsole);
     831           0 :     Q_EMIT consoleShown(rpcConsole);
     832           0 : }
     833             : 
     834           0 : void BitcoinGUI::showDebugWindowActivateConsole()
     835             : {
     836           0 :     rpcConsole->setTabFocus(RPCConsole::TabTypes::CONSOLE);
     837           0 :     showDebugWindow();
     838           0 : }
     839             : 
     840           0 : void BitcoinGUI::showHelpMessageClicked()
     841             : {
     842           0 :     helpMessageDialog->show();
     843           0 : }
     844             : 
     845             : #ifdef ENABLE_WALLET
     846           0 : void BitcoinGUI::openClicked()
     847             : {
     848           0 :     OpenURIDialog dlg(this);
     849           0 :     if(dlg.exec())
     850             :     {
     851           0 :         Q_EMIT receivedURI(dlg.getURI());
     852           0 :     }
     853           0 : }
     854             : 
     855           0 : void BitcoinGUI::gotoOverviewPage()
     856             : {
     857           0 :     overviewAction->setChecked(true);
     858           0 :     if (walletFrame) walletFrame->gotoOverviewPage();
     859           0 : }
     860             : 
     861           0 : void BitcoinGUI::gotoHistoryPage()
     862             : {
     863           0 :     historyAction->setChecked(true);
     864           0 :     if (walletFrame) walletFrame->gotoHistoryPage();
     865           0 : }
     866             : 
     867           0 : void BitcoinGUI::gotoReceiveCoinsPage()
     868             : {
     869           0 :     receiveCoinsAction->setChecked(true);
     870           0 :     if (walletFrame) walletFrame->gotoReceiveCoinsPage();
     871           0 : }
     872             : 
     873           0 : void BitcoinGUI::gotoSendCoinsPage(QString addr)
     874             : {
     875           0 :     sendCoinsAction->setChecked(true);
     876           0 :     if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
     877           0 : }
     878             : 
     879           0 : void BitcoinGUI::gotoSignMessageTab(QString addr)
     880             : {
     881           0 :     if (walletFrame) walletFrame->gotoSignMessageTab(addr);
     882           0 : }
     883             : 
     884           0 : void BitcoinGUI::gotoVerifyMessageTab(QString addr)
     885             : {
     886           0 :     if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
     887           0 : }
     888           0 : void BitcoinGUI::gotoLoadPSBT(bool from_clipboard)
     889             : {
     890           0 :     if (walletFrame) walletFrame->gotoLoadPSBT(from_clipboard);
     891           0 : }
     892             : #endif // ENABLE_WALLET
     893             : 
     894           0 : void BitcoinGUI::updateNetworkState()
     895             : {
     896           0 :     int count = clientModel->getNumConnections();
     897           0 :     QString icon;
     898           0 :     switch(count)
     899             :     {
     900           0 :     case 0: icon = ":/icons/connect_0"; break;
     901           0 :     case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
     902           0 :     case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
     903           0 :     case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
     904           0 :     default: icon = ":/icons/connect_4"; break;
     905             :     }
     906             : 
     907           0 :     QString tooltip;
     908             : 
     909           0 :     if (m_node.getNetworkActive()) {
     910           0 :         tooltip = tr("%n active connection(s) to Bitcoin network", "", count) + QString(".<br>") + tr("Click to disable network activity.");
     911           0 :     } else {
     912           0 :         tooltip = tr("Network activity disabled.") + QString("<br>") + tr("Click to enable network activity again.");
     913           0 :         icon = ":/icons/network_disabled";
     914             :     }
     915             : 
     916             :     // Don't word-wrap this (fixed-width) tooltip
     917           0 :     tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
     918           0 :     connectionsControl->setToolTip(tooltip);
     919             : 
     920           0 :     connectionsControl->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
     921           0 : }
     922             : 
     923           0 : void BitcoinGUI::setNumConnections(int count)
     924             : {
     925           0 :     updateNetworkState();
     926           0 : }
     927             : 
     928           0 : void BitcoinGUI::setNetworkActive(bool networkActive)
     929             : {
     930           0 :     updateNetworkState();
     931           0 : }
     932             : 
     933           0 : void BitcoinGUI::updateHeadersSyncProgressLabel()
     934             : {
     935           0 :     int64_t headersTipTime = clientModel->getHeaderTipTime();
     936           0 :     int headersTipHeight = clientModel->getHeaderTipHeight();
     937           0 :     int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
     938           0 :     if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
     939           0 :         progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
     940           0 : }
     941             : 
     942           0 : void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab)
     943             : {
     944           0 :     if (!clientModel || !clientModel->getOptionsModel())
     945             :         return;
     946             : 
     947           0 :     OptionsDialog dlg(this, enableWallet);
     948           0 :     dlg.setCurrentTab(tab);
     949           0 :     dlg.setModel(clientModel->getOptionsModel());
     950           0 :     dlg.exec();
     951           0 : }
     952             : 
     953           0 : void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header, SynchronizationState sync_state)
     954             : {
     955             : // Disabling macOS App Nap on initial sync, disk and reindex operations.
     956             : #ifdef Q_OS_MAC
     957           0 :     if (sync_state == SynchronizationState::POST_INIT) {
     958           0 :         m_app_nap_inhibitor->enableAppNap();
     959           0 :     } else {
     960           0 :         m_app_nap_inhibitor->disableAppNap();
     961             :     }
     962             : #endif
     963             : 
     964           0 :     if (modalOverlay)
     965             :     {
     966           0 :         if (header)
     967           0 :             modalOverlay->setKnownBestHeight(count, blockDate);
     968             :         else
     969           0 :             modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
     970             :     }
     971           0 :     if (!clientModel)
     972             :         return;
     973             : 
     974             :     // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
     975           0 :     statusBar()->clearMessage();
     976             : 
     977             :     // Acquire current block source
     978           0 :     enum BlockSource blockSource = clientModel->getBlockSource();
     979           0 :     switch (blockSource) {
     980             :         case BlockSource::NETWORK:
     981           0 :             if (header) {
     982           0 :                 updateHeadersSyncProgressLabel();
     983           0 :                 return;
     984             :             }
     985           0 :             progressBarLabel->setText(tr("Synchronizing with network..."));
     986           0 :             updateHeadersSyncProgressLabel();
     987           0 :             break;
     988             :         case BlockSource::DISK:
     989           0 :             if (header) {
     990           0 :                 progressBarLabel->setText(tr("Indexing blocks on disk..."));
     991           0 :             } else {
     992           0 :                 progressBarLabel->setText(tr("Processing blocks on disk..."));
     993             :             }
     994             :             break;
     995             :         case BlockSource::REINDEX:
     996           0 :             progressBarLabel->setText(tr("Reindexing blocks on disk..."));
     997           0 :             break;
     998             :         case BlockSource::NONE:
     999           0 :             if (header) {
    1000           0 :                 return;
    1001             :             }
    1002           0 :             progressBarLabel->setText(tr("Connecting to peers..."));
    1003           0 :             break;
    1004             :     }
    1005             : 
    1006           0 :     QString tooltip;
    1007             : 
    1008           0 :     QDateTime currentDate = QDateTime::currentDateTime();
    1009           0 :     qint64 secs = blockDate.secsTo(currentDate);
    1010             : 
    1011           0 :     tooltip = tr("Processed %n block(s) of transaction history.", "", count);
    1012             : 
    1013             :     // Set icon state: spinning if catching up, tick otherwise
    1014           0 :     if (secs < MAX_BLOCK_TIME_GAP) {
    1015           0 :         tooltip = tr("Up to date") + QString(".<br>") + tooltip;
    1016           0 :         labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
    1017             : 
    1018             : #ifdef ENABLE_WALLET
    1019           0 :         if(walletFrame)
    1020             :         {
    1021           0 :             walletFrame->showOutOfSyncWarning(false);
    1022           0 :             modalOverlay->showHide(true, true);
    1023             :         }
    1024             : #endif // ENABLE_WALLET
    1025             : 
    1026           0 :         progressBarLabel->setVisible(false);
    1027           0 :         progressBar->setVisible(false);
    1028             :     }
    1029             :     else
    1030             :     {
    1031           0 :         QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
    1032             : 
    1033           0 :         progressBarLabel->setVisible(true);
    1034           0 :         progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
    1035           0 :         progressBar->setMaximum(1000000000);
    1036           0 :         progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
    1037           0 :         progressBar->setVisible(true);
    1038             : 
    1039           0 :         tooltip = tr("Catching up...") + QString("<br>") + tooltip;
    1040           0 :         if(count != prevBlocks)
    1041             :         {
    1042           0 :             labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
    1043           0 :                 ":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
    1044           0 :                 .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
    1045           0 :             spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
    1046           0 :         }
    1047           0 :         prevBlocks = count;
    1048             : 
    1049             : #ifdef ENABLE_WALLET
    1050           0 :         if(walletFrame)
    1051             :         {
    1052           0 :             walletFrame->showOutOfSyncWarning(true);
    1053           0 :             modalOverlay->showHide();
    1054             :         }
    1055             : #endif // ENABLE_WALLET
    1056             : 
    1057           0 :         tooltip += QString("<br>");
    1058           0 :         tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
    1059           0 :         tooltip += QString("<br>");
    1060           0 :         tooltip += tr("Transactions after this will not yet be visible.");
    1061           0 :     }
    1062             : 
    1063             :     // Don't word-wrap this (fixed-width) tooltip
    1064           0 :     tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
    1065             : 
    1066           0 :     labelBlocksIcon->setToolTip(tooltip);
    1067           0 :     progressBarLabel->setToolTip(tooltip);
    1068           0 :     progressBar->setToolTip(tooltip);
    1069           0 : }
    1070             : 
    1071           0 : void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message)
    1072             : {
    1073             :     // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines).
    1074           0 :     QString strTitle{PACKAGE_NAME};
    1075             :     // Default to information icon
    1076             :     int nMBoxIcon = QMessageBox::Information;
    1077             :     int nNotifyIcon = Notificator::Information;
    1078             : 
    1079           0 :     QString msgType;
    1080           0 :     if (!title.isEmpty()) {
    1081           0 :         msgType = title;
    1082           0 :     } else {
    1083           0 :         switch (style) {
    1084             :         case CClientUIInterface::MSG_ERROR:
    1085           0 :             msgType = tr("Error");
    1086           0 :             message = tr("Error: %1").arg(message);
    1087           0 :             break;
    1088             :         case CClientUIInterface::MSG_WARNING:
    1089           0 :             msgType = tr("Warning");
    1090           0 :             message = tr("Warning: %1").arg(message);
    1091           0 :             break;
    1092             :         case CClientUIInterface::MSG_INFORMATION:
    1093           0 :             msgType = tr("Information");
    1094             :             // No need to prepend the prefix here.
    1095           0 :             break;
    1096             :         default:
    1097             :             break;
    1098             :         }
    1099             :     }
    1100             : 
    1101           0 :     if (!msgType.isEmpty()) {
    1102           0 :         strTitle += " - " + msgType;
    1103           0 :     }
    1104             : 
    1105           0 :     if (style & CClientUIInterface::ICON_ERROR) {
    1106             :         nMBoxIcon = QMessageBox::Critical;
    1107             :         nNotifyIcon = Notificator::Critical;
    1108           0 :     } else if (style & CClientUIInterface::ICON_WARNING) {
    1109             :         nMBoxIcon = QMessageBox::Warning;
    1110             :         nNotifyIcon = Notificator::Warning;
    1111           0 :     }
    1112             : 
    1113           0 :     if (style & CClientUIInterface::MODAL) {
    1114             :         // Check for buttons, use OK as default, if none was supplied
    1115             :         QMessageBox::StandardButton buttons;
    1116           0 :         if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
    1117             :             buttons = QMessageBox::Ok;
    1118             : 
    1119           0 :         showNormalIfMinimized();
    1120           0 :         QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
    1121           0 :         mBox.setTextFormat(Qt::PlainText);
    1122           0 :         mBox.setDetailedText(detailed_message);
    1123           0 :         int r = mBox.exec();
    1124           0 :         if (ret != nullptr)
    1125           0 :             *ret = r == QMessageBox::Ok;
    1126           0 :     } else {
    1127           0 :         notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message);
    1128             :     }
    1129           0 : }
    1130             : 
    1131           0 : void BitcoinGUI::changeEvent(QEvent *e)
    1132             : {
    1133           0 :     QMainWindow::changeEvent(e);
    1134             : #ifndef Q_OS_MAC // Ignored on Mac
    1135             :     if(e->type() == QEvent::WindowStateChange)
    1136             :     {
    1137             :         if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray())
    1138             :         {
    1139             :             QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
    1140             :             if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
    1141             :             {
    1142             :                 QTimer::singleShot(0, this, &BitcoinGUI::hide);
    1143             :                 e->ignore();
    1144             :             }
    1145             :             else if((wsevt->oldState() & Qt::WindowMinimized) && !isMinimized())
    1146             :             {
    1147             :                 QTimer::singleShot(0, this, &BitcoinGUI::show);
    1148             :                 e->ignore();
    1149             :             }
    1150             :         }
    1151             :     }
    1152             : #endif
    1153           0 : }
    1154             : 
    1155           0 : void BitcoinGUI::closeEvent(QCloseEvent *event)
    1156             : {
    1157             : #ifndef Q_OS_MAC // Ignored on Mac
    1158             :     if(clientModel && clientModel->getOptionsModel())
    1159             :     {
    1160             :         if(!clientModel->getOptionsModel()->getMinimizeOnClose())
    1161             :         {
    1162             :             // close rpcConsole in case it was open to make some space for the shutdown window
    1163             :             rpcConsole->close();
    1164             : 
    1165             :             QApplication::quit();
    1166             :         }
    1167             :         else
    1168             :         {
    1169             :             QMainWindow::showMinimized();
    1170             :             event->ignore();
    1171             :         }
    1172             :     }
    1173             : #else
    1174           0 :     QMainWindow::closeEvent(event);
    1175             : #endif
    1176           0 : }
    1177             : 
    1178           0 : void BitcoinGUI::showEvent(QShowEvent *event)
    1179             : {
    1180             :     // enable the debug window when the main window shows up
    1181           0 :     openRPCConsoleAction->setEnabled(true);
    1182           0 :     aboutAction->setEnabled(true);
    1183           0 :     optionsAction->setEnabled(true);
    1184           0 : }
    1185             : 
    1186             : #ifdef ENABLE_WALLET
    1187           0 : void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
    1188             : {
    1189             :     // On new transaction, make an info balloon
    1190           0 :     QString msg = tr("Date: %1\n").arg(date) +
    1191           0 :                   tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
    1192           0 :     if (m_node.walletClient().getWallets().size() > 1 && !walletName.isEmpty()) {
    1193           0 :         msg += tr("Wallet: %1\n").arg(walletName);
    1194           0 :     }
    1195           0 :     msg += tr("Type: %1\n").arg(type);
    1196           0 :     if (!label.isEmpty())
    1197           0 :         msg += tr("Label: %1\n").arg(label);
    1198           0 :     else if (!address.isEmpty())
    1199           0 :         msg += tr("Address: %1\n").arg(address);
    1200           0 :     message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
    1201           0 :              msg, CClientUIInterface::MSG_INFORMATION);
    1202           0 : }
    1203             : #endif // ENABLE_WALLET
    1204             : 
    1205           0 : void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
    1206             : {
    1207             :     // Accept only URIs
    1208           0 :     if(event->mimeData()->hasUrls())
    1209           0 :         event->acceptProposedAction();
    1210           0 : }
    1211             : 
    1212           0 : void BitcoinGUI::dropEvent(QDropEvent *event)
    1213             : {
    1214           0 :     if(event->mimeData()->hasUrls())
    1215             :     {
    1216           0 :         for (const QUrl &uri : event->mimeData()->urls())
    1217             :         {
    1218           0 :             Q_EMIT receivedURI(uri.toString());
    1219           0 :         }
    1220           0 :     }
    1221           0 :     event->acceptProposedAction();
    1222           0 : }
    1223             : 
    1224           0 : bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
    1225             : {
    1226             :     // Catch status tip events
    1227           0 :     if (event->type() == QEvent::StatusTip)
    1228             :     {
    1229             :         // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
    1230           0 :         if (progressBarLabel->isVisible() || progressBar->isVisible())
    1231           0 :             return true;
    1232             :     }
    1233           0 :     return QMainWindow::eventFilter(object, event);
    1234           0 : }
    1235             : 
    1236             : #ifdef ENABLE_WALLET
    1237           0 : bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
    1238             : {
    1239             :     // URI has to be valid
    1240           0 :     if (walletFrame && walletFrame->handlePaymentRequest(recipient))
    1241             :     {
    1242           0 :         showNormalIfMinimized();
    1243           0 :         gotoSendCoinsPage();
    1244           0 :         return true;
    1245             :     }
    1246           0 :     return false;
    1247           0 : }
    1248             : 
    1249           0 : void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled)
    1250             : {
    1251           0 :     labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(privkeyDisabled ? ":/icons/eye" : hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
    1252           0 :     labelWalletHDStatusIcon->setToolTip(privkeyDisabled ? tr("Private key <b>disabled</b>") : hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
    1253           0 :     labelWalletHDStatusIcon->show();
    1254             :     // eventually disable the QLabel to set its opacity to 50%
    1255           0 :     labelWalletHDStatusIcon->setEnabled(hdEnabled);
    1256           0 : }
    1257             : 
    1258           0 : void BitcoinGUI::setEncryptionStatus(int status)
    1259             : {
    1260           0 :     switch(status)
    1261             :     {
    1262             :     case WalletModel::Unencrypted:
    1263           0 :         labelWalletEncryptionIcon->hide();
    1264           0 :         encryptWalletAction->setChecked(false);
    1265           0 :         changePassphraseAction->setEnabled(false);
    1266           0 :         encryptWalletAction->setEnabled(true);
    1267           0 :         break;
    1268             :     case WalletModel::Unlocked:
    1269           0 :         labelWalletEncryptionIcon->show();
    1270           0 :         labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
    1271           0 :         labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
    1272           0 :         encryptWalletAction->setChecked(true);
    1273           0 :         changePassphraseAction->setEnabled(true);
    1274           0 :         encryptWalletAction->setEnabled(false);
    1275           0 :         break;
    1276             :     case WalletModel::Locked:
    1277           0 :         labelWalletEncryptionIcon->show();
    1278           0 :         labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
    1279           0 :         labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
    1280           0 :         encryptWalletAction->setChecked(true);
    1281           0 :         changePassphraseAction->setEnabled(true);
    1282           0 :         encryptWalletAction->setEnabled(false);
    1283           0 :         break;
    1284             :     }
    1285           0 : }
    1286             : 
    1287           0 : void BitcoinGUI::updateWalletStatus()
    1288             : {
    1289           0 :     if (!walletFrame) {
    1290             :         return;
    1291             :     }
    1292           0 :     WalletView * const walletView = walletFrame->currentWalletView();
    1293           0 :     if (!walletView) {
    1294           0 :         return;
    1295             :     }
    1296           0 :     WalletModel * const walletModel = walletView->getWalletModel();
    1297           0 :     setEncryptionStatus(walletModel->getEncryptionStatus());
    1298           0 :     setHDStatus(walletModel->wallet().privateKeysDisabled(), walletModel->wallet().hdEnabled());
    1299           0 : }
    1300             : #endif // ENABLE_WALLET
    1301             : 
    1302           0 : void BitcoinGUI::updateProxyIcon()
    1303             : {
    1304           0 :     std::string ip_port;
    1305           0 :     bool proxy_enabled = clientModel->getProxyInfo(ip_port);
    1306             : 
    1307           0 :     if (proxy_enabled) {
    1308           0 :         if (labelProxyIcon->pixmap() == nullptr) {
    1309           0 :             QString ip_port_q = QString::fromStdString(ip_port);
    1310           0 :             labelProxyIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/proxy").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
    1311           0 :             labelProxyIcon->setToolTip(tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
    1312           0 :         } else {
    1313           0 :             labelProxyIcon->show();
    1314             :         }
    1315             :     } else {
    1316           0 :         labelProxyIcon->hide();
    1317             :     }
    1318           0 : }
    1319             : 
    1320           0 : void BitcoinGUI::updateWindowTitle()
    1321             : {
    1322           0 :     QString window_title = PACKAGE_NAME;
    1323             : #ifdef ENABLE_WALLET
    1324           0 :     if (walletFrame) {
    1325           0 :         WalletModel* const wallet_model = walletFrame->currentWalletModel();
    1326           0 :         if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
    1327           0 :             window_title += " - " + wallet_model->getDisplayName();
    1328           0 :         }
    1329           0 :     }
    1330             : #endif
    1331           0 :     if (!m_network_style->getTitleAddText().isEmpty()) {
    1332           0 :         window_title += " - " + m_network_style->getTitleAddText();
    1333           0 :     }
    1334           0 :     setWindowTitle(window_title);
    1335           0 : }
    1336             : 
    1337           0 : void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
    1338             : {
    1339           0 :     if(!clientModel)
    1340             :         return;
    1341             : 
    1342           0 :     if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) && fToggleHidden) {
    1343           0 :         hide();
    1344           0 :     } else {
    1345           0 :         GUIUtil::bringToFront(this);
    1346             :     }
    1347           0 : }
    1348             : 
    1349           0 : void BitcoinGUI::toggleHidden()
    1350             : {
    1351           0 :     showNormalIfMinimized(true);
    1352           0 : }
    1353             : 
    1354           0 : void BitcoinGUI::detectShutdown()
    1355             : {
    1356           0 :     if (m_node.shutdownRequested())
    1357             :     {
    1358           0 :         if(rpcConsole)
    1359           0 :             rpcConsole->hide();
    1360           0 :         qApp->quit();
    1361           0 :     }
    1362           0 : }
    1363             : 
    1364           0 : void BitcoinGUI::showProgress(const QString &title, int nProgress)
    1365             : {
    1366           0 :     if (nProgress == 0) {
    1367           0 :         progressDialog = new QProgressDialog(title, QString(), 0, 100);
    1368           0 :         GUIUtil::PolishProgressDialog(progressDialog);
    1369           0 :         progressDialog->setWindowModality(Qt::ApplicationModal);
    1370           0 :         progressDialog->setMinimumDuration(0);
    1371           0 :         progressDialog->setAutoClose(false);
    1372           0 :         progressDialog->setValue(0);
    1373           0 :     } else if (nProgress == 100) {
    1374           0 :         if (progressDialog) {
    1375           0 :             progressDialog->close();
    1376           0 :             progressDialog->deleteLater();
    1377           0 :             progressDialog = nullptr;
    1378           0 :         }
    1379           0 :     } else if (progressDialog) {
    1380           0 :         progressDialog->setValue(nProgress);
    1381           0 :     }
    1382           0 : }
    1383             : 
    1384           0 : void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
    1385             : {
    1386           0 :     if (trayIcon)
    1387             :     {
    1388           0 :         trayIcon->setVisible(!fHideTrayIcon);
    1389           0 :     }
    1390           0 : }
    1391             : 
    1392           0 : void BitcoinGUI::showModalOverlay()
    1393             : {
    1394           0 :     if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
    1395           0 :         modalOverlay->toggleVisibility();
    1396           0 : }
    1397             : 
    1398           0 : static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, const std::string& caption, unsigned int style)
    1399             : {
    1400           0 :     bool modal = (style & CClientUIInterface::MODAL);
    1401             :     // The SECURE flag has no effect in the Qt GUI.
    1402             :     // bool secure = (style & CClientUIInterface::SECURE);
    1403           0 :     style &= ~CClientUIInterface::SECURE;
    1404           0 :     bool ret = false;
    1405             : 
    1406           0 :     QString detailed_message; // This is original message, in English, for googling and referencing.
    1407           0 :     if (message.original != message.translated) {
    1408           0 :         detailed_message = BitcoinGUI::tr("Original message:") + "\n" + QString::fromStdString(message.original);
    1409           0 :     }
    1410             : 
    1411             :     // In case of modal message, use blocking connection to wait for user to click a button
    1412           0 :     bool invoked = QMetaObject::invokeMethod(gui, "message",
    1413           0 :                                modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
    1414           0 :                                Q_ARG(QString, QString::fromStdString(caption)),
    1415           0 :                                Q_ARG(QString, QString::fromStdString(message.translated)),
    1416           0 :                                Q_ARG(unsigned int, style),
    1417           0 :                                Q_ARG(bool*, &ret),
    1418           0 :                                Q_ARG(QString, detailed_message));
    1419           0 :     assert(invoked);
    1420           0 :     return ret;
    1421           0 : }
    1422             : 
    1423           0 : void BitcoinGUI::subscribeToCoreSignals()
    1424             : {
    1425             :     // Connect signals to client
    1426           0 :     m_handler_message_box = m_node.handleMessageBox(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    1427           0 :     m_handler_question = m_node.handleQuestion(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_3, std::placeholders::_4));
    1428           0 : }
    1429             : 
    1430           0 : void BitcoinGUI::unsubscribeFromCoreSignals()
    1431             : {
    1432             :     // Disconnect signals from client
    1433           0 :     m_handler_message_box->disconnect();
    1434           0 :     m_handler_question->disconnect();
    1435           0 : }
    1436             : 
    1437           0 : bool BitcoinGUI::isPrivacyModeActivated() const
    1438             : {
    1439           0 :     assert(m_mask_values_action);
    1440           0 :     return m_mask_values_action->isChecked();
    1441             : }
    1442             : 
    1443           0 : UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
    1444           0 :     optionsModel(nullptr),
    1445           0 :     menu(nullptr)
    1446           0 : {
    1447           0 :     createContextMenu();
    1448           0 :     setToolTip(tr("Unit to show amounts in. Click to select another unit."));
    1449           0 :     QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
    1450           0 :     int max_width = 0;
    1451           0 :     const QFontMetrics fm(font());
    1452           0 :     for (const BitcoinUnits::Unit unit : units)
    1453             :     {
    1454           0 :         max_width = qMax(max_width, GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit)));
    1455           0 :     }
    1456           0 :     setMinimumSize(max_width, 0);
    1457           0 :     setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    1458           0 :     setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
    1459           0 : }
    1460             : 
    1461             : /** So that it responds to button clicks */
    1462           0 : void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
    1463             : {
    1464           0 :     onDisplayUnitsClicked(event->pos());
    1465           0 : }
    1466             : 
    1467             : /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
    1468           0 : void UnitDisplayStatusBarControl::createContextMenu()
    1469             : {
    1470           0 :     menu = new QMenu(this);
    1471           0 :     for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
    1472             :     {
    1473           0 :         QAction *menuAction = new QAction(QString(BitcoinUnits::longName(u)), this);
    1474           0 :         menuAction->setData(QVariant(u));
    1475           0 :         menu->addAction(menuAction);
    1476           0 :     }
    1477           0 :     connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection);
    1478           0 : }
    1479             : 
    1480             : /** Lets the control know about the Options Model (and its signals) */
    1481           0 : void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
    1482             : {
    1483           0 :     if (_optionsModel)
    1484             :     {
    1485           0 :         this->optionsModel = _optionsModel;
    1486             : 
    1487             :         // be aware of a display unit change reported by the OptionsModel object.
    1488           0 :         connect(_optionsModel, &OptionsModel::displayUnitChanged, this, &UnitDisplayStatusBarControl::updateDisplayUnit);
    1489             : 
    1490             :         // initialize the display units label with the current value in the model.
    1491           0 :         updateDisplayUnit(_optionsModel->getDisplayUnit());
    1492           0 :     }
    1493           0 : }
    1494             : 
    1495             : /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
    1496           0 : void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
    1497             : {
    1498           0 :     setText(BitcoinUnits::longName(newUnits));
    1499           0 : }
    1500             : 
    1501             : /** Shows context menu with Display Unit options by the mouse coordinates */
    1502           0 : void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
    1503             : {
    1504           0 :     QPoint globalPos = mapToGlobal(point);
    1505           0 :     menu->exec(globalPos);
    1506           0 : }
    1507             : 
    1508             : /** Tells underlying optionsModel to update its current display unit. */
    1509           0 : void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
    1510             : {
    1511           0 :     if (action)
    1512             :     {
    1513           0 :         optionsModel->setDisplayUnit(action->data());
    1514           0 :     }
    1515           0 : }

Generated by: LCOV version 1.15