Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
bitcoingui.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2019 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 <chain.h>
8#include <chainparams.h>
9#include <config.h>
10#include <interfaces/handler.h>
11#include <interfaces/node.h>
12#include <node/ui_interface.h>
13#include <qt/bitcoinunits.h>
14#include <qt/clientmodel.h>
16#include <qt/guiconstants.h>
17#include <qt/guiutil.h>
18#ifdef Q_OS_MAC
20#endif
21#include <qt/modaloverlay.h>
22#include <qt/networkstyle.h>
23#include <qt/notificator.h>
24#include <qt/openuridialog.h>
25#include <qt/optionsmodel.h>
26#include <qt/platformstyle.h>
27#include <qt/rpcconsole.h>
28#include <qt/utilitydialog.h>
29#ifdef ENABLE_WALLET
30#include <qt/walletcontroller.h>
31#include <qt/walletframe.h>
32#include <qt/walletmodel.h>
33#include <qt/walletview.h>
34#endif // ENABLE_WALLET
35#include <common/system.h>
36#include <util/translation.h>
37#include <validation.h>
38
39#include <functional>
40#include <memory>
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
66const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
67#if defined(Q_OS_MAC)
68 "macosx"
69#elif defined(Q_OS_WIN)
70 "windows"
71#else
72 "other"
73#endif
74 ;
75
78 const NetworkStyle *networkStyle, QWidget *parent)
79 : QMainWindow(parent), m_node(node), trayIconMenu{new QMenu()},
80 config(configIn), platformStyle(_platformStyle),
81 m_network_style(networkStyle) {
83 if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
84 // Restore failed (perhaps missing setting), center the window
85 move(QGuiApplication::primaryScreen()->availableGeometry().center() -
87 }
88
89#ifdef ENABLE_WALLET
91#endif // ENABLE_WALLET
92 QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
95
97 helpMessageDialog = new HelpMessageDialog(this, false);
98#ifdef ENABLE_WALLET
99 if (enableWallet) {
103 } else
104#endif // ENABLE_WALLET
105 {
112 }
113
115
116 // Accept D&D of URIs
117 setAcceptDrops(true);
118
119 // Create actions for the toolbar, menu bar and tray/dock icon
120 // Needs walletFrame to be initialized
122
123 // Create application menu bar
125
126 // Create the toolbars
128
129 // Create system tray icon and notification
130 if (QSystemTrayIcon::isSystemTrayAvailable()) {
132 }
134 new Notificator(QApplication::applicationName(), trayIcon, this);
135
136 // Create status bar
137 statusBar();
138
139 // Disable size grip because it looks ugly and nobody needs it
140 statusBar()->setSizeGripEnabled(false);
141
142 // Status bar notification icons
143 QFrame *frameBlocks = new QFrame();
144 frameBlocks->setContentsMargins(0, 0, 0, 0);
145 frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
147 frameBlocksLayout->setContentsMargins(3, 0, 3, 0);
148 frameBlocksLayout->setSpacing(3);
150 labelWalletEncryptionIcon = new QLabel();
151 labelWalletHDStatusIcon = new QLabel();
155 if (enableWallet) {
156 frameBlocksLayout->addStretch();
158 frameBlocksLayout->addStretch();
161 }
163 frameBlocksLayout->addStretch();
165 frameBlocksLayout->addStretch();
167 frameBlocksLayout->addStretch();
168
169 // Progress bar and label for blocks download
170 progressBarLabel = new QLabel();
171 progressBarLabel->setVisible(false);
173 progressBar->setAlignment(Qt::AlignCenter);
174 progressBar->setVisible(false);
175
176 // Override style sheet for progress bar for styles that have a segmented
177 // progress bar, as they make the text unreadable (workaround for issue
178 // #1071)
179 // See https://doc.qt.io/qt-5/gallery.html
180 QString curStyle = QApplication::style()->metaObject()->className();
181 if (curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle") {
182 progressBar->setStyleSheet(
183 "QProgressBar { background-color: #e8e8e8; border: 1px solid grey; "
184 "border-radius: 7px; padding: 1px; text-align: center; } "
185 "QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, "
186 "x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: "
187 "7px; margin: 0px; }");
188 }
189
190 statusBar()->addWidget(progressBarLabel);
191 statusBar()->addWidget(progressBar);
192 statusBar()->addPermanentWidget(frameBlocks);
193
194 // Install event filter to be able to catch status tip events
195 // (QEvent::StatusTip)
196 this->installEventFilter(this);
197
198 // Initially wallet actions should be disabled
200
201 // Subscribe to notifications from core
203
208
213#ifdef ENABLE_WALLET
214 if (enableWallet) {
217 }
218#endif
219
220#ifdef Q_OS_MAC
222#endif
223
225}
226
228 // Unsubscribe from notifications from core
230
232 settings.setValue("MainWindowGeometry", saveGeometry());
233 // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
234 if (trayIcon) {
235 trayIcon->hide();
236 }
237#ifdef Q_OS_MAC
238 delete m_app_nap_inhibitor;
239 delete appMenuBar;
241#endif
242
243 delete rpcConsole;
244}
245
249 &QActionGroup::setEnabled);
250
252 new QAction(platformStyle->SingleColorIcon(":/icons/overview"),
253 tr("&Overview"), this);
254 overviewAction->setStatusTip(tr("Show general overview of wallet"));
255 overviewAction->setToolTip(overviewAction->statusTip());
256 overviewAction->setCheckable(true);
257 overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
258 tabGroup->addAction(overviewAction);
259
261 platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
262 sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
263 sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
264 sendCoinsAction->setCheckable(true);
265 sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
266 tabGroup->addAction(sendCoinsAction);
267
268 sendCoinsMenuAction = new QAction(sendCoinsAction->text(), this);
269 sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
270 sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
271
273 platformStyle->SingleColorIcon(":/icons/receiving_addresses"),
274 tr("&Receive"), this);
275 receiveCoinsAction->setStatusTip(
276 tr("Request payments (generates QR codes and %1: URIs)")
277 .arg(QString::fromStdString(
279 receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
280 receiveCoinsAction->setCheckable(true);
281 receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
282 tabGroup->addAction(receiveCoinsAction);
283
285 receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
286 receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
287
289 new QAction(platformStyle->SingleColorIcon(":/icons/history"),
290 tr("&Transactions"), this);
291 historyAction->setStatusTip(tr("Browse transaction history"));
292 historyAction->setToolTip(historyAction->statusTip());
293 historyAction->setCheckable(true);
294 historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
295 tabGroup->addAction(historyAction);
296
297#ifdef ENABLE_WALLET
298 // These showNormalIfMinimized are needed because Send Coins and Receive
299 // Coins can be triggered from the tray menu, and need to show the GUI to be
300 // useful.
301 connect(overviewAction, &QAction::triggered,
302 [this] { showNormalIfMinimized(); });
303 connect(overviewAction, &QAction::triggered, this,
304 &BitcoinGUI::gotoOverviewPage);
305 connect(sendCoinsAction, &QAction::triggered,
306 [this] { showNormalIfMinimized(); });
307 connect(sendCoinsAction, &QAction::triggered,
308 [this] { gotoSendCoinsPage(); });
309 connect(sendCoinsMenuAction, &QAction::triggered,
310 [this] { showNormalIfMinimized(); });
311 connect(sendCoinsMenuAction, &QAction::triggered,
312 [this] { gotoSendCoinsPage(); });
313 connect(receiveCoinsAction, &QAction::triggered,
314 [this] { showNormalIfMinimized(); });
315 connect(receiveCoinsAction, &QAction::triggered, this,
316 &BitcoinGUI::gotoReceiveCoinsPage);
317 connect(receiveCoinsMenuAction, &QAction::triggered,
318 [this] { showNormalIfMinimized(); });
319 connect(receiveCoinsMenuAction, &QAction::triggered, this,
320 &BitcoinGUI::gotoReceiveCoinsPage);
321 connect(historyAction, &QAction::triggered,
322 [this] { showNormalIfMinimized(); });
323 connect(historyAction, &QAction::triggered, this,
324 &BitcoinGUI::gotoHistoryPage);
325#endif // ENABLE_WALLET
326
327 quitAction = new QAction(tr("E&xit"), this);
328 quitAction->setStatusTip(tr("Quit application"));
329 quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
330 quitAction->setMenuRole(QAction::QuitRole);
331 aboutAction = new QAction(tr("&About %1").arg(PACKAGE_NAME), this);
332 aboutAction->setStatusTip(
333 tr("Show information about %1").arg(PACKAGE_NAME));
334 aboutAction->setMenuRole(QAction::AboutRole);
335 aboutAction->setEnabled(false);
336 aboutQtAction = new QAction(tr("About &Qt"), this);
337 aboutQtAction->setStatusTip(tr("Show information about Qt"));
338 aboutQtAction->setMenuRole(QAction::AboutQtRole);
339 optionsAction = new QAction(tr("&Options..."), this);
340 optionsAction->setStatusTip(
341 tr("Modify configuration options for %1").arg(PACKAGE_NAME));
342 optionsAction->setMenuRole(QAction::PreferencesRole);
343 optionsAction->setEnabled(false);
344 toggleHideAction = new QAction(tr("&Show / Hide"), this);
345 toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
346
347 encryptWalletAction = new QAction(tr("&Encrypt Wallet..."), this);
348 encryptWalletAction->setStatusTip(
349 tr("Encrypt the private keys that belong to your wallet"));
350 encryptWalletAction->setCheckable(true);
351 backupWalletAction = new QAction(tr("&Backup Wallet..."), this);
352 backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
353 changePassphraseAction = new QAction(tr("&Change Passphrase..."), this);
354 changePassphraseAction->setStatusTip(
355 tr("Change the passphrase used for wallet encryption"));
356 signMessageAction = new QAction(tr("Sign &message..."), this);
357 signMessageAction->setStatusTip(
358 tr("Sign messages with your Bitcoin addresses to prove you own them"));
359 verifyMessageAction = new QAction(tr("&Verify message..."), this);
360 verifyMessageAction->setStatusTip(
361 tr("Verify messages to ensure they were signed with specified Bitcoin "
362 "addresses"));
363 m_load_psbt_action = new QAction(tr("Load PSBT..."), this);
364 m_load_psbt_action->setStatusTip(
365 tr("Load Partially Signed Bitcoin Transaction"));
366
367 openRPCConsoleAction = new QAction(tr("&Debug window"), this);
368 openRPCConsoleAction->setStatusTip(
369 tr("Open node debugging and diagnostic console"));
370 // initially disable the debug window menu item
371 openRPCConsoleAction->setEnabled(false);
372 openRPCConsoleAction->setObjectName("openRPCConsoleAction");
373
374 usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
375 usedSendingAddressesAction->setStatusTip(
376 tr("Show the list of used sending addresses and labels"));
378 new QAction(tr("&Receiving addresses"), this);
379 usedReceivingAddressesAction->setStatusTip(
380 tr("Show the list of used receiving addresses and labels"));
381
382 openAction = new QAction(tr("Open &URI..."), this);
383 openAction->setStatusTip(
384 tr("Open a %1: URI or payment request")
385 .arg(QString::fromStdString(
387
388 m_open_wallet_action = new QAction(tr("Open Wallet"), this);
389 m_open_wallet_action->setEnabled(false);
390 m_open_wallet_action->setStatusTip(tr("Open a wallet"));
391 m_open_wallet_menu = new QMenu(this);
392
393 m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
394 m_close_wallet_action->setStatusTip(tr("Close wallet"));
395
396 m_create_wallet_action = new QAction(tr("Create Wallet..."), this);
397 m_create_wallet_action->setEnabled(false);
398 m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
399
400 m_close_all_wallets_action = new QAction(tr("Close All Wallets..."), this);
401 m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
402
403 showHelpMessageAction = new QAction(tr("&Command-line options"), this);
404 showHelpMessageAction->setMenuRole(QAction::NoRole);
405 showHelpMessageAction->setStatusTip(
406 tr("Show the %1 help message to get a list with possible Bitcoin "
407 "command-line options")
408 .arg(PACKAGE_NAME));
409
410 m_mask_values_action = new QAction(tr("&Mask values"), this);
411 m_mask_values_action->setShortcut(
412 QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M));
413 m_mask_values_action->setStatusTip(
414 tr("Mask the values in the Overview tab"));
415 m_mask_values_action->setCheckable(true);
416
417 connect(quitAction, &QAction::triggered, qApp, QApplication::quit);
418 connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
419 connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
420 connect(optionsAction, &QAction::triggered, this,
422 connect(toggleHideAction, &QAction::triggered, this,
424 connect(showHelpMessageAction, &QAction::triggered, this,
426 connect(openRPCConsoleAction, &QAction::triggered, this,
428 // prevents an open debug window from becoming stuck/unusable on client
429 // shutdown
430 connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
431
432#ifdef ENABLE_WALLET
433 if (walletFrame) {
434 connect(encryptWalletAction, &QAction::triggered, walletFrame,
436 connect(backupWalletAction, &QAction::triggered, walletFrame,
438 connect(changePassphraseAction, &QAction::triggered, walletFrame,
440 connect(signMessageAction, &QAction::triggered,
441 [this] { showNormalIfMinimized(); });
442 connect(signMessageAction, &QAction::triggered,
443 [this] { gotoSignMessageTab(); });
444 connect(verifyMessageAction, &QAction::triggered,
445 [this] { showNormalIfMinimized(); });
446 connect(verifyMessageAction, &QAction::triggered,
447 [this] { gotoVerifyMessageTab(); });
448 connect(m_load_psbt_action, &QAction::triggered,
449 [this] { gotoLoadPSBT(); });
450 connect(usedSendingAddressesAction, &QAction::triggered, walletFrame,
454 connect(openAction, &QAction::triggered, this,
455 &BitcoinGUI::openClicked);
456 connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
457 m_open_wallet_menu->clear();
458 for (const std::pair<const std::string, bool> &i :
460 const std::string &path = i.first;
461 QString name = path.empty()
462 ? QString("[" + tr("default wallet") + "]")
463 : QString::fromStdString(path);
464 // Menu items remove single &. Single & are shown when && is in
465 // the string, but only the first occurrence. So replace only
466 // the first & with &&
467 name.replace(name.indexOf(QChar('&')), 1, QString("&&"));
468 QAction *action = m_open_wallet_menu->addAction(name);
469
470 if (i.second) {
471 // This wallet is already loaded
472 action->setEnabled(false);
473 continue;
474 }
475
476 connect(action, &QAction::triggered, [this, path] {
477 auto activity =
480 &BitcoinGUI::setCurrentWallet);
482 &QObject::deleteLater);
483 activity->open(path);
484 });
485 }
486 if (m_open_wallet_menu->isEmpty()) {
487 QAction *action =
488 m_open_wallet_menu->addAction(tr("No wallets available"));
489 action->setEnabled(false);
490 }
491 });
492 connect(m_close_wallet_action, &QAction::triggered, [this] {
494 this);
495 });
496 connect(m_create_wallet_action, &QAction::triggered, [this] {
499 &BitcoinGUI::setCurrentWallet);
501 &QObject::deleteLater);
502 activity->create();
503 });
504 connect(m_close_all_wallets_action, &QAction::triggered,
505 [this] { m_wallet_controller->closeAllWallets(this); });
506 connect(m_mask_values_action, &QAction::toggled, this,
508 }
509#endif // ENABLE_WALLET
510
511 connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this),
512 &QShortcut::activated, this,
514 connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this),
515 &QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
516}
517
519#ifdef Q_OS_MAC
520 // Create a decoupled menu bar on Mac which stays even if the window is
521 // closed
522 appMenuBar = new QMenuBar();
523#else
524 // Get the main window's menu bar on other platforms
526#endif
527
528 // Configure the menus
529 QMenu *file = appMenuBar->addMenu(tr("&File"));
530 if (walletFrame) {
531 file->addAction(m_create_wallet_action);
532 file->addAction(m_open_wallet_action);
533 file->addAction(m_close_wallet_action);
534 file->addAction(m_close_all_wallets_action);
535 file->addSeparator();
536 file->addAction(openAction);
537 file->addAction(backupWalletAction);
538 file->addAction(signMessageAction);
539 file->addAction(verifyMessageAction);
540 file->addAction(m_load_psbt_action);
541 file->addSeparator();
542 }
543 file->addAction(quitAction);
544
545 QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
546 if (walletFrame) {
547 settings->addAction(encryptWalletAction);
549 settings->addSeparator();
550 settings->addAction(m_mask_values_action);
551 settings->addSeparator();
552 }
553 settings->addAction(optionsAction);
554
555 QMenu *window_menu = appMenuBar->addMenu(tr("&Window"));
556
557 QAction *minimize_action = window_menu->addAction(tr("Minimize"));
558 minimize_action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
559 connect(minimize_action, &QAction::triggered,
560 [] { QApplication::activeWindow()->showMinimized(); });
561 connect(qApp, &QApplication::focusWindowChanged,
562 [minimize_action](QWindow *window) {
563 minimize_action->setEnabled(
564 window != nullptr &&
565 (window->flags() & Qt::Dialog) != Qt::Dialog &&
566 window->windowState() != Qt::WindowMinimized);
567 });
568
569#ifdef Q_OS_MAC
570 QAction *zoom_action = window_menu->addAction(tr("Zoom"));
571 connect(zoom_action, &QAction::triggered, [] {
572 QWindow *window = qApp->focusWindow();
573 if (window->windowState() != Qt::WindowMaximized) {
574 window->showMaximized();
575 } else {
576 window->showNormal();
577 }
578 });
579
580 connect(qApp, &QApplication::focusWindowChanged,
581 [zoom_action](QWindow *window) {
582 zoom_action->setEnabled(window != nullptr);
583 });
584#endif
585
586 if (walletFrame) {
587#ifdef Q_OS_MAC
588 window_menu->addSeparator();
589 QAction *main_window_action = window_menu->addAction(tr("Main Window"));
590 connect(main_window_action, &QAction::triggered,
591 [this] { GUIUtil::bringToFront(this); });
592#endif
593 window_menu->addSeparator();
596 }
597
598 window_menu->addSeparator();
603 connect(tab_action, &QAction::triggered, [this, tab_type] {
606 });
607 }
608
609 QMenu *help = appMenuBar->addMenu(tr("&Help"));
610 help->addAction(showHelpMessageAction);
611 help->addSeparator();
612 help->addAction(aboutAction);
613 help->addAction(aboutQtAction);
614}
615
617 if (walletFrame) {
618 QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
620 toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
621 toolbar->setMovable(false);
622 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
623 toolbar->addAction(overviewAction);
624 toolbar->addAction(sendCoinsAction);
625 toolbar->addAction(receiveCoinsAction);
626 toolbar->addAction(historyAction);
627 overviewAction->setChecked(true);
628
629#ifdef ENABLE_WALLET
630 QWidget *spacer = new QWidget();
631 spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
632 toolbar->addWidget(spacer);
633
634 m_wallet_selector = new QComboBox();
635 m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
637 static_cast<void (QComboBox::*)(int)>(
638 &QComboBox::currentIndexChanged),
639 this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
640
641 m_wallet_selector_label = new QLabel();
642 m_wallet_selector_label->setText(tr("Wallet:") + " ");
644
648
649 m_wallet_selector_label_action->setVisible(false);
650 m_wallet_selector_action->setVisible(false);
651#endif
652 }
653}
654
658 if (_clientModel) {
659 // Create system tray menu (or setup the dock menu) that late to prevent
660 // users from calling actions, while the client has not yet fully loaded
662
663 // Keep up to date with client
669
671 tip_info->header_height,
672 QDateTime::fromTime_t(tip_info->header_time), /*presync=*/false);
673 setNumBlocks(tip_info->block_height,
674 QDateTime::fromTime_t(tip_info->block_time),
675 tip_info->verification_progress, SyncType::BLOCK_SYNC,
679
680 // Receive and report messages from client model
682 [this](const QString &title, const QString &message,
683 unsigned int style) {
684 this->message(title, message, style);
685 });
686
687 // Show progress dialog
690
692 tip_info->block_time,
693 tip_info->verification_progress);
694
696
697#ifdef ENABLE_WALLET
698 if (walletFrame) {
700 }
701#endif // ENABLE_WALLET
703
704 OptionsModel *optionsModel = _clientModel->getOptionsModel();
705 if (optionsModel && trayIcon) {
706 // be aware of the tray icon disable state change reported by the
707 // OptionsModel object.
708 connect(optionsModel, &OptionsModel::hideTrayIconChanged, this,
710
711 // initialize the disable state of the tray icon with the current
712 // value in the model.
713 setTrayIconVisible(optionsModel->getHideTrayIcon());
714 }
715 } else {
716 // Disable possibility to show main window via action
717 toggleHideAction->setEnabled(false);
718 if (trayIconMenu) {
719 // Disable context menu on tray icon
720 trayIconMenu->clear();
721 }
722 // Propagate cleared model to child objects
723 rpcConsole->setClientModel(nullptr);
724#ifdef ENABLE_WALLET
725 if (walletFrame) {
726 walletFrame->setClientModel(nullptr);
727 }
728#endif // ENABLE_WALLET
730 }
731}
732
733#ifdef ENABLE_WALLET
734void BitcoinGUI::setWalletController(WalletController *wallet_controller) {
737
739
740 m_create_wallet_action->setEnabled(true);
741 m_open_wallet_action->setEnabled(true);
743
745 &BitcoinGUI::addWallet);
747 &BitcoinGUI::removeWallet);
748
749 for (WalletModel *wallet_model : m_wallet_controller->getOpenWallets()) {
750 addWallet(wallet_model);
751 }
752}
753
754WalletController *BitcoinGUI::getWalletController() {
755 return m_wallet_controller;
756}
757
758void BitcoinGUI::addWallet(WalletModel *walletModel) {
759 if (!walletFrame) {
760 return;
761 }
762 if (!walletFrame->addWallet(walletModel)) {
763 return;
764 }
765 rpcConsole->addWallet(walletModel);
766 if (m_wallet_selector->count() == 0) {
768 } else if (m_wallet_selector->count() == 1) {
769 m_wallet_selector_label_action->setVisible(true);
770 m_wallet_selector_action->setVisible(true);
771 }
772 const QString display_name = walletModel->getDisplayName();
773 m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
774}
775
776void BitcoinGUI::removeWallet(WalletModel *walletModel) {
777 if (!walletFrame) {
778 return;
779 }
780
783
784 int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
785 m_wallet_selector->removeItem(index);
786 if (m_wallet_selector->count() == 0) {
788 overviewAction->setChecked(true);
789 } else if (m_wallet_selector->count() == 1) {
790 m_wallet_selector_label_action->setVisible(false);
791 m_wallet_selector_action->setVisible(false);
792 }
793 rpcConsole->removeWallet(walletModel);
794 walletFrame->removeWallet(walletModel);
796}
797
798void BitcoinGUI::setCurrentWallet(WalletModel *wallet_model) {
799 if (!walletFrame) {
800 return;
801 }
803 for (int index = 0; index < m_wallet_selector->count(); ++index) {
804 if (m_wallet_selector->itemData(index).value<WalletModel *>() ==
805 wallet_model) {
806 m_wallet_selector->setCurrentIndex(index);
807 break;
808 }
809 }
811}
812
813void BitcoinGUI::setCurrentWalletBySelectorIndex(int index) {
815 m_wallet_selector->itemData(index).value<WalletModel *>();
816 if (wallet_model) {
817 setCurrentWallet(wallet_model);
818 }
819}
820
821void BitcoinGUI::removeAllWallets() {
822 if (!walletFrame) {
823 return;
824 }
827}
828#endif // ENABLE_WALLET
829
831 overviewAction->setEnabled(enabled);
832 sendCoinsAction->setEnabled(enabled);
833 sendCoinsMenuAction->setEnabled(enabled);
834 receiveCoinsAction->setEnabled(enabled);
835 receiveCoinsMenuAction->setEnabled(enabled);
836 historyAction->setEnabled(enabled);
837 encryptWalletAction->setEnabled(enabled);
838 backupWalletAction->setEnabled(enabled);
839 changePassphraseAction->setEnabled(enabled);
840 signMessageAction->setEnabled(enabled);
841 verifyMessageAction->setEnabled(enabled);
842 usedSendingAddressesAction->setEnabled(enabled);
843 usedReceivingAddressesAction->setEnabled(enabled);
844 openAction->setEnabled(enabled);
845 m_close_wallet_action->setEnabled(enabled);
846 m_close_all_wallets_action->setEnabled(enabled);
847}
848
850 assert(QSystemTrayIcon::isSystemTrayAvailable());
851
852#ifndef Q_OS_MAC
853 if (QSystemTrayIcon::isSystemTrayAvailable()) {
854 trayIcon =
856 QString toolTip = tr("%1 client").arg(PACKAGE_NAME) + " " +
858 trayIcon->setToolTip(toolTip);
859 }
860#endif
861}
862
864#ifndef Q_OS_MAC
865 // Return if trayIcon is unset (only on non-macOSes)
866 if (!trayIcon) {
867 return;
868 }
869
870 trayIcon->setContextMenu(trayIconMenu.get());
871 connect(trayIcon, &QSystemTrayIcon::activated, this,
873#else
874 // Note: On macOS, the Dock icon is used to provide the tray's
875 // functionality.
878 &BitcoinGUI::macosDockIconActivated);
879 trayIconMenu->setAsDockMenu();
880#endif
881
882 // Configuration of the tray icon (or Dock icon) menu
883#ifndef Q_OS_MAC
884 // Note: On macOS, the Dock icon's menu already has Show / Hide action.
885 trayIconMenu->addAction(toggleHideAction);
886 trayIconMenu->addSeparator();
887#endif
888 if (enableWallet) {
891 trayIconMenu->addSeparator();
894 trayIconMenu->addSeparator();
895 }
896 trayIconMenu->addAction(optionsAction);
898#ifndef Q_OS_MAC
899 // This is built-in on macOS
900 trayIconMenu->addSeparator();
901 trayIconMenu->addAction(quitAction);
902#endif
903}
904
905#ifndef Q_OS_MAC
906void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) {
907 if (reason == QSystemTrayIcon::Trigger) {
908 // Click on system tray icon triggers show/hide of the main window
909 toggleHidden();
910 }
911}
912#else
913void BitcoinGUI::macosDockIconActivated() {
914 show();
916}
917#endif
918
922
924 if (!clientModel) {
925 return;
926 }
927
928 HelpMessageDialog dlg(this, true);
929 dlg.exec();
930}
931
936
941
945
946#ifdef ENABLE_WALLET
947void BitcoinGUI::openClicked() {
949 if (dlg.exec()) {
950 Q_EMIT receivedURI(dlg.getURI());
951 }
952}
953
954void BitcoinGUI::gotoOverviewPage() {
955 overviewAction->setChecked(true);
956 if (walletFrame) {
958 }
959}
960
961void BitcoinGUI::gotoHistoryPage() {
962 historyAction->setChecked(true);
963 if (walletFrame) {
965 }
966}
967
968void BitcoinGUI::gotoReceiveCoinsPage() {
969 receiveCoinsAction->setChecked(true);
970 if (walletFrame) {
972 }
973}
974
975void BitcoinGUI::gotoSendCoinsPage(QString addr) {
976 sendCoinsAction->setChecked(true);
977 if (walletFrame) {
979 }
980}
981
982void BitcoinGUI::gotoSignMessageTab(QString addr) {
983 if (walletFrame) {
985 }
986}
987
988void BitcoinGUI::gotoVerifyMessageTab(QString addr) {
989 if (walletFrame) {
991 }
992}
993void BitcoinGUI::gotoLoadPSBT() {
994 if (walletFrame) {
996 }
997}
998#endif // ENABLE_WALLET
999
1002 QString icon;
1003 switch (count) {
1004 case 0:
1005 icon = ":/icons/connect_0";
1006 break;
1007 case 1:
1008 case 2:
1009 case 3:
1010 icon = ":/icons/connect_1";
1011 break;
1012 case 4:
1013 case 5:
1014 case 6:
1015 icon = ":/icons/connect_2";
1016 break;
1017 case 7:
1018 case 8:
1019 case 9:
1020 icon = ":/icons/connect_3";
1021 break;
1022 default:
1023 icon = ":/icons/connect_4";
1024 break;
1025 }
1026
1028
1029 if (m_node.getNetworkActive()) {
1030 tooltip = tr("%n active connection(s) to Bitcoin network", "", count) +
1031 QString(".<br>") + tr("Click to disable network activity.");
1032 } else {
1033 tooltip = tr("Network activity disabled.") + QString("<br>") +
1034 tr("Click to enable network activity again.");
1035 icon = ":/icons/network_disabled";
1036 }
1037
1038 // Don't word-wrap this (fixed-width) tooltip
1039 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1040 connectionsControl->setToolTip(tooltip);
1041
1044}
1045
1049
1053
1057 int estHeadersLeft =
1058 (GetTime() - headersTipTime) /
1061 progressBarLabel->setText(
1062 tr("Syncing Headers (%1%)...")
1063 .arg(QString::number(100.0 /
1066 'f', 1)));
1067 }
1068}
1069
1071 const QDateTime &blockDate) {
1072 int estHeadersLeft = blockDate.secsTo(QDateTime::currentDateTime()) /
1075 progressBarLabel->setText(
1076 tr("Pre-syncing Headers (%1%)…")
1077 .arg(QString::number(100.0 / (height + estHeadersLeft) * height,
1078 'f', 1)));
1079 }
1080}
1081
1084 return;
1085 }
1086
1088 dlg.setCurrentTab(tab);
1089 dlg.setModel(clientModel->getOptionsModel());
1090 dlg.exec();
1091}
1092
1096// Disabling macOS App Nap on initial sync, disk and reindex operations.
1097#ifdef Q_OS_MAC
1099 m_app_nap_inhibitor->enableAppNap();
1100 } else {
1101 m_app_nap_inhibitor->disableAppNap();
1102 }
1103#endif
1104
1105 if (modalOverlay) {
1109 } else {
1111 }
1112 }
1113 if (!clientModel) {
1114 return;
1115 }
1116
1117 // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait
1118 // until chain-sync starts -> garbled text)
1119 statusBar()->clearMessage();
1120
1121 // Acquire current block source
1123 switch (blockSource) {
1127 return;
1128 } else if (synctype == SyncType::HEADER_SYNC) {
1130 return;
1131 }
1132 progressBarLabel->setText(tr("Synchronizing with network..."));
1134 break;
1135 case BlockSource::DISK:
1137 progressBarLabel->setText(tr("Indexing blocks on disk..."));
1138 } else {
1139 progressBarLabel->setText(tr("Processing blocks on disk..."));
1140 }
1141 break;
1142 case BlockSource::NONE:
1144 return;
1145 }
1146 progressBarLabel->setText(tr("Connecting to peers..."));
1147 break;
1148 }
1149
1151
1152 QDateTime currentDate = QDateTime::currentDateTime();
1153 qint64 secs = blockDate.secsTo(currentDate);
1154
1155 tooltip = tr("Processed %n block(s) of transaction history.", "", count);
1156
1157 // Set icon state: spinning if catching up, tick otherwise
1158 if (secs < MAX_BLOCK_TIME_GAP) {
1159 tooltip = tr("Up to date") + QString(".<br>") + tooltip;
1160 labelBlocksIcon->setPixmap(
1161 platformStyle->SingleColorIcon(":/icons/synced")
1163
1164#ifdef ENABLE_WALLET
1165 if (walletFrame) {
1167 modalOverlay->showHide(true, true);
1168 }
1169#endif // ENABLE_WALLET
1170
1171 progressBarLabel->setVisible(false);
1172 progressBar->setVisible(false);
1173 } else {
1175
1176 progressBarLabel->setVisible(true);
1177 progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
1178 progressBar->setMaximum(1000000000);
1179 progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
1180 progressBar->setVisible(true);
1181
1182 tooltip = tr("Catching up...") + QString("<br>") + tooltip;
1183 if (count != prevBlocks) {
1184 labelBlocksIcon->setPixmap(
1186 ->SingleColorIcon(QString(":/animation/spinner-%1")
1187 .arg(spinnerFrame, 3, 10, QChar('0')))
1190 }
1191 prevBlocks = count;
1192
1193#ifdef ENABLE_WALLET
1194 if (walletFrame) {
1197 }
1198#endif // ENABLE_WALLET
1199
1200 tooltip += QString("<br>");
1201 tooltip +=
1202 tr("Last received block was generated %1 ago.").arg(timeBehindText);
1203 tooltip += QString("<br>");
1204 tooltip += tr("Transactions after this will not yet be visible.");
1205 }
1206
1207 // Don't word-wrap this (fixed-width) tooltip
1208 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1209
1210 labelBlocksIcon->setToolTip(tooltip);
1211 progressBarLabel->setToolTip(tooltip);
1212 progressBar->setToolTip(tooltip);
1213}
1214
1215void BitcoinGUI::message(const QString &title, QString message,
1216 unsigned int style, bool *ret,
1217 const QString &detailed_message) {
1218 // Default title. On macOS, the window title is ignored (as required by the
1219 // macOS Guidelines).
1221 // Default to information icon
1222 int nMBoxIcon = QMessageBox::Information;
1224
1226 if (!title.isEmpty()) {
1227 msgType = title;
1228 } else {
1229 switch (style) {
1231 msgType = tr("Error");
1232 message = tr("Error: %1").arg(message);
1233 break;
1235 msgType = tr("Warning");
1236 message = tr("Warning: %1").arg(message);
1237 break;
1239 msgType = tr("Information");
1240 // No need to prepend the prefix here.
1241 break;
1242 default:
1243 break;
1244 }
1245 }
1246
1247 if (!msgType.isEmpty()) {
1248 strTitle += " - " + msgType;
1249 }
1250
1252 nMBoxIcon = QMessageBox::Critical;
1255 nMBoxIcon = QMessageBox::Warning;
1257 }
1258
1260 // Check for buttons, use OK as default, if none was supplied
1261 auto buttons = static_cast<QMessageBox::StandardButton>(
1263 if (buttons) {
1264 buttons = QMessageBox::Ok;
1265 }
1266
1268 QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle,
1269 message, buttons, this);
1270 mBox.setTextFormat(Qt::PlainText);
1271 mBox.setDetailedText(detailed_message);
1272 int r = mBox.exec();
1273 if (ret != nullptr) {
1274 *ret = r == QMessageBox::Ok;
1275 }
1276 } else {
1278 strTitle, message);
1279 }
1280}
1281
1283 QMainWindow::changeEvent(e);
1284#ifndef Q_OS_MAC // Ignored on Mac
1285 if (e->type() == QEvent::WindowStateChange) {
1289 static_cast<QWindowStateChangeEvent *>(e);
1290 if (!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) {
1291 QTimer::singleShot(0, this, &BitcoinGUI::hide);
1292 e->ignore();
1293 } else if ((wsevt->oldState() & Qt::WindowMinimized) &&
1294 !isMinimized()) {
1295 QTimer::singleShot(0, this, &BitcoinGUI::show);
1296 e->ignore();
1297 }
1298 }
1299 }
1300#endif
1301}
1302
1304#ifndef Q_OS_MAC // Ignored on Mac
1307 // close rpcConsole in case it was open to make some space for the
1308 // shutdown window
1309 rpcConsole->close();
1310
1311 QApplication::quit();
1312 } else {
1313 QMainWindow::showMinimized();
1314 event->ignore();
1315 }
1316 }
1317#else
1318 QMainWindow::closeEvent(event);
1319#endif
1320}
1321
1323 // enable the debug window when the main window shows up
1324 openRPCConsoleAction->setEnabled(true);
1325 aboutAction->setEnabled(true);
1326 optionsAction->setEnabled(true);
1327}
1328
1329#ifdef ENABLE_WALLET
1330void BitcoinGUI::incomingTransaction(const QString &date, int unit,
1331 const Amount amount, const QString &type,
1332 const QString &address,
1333 const QString &label,
1334 const QString &walletName) {
1335 // On new transaction, make an info balloon
1336 QString msg = tr("Date: %1\n").arg(date) +
1337 tr("Amount: %1\n")
1338 .arg(BitcoinUnits::formatWithUnit(unit, amount, true));
1339 if (m_node.walletClient().getWallets().size() > 1 &&
1340 !walletName.isEmpty()) {
1341 msg += tr("Wallet: %1\n").arg(walletName);
1342 }
1343 msg += tr("Type: %1\n").arg(type);
1344 if (!label.isEmpty()) {
1345 msg += tr("Label: %1\n").arg(label);
1346 } else if (!address.isEmpty()) {
1347 msg += tr("Address: %1\n").arg(address);
1348 }
1349 message(amount < Amount::zero() ? tr("Sent transaction")
1350 : tr("Incoming transaction"),
1351 msg, CClientUIInterface::MSG_INFORMATION);
1352}
1353#endif // ENABLE_WALLET
1354
1356 // Accept only URIs
1357 if (event->mimeData()->hasUrls()) {
1358 event->acceptProposedAction();
1359 }
1360}
1361
1363 if (event->mimeData()->hasUrls()) {
1364 for (const QUrl &uri : event->mimeData()->urls()) {
1365 Q_EMIT receivedURI(uri.toString());
1366 }
1367 }
1368 event->acceptProposedAction();
1369}
1370
1371bool BitcoinGUI::eventFilter(QObject *object, QEvent *event) {
1372 // Catch status tip events
1373 if (event->type() == QEvent::StatusTip) {
1374 // Prevent adding text from setStatusTip(), if we currently use the
1375 // status bar for displaying other stuff
1376 if (progressBarLabel->isVisible() || progressBar->isVisible()) {
1377 return true;
1378 }
1379 }
1380 return QMainWindow::eventFilter(object, event);
1381}
1382
1383#ifdef ENABLE_WALLET
1384bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient &recipient) {
1385 // URI has to be valid
1386 if (walletFrame && walletFrame->handlePaymentRequest(recipient)) {
1388 gotoSendCoinsPage();
1389 return true;
1390 }
1391 return false;
1392}
1393
1394void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled) {
1395 labelWalletHDStatusIcon->setPixmap(
1397 ->SingleColorIcon(privkeyDisabled ? ":/icons/eye"
1398 : hdEnabled ? ":/icons/hd_enabled"
1399 : ":/icons/hd_disabled")
1401 labelWalletHDStatusIcon->setToolTip(
1402 privkeyDisabled ? tr("Private key <b>disabled</b>")
1403 : hdEnabled ? tr("HD key generation is <b>enabled</b>")
1404 : tr("HD key generation is <b>disabled</b>"));
1406 // eventually disable the QLabel to set its opacity to 50%
1407 labelWalletHDStatusIcon->setEnabled(hdEnabled);
1408}
1409
1410void BitcoinGUI::setEncryptionStatus(int status) {
1411 switch (status) {
1414 encryptWalletAction->setChecked(false);
1415 changePassphraseAction->setEnabled(false);
1416 encryptWalletAction->setEnabled(true);
1417 break;
1420 labelWalletEncryptionIcon->setPixmap(
1421 platformStyle->SingleColorIcon(":/icons/lock_open")
1423 labelWalletEncryptionIcon->setToolTip(
1424 tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1425 encryptWalletAction->setChecked(true);
1426 changePassphraseAction->setEnabled(true);
1427 encryptWalletAction->setEnabled(false);
1428 break;
1431 labelWalletEncryptionIcon->setPixmap(
1432 platformStyle->SingleColorIcon(":/icons/lock_closed")
1434 labelWalletEncryptionIcon->setToolTip(
1435 tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1436 encryptWalletAction->setChecked(true);
1437 changePassphraseAction->setEnabled(true);
1438 encryptWalletAction->setEnabled(false);
1439 break;
1440 }
1441}
1442
1443void BitcoinGUI::updateWalletStatus() {
1444 if (!walletFrame) {
1445 return;
1446 }
1448 if (!walletView) {
1449 return;
1450 }
1451 WalletModel *const walletModel = walletView->getWalletModel();
1453 setHDStatus(walletModel->wallet().privateKeysDisabled(),
1454 walletModel->wallet().hdEnabled());
1455}
1456#endif // ENABLE_WALLET
1457
1459 std::string ip_port;
1461
1462 if (proxy_enabled) {
1463 if (!labelProxyIcon->hasPixmap()) {
1464 QString ip_port_q = QString::fromStdString(ip_port);
1465 labelProxyIcon->setPixmap(
1466 platformStyle->SingleColorIcon(":/icons/proxy")
1468 labelProxyIcon->setToolTip(
1469 tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
1470 } else {
1471 labelProxyIcon->show();
1472 }
1473 } else {
1474 labelProxyIcon->hide();
1475 }
1476}
1477
1480#ifdef ENABLE_WALLET
1481 if (walletFrame) {
1483 if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
1485 }
1486 }
1487#endif
1488 if (!m_network_style->getTitleAddText().isEmpty()) {
1490 }
1492}
1493
1495 if (!clientModel) {
1496 return;
1497 }
1498
1499 if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) &&
1500 fToggleHidden) {
1501 hide();
1502 } else {
1504 }
1505}
1506
1510
1512 if (m_node.shutdownRequested()) {
1513 if (rpcConsole) {
1514 rpcConsole->hide();
1515 }
1516 qApp->quit();
1517 }
1518}
1519
1521 if (nProgress == 0) {
1522 progressDialog = new QProgressDialog(title, QString(), 0, 100);
1524 progressDialog->setWindowModality(Qt::ApplicationModal);
1525 progressDialog->setMinimumDuration(0);
1526 progressDialog->setAutoClose(false);
1527 progressDialog->setValue(0);
1528 } else if (nProgress == 100) {
1529 if (progressDialog) {
1530 progressDialog->close();
1531 progressDialog->deleteLater();
1532 progressDialog = nullptr;
1533 }
1534 } else if (progressDialog) {
1535 progressDialog->setValue(nProgress);
1536 }
1537}
1538
1539void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) {
1540 if (trayIcon) {
1541 trayIcon->setVisible(!fHideTrayIcon);
1542 }
1543}
1544
1546 if (modalOverlay &&
1547 (progressBar->isVisible() || modalOverlay->isLayerVisible())) {
1549 }
1550}
1551
1552static bool ThreadSafeMessageBox(BitcoinGUI *gui, const bilingual_str &message,
1553 const std::string &caption,
1554 unsigned int style) {
1556 // The SECURE flag has no effect in the Qt GUI.
1557 // bool secure = (style & CClientUIInterface::SECURE);
1558 style &= ~CClientUIInterface::SECURE;
1559 bool ret = false;
1560 // This is original message, in English, for googling and referencing.
1562 if (message.original != message.translated) {
1563 detailed_message = BitcoinGUI::tr("Original message:") + "\n" +
1564 QString::fromStdString(message.original);
1565 }
1566
1567 // In case of modal message, use blocking connection to wait for user to
1568 // click a button
1569 bool invoked = QMetaObject::invokeMethod(
1570 gui, "message",
1571 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1572 Q_ARG(QString, QString::fromStdString(caption)),
1573 Q_ARG(QString, QString::fromStdString(message.translated)),
1574 Q_ARG(unsigned int, style), Q_ARG(bool *, &ret),
1576 assert(invoked);
1577 return ret;
1578}
1579
1581 // Connect signals to client
1583 std::bind(ThreadSafeMessageBox, this, std::placeholders::_1,
1584 std::placeholders::_2, std::placeholders::_3));
1586 std::bind(ThreadSafeMessageBox, this, std::placeholders::_1,
1587 std::placeholders::_3, std::placeholders::_4));
1588}
1589
1591 // Disconnect signals from client
1592 m_handler_message_box->disconnect();
1593 m_handler_question->disconnect();
1594}
1595
1598 return m_mask_values_action->isChecked();
1599}
1600
1602 const PlatformStyle *platformStyle)
1603 : optionsModel(nullptr), menu(nullptr) {
1605 setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1607 int max_width = 0;
1608 const QFontMetrics fm(font());
1609 for (const BitcoinUnits::Unit unit : units) {
1612 }
1614 setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1615 setStyleSheet(QString("QLabel { color : %1 }")
1616 .arg(platformStyle->SingleColor().name()));
1617}
1618
1623
1627 menu = new QMenu(this);
1630 new QAction(QString(BitcoinUnits::longName(u)), this);
1631 menuAction->setData(QVariant(u));
1632 menu->addAction(menuAction);
1633 }
1634 connect(menu, &QMenu::triggered, this,
1636}
1637
1640 if (_optionsModel) {
1642
1643 // be aware of a display unit change reported by the OptionsModel
1644 // object.
1645 connect(_optionsModel, &OptionsModel::displayUnitChanged, this,
1647
1648 // initialize the display units label with the current value in the
1649 // model.
1650 updateDisplayUnit(_optionsModel->getDisplayUnit());
1651 }
1652}
1653
1659
1665
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const bilingual_str &message, const std::string &caption, unsigned int style)
static constexpr int64_t MAX_BLOCK_TIME_GAP
Maximum gap between node time and block time used for the "Catching up..." mode in GUI.
Definition chain.h:44
const CChainParams & Params()
Return the currently selected parameters.
Bitcoin GUI main class.
Definition bitcoingui.h:68
void updateHeadersPresyncProgressLabel(int64_t height, const QDateTime &blockDate)
GUIUtil::ClickableProgressBar * progressBar
Definition bitcoingui.h:138
QAction * m_close_all_wallets_action
Definition bitcoingui.h:169
void showEvent(QShowEvent *event) override
QLabel * progressBarLabel
Definition bitcoingui.h:137
QAction * m_open_wallet_action
Definition bitcoingui.h:166
const Config * config
Definition bitcoingui.h:192
static const std::string DEFAULT_UIPLATFORM
Definition bitcoingui.h:72
QAction * openAction
Definition bitcoingui.h:163
void setNumBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state)
Set number of blocks and last block date shown in the UI.
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
GUIUtil::ClickableLabel * connectionsControl
Definition bitcoingui.h:135
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
ModalOverlay * modalOverlay
Definition bitcoingui.h:182
QAction * changePassphraseAction
Definition bitcoingui.h:160
void openOptionsDialogWithTab(OptionsDialog::Tab tab)
Open the OptionsDialog on the specified tab index.
QAction * receiveCoinsMenuAction
Definition bitcoingui.h:155
int prevBlocks
Keep track of previous number of blocks, to detect progress.
Definition bitcoingui.h:189
QAction * openRPCConsoleAction
Definition bitcoingui.h:162
const NetworkStyle *const m_network_style
Definition bitcoingui.h:194
void changeEvent(QEvent *e) override
GUIUtil::ClickableLabel * labelProxyIcon
Definition bitcoingui.h:134
void optionsClicked()
Show configuration dialog.
QAction * historyAction
Definition bitcoingui.h:144
bool eventFilter(QObject *object, QEvent *event) override
QMenu * m_open_wallet_menu
Definition bitcoingui.h:167
QAction * toggleHideAction
Definition bitcoingui.h:157
void createTrayIcon()
Create system tray icon and notification.
QAction * quitAction
Definition bitcoingui.h:145
void setPrivacy(bool privacy)
QProgressDialog * progressDialog
Definition bitcoingui.h:139
std::unique_ptr< interfaces::Handler > m_handler_message_box
Definition bitcoingui.h:126
WalletFrame * walletFrame
Definition bitcoingui.h:129
void updateProxyIcon()
Set the proxy-enabled icon as shown in the UI.
QAction * receiveCoinsAction
Definition bitcoingui.h:154
const std::unique_ptr< QMenu > trayIconMenu
Definition bitcoingui.h:178
QAction * usedSendingAddressesAction
Definition bitcoingui.h:148
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
void closeEvent(QCloseEvent *event) override
QAction * verifyMessageAction
Definition bitcoingui.h:151
void createTrayIconMenu()
Create system tray menu (or setup the dock menu)
HelpMessageDialog * helpMessageDialog
Definition bitcoingui.h:181
void aboutClicked()
Show about dialog.
void toggleHidden()
Simply calls showNormalIfMinimized(true) for use in SLOT() macro.
QAction * encryptWalletAction
Definition bitcoingui.h:158
void updateNetworkState()
Update UI with latest network info from model.
void createActions()
Create the main UI actions.
void showDebugWindow()
Show debug window.
QAction * m_mask_values_action
Definition bitcoingui.h:172
int spinnerFrame
Definition bitcoingui.h:190
QAction * aboutAction
Definition bitcoingui.h:153
void consoleShown(RPCConsole *console)
Signal raised when RPC console shown.
bool isPrivacyModeActivated() const
void showDebugWindowActivateConsole()
Show debug window and set focus to the console.
void dropEvent(QDropEvent *event) override
void showProgress(const QString &title, int nProgress)
Show progress dialog e.g.
QAction * usedReceivingAddressesAction
Definition bitcoingui.h:149
void subscribeToCoreSignals()
Connect core signals to GUI client.
void createToolBars()
Create the toolbars.
QAction * m_wallet_selector_action
Definition bitcoingui.h:171
UnitDisplayStatusBarControl * unitDisplayControl
Definition bitcoingui.h:131
QAction * optionsAction
Definition bitcoingui.h:156
void updateWindowTitle()
void setWalletActionsEnabled(bool enabled)
Enable or disable all wallet-related actions.
const PlatformStyle * platformStyle
Definition bitcoingui.h:193
void dragEnterEvent(QDragEnterEvent *event) override
QAction * m_close_wallet_action
Definition bitcoingui.h:168
QLabel * labelWalletEncryptionIcon
Definition bitcoingui.h:132
QAction * overviewAction
Definition bitcoingui.h:143
GUIUtil::ClickableLabel * labelBlocksIcon
Definition bitcoingui.h:136
interfaces::Node & m_node
Definition bitcoingui.h:124
QAction * m_create_wallet_action
Definition bitcoingui.h:165
QAction * m_load_psbt_action
Definition bitcoingui.h:152
void detectShutdown()
called by a timer to check if ShutdownRequested() has been set
QAction * m_wallet_selector_label_action
Definition bitcoingui.h:170
WalletController * m_wallet_controller
Definition bitcoingui.h:125
bool enableWallet
Definition bitcoingui.h:102
RPCConsole * rpcConsole
Definition bitcoingui.h:180
QAction * backupWalletAction
Definition bitcoingui.h:159
QAction * sendCoinsMenuAction
Definition bitcoingui.h:147
QAction * showHelpMessageAction
Definition bitcoingui.h:164
QAction * aboutQtAction
Definition bitcoingui.h:161
QComboBox * m_wallet_selector
Definition bitcoingui.h:175
QLabel * m_wallet_selector_label
Definition bitcoingui.h:174
void showNormalIfMinimized()
Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHid...
Definition bitcoingui.h:331
ClientModel * clientModel
Definition bitcoingui.h:128
void updateHeadersSyncProgressLabel()
void setTrayIconVisible(bool)
When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly.
void createMenuBar()
Create the menu bar and sub-menus.
QSystemTrayIcon * trayIcon
Definition bitcoingui.h:177
void message(const QString &title, QString message, unsigned int style, bool *ret=nullptr, const QString &detailed_message=QString())
Notify the user of an event from the core network or transaction handling code.
void showHelpMessageClicked()
Show help message dialog.
QAction * sendCoinsAction
Definition bitcoingui.h:146
QToolBar * appToolBar
Definition bitcoingui.h:142
QLabel * labelWalletHDStatusIcon
Definition bitcoingui.h:133
void setNumConnections(int count)
Set number of connections shown in the UI.
void trayIconActivated(QSystemTrayIcon::ActivationReason reason)
Handle tray icon clicked.
QAction * signMessageAction
Definition bitcoingui.h:150
void showModalOverlay()
Notificator * notificator
Definition bitcoingui.h:179
BitcoinGUI(interfaces::Node &node, const Config *, const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent=nullptr)
std::unique_ptr< interfaces::Handler > m_handler_question
Definition bitcoingui.h:127
QMenuBar * appMenuBar
Definition bitcoingui.h:141
void setNetworkActive(bool networkActive)
Set network state shown in the UI.
static QString formatWithUnit(int unit, const Amount amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as string (with unit)
static QString longName(int unit)
Long name.
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
Unit
Currency units Please add only sensible ones.
const Consensus::Params & GetConsensus() const
Definition chainparams.h:92
const std::string & CashAddrPrefix() const
Signals for UI communication.
@ BTN_MASK
Mask of all available buttons in CClientUIInterface::MessageBoxFlags This needs to be updated,...
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
@ MODAL
Force blocking, modal message box dialog (not just OS notification)
Model for Bitcoin network client.
Definition clientmodel.h:43
void showProgress(const QString &title, int nProgress)
int getHeaderTipHeight() const
int getNumConnections(NumConnections flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
void message(const QString &title, const QString &message, unsigned int style)
Fired when a message should be reported to the user.
void numConnectionsChanged(int count)
BlockSource getBlockSource() const
Returns the block source of the current importing/syncing state.
int64_t getHeaderTipTime() const
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state)
OptionsModel * getOptionsModel()
bool getProxyInfo(std::string &ip_port) const
void networkActiveChanged(bool networkActive)
virtual const CChainParams & GetChainParams() const =0
void created(WalletModel *wallet_model)
bool hasPixmap() const
Definition guiutil.cpp:907
void clicked(const QPoint &point)
Emitted when the label is clicked.
void clicked(const QPoint &point)
Emitted when the progressbar is clicked.
"Help message" dialog box
macOS-specific Dock icon handler.
static MacDockIconHandler * instance()
Modal overlay to display information about the chain-sync state.
void showHide(bool hide=false, bool userRequested=false)
void tipUpdate(int count, const QDateTime &blockDate, double nVerificationProgress)
void toggleVisibility()
void triggered(bool hidden)
bool isLayerVisible() const
void setKnownBestHeight(int count, const QDateTime &blockDate, bool presync)
const QIcon & getTrayAndWindowIcon() const
const QString & getTitleAddText() const
Cross-platform desktop notification client.
Definition notificator.h:24
@ Information
Informational message.
Definition notificator.h:37
@ Critical
An error occurred.
Definition notificator.h:39
@ Warning
Notify user of potential problem.
Definition notificator.h:38
void notify(Class cls, const QString &title, const QString &text, const QIcon &icon=QIcon(), int millisTimeout=10000)
Show notification message.
void opened(WalletModel *wallet_model)
Preferences dialog.
Interface from Qt to configuration data structure for Bitcoin client.
void setDisplayUnit(const QVariant &value)
Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal.
void displayUnitChanged(int unit)
bool getMinimizeToTray() const
bool getMinimizeOnClose() const
bool getHideTrayIcon() const
void hideTrayIconChanged(bool)
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
QColor SingleColor() const
Local Bitcoin RPC console.
Definition rpcconsole.h:36
std::vector< TabTypes > tabs() const
Definition rpcconsole.h:68
QString tabTitle(TabTypes tab_type) const
QKeySequence tabShortcut(TabTypes tab_type) const
void addWallet(WalletModel *const walletModel)
void removeWallet(WalletModel *const walletModel)
void setClientModel(ClientModel *model=nullptr, int bestblock_height=0, int64_t bestblock_date=0, double verification_progress=0.0)
void setTabFocus(enum TabTypes tabType)
set which tab has the focus (is visible)
void mousePressEvent(QMouseEvent *event) override
So that it responds to left-button clicks.
void updateDisplayUnit(int newUnits)
When Display Units are changed on OptionsModel it will refresh the display text of the control on the...
void createContextMenu()
Creates context menu, its actions, and wires up all the relevant signals for mouse events.
OptionsModel * optionsModel
Definition bitcoingui.h:362
UnitDisplayStatusBarControl(const PlatformStyle *platformStyle)
void onMenuSelection(QAction *action)
Tells underlying optionsModel to update its current display unit.
void setOptionsModel(OptionsModel *optionsModel)
Lets the control know about the Options Model (and its signals)
void onDisplayUnitsClicked(const QPoint &point)
Shows context menu with Display Unit options by the mouse coordinates.
Controller between interfaces::Node, WalletModel instances and the GUI.
void walletAdded(WalletModel *wallet_model)
void closeAllWallets(QWidget *parent=nullptr)
std::map< std::string, bool > listWalletDir() const
Returns all wallet names in the wallet dir mapped to whether the wallet is loaded.
void walletRemoved(WalletModel *wallet_model)
void closeWallet(WalletModel *wallet_model, QWidget *parent=nullptr)
A container for embedding all wallet-related controls into BitcoinGUI.
Definition walletframe.h:29
void removeAllWallets()
bool addWallet(WalletModel *walletModel)
void changePassphrase()
Change encrypted wallet passphrase.
void requestedSyncWarningInfo()
Notify that the user has requested more information about the out-of-sync warning.
WalletModel * currentWalletModel() const
void gotoHistoryPage()
Switch to history (transactions) page.
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
WalletView * currentWalletView() const
void gotoOverviewPage()
Switch to overview (home) page.
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
void removeWallet(WalletModel *wallet_model)
void setClientModel(ClientModel *clientModel)
void backupWallet()
Backup the wallet.
void usedSendingAddresses()
Show used sending addresses.
void encryptWallet()
Encrypt the wallet.
void gotoLoadPSBT()
Load Partially Signed Bitcoin Transaction.
void usedReceivingAddresses()
Show used receiving addresses.
void setCurrentWallet(WalletModel *wallet_model)
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
void showOutOfSyncWarning(bool fShow)
void gotoReceiveCoinsPage()
Switch to receive coins page.
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Interface to Bitcoin wallet from Qt view code.
Definition walletmodel.h:47
EncryptionStatus getEncryptionStatus() const
interfaces::Wallet & wallet() const
QString getDisplayName() const
static bool isWalletEnabled()
WalletView class.
Definition walletview.h:34
Top-level interface for a bitcoin node (bitcoind process).
Definition node.h:59
virtual void setNetworkActive(bool active)=0
Set network active.
virtual std::unique_ptr< Handler > handleMessageBox(MessageBoxFn fn)=0
virtual bool getNetworkActive()=0
Get network active.
virtual std::unique_ptr< Handler > handleQuestion(QuestionFn fn)=0
virtual WalletClient & walletClient()=0
Get wallet client.
virtual bool shutdownRequested()=0
Return whether shutdown was requested.
virtual std::vector< std::unique_ptr< Wallet > > getWallets()=0
Return interfaces for accessing wallets (if any).
virtual bool hdEnabled()=0
virtual bool privateKeysDisabled()=0
SyncType
Definition clientmodel.h:40
@ HEADER_PRESYNC
BlockSource
Definition clientmodel.h:34
#define SPINNER_FRAMES
static const int STATUSBAR_ICONSIZE
static constexpr int HEADER_HEIGHT_DELTA_SYNC
The required delta of headers to the estimated number of available headers until we show the IBD prog...
bool isObscured(QWidget *w)
Definition guiutil.cpp:382
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
Definition guiutil.cpp:366
void handleCloseWindowShortcut(QWidget *w)
Definition guiutil.cpp:407
void PolishProgressDialog(QProgressDialog *dialog)
Definition guiutil.cpp:953
ClickableProgressBar ProgressBar
Definition guiutil.h:320
void bringToFront(QWidget *w)
Definition guiutil.cpp:390
QString formatNiceTimeOffset(qint64 secs)
Definition guiutil.cpp:864
int TextWidth(const QFontMetrics &fm, const QString &text)
Returns the distance in pixels appropriate for drawing a subsequent character after text.
Definition guiutil.cpp:945
Definition init.h:28
NodeContext & m_node
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
const char * name
Definition rest.cpp:47
static RPCHelpMan help()
Definition server.cpp:182
static constexpr Amount zero() noexcept
Definition amount.h:32
int64_t nPowTargetSpacing
Definition params.h:80
Bilingual messages:
Definition translation.h:17
std::string translated
Definition translation.h:19
std::string original
Definition translation.h:18
Block and header tip information.
Definition node.h:50
static int count
Definition tests.c:31
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition time.cpp:109
assert(!tx.IsCoinBase())
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition validation.h:114