Bitcoin Core 29.99.0
P2P Digital Currency
bitcoingui.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2022 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 <bitcoin-build-config.h> // IWYU pragma: keep
6
7#include <qt/bitcoingui.h>
8
9#include <qt/bitcoinunits.h>
10#include <qt/clientmodel.h>
12#include <qt/guiconstants.h>
13#include <qt/guiutil.h>
14#include <qt/modaloverlay.h>
15#include <qt/networkstyle.h>
16#include <qt/notificator.h>
17#include <qt/openuridialog.h>
18#include <qt/optionsdialog.h>
19#include <qt/optionsmodel.h>
20#include <qt/platformstyle.h>
21#include <qt/rpcconsole.h>
22#include <qt/utilitydialog.h>
23
24#ifdef ENABLE_WALLET
25#include <qt/walletcontroller.h>
26#include <qt/walletframe.h>
27#include <qt/walletmodel.h>
28#include <qt/walletview.h>
29#endif // ENABLE_WALLET
30
31#ifdef Q_OS_MACOS
33#endif
34
35#include <chain.h>
36#include <chainparams.h>
37#include <common/system.h>
38#include <interfaces/handler.h>
39#include <interfaces/node.h>
40#include <node/interface_ui.h>
41#include <util/translation.h>
42#include <validation.h>
43
44#include <functional>
45
46#include <QAction>
47#include <QActionGroup>
48#include <QApplication>
49#include <QComboBox>
50#include <QCursor>
51#include <QDateTime>
52#include <QDragEnterEvent>
53#include <QInputDialog>
54#include <QKeySequence>
55#include <QListWidget>
56#include <QMenu>
57#include <QMenuBar>
58#include <QMessageBox>
59#include <QMimeData>
60#include <QProgressDialog>
61#include <QScreen>
62#include <QSettings>
63#include <QShortcut>
64#include <QStackedWidget>
65#include <QStatusBar>
66#include <QStyle>
67#include <QSystemTrayIcon>
68#include <QTimer>
69#include <QToolBar>
70#include <QUrlQuery>
71#include <QVBoxLayout>
72#include <QWindow>
73
74
75const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
76#if defined(Q_OS_MACOS)
77 "macosx"
78#elif defined(Q_OS_WIN)
79 "windows"
80#else
81 "other"
82#endif
83 ;
84
85BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
86 QMainWindow(parent),
87 m_node(node),
88 trayIconMenu{new QMenu()},
89 platformStyle(_platformStyle),
90 m_network_style(networkStyle)
91{
92 QSettings settings;
93 if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
94 // Restore failed (perhaps missing setting), center the window
95 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
96 }
97
98 setContextMenuPolicy(Qt::PreventContextMenu);
99
100#ifdef ENABLE_WALLET
102#endif // ENABLE_WALLET
103 QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
104 setWindowIcon(m_network_style->getTrayAndWindowIcon());
106
107 rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
108 helpMessageDialog = new HelpMessageDialog(this, false);
109#ifdef ENABLE_WALLET
110 if(enableWallet)
111 {
113 walletFrame = new WalletFrame(_platformStyle, this);
115 connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
116 this->message(title, message, style);
117 });
118 connect(walletFrame, &WalletFrame::currentWalletSet, [this] { updateWalletStatus(); });
119 setCentralWidget(walletFrame);
120 } else
121#endif // ENABLE_WALLET
122 {
123 /* When compiled without wallet or -disablewallet is provided,
124 * the central widget is the rpc console.
125 */
126 setCentralWidget(rpcConsole);
127 Q_EMIT consoleShown(rpcConsole);
128 }
129
130 modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
131
132 // Accept D&D of URIs
133 setAcceptDrops(true);
134
135 // Create actions for the toolbar, menu bar and tray/dock icon
136 // Needs walletFrame to be initialized
138
139 // Create application menu bar
141
142 // Create the toolbars
144
145 // Create system tray icon and notification
146 if (QSystemTrayIcon::isSystemTrayAvailable()) {
148 }
149 notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
150
151 // Create status bar
152 statusBar();
153
154 // Disable size grip because it looks ugly and nobody needs it
155 statusBar()->setSizeGripEnabled(false);
156
157 // Status bar notification icons
158 QFrame *frameBlocks = new QFrame();
159 frameBlocks->setContentsMargins(0,0,0,0);
160 frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
161 QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
162 frameBlocksLayout->setContentsMargins(3,0,3,0);
163 frameBlocksLayout->setSpacing(3);
170 if(enableWallet)
171 {
172 frameBlocksLayout->addStretch();
173 frameBlocksLayout->addWidget(unitDisplayControl);
174 frameBlocksLayout->addStretch();
175 frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
177 frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
179 }
180 frameBlocksLayout->addWidget(labelProxyIcon);
181 frameBlocksLayout->addStretch();
182 frameBlocksLayout->addWidget(connectionsControl);
183 frameBlocksLayout->addStretch();
184 frameBlocksLayout->addWidget(labelBlocksIcon);
185 frameBlocksLayout->addStretch();
186
187 // Progress bar and label for blocks download
188 progressBarLabel = new QLabel();
189 progressBarLabel->setVisible(false);
191 progressBar->setAlignment(Qt::AlignCenter);
192 progressBar->setVisible(false);
193
194 // Override style sheet for progress bar for styles that have a segmented progress bar,
195 // as they make the text unreadable (workaround for issue #1071)
196 // See https://doc.qt.io/qt-5/gallery.html
197 QString curStyle = QApplication::style()->metaObject()->className();
198 if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
199 {
200 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; }");
201 }
202
203 statusBar()->addWidget(progressBarLabel);
204 statusBar()->addWidget(progressBar);
205 statusBar()->addPermanentWidget(frameBlocks);
206
207 // Install event filter to be able to catch status tip events (QEvent::StatusTip)
208 this->installEventFilter(this);
209
210 // Initially wallet actions should be disabled
212
213 // Subscribe to notifications from core
215
218 });
219
222
223#ifdef Q_OS_MACOS
224 m_app_nap_inhibitor = new CAppNapInhibitor;
225#endif
226
228}
229
231{
232 // Unsubscribe from notifications from core
234
235 QSettings settings;
236 settings.setValue("MainWindowGeometry", saveGeometry());
237 if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
238 trayIcon->hide();
239#ifdef Q_OS_MACOS
240 delete m_app_nap_inhibitor;
242#endif
243
244 delete rpcConsole;
245}
246
248{
249 QActionGroup *tabGroup = new QActionGroup(this);
250 connect(modalOverlay, &ModalOverlay::triggered, tabGroup, &QActionGroup::setEnabled);
251
252 overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
253 overviewAction->setStatusTip(tr("Show general overview of wallet"));
254 overviewAction->setToolTip(overviewAction->statusTip());
255 overviewAction->setCheckable(true);
256 overviewAction->setShortcut(QKeySequence(QStringLiteral("Alt+1")));
257 tabGroup->addAction(overviewAction);
258
259 sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
260 sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
261 sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
262 sendCoinsAction->setCheckable(true);
263 sendCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+2")));
264 tabGroup->addAction(sendCoinsAction);
265
266 receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
267 receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
268 receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
269 receiveCoinsAction->setCheckable(true);
270 receiveCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+3")));
271 tabGroup->addAction(receiveCoinsAction);
272
273 historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
274 historyAction->setStatusTip(tr("Browse transaction history"));
275 historyAction->setToolTip(historyAction->statusTip());
276 historyAction->setCheckable(true);
277 historyAction->setShortcut(QKeySequence(QStringLiteral("Alt+4")));
278 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 connect(overviewAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
284 connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage);
285 connect(sendCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
286 connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); });
287 connect(receiveCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
288 connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
289 connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
290 connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage);
291#endif // ENABLE_WALLET
292
293 quitAction = new QAction(tr("E&xit"), this);
294 quitAction->setStatusTip(tr("Quit application"));
295 quitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));
296 quitAction->setMenuRole(QAction::QuitRole);
297 aboutAction = new QAction(tr("&About %1").arg(CLIENT_NAME), this);
298 aboutAction->setStatusTip(tr("Show information about %1").arg(CLIENT_NAME));
299 aboutAction->setMenuRole(QAction::AboutRole);
300 aboutAction->setEnabled(false);
301 aboutQtAction = new QAction(tr("About &Qt"), this);
302 aboutQtAction->setStatusTip(tr("Show information about Qt"));
303 aboutQtAction->setMenuRole(QAction::AboutQtRole);
304 optionsAction = new QAction(tr("&Options…"), this);
305 optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(CLIENT_NAME));
306 optionsAction->setMenuRole(QAction::PreferencesRole);
307 optionsAction->setEnabled(false);
308
309 encryptWalletAction = new QAction(tr("&Encrypt Wallet…"), this);
310 encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
311 encryptWalletAction->setCheckable(true);
312 backupWalletAction = new QAction(tr("&Backup Wallet…"), this);
313 backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
314 changePassphraseAction = new QAction(tr("&Change Passphrase…"), this);
315 changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
316 signMessageAction = new QAction(tr("Sign &message…"), this);
317 signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
318 verifyMessageAction = new QAction(tr("&Verify message…"), this);
319 verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
320 m_load_psbt_action = new QAction(tr("&Load PSBT from file…"), this);
321 m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
322 m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from &clipboard…"), this);
323 m_load_psbt_clipboard_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction from clipboard"));
324
325 openRPCConsoleAction = new QAction(tr("Node window"), this);
326 openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
327 // initially disable the debug window menu item
328 openRPCConsoleAction->setEnabled(false);
329 openRPCConsoleAction->setObjectName("openRPCConsoleAction");
330
331 usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
332 usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
333 usedReceivingAddressesAction = new QAction(tr("&Receiving addresses"), this);
334 usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
335
336 openAction = new QAction(tr("Open &URI…"), this);
337 openAction->setStatusTip(tr("Open a bitcoin: URI"));
338
339 m_open_wallet_action = new QAction(tr("Open Wallet"), this);
340 m_open_wallet_action->setEnabled(false);
341 m_open_wallet_action->setStatusTip(tr("Open a wallet"));
342 m_open_wallet_menu = new QMenu(this);
343
344 m_close_wallet_action = new QAction(tr("Close Wallet…"), this);
345 m_close_wallet_action->setStatusTip(tr("Close wallet"));
346
347 m_create_wallet_action = new QAction(tr("Create Wallet…"), this);
348 m_create_wallet_action->setEnabled(false);
349 m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
350
351 //: Name of the menu item that restores wallet from a backup file.
352 m_restore_wallet_action = new QAction(tr("Restore Wallet…"), this);
353 m_restore_wallet_action->setEnabled(false);
354 //: Status tip for Restore Wallet menu item
355 m_restore_wallet_action->setStatusTip(tr("Restore a wallet from a backup file"));
356
357 m_close_all_wallets_action = new QAction(tr("Close All Wallets…"), this);
358 m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
359
360 m_migrate_wallet_action = new QAction(tr("Migrate Wallet"), this);
361 m_migrate_wallet_action->setEnabled(false);
362 m_migrate_wallet_action->setStatusTip(tr("Migrate a wallet"));
363 m_migrate_wallet_menu = new QMenu(this);
364
365 showHelpMessageAction = new QAction(tr("&Command-line options"), this);
366 showHelpMessageAction->setMenuRole(QAction::NoRole);
367 showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(CLIENT_NAME));
368
369 m_mask_values_action = new QAction(tr("&Mask values"), this);
370 m_mask_values_action->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_M));
371 m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab"));
372 m_mask_values_action->setCheckable(true);
373
374 connect(quitAction, &QAction::triggered, this, &BitcoinGUI::quitRequested);
375 connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
376 connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
377 connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked);
378 connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked);
379 connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow);
380 // prevents an open debug window from becoming stuck/unusable on client shutdown
381 connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
382
383#ifdef ENABLE_WALLET
384 if(walletFrame)
385 {
386 connect(encryptWalletAction, &QAction::triggered, walletFrame, &WalletFrame::encryptWallet);
387 connect(backupWalletAction, &QAction::triggered, walletFrame, &WalletFrame::backupWallet);
389 connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
390 connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
391 connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
392 connect(m_load_psbt_clipboard_action, &QAction::triggered, [this]{ gotoLoadPSBT(true); });
393 connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
394 connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
397 connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked);
398 connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
399 m_open_wallet_menu->clear();
400 for (const auto& [path, info] : m_wallet_controller->listWalletDir()) {
401 const auto& [loaded, format] = info;
402 QString name = GUIUtil::WalletDisplayName(path);
403 // An single ampersand in the menu item's text sets a shortcut for this item.
404 // Single & are shown when && is in the string. So replace & with &&.
405 name.replace(QChar('&'), QString("&&"));
406 bool is_legacy = format == "bdb";
407 if (is_legacy) {
408 name += " (needs migration)";
409 }
410 QAction* action = m_open_wallet_menu->addAction(name);
411
412 if (loaded || is_legacy) {
413 // This wallet is already loaded or it is a legacy wallet
414 action->setEnabled(false);
415 continue;
416 }
417
418 connect(action, &QAction::triggered, [this, path] {
419 auto activity = new OpenWalletActivity(m_wallet_controller, this);
420 connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
421 connect(activity, &OpenWalletActivity::opened, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
422 activity->open(path);
423 });
424 }
425 if (m_open_wallet_menu->isEmpty()) {
426 QAction* action = m_open_wallet_menu->addAction(tr("No wallets available"));
427 action->setEnabled(false);
428 }
429 });
430 connect(m_restore_wallet_action, &QAction::triggered, [this] {
431 //: Name of the wallet data file format.
432 QString name_data_file = tr("Wallet Data");
433
434 //: The title for Restore Wallet File Windows
435 QString title_windows = tr("Load Wallet Backup");
436
437 QString backup_file = GUIUtil::getOpenFileName(this, title_windows, QString(), name_data_file + QLatin1String(" (*.dat)"), nullptr);
438 if (backup_file.isEmpty()) return;
439
440 bool wallet_name_ok;
441 /*: Title of pop-up window shown when the user is attempting to
442 restore a wallet. */
443 QString title = tr("Restore Wallet");
444 //: Label of the input field where the name of the wallet is entered.
445 QString label = tr("Wallet Name");
446 QString wallet_name = QInputDialog::getText(this, title, label, QLineEdit::Normal, "", &wallet_name_ok);
447 if (!wallet_name_ok || wallet_name.isEmpty()) return;
448
449 auto activity = new RestoreWalletActivity(m_wallet_controller, this);
450 connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
451 connect(activity, &RestoreWalletActivity::restored, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
452
453 auto backup_file_path = fs::PathFromString(backup_file.toStdString());
454 activity->restore(backup_file_path, wallet_name.toStdString());
455 });
456 connect(m_close_wallet_action, &QAction::triggered, [this] {
458 });
459 connect(m_create_wallet_action, &QAction::triggered, this, &BitcoinGUI::createWallet);
460 connect(m_close_all_wallets_action, &QAction::triggered, [this] {
462 });
463 connect(m_migrate_wallet_menu, &QMenu::aboutToShow, [this] {
464 m_migrate_wallet_menu->clear();
465 for (const auto& [wallet_name, info] : m_wallet_controller->listWalletDir()) {
466 const auto& [loaded, format] = info;
467
468 if (format != "bdb") { // Skip already migrated wallets
469 continue;
470 }
471
472 QString name = GUIUtil::WalletDisplayName(wallet_name);
473 // An single ampersand in the menu item's text sets a shortcut for this item.
474 // Single & are shown when && is in the string. So replace & with &&.
475 name.replace(QChar('&'), QString("&&"));
476 QAction* action = m_migrate_wallet_menu->addAction(name);
477
478 connect(action, &QAction::triggered, [this, wallet_name] {
479 auto activity = new MigrateWalletActivity(m_wallet_controller, this);
480 connect(activity, &MigrateWalletActivity::migrated, this, &BitcoinGUI::setCurrentWallet);
481 activity->migrate(wallet_name);
482 });
483 }
484 if (m_migrate_wallet_menu->isEmpty()) {
485 QAction* action = m_migrate_wallet_menu->addAction(tr("No wallets available"));
486 action->setEnabled(false);
487 }
488 });
489 connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::setPrivacy);
490 connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::enableHistoryAction);
491 }
492#endif // ENABLE_WALLET
493
494 connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindowActivateConsole);
495 connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_D), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
496}
497
499{
500 appMenuBar = menuBar();
501
502 // Configure the menus
503 QMenu *file = appMenuBar->addMenu(tr("&File"));
504 if(walletFrame)
505 {
506 file->addAction(m_create_wallet_action);
507 file->addAction(m_open_wallet_action);
508 file->addAction(m_close_wallet_action);
509 file->addAction(m_close_all_wallets_action);
510 file->addAction(m_migrate_wallet_action);
511 file->addSeparator();
512 file->addAction(backupWalletAction);
513 file->addAction(m_restore_wallet_action);
514 file->addSeparator();
515 file->addAction(openAction);
516 file->addAction(signMessageAction);
517 file->addAction(verifyMessageAction);
518 file->addAction(m_load_psbt_action);
519 file->addAction(m_load_psbt_clipboard_action);
520 file->addSeparator();
521 }
522 file->addAction(quitAction);
523
524 QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
525 if(walletFrame)
526 {
527 settings->addAction(encryptWalletAction);
528 settings->addAction(changePassphraseAction);
529 settings->addSeparator();
530 settings->addAction(m_mask_values_action);
531 settings->addSeparator();
532 }
533 settings->addAction(optionsAction);
534
535 QMenu* window_menu = appMenuBar->addMenu(tr("&Window"));
536
537 QAction* minimize_action = window_menu->addAction(tr("&Minimize"));
538 minimize_action->setShortcut(QKeySequence(tr("Ctrl+M")));
539 connect(minimize_action, &QAction::triggered, [] {
540 QApplication::activeWindow()->showMinimized();
541 });
542 connect(qApp, &QApplication::focusWindowChanged, this, [minimize_action] (QWindow* window) {
543 minimize_action->setEnabled(window != nullptr && (window->flags() & Qt::Dialog) != Qt::Dialog && window->windowState() != Qt::WindowMinimized);
544 });
545
546#ifdef Q_OS_MACOS
547 QAction* zoom_action = window_menu->addAction(tr("Zoom"));
548 connect(zoom_action, &QAction::triggered, [] {
549 QWindow* window = qApp->focusWindow();
550 if (window->windowState() != Qt::WindowMaximized) {
551 window->showMaximized();
552 } else {
553 window->showNormal();
554 }
555 });
556
557 connect(qApp, &QApplication::focusWindowChanged, this, [zoom_action] (QWindow* window) {
558 zoom_action->setEnabled(window != nullptr);
559 });
560#endif
561
562 if (walletFrame) {
563#ifdef Q_OS_MACOS
564 window_menu->addSeparator();
565 QAction* main_window_action = window_menu->addAction(tr("Main Window"));
566 connect(main_window_action, &QAction::triggered, [this] {
568 });
569#endif
570 window_menu->addSeparator();
571 window_menu->addAction(usedSendingAddressesAction);
572 window_menu->addAction(usedReceivingAddressesAction);
573 }
574
575 window_menu->addSeparator();
576 for (RPCConsole::TabTypes tab_type : rpcConsole->tabs()) {
577 QAction* tab_action = window_menu->addAction(rpcConsole->tabTitle(tab_type));
578 tab_action->setShortcut(rpcConsole->tabShortcut(tab_type));
579 connect(tab_action, &QAction::triggered, [this, tab_type] {
580 rpcConsole->setTabFocus(tab_type);
582 });
583 }
584
585 QMenu *help = appMenuBar->addMenu(tr("&Help"));
586 help->addAction(showHelpMessageAction);
587 help->addSeparator();
588 help->addAction(aboutAction);
589 help->addAction(aboutQtAction);
590}
591
593{
594 if(walletFrame)
595 {
596 QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
597 appToolBar = toolbar;
598 toolbar->setMovable(false);
599 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
600 toolbar->addAction(overviewAction);
601 toolbar->addAction(sendCoinsAction);
602 toolbar->addAction(receiveCoinsAction);
603 toolbar->addAction(historyAction);
604 overviewAction->setChecked(true);
605
606#ifdef ENABLE_WALLET
607 QWidget *spacer = new QWidget();
608 spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
609 toolbar->addWidget(spacer);
610
611 m_wallet_selector = new QComboBox();
612 m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
613 connect(m_wallet_selector, qOverload<int>(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
614
615 m_wallet_selector_label = new QLabel();
616 m_wallet_selector_label->setText(tr("Wallet:") + " ");
618
621
622 m_wallet_selector_label_action->setVisible(false);
623 m_wallet_selector_action->setVisible(false);
624#endif
625 }
626}
627
629{
630 this->clientModel = _clientModel;
631 if(_clientModel)
632 {
633 // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
634 // while the client has not yet fully loaded
636
637 // Keep up to date with client
641 });
644
645 modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromSecsSinceEpoch(tip_info->header_time), /*presync=*/false);
646 setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), tip_info->verification_progress, SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD);
647 connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks);
648
649 // Receive and report messages from client model
650 connect(_clientModel, &ClientModel::message, [this](const QString &title, const QString &message, unsigned int style){
651 this->message(title, message, style);
652 });
653
654 // Show progress dialog
655 connect(_clientModel, &ClientModel::showProgress, this, &BitcoinGUI::showProgress);
656
657 rpcConsole->setClientModel(_clientModel, tip_info->block_height, tip_info->block_time, tip_info->verification_progress);
658
660
661#ifdef ENABLE_WALLET
662 if(walletFrame)
663 {
664 walletFrame->setClientModel(_clientModel);
665 }
666#endif // ENABLE_WALLET
668
669 OptionsModel* optionsModel = _clientModel->getOptionsModel();
670 if (optionsModel && trayIcon) {
671 // be aware of the tray icon disable state change reported by the OptionsModel object.
672 connect(optionsModel, &OptionsModel::showTrayIconChanged, trayIcon, &QSystemTrayIcon::setVisible);
673
674 // initialize the disable state of the tray icon with the current value in the model.
675 trayIcon->setVisible(optionsModel->getShowTrayIcon());
676 }
677
678 m_mask_values_action->setChecked(_clientModel->getOptionsModel()->getOption(OptionsModel::OptionID::MaskValues).toBool());
679 } else {
680 // Shutdown requested, disable menus
681 if (trayIconMenu)
682 {
683 // Disable context menu on tray icon
684 trayIconMenu->clear();
685 }
686 // Propagate cleared model to child objects
687 rpcConsole->setClientModel(nullptr);
688#ifdef ENABLE_WALLET
689 if (walletFrame)
690 {
691 walletFrame->setClientModel(nullptr);
692 }
693#endif // ENABLE_WALLET
695 // Disable top bar menu actions
696 appMenuBar->clear();
697 }
698}
699
700#ifdef ENABLE_WALLET
701void BitcoinGUI::enableHistoryAction(bool privacy)
702{
704 historyAction->setEnabled(!privacy);
705 if (historyAction->isChecked()) gotoOverviewPage();
706 }
707}
708
709void BitcoinGUI::setWalletController(WalletController* wallet_controller, bool show_loading_minimized)
710{
712 assert(wallet_controller);
713
714 m_wallet_controller = wallet_controller;
715
716 m_create_wallet_action->setEnabled(true);
717 m_open_wallet_action->setEnabled(true);
719 m_restore_wallet_action->setEnabled(true);
720 m_migrate_wallet_action->setEnabled(true);
722
723 GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
724 connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
725 connect(wallet_controller, &WalletController::destroyed, this, [this] {
726 // wallet_controller gets destroyed manually, but it leaves our member copy dangling
727 m_wallet_controller = nullptr;
728 });
729
730 auto activity = new LoadWalletsActivity(m_wallet_controller, this);
731 activity->load(show_loading_minimized);
732}
733
734WalletController* BitcoinGUI::getWalletController()
735{
736 return m_wallet_controller;
737}
738
739void BitcoinGUI::addWallet(WalletModel* walletModel)
740{
741 if (!walletFrame || !m_wallet_controller) return;
742
743 WalletView* wallet_view = new WalletView(walletModel, platformStyle, walletFrame);
744 if (!walletFrame->addView(wallet_view)) return;
745
746 rpcConsole->addWallet(walletModel);
747 if (m_wallet_selector->count() == 0) {
749 } else if (m_wallet_selector->count() == 1) {
750 m_wallet_selector_label_action->setVisible(true);
751 m_wallet_selector_action->setVisible(true);
752 }
753
755 connect(wallet_view, &WalletView::transactionClicked, this, &BitcoinGUI::gotoHistoryPage);
756 connect(wallet_view, &WalletView::coinsSent, this, &BitcoinGUI::gotoHistoryPage);
757 connect(wallet_view, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
758 this->message(title, message, style);
759 });
760 connect(wallet_view, &WalletView::encryptionStatusChanged, this, &BitcoinGUI::updateWalletStatus);
761 connect(wallet_view, &WalletView::incomingTransaction, this, &BitcoinGUI::incomingTransaction);
762 connect(this, &BitcoinGUI::setPrivacy, wallet_view, &WalletView::setPrivacy);
763 const bool privacy = isPrivacyModeActivated();
764 wallet_view->setPrivacy(privacy);
765 enableHistoryAction(privacy);
766 const QString display_name = walletModel->getDisplayName();
767 m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
768}
769
770void BitcoinGUI::removeWallet(WalletModel* walletModel)
771{
772 if (!walletFrame) return;
773
776
777 int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
778 m_wallet_selector->removeItem(index);
779 if (m_wallet_selector->count() == 0) {
781 overviewAction->setChecked(true);
782 } else if (m_wallet_selector->count() == 1) {
783 m_wallet_selector_label_action->setVisible(false);
784 m_wallet_selector_action->setVisible(false);
785 }
786 rpcConsole->removeWallet(walletModel);
787 walletFrame->removeWallet(walletModel);
789}
790
791void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
792{
793 if (!walletFrame || !m_wallet_controller) return;
794 walletFrame->setCurrentWallet(wallet_model);
795 for (int index = 0; index < m_wallet_selector->count(); ++index) {
796 if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
797 m_wallet_selector->setCurrentIndex(index);
798 break;
799 }
800 }
802}
803
804void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
805{
806 WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
807 if (wallet_model) setCurrentWallet(wallet_model);
808}
809
810void BitcoinGUI::removeAllWallets()
811{
812 if(!walletFrame)
813 return;
816}
817#endif // ENABLE_WALLET
818
820{
821 overviewAction->setEnabled(enabled);
822 sendCoinsAction->setEnabled(enabled);
823 receiveCoinsAction->setEnabled(enabled);
824 historyAction->setEnabled(enabled);
825 encryptWalletAction->setEnabled(enabled);
826 backupWalletAction->setEnabled(enabled);
827 changePassphraseAction->setEnabled(enabled);
828 signMessageAction->setEnabled(enabled);
829 verifyMessageAction->setEnabled(enabled);
830 usedSendingAddressesAction->setEnabled(enabled);
831 usedReceivingAddressesAction->setEnabled(enabled);
832 openAction->setEnabled(enabled);
833 m_close_wallet_action->setEnabled(enabled);
834 m_close_all_wallets_action->setEnabled(enabled);
835}
836
838{
839 assert(QSystemTrayIcon::isSystemTrayAvailable());
840
841#ifndef Q_OS_MACOS
842 if (QSystemTrayIcon::isSystemTrayAvailable()) {
843 trayIcon = new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
844 QString toolTip = tr("%1 client").arg(CLIENT_NAME) + " " + m_network_style->getTitleAddText();
845 trayIcon->setToolTip(toolTip);
846 }
847#endif
848}
849
851{
852#ifndef Q_OS_MACOS
853 if (!trayIcon) return;
854#endif // Q_OS_MACOS
855
856 // Configuration of the tray icon (or Dock icon) menu.
857 QAction* show_hide_action{nullptr};
858#ifndef Q_OS_MACOS
859 // Note: On macOS, the Dock icon's menu already has Show / Hide action.
860 show_hide_action = trayIconMenu->addAction(QString(), this, &BitcoinGUI::toggleHidden);
861 trayIconMenu->addSeparator();
862#endif // Q_OS_MACOS
863
864 QAction* send_action{nullptr};
865 QAction* receive_action{nullptr};
866 QAction* sign_action{nullptr};
867 QAction* verify_action{nullptr};
868 if (enableWallet) {
869 send_action = trayIconMenu->addAction(sendCoinsAction->text(), sendCoinsAction, &QAction::trigger);
870 receive_action = trayIconMenu->addAction(receiveCoinsAction->text(), receiveCoinsAction, &QAction::trigger);
871 trayIconMenu->addSeparator();
872 sign_action = trayIconMenu->addAction(signMessageAction->text(), signMessageAction, &QAction::trigger);
873 verify_action = trayIconMenu->addAction(verifyMessageAction->text(), verifyMessageAction, &QAction::trigger);
874 trayIconMenu->addSeparator();
875 }
876 QAction* options_action = trayIconMenu->addAction(optionsAction->text(), optionsAction, &QAction::trigger);
877 options_action->setMenuRole(QAction::PreferencesRole);
878 QAction* node_window_action = trayIconMenu->addAction(openRPCConsoleAction->text(), openRPCConsoleAction, &QAction::trigger);
879 QAction* quit_action{nullptr};
880#ifndef Q_OS_MACOS
881 // Note: On macOS, the Dock icon's menu already has Quit action.
882 trayIconMenu->addSeparator();
883 quit_action = trayIconMenu->addAction(quitAction->text(), quitAction, &QAction::trigger);
884
885 trayIcon->setContextMenu(trayIconMenu.get());
886 connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
887 if (reason == QSystemTrayIcon::Trigger) {
888 // Click on system tray icon triggers show/hide of the main window
889 toggleHidden();
890 }
891 });
892#else
893 // Note: On macOS, the Dock icon is used to provide the tray's functionality.
895 connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] {
896 if (m_node.shutdownRequested()) return; // nothing to show, node is shutting down.
897 show();
898 activateWindow();
899 });
900 trayIconMenu->setAsDockMenu();
901#endif // Q_OS_MACOS
902
903 connect(
904 // Using QSystemTrayIcon::Context is not reliable.
905 // See https://bugreports.qt.io/browse/QTBUG-91697
906 trayIconMenu.get(), &QMenu::aboutToShow,
907 [this, show_hide_action, send_action, receive_action, sign_action, verify_action, options_action, node_window_action, quit_action] {
908 if (m_node.shutdownRequested()) return; // nothing to do, node is shutting down.
909
910 if (show_hide_action) show_hide_action->setText(
911 (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ?
912 tr("&Hide") :
913 tr("S&how"));
914 if (QApplication::activeModalWidget()) {
915 for (QAction* a : trayIconMenu.get()->actions()) {
916 a->setEnabled(false);
917 }
918 } else {
919 if (show_hide_action) show_hide_action->setEnabled(true);
920 if (enableWallet) {
921 send_action->setEnabled(sendCoinsAction->isEnabled());
922 receive_action->setEnabled(receiveCoinsAction->isEnabled());
923 sign_action->setEnabled(signMessageAction->isEnabled());
924 verify_action->setEnabled(verifyMessageAction->isEnabled());
925 }
926 options_action->setEnabled(optionsAction->isEnabled());
927 node_window_action->setEnabled(openRPCConsoleAction->isEnabled());
928 if (quit_action) quit_action->setEnabled(true);
929 }
930 });
931}
932
934{
936}
937
939{
940 if(!clientModel)
941 return;
942
943 auto dlg = new HelpMessageDialog(this, /*about=*/true);
945}
946
948{
950 Q_EMIT consoleShown(rpcConsole);
951}
952
954{
957}
958
960{
962}
963
964#ifdef ENABLE_WALLET
965void BitcoinGUI::openClicked()
966{
967 OpenURIDialog dlg(platformStyle, this);
968 if(dlg.exec())
969 {
970 Q_EMIT receivedURI(dlg.getURI());
971 }
972}
973
974void BitcoinGUI::gotoOverviewPage()
975{
976 overviewAction->setChecked(true);
978}
979
980void BitcoinGUI::gotoHistoryPage()
981{
982 historyAction->setChecked(true);
984}
985
986void BitcoinGUI::gotoReceiveCoinsPage()
987{
988 receiveCoinsAction->setChecked(true);
990}
991
992void BitcoinGUI::gotoSendCoinsPage(QString addr)
993{
994 sendCoinsAction->setChecked(true);
996}
997
998void BitcoinGUI::gotoSignMessageTab(QString addr)
999{
1001}
1002
1003void BitcoinGUI::gotoVerifyMessageTab(QString addr)
1004{
1006}
1007void BitcoinGUI::gotoLoadPSBT(bool from_clipboard)
1008{
1009 if (walletFrame) walletFrame->gotoLoadPSBT(from_clipboard);
1010}
1011#endif // ENABLE_WALLET
1012
1014{
1015 if (!clientModel) return;
1017 QString icon;
1018 switch(count)
1019 {
1020 case 0: icon = ":/icons/connect_0"; break;
1021 case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
1022 case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
1023 case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
1024 default: icon = ":/icons/connect_4"; break;
1025 }
1026
1027 QString tooltip;
1028
1029 if (m_node.getNetworkActive()) {
1030 //: A substring of the tooltip.
1031 tooltip = tr("%n active connection(s) to Bitcoin network.", "", count);
1032 } else {
1033 //: A substring of the tooltip.
1034 tooltip = tr("Network activity disabled.");
1035 icon = ":/icons/network_disabled";
1036 }
1037
1038 // Don't word-wrap this (fixed-width) tooltip
1039 tooltip = QLatin1String("<nobr>") + tooltip + QLatin1String("<br>") +
1040 //: A substring of the tooltip. "More actions" are available via the context menu.
1041 tr("Click for more actions.") + QLatin1String("</nobr>");
1042 connectionsControl->setToolTip(tooltip);
1043
1045}
1046
1048{
1050}
1051
1052void BitcoinGUI::setNetworkActive(bool network_active)
1053{
1055 m_network_context_menu->clear();
1056 m_network_context_menu->addAction(
1057 //: A context menu item. The "Peers tab" is an element of the "Node window".
1058 tr("Show Peers tab"),
1059 [this] {
1062 });
1063 m_network_context_menu->addAction(
1064 network_active ?
1065 //: A context menu item.
1066 tr("Disable network activity") :
1067 //: A context menu item. The network activity was disabled previously.
1068 tr("Enable network activity"),
1069 [this, new_state = !network_active] { m_node.setNetworkActive(new_state); });
1070}
1071
1073{
1074 int64_t headersTipTime = clientModel->getHeaderTipTime();
1075 int headersTipHeight = clientModel->getHeaderTipHeight();
1076 int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
1077 if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
1078 progressBarLabel->setText(tr("Syncing Headers (%1%)…").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
1079}
1080
1081void BitcoinGUI::updateHeadersPresyncProgressLabel(int64_t height, const QDateTime& blockDate)
1082{
1083 int estHeadersLeft = blockDate.secsTo(QDateTime::currentDateTime()) / Params().GetConsensus().nPowTargetSpacing;
1084 if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
1085 progressBarLabel->setText(tr("Pre-syncing Headers (%1%)…").arg(QString::number(100.0 / (height+estHeadersLeft)*height, 'f', 1)));
1086}
1087
1089{
1091 return;
1092
1093 auto dlg = new OptionsDialog(this, enableWallet);
1095 dlg->setCurrentTab(tab);
1096 dlg->setClientModel(clientModel);
1097 dlg->setModel(clientModel->getOptionsModel());
1099}
1100
1101void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state)
1102{
1103// Disabling macOS App Nap on initial sync, disk and reindex operations.
1104#ifdef Q_OS_MACOS
1105 if (sync_state == SynchronizationState::POST_INIT) {
1106 m_app_nap_inhibitor->enableAppNap();
1107 } else {
1108 m_app_nap_inhibitor->disableAppNap();
1109 }
1110#endif
1111
1112 if (modalOverlay)
1113 {
1114 if (synctype != SyncType::BLOCK_SYNC)
1116 else
1117 modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
1118 }
1119 if (!clientModel)
1120 return;
1121
1122 // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
1123 statusBar()->clearMessage();
1124
1125 // Acquire current block source
1126 BlockSource blockSource{clientModel->getBlockSource()};
1127 switch (blockSource) {
1129 if (synctype == SyncType::HEADER_PRESYNC) {
1131 return;
1132 } else if (synctype == SyncType::HEADER_SYNC) {
1134 return;
1135 }
1136 progressBarLabel->setText(tr("Synchronizing with network…"));
1138 break;
1139 case BlockSource::DISK:
1140 if (synctype != SyncType::BLOCK_SYNC) {
1141 progressBarLabel->setText(tr("Indexing blocks on disk…"));
1142 } else {
1143 progressBarLabel->setText(tr("Processing blocks on disk…"));
1144 }
1145 break;
1146 case BlockSource::NONE:
1147 if (synctype != SyncType::BLOCK_SYNC) {
1148 return;
1149 }
1150 progressBarLabel->setText(tr("Connecting to peers…"));
1151 break;
1152 }
1153
1154 QString tooltip;
1155
1156 QDateTime currentDate = QDateTime::currentDateTime();
1157 qint64 secs = blockDate.secsTo(currentDate);
1158
1159 tooltip = tr("Processed %n block(s) of transaction history.", "", count);
1160
1161 // Set icon state: spinning if catching up, tick otherwise
1162 if (secs < MAX_BLOCK_TIME_GAP) {
1163 tooltip = tr("Up to date") + QString(".<br>") + tooltip;
1164 labelBlocksIcon->setThemedPixmap(QStringLiteral(":/icons/synced"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
1165
1166#ifdef ENABLE_WALLET
1167 if(walletFrame)
1168 {
1170 modalOverlay->showHide(true, true);
1171 }
1172#endif // ENABLE_WALLET
1173
1174 progressBarLabel->setVisible(false);
1175 progressBar->setVisible(false);
1176 }
1177 else
1178 {
1179 QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
1180
1181 progressBarLabel->setVisible(true);
1182 progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
1183 progressBar->setMaximum(1000000000);
1184 progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
1185 progressBar->setVisible(true);
1186
1187 tooltip = tr("Catching up…") + QString("<br>") + tooltip;
1188 if(count != prevBlocks)
1189 {
1191 QString(":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')),
1194 }
1195 prevBlocks = count;
1196
1197#ifdef ENABLE_WALLET
1198 if(walletFrame)
1199 {
1202 }
1203#endif // ENABLE_WALLET
1204
1205 tooltip += QString("<br>");
1206 tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
1207 tooltip += QString("<br>");
1208 tooltip += tr("Transactions after this will not yet be visible.");
1209 }
1210
1211 // Don't word-wrap this (fixed-width) tooltip
1212 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1213
1214 labelBlocksIcon->setToolTip(tooltip);
1215 progressBarLabel->setToolTip(tooltip);
1216 progressBar->setToolTip(tooltip);
1217}
1218
1220{
1221#ifdef ENABLE_WALLET
1222 auto activity = new CreateWalletActivity(getWalletController(), this);
1223 connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet);
1224 connect(activity, &CreateWalletActivity::created, rpcConsole, &RPCConsole::setCurrentWallet);
1225 activity->create();
1226#endif // ENABLE_WALLET
1227}
1228
1229void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message)
1230{
1231 // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines).
1232 QString strTitle{CLIENT_NAME};
1233 // Default to information icon
1234 int nMBoxIcon = QMessageBox::Information;
1235 int nNotifyIcon = Notificator::Information;
1236
1237 QString msgType;
1238 if (!title.isEmpty()) {
1239 msgType = title;
1240 } else {
1241 switch (style) {
1243 msgType = tr("Error");
1244 message = tr("Error: %1").arg(message);
1245 break;
1247 msgType = tr("Warning");
1248 message = tr("Warning: %1").arg(message);
1249 break;
1251 msgType = tr("Information");
1252 // No need to prepend the prefix here.
1253 break;
1254 default:
1255 break;
1256 }
1257 }
1258
1259 if (!msgType.isEmpty()) {
1260 strTitle += " - " + msgType;
1261 }
1262
1263 if (style & CClientUIInterface::ICON_ERROR) {
1264 nMBoxIcon = QMessageBox::Critical;
1265 nNotifyIcon = Notificator::Critical;
1266 } else if (style & CClientUIInterface::ICON_WARNING) {
1267 nMBoxIcon = QMessageBox::Warning;
1268 nNotifyIcon = Notificator::Warning;
1269 }
1270
1271 if (style & CClientUIInterface::MODAL) {
1272 // Check for buttons, use OK as default, if none was supplied
1273 QMessageBox::StandardButton buttons;
1274 if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
1275 buttons = QMessageBox::Ok;
1276
1278 QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
1279 mBox.setTextFormat(Qt::PlainText);
1280 mBox.setDetailedText(detailed_message);
1281 int r = mBox.exec();
1282 if (ret != nullptr)
1283 *ret = r == QMessageBox::Ok;
1284 } else {
1285 notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message);
1286 }
1287}
1288
1290{
1291 if (e->type() == QEvent::PaletteChange) {
1292 overviewAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/overview")));
1293 sendCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/send")));
1294 receiveCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/receiving_addresses")));
1295 historyAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/history")));
1296 }
1297
1298 QMainWindow::changeEvent(e);
1299
1300#ifndef Q_OS_MACOS // Ignored on Mac
1301 if(e->type() == QEvent::WindowStateChange)
1302 {
1304 {
1305 QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
1306 if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
1307 {
1308 QTimer::singleShot(0, this, &BitcoinGUI::hide);
1309 e->ignore();
1310 }
1311 else if((wsevt->oldState() & Qt::WindowMinimized) && !isMinimized())
1312 {
1313 QTimer::singleShot(0, this, &BitcoinGUI::show);
1314 e->ignore();
1315 }
1316 }
1317 }
1318#endif
1319}
1320
1321void BitcoinGUI::closeEvent(QCloseEvent *event)
1322{
1323#ifndef Q_OS_MACOS // Ignored on Mac
1325 {
1327 {
1328 // close rpcConsole in case it was open to make some space for the shutdown window
1329 rpcConsole->close();
1330
1331 Q_EMIT quitRequested();
1332 }
1333 else
1334 {
1335 QMainWindow::showMinimized();
1336 event->ignore();
1337 }
1338 }
1339#else
1340 QMainWindow::closeEvent(event);
1341#endif
1342}
1343
1344void BitcoinGUI::showEvent(QShowEvent *event)
1345{
1346 // enable the debug window when the main window shows up
1347 openRPCConsoleAction->setEnabled(true);
1348 aboutAction->setEnabled(true);
1349 optionsAction->setEnabled(true);
1350}
1351
1352#ifdef ENABLE_WALLET
1353void BitcoinGUI::incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
1354{
1355 // On new transaction, make an info balloon
1356 QString msg = tr("Date: %1\n").arg(date) +
1357 tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
1358 if (m_node.walletLoader().getWallets().size() > 1 && !walletName.isEmpty()) {
1359 msg += tr("Wallet: %1\n").arg(walletName);
1360 }
1361 msg += tr("Type: %1\n").arg(type);
1362 if (!label.isEmpty())
1363 msg += tr("Label: %1\n").arg(label);
1364 else if (!address.isEmpty())
1365 msg += tr("Address: %1\n").arg(address);
1366 message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
1368}
1369#endif // ENABLE_WALLET
1370
1371void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
1372{
1373 // Accept only URIs
1374 if(event->mimeData()->hasUrls())
1375 event->acceptProposedAction();
1376}
1377
1378void BitcoinGUI::dropEvent(QDropEvent *event)
1379{
1380 if(event->mimeData()->hasUrls())
1381 {
1382 for (const QUrl &uri : event->mimeData()->urls())
1383 {
1384 Q_EMIT receivedURI(uri.toString());
1385 }
1386 }
1387 event->acceptProposedAction();
1388}
1389
1390bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
1391{
1392 // Catch status tip events
1393 if (event->type() == QEvent::StatusTip)
1394 {
1395 // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
1396 if (progressBarLabel->isVisible() || progressBar->isVisible())
1397 return true;
1398 }
1399 return QMainWindow::eventFilter(object, event);
1400}
1401
1402#ifdef ENABLE_WALLET
1403bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
1404{
1405 // URI has to be valid
1406 if (walletFrame && walletFrame->handlePaymentRequest(recipient))
1407 {
1409 gotoSendCoinsPage();
1410 return true;
1411 }
1412 return false;
1413}
1414
1415void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled)
1416{
1417 labelWalletHDStatusIcon->setThemedPixmap(privkeyDisabled ? QStringLiteral(":/icons/eye") : hdEnabled ? QStringLiteral(":/icons/hd_enabled") : QStringLiteral(":/icons/hd_disabled"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
1418 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>"));
1420}
1421
1422void BitcoinGUI::setEncryptionStatus(int status)
1423{
1424 switch(status)
1425 {
1428 encryptWalletAction->setChecked(false);
1429 changePassphraseAction->setEnabled(false);
1430 encryptWalletAction->setEnabled(false);
1431 break;
1434 encryptWalletAction->setChecked(false);
1435 changePassphraseAction->setEnabled(false);
1436 encryptWalletAction->setEnabled(true);
1437 break;
1441 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1442 encryptWalletAction->setChecked(true);
1443 changePassphraseAction->setEnabled(true);
1444 encryptWalletAction->setEnabled(false);
1445 break;
1448 labelWalletEncryptionIcon->setThemedPixmap(QStringLiteral(":/icons/lock_closed"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
1449 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1450 encryptWalletAction->setChecked(true);
1451 changePassphraseAction->setEnabled(true);
1452 encryptWalletAction->setEnabled(false);
1453 break;
1454 }
1455}
1456
1457void BitcoinGUI::updateWalletStatus()
1458{
1460
1461 WalletView * const walletView = walletFrame->currentWalletView();
1462 if (!walletView) {
1463 return;
1464 }
1465 WalletModel * const walletModel = walletView->getWalletModel();
1466 setEncryptionStatus(walletModel->getEncryptionStatus());
1467 setHDStatus(walletModel->wallet().privateKeysDisabled(), walletModel->wallet().hdEnabled());
1468}
1469#endif // ENABLE_WALLET
1470
1472{
1473 std::string ip_port;
1474 bool proxy_enabled = clientModel->getProxyInfo(ip_port);
1475
1476 if (proxy_enabled) {
1478 QString ip_port_q = QString::fromStdString(ip_port);
1480 labelProxyIcon->setToolTip(tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
1481 } else {
1482 labelProxyIcon->show();
1483 }
1484 } else {
1485 labelProxyIcon->hide();
1486 }
1487}
1488
1490{
1491 QString window_title = CLIENT_NAME;
1492#ifdef ENABLE_WALLET
1493 if (walletFrame) {
1494 WalletModel* const wallet_model = walletFrame->currentWalletModel();
1495 if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
1496 window_title += " - " + wallet_model->getDisplayName();
1497 }
1498 }
1499#endif
1500 if (!m_network_style->getTitleAddText().isEmpty()) {
1501 window_title += " - " + m_network_style->getTitleAddText();
1502 }
1503 setWindowTitle(window_title);
1504}
1505
1507{
1508 if(!clientModel)
1509 return;
1510
1511 if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) && fToggleHidden) {
1512 hide();
1513 } else {
1515 }
1516}
1517
1519{
1521}
1522
1524{
1526 {
1527 if(rpcConsole)
1528 rpcConsole->hide();
1529 Q_EMIT quitRequested();
1530 }
1531}
1532
1533void BitcoinGUI::showProgress(const QString &title, int nProgress)
1534{
1535 if (nProgress == 0) {
1536 progressDialog = new QProgressDialog(title, QString(), 0, 100);
1538 progressDialog->setWindowModality(Qt::ApplicationModal);
1539 progressDialog->setAutoClose(false);
1540 progressDialog->setValue(0);
1541 } else if (nProgress == 100) {
1542 if (progressDialog) {
1543 progressDialog->close();
1544 progressDialog->deleteLater();
1545 progressDialog = nullptr;
1546 }
1547 } else if (progressDialog) {
1548 progressDialog->setValue(nProgress);
1549 }
1550}
1551
1553{
1554 if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
1556}
1557
1558static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, const std::string& caption, unsigned int style)
1559{
1560 bool modal = (style & CClientUIInterface::MODAL);
1561 // The SECURE flag has no effect in the Qt GUI.
1562 // bool secure = (style & CClientUIInterface::SECURE);
1563 style &= ~CClientUIInterface::SECURE;
1564 bool ret = false;
1565
1566 QString detailed_message; // This is original message, in English, for googling and referencing.
1567 if (message.original != message.translated) {
1568 detailed_message = BitcoinGUI::tr("Original message:") + "\n" + QString::fromStdString(message.original);
1569 }
1570
1571 // In case of modal message, use blocking connection to wait for user to click a button
1572 bool invoked = QMetaObject::invokeMethod(gui, "message",
1573 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1574 Q_ARG(QString, QString::fromStdString(caption)),
1575 Q_ARG(QString, QString::fromStdString(message.translated)),
1576 Q_ARG(unsigned int, style),
1577 Q_ARG(bool*, &ret),
1578 Q_ARG(QString, detailed_message));
1579 assert(invoked);
1580 return ret;
1581}
1582
1584{
1585 // Connect signals to client
1586 m_handler_message_box = m_node.handleMessageBox(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
1587 m_handler_question = m_node.handleQuestion(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_3, std::placeholders::_4));
1588}
1589
1591{
1592 // Disconnect signals from client
1593 m_handler_message_box->disconnect();
1594 m_handler_question->disconnect();
1595}
1596
1598{
1600 return m_mask_values_action->isChecked();
1601}
1602
1604 : m_platform_style{platformStyle}
1605{
1607 setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1608 QList<BitcoinUnit> units = BitcoinUnits::availableUnits();
1609 int max_width = 0;
1610 const QFontMetrics fm(font());
1611 for (const BitcoinUnit unit : units) {
1612 max_width = qMax(max_width, GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit)));
1613 }
1614 setMinimumSize(max_width, 0);
1615 setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1616 setStyleSheet(QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name()));
1617}
1618
1621{
1622 onDisplayUnitsClicked(event->pos());
1623}
1624
1626{
1627 if (e->type() == QEvent::PaletteChange) {
1628 QString style = QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name());
1629 if (style != styleSheet()) {
1630 setStyleSheet(style);
1631 }
1632 }
1633
1634 QLabel::changeEvent(e);
1635}
1636
1639{
1640 menu = new QMenu(this);
1641 for (const BitcoinUnit u : BitcoinUnits::availableUnits()) {
1642 menu->addAction(BitcoinUnits::longName(u))->setData(QVariant::fromValue(u));
1643 }
1644 connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection);
1645}
1646
1649{
1650 if (_optionsModel)
1651 {
1652 this->optionsModel = _optionsModel;
1653
1654 // be aware of a display unit change reported by the OptionsModel object.
1656
1657 // initialize the display units label with the current value in the model.
1658 updateDisplayUnit(_optionsModel->getDisplayUnit());
1659 }
1660}
1661
1664{
1665 setText(BitcoinUnits::longName(newUnits));
1666}
1667
1670{
1671 QPoint globalPos = mapToGlobal(point);
1672 menu->exec(globalPos);
1673}
1674
1677{
1678 if (action)
1679 {
1680 optionsModel->setDisplayUnit(action->data());
1681 }
1682}
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
int ret
if(!SetupNetworking())
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
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:45
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:130
QAction * m_close_all_wallets_action
Definition: bitcoingui.h:160
void showEvent(QShowEvent *event) override
QLabel * progressBarLabel
Definition: bitcoingui.h:129
QAction * m_open_wallet_action
Definition: bitcoingui.h:156
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:72
QAction * openAction
Definition: bitcoingui.h:153
void createWallet()
Launch the wallet creation modal (no-op if wallet is not compiled)
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.
Definition: bitcoingui.cpp:628
GUIUtil::ClickableLabel * connectionsControl
Definition: bitcoingui.h:127
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
ModalOverlay * modalOverlay
Definition: bitcoingui.h:175
GUIUtil::ThemedLabel * labelWalletEncryptionIcon
Definition: bitcoingui.h:124
QAction * changePassphraseAction
Definition: bitcoingui.h:150
void openOptionsDialogWithTab(OptionsDialog::Tab tab)
Open the OptionsDialog on the specified tab index.
int prevBlocks
Keep track of previous number of blocks, to detect progress.
Definition: bitcoingui.h:184
QAction * openRPCConsoleAction
Definition: bitcoingui.h:152
const NetworkStyle *const m_network_style
Definition: bitcoingui.h:188
void changeEvent(QEvent *e) override
GUIUtil::ClickableLabel * labelProxyIcon
Definition: bitcoingui.h:126
void optionsClicked()
Show configuration dialog.
Definition: bitcoingui.cpp:933
QAction * historyAction
Definition: bitcoingui.h:136
bool eventFilter(QObject *object, QEvent *event) override
QMenu * m_open_wallet_menu
Definition: bitcoingui.h:157
void createTrayIcon()
Create system tray icon and notification.
Definition: bitcoingui.cpp:837
QAction * m_load_psbt_clipboard_action
Definition: bitcoingui.h:144
QAction * quitAction
Definition: bitcoingui.h:137
void setNetworkActive(bool network_active)
Set network state shown in the UI.
void setPrivacy(bool privacy)
QProgressDialog * progressDialog
Definition: bitcoingui.h:131
BitcoinGUI(interfaces::Node &node, const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent=nullptr)
Definition: bitcoingui.cpp:85
std::unique_ptr< interfaces::Handler > m_handler_message_box
Definition: bitcoingui.h:118
WalletFrame * walletFrame
Definition: bitcoingui.h:121
void updateProxyIcon()
Set the proxy-enabled icon as shown in the UI.
QAction * m_restore_wallet_action
Definition: bitcoingui.h:158
QAction * receiveCoinsAction
Definition: bitcoingui.h:146
const std::unique_ptr< QMenu > trayIconMenu
Definition: bitcoingui.h:171
QAction * usedSendingAddressesAction
Definition: bitcoingui.h:139
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
void closeEvent(QCloseEvent *event) override
QAction * verifyMessageAction
Definition: bitcoingui.h:142
QAction * m_migrate_wallet_action
Definition: bitcoingui.h:164
void createTrayIconMenu()
Create system tray menu (or setup the dock menu)
Definition: bitcoingui.cpp:850
HelpMessageDialog * helpMessageDialog
Definition: bitcoingui.h:174
void aboutClicked()
Show about dialog.
Definition: bitcoingui.cpp:938
void toggleHidden()
Simply calls showNormalIfMinimized(true)
QAction * encryptWalletAction
Definition: bitcoingui.h:148
void updateNetworkState()
Update UI with latest network info from model.
void createActions()
Create the main UI actions.
Definition: bitcoingui.cpp:247
void showDebugWindow()
Show debug window.
Definition: bitcoingui.cpp:947
QAction * m_mask_values_action
Definition: bitcoingui.h:163
int spinnerFrame
Definition: bitcoingui.h:185
QAction * aboutAction
Definition: bitcoingui.h:145
void consoleShown(RPCConsole *console)
Signal raised when RPC console shown.
bool isPrivacyModeActivated() const
QMenu * m_migrate_wallet_menu
Definition: bitcoingui.h:165
void showDebugWindowActivateConsole()
Show debug window and set focus to the console.
Definition: bitcoingui.cpp:953
void dropEvent(QDropEvent *event) override
void showProgress(const QString &title, int nProgress)
Show progress dialog e.g.
QAction * usedReceivingAddressesAction
Definition: bitcoingui.h:140
void subscribeToCoreSignals()
Connect core signals to GUI client.
void createToolBars()
Create the toolbars.
Definition: bitcoingui.cpp:592
QAction * m_wallet_selector_action
Definition: bitcoingui.h:162
UnitDisplayStatusBarControl * unitDisplayControl
Definition: bitcoingui.h:123
QAction * optionsAction
Definition: bitcoingui.h:147
void updateWindowTitle()
void setWalletActionsEnabled(bool enabled)
Enable or disable all wallet-related actions.
Definition: bitcoingui.cpp:819
const PlatformStyle * platformStyle
Definition: bitcoingui.h:187
void dragEnterEvent(QDragEnterEvent *event) override
QAction * m_close_wallet_action
Definition: bitcoingui.h:159
QAction * overviewAction
Definition: bitcoingui.h:135
GUIUtil::ClickableLabel * labelBlocksIcon
Definition: bitcoingui.h:128
interfaces::Node & m_node
Definition: bitcoingui.h:116
QAction * m_create_wallet_action
Definition: bitcoingui.h:155
QAction * m_load_psbt_action
Definition: bitcoingui.h:143
void detectShutdown()
called by a timer to check if shutdown has been requested
QAction * m_wallet_selector_label_action
Definition: bitcoingui.h:161
WalletController * m_wallet_controller
Definition: bitcoingui.h:117
bool enableWallet
Definition: bitcoingui.h:95
RPCConsole * rpcConsole
Definition: bitcoingui.h:173
QMenu * m_network_context_menu
Definition: bitcoingui.h:177
QAction * backupWalletAction
Definition: bitcoingui.h:149
QAction * showHelpMessageAction
Definition: bitcoingui.h:154
QAction * aboutQtAction
Definition: bitcoingui.h:151
QComboBox * m_wallet_selector
Definition: bitcoingui.h:168
QLabel * m_wallet_selector_label
Definition: bitcoingui.h:167
void showNormalIfMinimized()
Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHid...
Definition: bitcoingui.h:311
ClientModel * clientModel
Definition: bitcoingui.h:120
void updateHeadersSyncProgressLabel()
void createMenuBar()
Create the menu bar and sub-menus.
Definition: bitcoingui.cpp:498
QSystemTrayIcon * trayIcon
Definition: bitcoingui.h:170
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.
Definition: bitcoingui.cpp:959
QAction * sendCoinsAction
Definition: bitcoingui.h:138
void quitRequested()
QToolBar * appToolBar
Definition: bitcoingui.h:134
void setNumConnections(int count)
Set number of connections shown in the UI.
QAction * signMessageAction
Definition: bitcoingui.h:141
GUIUtil::ThemedLabel * labelWalletHDStatusIcon
Definition: bitcoingui.h:125
void showModalOverlay()
Notificator * notificator
Definition: bitcoingui.h:172
std::unique_ptr< interfaces::Handler > m_handler_question
Definition: bitcoingui.h:119
QMenuBar * appMenuBar
Definition: bitcoingui.h:133
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
static QString longName(Unit unit)
Long name.
static QString formatWithUnit(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as string (with unit)
Unit
Bitcoin units.
Definition: bitcoinunits.h:42
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:81
Signals for UI communication.
Definition: interface_ui.h:26
@ BTN_MASK
Mask of all available buttons in CClientUIInterface::MessageBoxFlags This needs to be updated,...
Definition: interface_ui.h:56
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
Definition: interface_ui.h:66
@ MODAL
Force blocking, modal message box dialog (not just OS notification)
Definition: interface_ui.h:60
Model for Bitcoin network client.
Definition: clientmodel.h:57
void showProgress(const QString &title, int nProgress)
int getHeaderTipHeight() const
Definition: clientmodel.cpp:98
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
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:84
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)
void created(WalletModel *wallet_model)
void clicked(const QPoint &point)
Emitted when the label is clicked.
void clicked(const QPoint &point)
Emitted when the progressbar is clicked.
void setThemedPixmap(const QString &image_filename, int width, int height)
Definition: guiutil.cpp:854
"Help message" dialog box
Definition: utilitydialog.h:21
macOS-specific Dock icon handler.
static MacDockIconHandler * instance()
void migrated(WalletModel *wallet_model)
Modal overlay to display information about the chain-sync state.
Definition: modaloverlay.h:21
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
Definition: modaloverlay.h:33
void setKnownBestHeight(int count, const QDateTime &blockDate, bool presync)
const QIcon & getTrayAndWindowIcon() const
Definition: networkstyle.h:23
const QString & getTitleAddText() const
Definition: networkstyle.h:24
Cross-platform desktop notification client.
Definition: notificator.h:23
@ Information
Informational message.
Definition: notificator.h:36
@ Critical
An error occurred.
Definition: notificator.h:38
@ Warning
Notify user of potential problem.
Definition: notificator.h:37
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.
Definition: optionsdialog.h:37
void quitOnReset()
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:43
void displayUnitChanged(BitcoinUnit unit)
void showTrayIconChanged(bool)
bool getMinimizeToTray() const
Definition: optionsmodel.h:101
BitcoinUnit getDisplayUnit() const
Definition: optionsmodel.h:103
bool getShowTrayIcon() const
Definition: optionsmodel.h:100
QVariant getOption(OptionID option, const std::string &suffix="") const
bool getMinimizeOnClose() const
Definition: optionsmodel.h:102
void setDisplayUnit(const QVariant &new_unit)
Updates current unit in memory, settings and emits displayUnitChanged(new_unit) signal.
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:42
std::vector< TabTypes > tabs() const
Definition: rpcconsole.h:76
QString tabTitle(TabTypes tab_type) const
QKeySequence tabShortcut(TabTypes tab_type) const
void setClientModel(ClientModel *model=nullptr, int bestblock_height=0, int64_t bestblock_date=0, double verification_progress=0.0)
Definition: rpcconsole.cpp:654
void setTabFocus(enum TabTypes tabType)
set which tab has the focus (is visible)
void restored(WalletModel *wallet_model)
void changeEvent(QEvent *e) override
void mousePressEvent(QMouseEvent *event) override
So that it responds to left-button clicks.
void createContextMenu()
Creates context menu, its actions, and wires up all the relevant signals for mouse events.
void updateDisplayUnit(BitcoinUnit newUnits)
When Display Units are changed on OptionsModel it will refresh the display text of the control on the...
OptionsModel * optionsModel
Definition: bitcoingui.h:340
UnitDisplayStatusBarControl(const PlatformStyle *platformStyle)
void onMenuSelection(QAction *action)
Tells underlying optionsModel to update its current display unit.
const PlatformStyle * m_platform_style
Definition: bitcoingui.h:342
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)
void walletRemoved(WalletModel *wallet_model)
void closeWallet(WalletModel *wallet_model, QWidget *parent=nullptr)
std::map< std::string, std::pair< bool, std::string > > listWalletDir() const
Returns all wallet names in the wallet dir mapped to whether the wallet is loaded.
A container for embedding all wallet-related controls into BitcoinGUI.
Definition: walletframe.h:29
void removeAllWallets()
void currentWalletSet()
bool addView(WalletView *walletView)
Definition: walletframe.cpp:69
void changePassphrase()
Change encrypted wallet passphrase.
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)
Definition: walletframe.cpp:60
void backupWallet()
Backup the wallet.
void usedSendingAddresses()
Show used sending addresses.
void createWalletButtonClicked()
void encryptWallet()
Encrypt the wallet.
void usedReceivingAddresses()
Show used receiving addresses.
void message(const QString &title, const QString &message, unsigned int style)
void setCurrentWallet(WalletModel *wallet_model)
Definition: walletframe.cpp:91
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
void gotoLoadPSBT(bool from_clipboard=false)
Load Partially Signed Bitcoin Transaction.
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:49
EncryptionStatus getEncryptionStatus() const
interfaces::Wallet & wallet() const
Definition: walletmodel.h:139
QString getDisplayName() const
static bool isWalletEnabled()
QString getWalletName() const
void outOfSyncWarningClicked()
Notify that the out of sync warning icon has been pressed.
WalletModel * getWalletModel() const noexcept
Definition: walletview.h:46
void message(const QString &title, const QString &message, unsigned int style)
Fired when a message should be reported to the user.
void incomingTransaction(const QString &date, BitcoinUnit unit, const CAmount &amount, const QString &type, const QString &address, const QString &label, const QString &walletName)
Notify that a new transaction appeared.
void transactionClicked()
void coinsSent()
void setPrivacy(bool privacy)
void encryptionStatusChanged()
Encryption status of wallet changed.
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:71
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 WalletLoader & walletLoader()=0
Get wallet loader.
virtual bool shutdownRequested()=0
Return whether shutdown was requested.
virtual bool hdEnabled()=0
virtual bool privateKeysDisabled()=0
virtual std::vector< std::unique_ptr< Wallet > > getWallets()=0
Return interfaces for accessing wallets (if any).
SyncType
Definition: clientmodel.h:42
@ HEADER_PRESYNC
BlockSource
Definition: clientmodel.h:36
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:174
#define SPINNER_FRAMES
Definition: guiconstants.h:47
static const int STATUSBAR_ICONSIZE
Definition: guiconstants.h:23
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...
Definition: modaloverlay.h:13
bool isObscured(QWidget *w)
Definition: guiutil.cpp:397
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
Definition: guiutil.cpp:378
QString WalletDisplayName(const QString &name)
Definition: guiutil.cpp:990
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
Definition: guiutil.cpp:948
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:983
void handleCloseWindowShortcut(QWidget *w)
Definition: guiutil.cpp:431
void PolishProgressDialog(QProgressDialog *dialog)
Definition: guiutil.cpp:901
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
Definition: guiutil.cpp:353
ClickableProgressBar ProgressBar
Definition: guiutil.h:300
void bringToFront(QWidget *w)
Definition: guiutil.cpp:406
bool HasPixmap(const QLabel *label)
Returns true if pixmap has been set.
Definition: guiutil.cpp:960
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:787
auto ExceptionSafeConnect(Sender sender, Signal signal, Receiver receiver, Slot method, Qt::ConnectionType type=Qt::AutoConnection)
A drop-in replacement of QObject::connect function (see: https://doc.qt.io/qt-5/qobject....
Definition: guiutil.h:369
int TextWidth(const QFontMetrics &fm, const QString &text)
Returns the distance in pixels appropriate for drawing a subsequent character after text.
Definition: guiutil.cpp:915
Warning
Definition: warning.h:9
Definition: messages.h:20
const char * name
Definition: rest.cpp:49
static RPCHelpMan help()
Definition: server.cpp:127
int64_t nPowTargetSpacing
Definition: params.h:119
Bilingual messages:
Definition: translation.h:24
std::string translated
Definition: translation.h:26
std::string original
Definition: translation.h:25
Block and header tip information.
Definition: node.h:51
static int count
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:76
assert(!tx.IsCoinBase())
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:86