Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
bitcoingui.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-present 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 <QAction>
45#include <QActionGroup>
46#include <QApplication>
47#include <QComboBox>
48#include <QCursor>
49#include <QDateTime>
50#include <QDragEnterEvent>
51#include <QInputDialog>
52#include <QKeySequence>
53#include <QListWidget>
54#include <QMenu>
55#include <QMenuBar>
56#include <QMessageBox>
57#include <QMimeData>
58#include <QProgressDialog>
59#include <QScreen>
60#include <QSettings>
61#include <QShortcut>
62#include <QStackedWidget>
63#include <QStatusBar>
64#include <QStyle>
65#include <QSystemTrayIcon>
66#include <QTimer>
67#include <QToolBar>
68#include <QUrlQuery>
69#include <QVBoxLayout>
70#include <QWindow>
71
72
79static constexpr int64_t MAX_BLOCK_TIME_GAP = 90 * 60;
80
81const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
82#if defined(Q_OS_MACOS)
83 "macosx"
84#elif defined(Q_OS_WIN)
85 "windows"
86#else
87 "other"
88#endif
89 ;
90
92 QMainWindow(parent),
93 m_node(node),
94 trayIconMenu{new QMenu()},
95 platformStyle(_platformStyle),
96 m_network_style(networkStyle)
97{
99 if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
100 // Restore failed (perhaps missing setting), center the window
101 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
102 }
103
104 setContextMenuPolicy(Qt::PreventContextMenu);
105
106#ifdef ENABLE_WALLET
108#endif // ENABLE_WALLET
109 QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
112
113 rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
114 helpMessageDialog = new HelpMessageDialog(this, false);
115#ifdef ENABLE_WALLET
116 if(enableWallet)
117 {
121 connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
122 this->message(title, message, style);
123 });
126 } else
127#endif // ENABLE_WALLET
128 {
129 /* When compiled without wallet or -disablewallet is provided,
130 * the central widget is the rpc console.
131 */
134 }
135
137
138 // Accept D&D of URIs
139 setAcceptDrops(true);
140
141 // Create actions for the toolbar, menu bar and tray/dock icon
142 // Needs walletFrame to be initialized
144
145 // Create application menu bar
147
148 // Create the toolbars
150
151 // Create system tray icon and notification
152 if (QSystemTrayIcon::isSystemTrayAvailable()) {
154 }
155 notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
156
157 // Create status bar
158 statusBar();
159
160 // Disable size grip because it looks ugly and nobody needs it
161 statusBar()->setSizeGripEnabled(false);
162
163 // Status bar notification icons
164 QFrame *frameBlocks = new QFrame();
165 frameBlocks->setContentsMargins(0,0,0,0);
166 frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
168 frameBlocksLayout->setContentsMargins(3,0,3,0);
169 frameBlocksLayout->setSpacing(3);
176 if(enableWallet)
177 {
178 frameBlocksLayout->addStretch();
180 frameBlocksLayout->addStretch();
185 }
187 frameBlocksLayout->addStretch();
189 frameBlocksLayout->addStretch();
191 frameBlocksLayout->addStretch();
192
193 // Progress bar and label for blocks download
194 progressBarLabel = new QLabel();
195 progressBarLabel->setVisible(false);
197 progressBar->setAlignment(Qt::AlignCenter);
198 progressBar->setVisible(false);
199
200 // Override style sheet for progress bar for styles that have a segmented progress bar,
201 // as they make the text unreadable (workaround for issue #1071)
202 // See https://doc.qt.io/qt-5/gallery.html
203 QString curStyle = QApplication::style()->metaObject()->className();
204 if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
205 {
206 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; }");
207 }
208
209 statusBar()->addWidget(progressBarLabel);
210 statusBar()->addWidget(progressBar);
211 statusBar()->addPermanentWidget(frameBlocks);
212
213 // Install event filter to be able to catch status tip events (QEvent::StatusTip)
214 this->installEventFilter(this);
215
216 // Initially wallet actions should be disabled
218
219 // Subscribe to notifications from core
221
224 });
225
228
229#ifdef Q_OS_MACOS
231#endif
232
234}
235
237{
238 // Unsubscribe from notifications from core
240
242 settings.setValue("MainWindowGeometry", saveGeometry());
243 if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
244 trayIcon->hide();
245#ifdef Q_OS_MACOS
246 delete m_app_nap_inhibitor;
248#endif
249
250 delete rpcConsole;
251}
252
254{
256 connect(modalOverlay, &ModalOverlay::triggered, tabGroup, &QActionGroup::setEnabled);
257
258 overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
259 overviewAction->setStatusTip(tr("Show general overview of wallet"));
260 overviewAction->setToolTip(overviewAction->statusTip());
261 overviewAction->setCheckable(true);
262 overviewAction->setShortcut(QKeySequence(QStringLiteral("Alt+1")));
263 tabGroup->addAction(overviewAction);
264
265 sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
266 sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
267 sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
268 sendCoinsAction->setCheckable(true);
269 sendCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+2")));
270 tabGroup->addAction(sendCoinsAction);
271
272 receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
273 receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
274 receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
275 receiveCoinsAction->setCheckable(true);
276 receiveCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+3")));
277 tabGroup->addAction(receiveCoinsAction);
278
279 historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
280 historyAction->setStatusTip(tr("Browse transaction history"));
281 historyAction->setToolTip(historyAction->statusTip());
282 historyAction->setCheckable(true);
283 historyAction->setShortcut(QKeySequence(QStringLiteral("Alt+4")));
284 tabGroup->addAction(historyAction);
285
286#ifdef ENABLE_WALLET
287 // These showNormalIfMinimized are needed because Send Coins and Receive Coins
288 // can be triggered from the tray menu, and need to show the GUI to be useful.
289 connect(overviewAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
290 connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage);
291 connect(sendCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
292 connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); });
293 connect(receiveCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
294 connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
295 connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
296 connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage);
297#endif // ENABLE_WALLET
298
299 quitAction = new QAction(tr("E&xit"), this);
300 quitAction->setStatusTip(tr("Quit application"));
301 quitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));
302 quitAction->setMenuRole(QAction::QuitRole);
303 aboutAction = new QAction(tr("&About %1").arg(CLIENT_NAME), this);
304 aboutAction->setStatusTip(tr("Show information about %1").arg(CLIENT_NAME));
305 aboutAction->setMenuRole(QAction::AboutRole);
306 aboutAction->setEnabled(false);
307 aboutQtAction = new QAction(tr("About &Qt"), this);
308 aboutQtAction->setStatusTip(tr("Show information about Qt"));
309 aboutQtAction->setMenuRole(QAction::AboutQtRole);
310 optionsAction = new QAction(tr("&Options…"), this);
311 optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(CLIENT_NAME));
312 optionsAction->setMenuRole(QAction::PreferencesRole);
313 optionsAction->setEnabled(false);
314
315 encryptWalletAction = new QAction(tr("&Encrypt Wallet…"), this);
316 encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
317 encryptWalletAction->setCheckable(true);
318 backupWalletAction = new QAction(tr("&Backup Wallet…"), this);
319 backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
320 changePassphraseAction = new QAction(tr("&Change Passphrase…"), this);
321 changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
322 signMessageAction = new QAction(tr("Sign &message…"), this);
323 signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
324 verifyMessageAction = new QAction(tr("&Verify message…"), this);
325 verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
326 m_load_psbt_action = new QAction(tr("&Load PSBT from file…"), this);
327 m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
328 m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from &clipboard…"), this);
329 m_load_psbt_clipboard_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction from clipboard"));
330
331 openRPCConsoleAction = new QAction(tr("Node window"), this);
332 openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
333 // initially disable the debug window menu item
334 openRPCConsoleAction->setEnabled(false);
335 openRPCConsoleAction->setObjectName("openRPCConsoleAction");
336
337 usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
338 usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
339 usedReceivingAddressesAction = new QAction(tr("&Receiving addresses"), this);
340 usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
341
342 openAction = new QAction(tr("Open &URI…"), this);
343 openAction->setStatusTip(tr("Open a bitcoin: URI"));
344
345 m_open_wallet_action = new QAction(tr("Open Wallet"), this);
346 m_open_wallet_action->setEnabled(false);
347 m_open_wallet_action->setStatusTip(tr("Open a wallet"));
348 m_open_wallet_menu = new QMenu(this);
349
350 m_close_wallet_action = new QAction(tr("Close Wallet…"), this);
351 m_close_wallet_action->setStatusTip(tr("Close wallet"));
352
353 m_create_wallet_action = new QAction(tr("Create Wallet…"), this);
354 m_create_wallet_action->setEnabled(false);
355 m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
356
357 //: Name of the menu item that restores wallet from a backup file.
358 m_restore_wallet_action = new QAction(tr("Restore Wallet…"), this);
359 m_restore_wallet_action->setEnabled(false);
360 //: Status tip for Restore Wallet menu item
361 m_restore_wallet_action->setStatusTip(tr("Restore a wallet from a backup file"));
362
363 m_close_all_wallets_action = new QAction(tr("Close All Wallets…"), this);
364 m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
365
366 m_migrate_wallet_action = new QAction(tr("Migrate Wallet"), this);
367 m_migrate_wallet_action->setEnabled(false);
368 m_migrate_wallet_action->setStatusTip(tr("Migrate a wallet"));
369 m_migrate_wallet_menu = new QMenu(this);
370
371 showHelpMessageAction = new QAction(tr("&Command-line options"), this);
372 showHelpMessageAction->setMenuRole(QAction::NoRole);
373 showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(CLIENT_NAME));
374
375 m_mask_values_action = new QAction(tr("&Mask values"), this);
376 m_mask_values_action->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_M));
377 m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab"));
378 m_mask_values_action->setCheckable(true);
379
380 m_export_watchonly_action = new QAction(tr("Export watch-only wallet"), this);
381 m_export_watchonly_action->setEnabled(false);
382 m_export_watchonly_action->setStatusTip(tr("Export a watch-only version of the current wallet that can be restored onto another node."));
383
384 connect(quitAction, &QAction::triggered, this, &BitcoinGUI::quitRequested);
385 connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
386 connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
387 connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked);
388 connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked);
389 connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow);
390 // prevents an open debug window from becoming stuck/unusable on client shutdown
391 connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
392
393#ifdef ENABLE_WALLET
394 if(walletFrame)
395 {
396 connect(encryptWalletAction, &QAction::triggered, walletFrame, &WalletFrame::encryptWallet);
397 connect(backupWalletAction, &QAction::triggered, walletFrame, &WalletFrame::backupWallet);
399 connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
400 connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
401 connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
402 connect(m_load_psbt_clipboard_action, &QAction::triggered, [this]{ gotoLoadPSBT(true); });
403 connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
404 connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
407 connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked);
408 connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
409 m_open_wallet_menu->clear();
410 for (const auto& [path, info] : m_wallet_controller->listWalletDir()) {
411 const auto& [loaded, format] = info;
413 // An single ampersand in the menu item's text sets a shortcut for this item.
414 // Single & are shown when && is in the string. So replace & with &&.
415 name.replace(QChar('&'), QString("&&"));
416 bool is_legacy = format == "bdb";
417 if (is_legacy) {
418 name += " (needs migration)";
419 }
420 QAction* action = m_open_wallet_menu->addAction(name);
421
422 if (loaded || is_legacy) {
423 // This wallet is already loaded or it is a legacy wallet
424 action->setEnabled(false);
425 continue;
426 }
427
428 connect(action, &QAction::triggered, [this, path] {
429 auto activity = new OpenWalletActivity(m_wallet_controller, this);
430 connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
431 connect(activity, &OpenWalletActivity::opened, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
432 activity->open(path);
433 });
434 }
435 if (m_open_wallet_menu->isEmpty()) {
436 QAction* action = m_open_wallet_menu->addAction(tr("No wallets available"));
437 action->setEnabled(false);
438 }
439 });
440 connect(m_restore_wallet_action, &QAction::triggered, [this] {
441 //: Name of the wallet data file format.
442 QString name_data_file = tr("Wallet Data");
443
444 //: The title for Restore Wallet File Windows
445 QString title_windows = tr("Load Wallet Backup");
446
447 QString backup_file = GUIUtil::getOpenFileName(this, title_windows, QString(), name_data_file + QLatin1String(" (*.dat *.wallet);;") + tr("All Files") + QLatin1String(" (*)"), nullptr);
448 if (backup_file.isEmpty()) return;
449
450 bool wallet_name_ok;
451 /*: Title of pop-up window shown when the user is attempting to
452 restore a wallet. */
453 QString title = tr("Restore Wallet");
454 //: Label of the input field where the name of the wallet is entered.
455 QString label = tr("Wallet Name");
456 QString wallet_name = QInputDialog::getText(this, title, label, QLineEdit::Normal, "", &wallet_name_ok);
457 if (!wallet_name_ok) return;
458 if (wallet_name.isEmpty()) {
459 QMessageBox::critical(nullptr, tr("Invalid Wallet Name"), tr("Wallet name cannot be empty"));
460 return;
461 }
462
463 auto activity = new RestoreWalletActivity(m_wallet_controller, this);
464 connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
465 connect(activity, &RestoreWalletActivity::restored, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
466
467 auto backup_file_path = fs::PathFromString(backup_file.toStdString());
468 activity->restore(backup_file_path, wallet_name.toStdString());
469 });
470 connect(m_close_wallet_action, &QAction::triggered, [this] {
471 m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
472 });
473 connect(m_create_wallet_action, &QAction::triggered, this, &BitcoinGUI::createWallet);
474 connect(m_close_all_wallets_action, &QAction::triggered, [this] {
475 m_wallet_controller->closeAllWallets(this);
476 });
477 connect(m_migrate_wallet_menu, &QMenu::aboutToShow, [this] {
478 m_migrate_wallet_menu->clear();
479 for (const auto& [wallet_name, info] : m_wallet_controller->listWalletDir()) {
480 const auto& [loaded, format] = info;
481
482 if (format != "bdb") { // Skip already migrated wallets
483 continue;
484 }
485
487 // An single ampersand in the menu item's text sets a shortcut for this item.
488 // Single & are shown when && is in the string. So replace & with &&.
489 name.replace(QChar('&'), QString("&&"));
491
492 connect(action, &QAction::triggered, [this, wallet_name] {
493 auto activity = new MigrateWalletActivity(m_wallet_controller, this);
494 connect(activity, &MigrateWalletActivity::migrated, this, &BitcoinGUI::setCurrentWallet);
495 activity->migrate(wallet_name);
496 });
497 }
498 if (m_migrate_wallet_menu->isEmpty()) {
499 QAction* action = m_migrate_wallet_menu->addAction(tr("No wallets available"));
500 action->setEnabled(false);
501 }
502 m_migrate_wallet_menu->addSeparator();
503 QAction* restore_migrate_file_action = m_migrate_wallet_menu->addAction(tr("Restore and Migrate Wallet File…"));
504 restore_migrate_file_action->setEnabled(true);
505
506 connect(restore_migrate_file_action, &QAction::triggered, [this] {
507 QString name_data_file = tr("Wallet Data");
508 QString title_windows = tr("Restore and Migrate Wallet Backup");
509
511 if (backup_file.isEmpty()) return;
512
513 bool wallet_name_ok;
514 /*: Title of pop-up window shown when the user is attempting to
515 restore a wallet. */
516 QString title = tr("Restore and Migrate Wallet");
517 //: Label of the input field where the name of the wallet is entered.
518 QString label = tr("Wallet Name");
519 QString wallet_name = QInputDialog::getText(this, title, label, QLineEdit::Normal, "", &wallet_name_ok);
520 if (!wallet_name_ok || wallet_name.isEmpty()) return;
521
522 auto activity = new MigrateWalletActivity(m_wallet_controller, this);
523 connect(activity, &MigrateWalletActivity::migrated, this, &BitcoinGUI::setCurrentWallet);
524 connect(activity, &MigrateWalletActivity::migrated, rpcConsole, &RPCConsole::setCurrentWallet);
525 auto backup_file_path = fs::PathFromString(backup_file.toStdString());
526 activity->restore_and_migrate(backup_file_path, wallet_name.toStdString());
527 });
528 });
529 connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::setPrivacy);
530 connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::enableHistoryAction);
531 GUIUtil::ExceptionSafeConnect(m_export_watchonly_action, &QAction::triggered, [this](bool) {
532 QString destination = GUIUtil::getSaveFileName(this,
533 tr("Save Watch-only Wallet Export"), QString(),
534 //: Name of the wallet data file format.
535 tr("Wallet Data") + QLatin1String(" (*.dat)"), nullptr);
536
537 if (destination.isEmpty()) return;
539 if (!Assume(model)) return;
541 if (export_res) {
542 QMessageBox::information(nullptr, tr("Export Successful"), tr("The wallet has been exported to ") + QString::fromStdString(*export_res));
543 } else {
544 QMessageBox::critical(nullptr, tr("Export Error"), QString::fromStdString(util::ErrorString(export_res).translated));
545 }
546 });
547 }
548#endif // ENABLE_WALLET
549
550 connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindowActivateConsole);
551 connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_D), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
552}
553
555{
557
558 // Configure the menus
559 QMenu *file = appMenuBar->addMenu(tr("&File"));
560 if(walletFrame)
561 {
562 file->addAction(m_create_wallet_action);
563 file->addAction(m_open_wallet_action);
564 file->addAction(m_close_wallet_action);
565 file->addAction(m_close_all_wallets_action);
566 file->addAction(m_migrate_wallet_action);
567 file->addSeparator();
568 file->addAction(backupWalletAction);
569 file->addAction(m_restore_wallet_action);
570 file->addAction(m_export_watchonly_action);
571 file->addSeparator();
572 file->addAction(openAction);
573 file->addAction(signMessageAction);
574 file->addAction(verifyMessageAction);
575 file->addAction(m_load_psbt_action);
576 file->addAction(m_load_psbt_clipboard_action);
577 file->addSeparator();
578 }
579 file->addAction(quitAction);
580
581 QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
582 if(walletFrame)
583 {
584 settings->addAction(encryptWalletAction);
586 settings->addSeparator();
587 settings->addAction(m_mask_values_action);
588 settings->addSeparator();
589 }
590 settings->addAction(optionsAction);
591
592 QMenu* window_menu = appMenuBar->addMenu(tr("&Window"));
593
594 QAction* minimize_action = window_menu->addAction(tr("&Minimize"));
595 minimize_action->setShortcut(QKeySequence(tr("Ctrl+M")));
596 connect(minimize_action, &QAction::triggered, [] {
597 QApplication::activeWindow()->showMinimized();
598 });
599 connect(qApp, &QApplication::focusWindowChanged, this, [minimize_action] (QWindow* window) {
600 minimize_action->setEnabled(window != nullptr && (window->flags() & Qt::Dialog) != Qt::Dialog && window->windowState() != Qt::WindowMinimized);
601 });
602
603#ifdef Q_OS_MACOS
604 QAction* zoom_action = window_menu->addAction(tr("Zoom"));
605 connect(zoom_action, &QAction::triggered, [] {
606 QWindow* window = qApp->focusWindow();
607 if (window->windowState() != Qt::WindowMaximized) {
608 window->showMaximized();
609 } else {
610 window->showNormal();
611 }
612 });
613
614 connect(qApp, &QApplication::focusWindowChanged, this, [zoom_action] (QWindow* window) {
615 zoom_action->setEnabled(window != nullptr);
616 });
617#endif
618
619 if (walletFrame) {
620#ifdef Q_OS_MACOS
621 window_menu->addSeparator();
622 QAction* main_window_action = window_menu->addAction(tr("Main Window"));
623 connect(main_window_action, &QAction::triggered, [this] {
625 });
626#endif
627 window_menu->addSeparator();
630 }
631
632 window_menu->addSeparator();
636 connect(tab_action, &QAction::triggered, [this, tab_type] {
639 });
640 }
641
642 QMenu *help = appMenuBar->addMenu(tr("&Help"));
643 help->addAction(showHelpMessageAction);
644 help->addSeparator();
645 help->addAction(aboutAction);
646 help->addAction(aboutQtAction);
647}
648
650{
651 if(walletFrame)
652 {
653 QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
655 toolbar->setMovable(false);
656 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
657 toolbar->addAction(overviewAction);
658 toolbar->addAction(sendCoinsAction);
659 toolbar->addAction(receiveCoinsAction);
660 toolbar->addAction(historyAction);
661 overviewAction->setChecked(true);
662
663#ifdef ENABLE_WALLET
664 QWidget *spacer = new QWidget();
665 spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
666 toolbar->addWidget(spacer);
667
668 m_wallet_selector = new QComboBox();
669 m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
670 connect(m_wallet_selector, qOverload<int>(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
671
672 m_wallet_selector_label = new QLabel();
673 m_wallet_selector_label->setText(tr("Wallet:") + " ");
675
678
679 m_wallet_selector_label_action->setVisible(false);
680 m_wallet_selector_action->setVisible(false);
681#endif
682 }
683}
684
686{
688 if(_clientModel)
689 {
690 // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
691 // while the client has not yet fully loaded
693
694 // Keep up to date with client
698 });
701
702 modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromSecsSinceEpoch(tip_info->header_time), /*presync=*/false);
703 setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), tip_info->verification_progress, SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD);
705
706 // Receive and report messages from client model
707 connect(_clientModel, &ClientModel::message, [this](const QString &title, const QString &message, unsigned int style){
708 this->message(title, message, style);
709 });
710
711 // Show progress dialog
713
714 rpcConsole->setClientModel(_clientModel, tip_info->block_height, tip_info->block_time, tip_info->verification_progress);
715
717
718#ifdef ENABLE_WALLET
719 if(walletFrame)
720 {
722 }
723#endif // ENABLE_WALLET
725
726 OptionsModel* optionsModel = _clientModel->getOptionsModel();
727 if (optionsModel && trayIcon) {
728 // be aware of the tray icon disable state change reported by the OptionsModel object.
729 connect(optionsModel, &OptionsModel::showTrayIconChanged, trayIcon, &QSystemTrayIcon::setVisible);
730
731 // initialize the disable state of the tray icon with the current value in the model.
732 trayIcon->setVisible(optionsModel->getShowTrayIcon());
733 }
734
735 m_mask_values_action->setChecked(_clientModel->getOptionsModel()->getOption(OptionsModel::OptionID::MaskValues).toBool());
736 } else {
737 // Shutdown requested, disable menus
738 if (trayIconMenu)
739 {
740 // Disable context menu on tray icon
741 trayIconMenu->clear();
742 }
743 // Propagate cleared model to child objects
744 rpcConsole->setClientModel(nullptr);
745#ifdef ENABLE_WALLET
746 if (walletFrame)
747 {
748 walletFrame->setClientModel(nullptr);
749 }
750#endif // ENABLE_WALLET
752 // Disable top bar menu actions
753 appMenuBar->clear();
754 }
755}
756
757#ifdef ENABLE_WALLET
758void BitcoinGUI::enableHistoryAction(bool privacy)
759{
761 historyAction->setEnabled(!privacy);
762 if (historyAction->isChecked()) gotoOverviewPage();
763 }
764}
765
766void BitcoinGUI::setWalletController(WalletController* wallet_controller, bool show_loading_minimized)
767{
768 assert(!m_wallet_controller);
770
771 m_wallet_controller = wallet_controller;
772
773 m_create_wallet_action->setEnabled(true);
774 m_open_wallet_action->setEnabled(true);
776 m_restore_wallet_action->setEnabled(true);
777 m_migrate_wallet_action->setEnabled(true);
779
781 connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
782 connect(wallet_controller, &WalletController::destroyed, this, [this] {
783 // wallet_controller gets destroyed manually, but it leaves our member copy dangling
784 m_wallet_controller = nullptr;
785 });
786
787 auto activity = new LoadWalletsActivity(m_wallet_controller, this);
789}
790
791WalletController* BitcoinGUI::getWalletController()
792{
793 return m_wallet_controller;
794}
795
796void BitcoinGUI::addWallet(WalletModel* walletModel)
797{
798 if (!walletFrame || !m_wallet_controller) return;
799
801 if (!walletFrame->addView(wallet_view)) return;
802
803 rpcConsole->addWallet(walletModel);
804 if (m_wallet_selector->count() == 0) {
806 } else if (m_wallet_selector->count() == 1) {
807 m_wallet_selector_label_action->setVisible(true);
808 m_wallet_selector_action->setVisible(true);
809 }
810
812 connect(wallet_view, &WalletView::transactionClicked, this, &BitcoinGUI::gotoHistoryPage);
813 connect(wallet_view, &WalletView::coinsSent, this, &BitcoinGUI::gotoHistoryPage);
814 connect(wallet_view, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
815 this->message(title, message, style);
816 });
817 connect(wallet_view, &WalletView::encryptionStatusChanged, this, &BitcoinGUI::updateWalletStatus);
818 connect(wallet_view, &WalletView::incomingTransaction, this, &BitcoinGUI::incomingTransaction);
820 wallet_view->setPrivacy(isPrivacyModeActivated());
821 const QString display_name = walletModel->getDisplayName();
822 m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
823}
824
825void BitcoinGUI::removeWallet(WalletModel* walletModel)
826{
827 if (!walletFrame) return;
828
831
832 int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
833 m_wallet_selector->removeItem(index);
834 if (m_wallet_selector->count() == 0) {
836 overviewAction->setChecked(true);
837 } else if (m_wallet_selector->count() == 1) {
838 m_wallet_selector_label_action->setVisible(false);
839 m_wallet_selector_action->setVisible(false);
840 }
841 rpcConsole->removeWallet(walletModel);
842 walletFrame->removeWallet(walletModel);
844}
845
846void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
847{
848 if (!walletFrame || !m_wallet_controller) return;
850 for (int index = 0; index < m_wallet_selector->count(); ++index) {
851 if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
852 m_wallet_selector->setCurrentIndex(index);
853 break;
854 }
855 }
856 m_export_watchonly_action->setEnabled(!wallet_model->wallet().privateKeysDisabled());
858}
859
860void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
861{
862 WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
863 if (wallet_model) setCurrentWallet(wallet_model);
864}
865
866#endif // ENABLE_WALLET
867
869{
870 overviewAction->setEnabled(enabled);
871 sendCoinsAction->setEnabled(enabled);
872 receiveCoinsAction->setEnabled(enabled);
873 historyAction->setEnabled(enabled && !isPrivacyModeActivated());
874 encryptWalletAction->setEnabled(enabled);
875 backupWalletAction->setEnabled(enabled);
876 changePassphraseAction->setEnabled(enabled);
877 signMessageAction->setEnabled(enabled);
878 verifyMessageAction->setEnabled(enabled);
879 usedSendingAddressesAction->setEnabled(enabled);
880 usedReceivingAddressesAction->setEnabled(enabled);
881 openAction->setEnabled(enabled);
882 m_close_wallet_action->setEnabled(enabled);
883 m_close_all_wallets_action->setEnabled(enabled);
884 m_export_watchonly_action->setEnabled(enabled);
885}
886
888{
889 assert(QSystemTrayIcon::isSystemTrayAvailable());
890
891#ifndef Q_OS_MACOS
892 if (QSystemTrayIcon::isSystemTrayAvailable()) {
894 QString toolTip = tr("%1 client").arg(CLIENT_NAME) + " " + m_network_style->getTitleAddText();
895 trayIcon->setToolTip(toolTip);
896 }
897#endif
898}
899
901{
902#ifndef Q_OS_MACOS
903 if (!trayIcon) return;
904#endif // Q_OS_MACOS
905
906 // Configuration of the tray icon (or Dock icon) menu.
907 QAction* show_hide_action{nullptr};
908#ifndef Q_OS_MACOS
909 // Note: On macOS, the Dock icon's menu already has Show / Hide action.
911 trayIconMenu->addSeparator();
912#endif // Q_OS_MACOS
913
914 QAction* send_action{nullptr};
915 QAction* receive_action{nullptr};
916 QAction* sign_action{nullptr};
917 QAction* verify_action{nullptr};
918 if (enableWallet) {
919 send_action = trayIconMenu->addAction(sendCoinsAction->text(), sendCoinsAction, &QAction::trigger);
920 receive_action = trayIconMenu->addAction(receiveCoinsAction->text(), receiveCoinsAction, &QAction::trigger);
921 trayIconMenu->addSeparator();
922 sign_action = trayIconMenu->addAction(signMessageAction->text(), signMessageAction, &QAction::trigger);
923 verify_action = trayIconMenu->addAction(verifyMessageAction->text(), verifyMessageAction, &QAction::trigger);
924 trayIconMenu->addSeparator();
925 }
926 QAction* options_action = trayIconMenu->addAction(optionsAction->text(), optionsAction, &QAction::trigger);
927 options_action->setMenuRole(QAction::PreferencesRole);
928 QAction* node_window_action = trayIconMenu->addAction(openRPCConsoleAction->text(), openRPCConsoleAction, &QAction::trigger);
929 QAction* quit_action{nullptr};
930#ifndef Q_OS_MACOS
931 // Note: On macOS, the Dock icon's menu already has Quit action.
932 trayIconMenu->addSeparator();
933 quit_action = trayIconMenu->addAction(quitAction->text(), quitAction, &QAction::trigger);
934
935 trayIcon->setContextMenu(trayIconMenu.get());
936 connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
937 if (reason == QSystemTrayIcon::Trigger) {
938 // Click on system tray icon triggers show/hide of the main window
939 toggleHidden();
940 }
941 });
942#else
943 // Note: On macOS, the Dock icon is used to provide the tray's functionality.
946 if (m_node.shutdownRequested()) return; // nothing to show, node is shutting down.
947 show();
949 });
950 trayIconMenu->setAsDockMenu();
951#endif // Q_OS_MACOS
952
953 connect(
954 // Using QSystemTrayIcon::Context is not reliable.
955 // See https://bugreports.qt.io/browse/QTBUG-91697
956 trayIconMenu.get(), &QMenu::aboutToShow,
958 if (m_node.shutdownRequested()) return; // nothing to do, node is shutting down.
959
960 if (show_hide_action) show_hide_action->setText(
961 (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ?
962 tr("&Hide") :
963 tr("S&how"));
964 if (QApplication::activeModalWidget()) {
965 for (QAction* a : trayIconMenu.get()->actions()) {
966 a->setEnabled(false);
967 }
968 } else {
969 if (show_hide_action) show_hide_action->setEnabled(true);
970 if (enableWallet) {
971 send_action->setEnabled(sendCoinsAction->isEnabled());
972 receive_action->setEnabled(receiveCoinsAction->isEnabled());
973 sign_action->setEnabled(signMessageAction->isEnabled());
974 verify_action->setEnabled(verifyMessageAction->isEnabled());
975 }
976 options_action->setEnabled(optionsAction->isEnabled());
977 node_window_action->setEnabled(openRPCConsoleAction->isEnabled());
978 if (quit_action) quit_action->setEnabled(true);
979 }
980 });
981}
982
987
989{
990 if(!clientModel)
991 return;
992
993 auto dlg = new HelpMessageDialog(this, /*about=*/true);
995}
996
1002
1008
1013
1014#ifdef ENABLE_WALLET
1015void BitcoinGUI::openClicked()
1016{
1018 if(dlg.exec())
1019 {
1020 Q_EMIT receivedURI(dlg.getURI());
1021 }
1022}
1023
1024void BitcoinGUI::gotoOverviewPage()
1025{
1026 overviewAction->setChecked(true);
1028}
1029
1030void BitcoinGUI::gotoHistoryPage()
1031{
1032 historyAction->setChecked(true);
1034}
1035
1036void BitcoinGUI::gotoReceiveCoinsPage()
1037{
1038 receiveCoinsAction->setChecked(true);
1040}
1041
1042void BitcoinGUI::gotoSendCoinsPage(QString addr)
1043{
1044 sendCoinsAction->setChecked(true);
1046}
1047
1048void BitcoinGUI::gotoSignMessageTab(QString addr)
1049{
1051}
1052
1053void BitcoinGUI::gotoVerifyMessageTab(QString addr)
1054{
1056}
1057void BitcoinGUI::gotoLoadPSBT(bool from_clipboard)
1058{
1060}
1061#endif // ENABLE_WALLET
1062
1064{
1065 if (!clientModel) return;
1067 QString icon;
1068 switch(count)
1069 {
1070 case 0: icon = ":/icons/connect_0"; break;
1071 case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
1072 case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
1073 case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
1074 default: icon = ":/icons/connect_4"; break;
1075 }
1076
1078
1079 if (m_node.getNetworkActive()) {
1080 //: A substring of the tooltip.
1081 tooltip = tr("%n active connection(s) to Bitcoin network.", "", count);
1082 } else {
1083 //: A substring of the tooltip.
1084 tooltip = tr("Network activity disabled.");
1085 icon = ":/icons/network_disabled";
1086 }
1087
1088 // Don't word-wrap this (fixed-width) tooltip
1089 tooltip = QLatin1String("<nobr>") + tooltip + QLatin1String("<br>") +
1090 //: A substring of the tooltip. "More actions" are available via the context menu.
1091 tr("Click for more actions.") + QLatin1String("</nobr>");
1092 connectionsControl->setToolTip(tooltip);
1093
1095}
1096
1101
1103{
1105 m_network_context_menu->clear();
1106 m_network_context_menu->addAction(
1107 //: A context menu item. The "Peers tab" is an element of the "Node window".
1108 tr("Show Peers tab"),
1109 [this] {
1112 });
1113 m_network_context_menu->addAction(
1115 //: A context menu item.
1116 tr("Disable network activity") :
1117 //: A context menu item. The network activity was disabled previously.
1118 tr("Enable network activity"),
1120}
1121
1130
1132{
1133 int estHeadersLeft = blockDate.secsTo(QDateTime::currentDateTime()) / Params().GetConsensus().nPowTargetSpacing;
1135 progressBarLabel->setText(tr("Pre-syncing Headers (%1%)…").arg(QString::number(100.0 / (height+estHeadersLeft)*height, 'f', 1)));
1136}
1137
1139{
1141 return;
1142
1143 auto dlg = new OptionsDialog(this, enableWallet);
1145 dlg->setCurrentTab(tab);
1146 dlg->setClientModel(clientModel);
1147 dlg->setModel(clientModel->getOptionsModel());
1149}
1150
1152{
1153// Disabling macOS App Nap on initial sync, disk and reindex operations.
1154#ifdef Q_OS_MACOS
1156 m_app_nap_inhibitor->enableAppNap();
1157 } else {
1158 m_app_nap_inhibitor->disableAppNap();
1159 }
1160#endif
1161
1162 if (modalOverlay)
1163 {
1166 else
1168 }
1169 if (!clientModel)
1170 return;
1171
1172 // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
1173 statusBar()->clearMessage();
1174
1175 // Acquire current block source
1177 switch (blockSource) {
1181 return;
1182 } else if (synctype == SyncType::HEADER_SYNC) {
1184 return;
1185 }
1186 progressBarLabel->setText(tr("Synchronizing with network…"));
1188 break;
1189 case BlockSource::DISK:
1191 progressBarLabel->setText(tr("Indexing blocks on disk…"));
1192 } else {
1193 progressBarLabel->setText(tr("Processing blocks on disk…"));
1194 }
1195 break;
1196 case BlockSource::NONE:
1198 return;
1199 }
1200 progressBarLabel->setText(tr("Connecting to peers…"));
1201 break;
1202 }
1203
1205
1206 QDateTime currentDate = QDateTime::currentDateTime();
1207 qint64 secs = blockDate.secsTo(currentDate);
1208
1209 tooltip = tr("Processed %n block(s) of transaction history.", "", count);
1210
1211 // Set icon state: spinning if catching up, tick otherwise
1212 if (secs < MAX_BLOCK_TIME_GAP) {
1213 tooltip = tr("Up to date") + QString(".<br>") + tooltip;
1215
1216#ifdef ENABLE_WALLET
1217 if(walletFrame)
1218 {
1220 modalOverlay->showHide(true, true);
1221 }
1222#endif // ENABLE_WALLET
1223
1224 progressBarLabel->setVisible(false);
1225 progressBar->setVisible(false);
1226 }
1227 else
1228 {
1230
1231 progressBarLabel->setVisible(true);
1232 progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
1233 progressBar->setMaximum(1000000000);
1234 progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
1235 progressBar->setVisible(true);
1236
1237 tooltip = tr("Catching up…") + QString("<br>") + tooltip;
1238 if(count != prevBlocks)
1239 {
1241 QString(":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')),
1244 }
1245 prevBlocks = count;
1246
1247#ifdef ENABLE_WALLET
1248 if(walletFrame)
1249 {
1252 }
1253#endif // ENABLE_WALLET
1254
1255 tooltip += QString("<br>");
1256 tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
1257 tooltip += QString("<br>");
1258 tooltip += tr("Transactions after this will not yet be visible.");
1259 }
1260
1261 // Don't word-wrap this (fixed-width) tooltip
1262 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1263
1264 labelBlocksIcon->setToolTip(tooltip);
1265 progressBarLabel->setToolTip(tooltip);
1266 progressBar->setToolTip(tooltip);
1267}
1268
1270{
1271#ifdef ENABLE_WALLET
1273 connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet);
1274 connect(activity, &CreateWalletActivity::created, rpcConsole, &RPCConsole::setCurrentWallet);
1275 activity->create();
1276#endif // ENABLE_WALLET
1277}
1278
1279void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message)
1280{
1281 // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines).
1283 // Default to information icon
1284 int nMBoxIcon = QMessageBox::Information;
1286
1288 if (!title.isEmpty()) {
1289 msgType = title;
1290 } else {
1291 switch (style) {
1293 msgType = tr("Error");
1294 message = tr("Error: %1").arg(message);
1295 break;
1297 msgType = tr("Warning");
1298 message = tr("Warning: %1").arg(message);
1299 break;
1301 msgType = tr("Information");
1302 // No need to prepend the prefix here.
1303 break;
1304 default:
1305 break;
1306 }
1307 }
1308
1309 if (!msgType.isEmpty()) {
1310 strTitle += " - " + msgType;
1311 }
1312
1314 nMBoxIcon = QMessageBox::Critical;
1317 nMBoxIcon = QMessageBox::Warning;
1319 }
1320
1322 // Check for buttons, use OK as default, if none was supplied
1323 QMessageBox::StandardButton buttons;
1324 if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
1325 buttons = QMessageBox::Ok;
1326
1328 QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
1329 mBox.setTextFormat(Qt::PlainText);
1330 mBox.setDetailedText(detailed_message);
1331 int r = mBox.exec();
1332 if (ret != nullptr)
1333 *ret = r == QMessageBox::Ok;
1334 } else {
1336 }
1337}
1338
1340{
1341 if (e->type() == QEvent::PaletteChange) {
1342 overviewAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/overview")));
1343 sendCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/send")));
1344 receiveCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/receiving_addresses")));
1345 historyAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/history")));
1346 }
1347
1348 QMainWindow::changeEvent(e);
1349
1350#ifndef Q_OS_MACOS // Ignored on Mac
1351 if(e->type() == QEvent::WindowStateChange)
1352 {
1354 {
1356 if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
1357 {
1358 QTimer::singleShot(0, this, &BitcoinGUI::hide);
1359 e->ignore();
1360 }
1361 else if((wsevt->oldState() & Qt::WindowMinimized) && !isMinimized())
1362 {
1363 QTimer::singleShot(0, this, &BitcoinGUI::show);
1364 e->ignore();
1365 }
1366 }
1367 }
1368#endif
1369}
1370
1372{
1373#ifndef Q_OS_MACOS // Ignored on Mac
1375 {
1377 {
1378 // close rpcConsole in case it was open to make some space for the shutdown window
1379 rpcConsole->close();
1380
1382 }
1383 else
1384 {
1385 QMainWindow::showMinimized();
1386 event->ignore();
1387 }
1388 }
1389#else
1390 QMainWindow::closeEvent(event);
1391#endif
1392}
1393
1395{
1396 // enable the debug window when the main window shows up
1397 openRPCConsoleAction->setEnabled(true);
1398 aboutAction->setEnabled(true);
1399 optionsAction->setEnabled(true);
1400}
1401
1402#ifdef ENABLE_WALLET
1403void BitcoinGUI::incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
1404{
1405 // On new transaction, make an info balloon
1406 QString msg = tr("Date: %1\n").arg(date) +
1407 tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
1408 if (m_node.walletLoader().getWallets().size() > 1 && !walletName.isEmpty()) {
1409 msg += tr("Wallet: %1\n").arg(walletName);
1410 }
1411 msg += tr("Type: %1\n").arg(type);
1412 if (!label.isEmpty())
1413 msg += tr("Label: %1\n").arg(label);
1414 else if (!address.isEmpty())
1415 msg += tr("Address: %1\n").arg(address);
1416 message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
1417 msg, CClientUIInterface::MSG_INFORMATION);
1418}
1419#endif // ENABLE_WALLET
1420
1422{
1423 // Accept only URIs
1424 if(event->mimeData()->hasUrls())
1425 event->acceptProposedAction();
1426}
1427
1429{
1430 if(event->mimeData()->hasUrls())
1431 {
1432 for (const QUrl &uri : event->mimeData()->urls())
1433 {
1434 Q_EMIT receivedURI(uri.toString());
1435 }
1436 }
1437 event->acceptProposedAction();
1438}
1439
1440bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
1441{
1442 // Catch status tip events
1443 if (event->type() == QEvent::StatusTip)
1444 {
1445 // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
1446 if (progressBarLabel->isVisible() || progressBar->isVisible())
1447 return true;
1448 }
1449 return QMainWindow::eventFilter(object, event);
1450}
1451
1452#ifdef ENABLE_WALLET
1453bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
1454{
1455 // URI has to be valid
1456 if (walletFrame && walletFrame->handlePaymentRequest(recipient))
1457 {
1459 gotoSendCoinsPage();
1460 return true;
1461 }
1462 return false;
1463}
1464
1465void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled)
1466{
1467 labelWalletHDStatusIcon->setThemedPixmap(privkeyDisabled ? QStringLiteral(":/icons/eye") : hdEnabled ? QStringLiteral(":/icons/hd_enabled") : QStringLiteral(":/icons/hd_disabled"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
1468 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>"));
1470}
1471
1472void BitcoinGUI::setEncryptionStatus(int status)
1473{
1474 switch(status)
1475 {
1478 encryptWalletAction->setChecked(false);
1479 changePassphraseAction->setEnabled(false);
1480 encryptWalletAction->setEnabled(false);
1481 break;
1484 encryptWalletAction->setChecked(false);
1485 changePassphraseAction->setEnabled(false);
1486 encryptWalletAction->setEnabled(true);
1487 break;
1491 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1492 encryptWalletAction->setChecked(true);
1493 changePassphraseAction->setEnabled(true);
1494 encryptWalletAction->setEnabled(false);
1495 break;
1499 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1500 encryptWalletAction->setChecked(true);
1501 changePassphraseAction->setEnabled(true);
1502 encryptWalletAction->setEnabled(false);
1503 break;
1504 }
1505}
1506
1507void BitcoinGUI::updateWalletStatus()
1508{
1510
1512 if (!walletView) {
1513 return;
1514 }
1515 WalletModel * const walletModel = walletView->getWalletModel();
1517 setHDStatus(walletModel->wallet().privateKeysDisabled(), walletModel->wallet().hdEnabled());
1518}
1519#endif // ENABLE_WALLET
1520
1522{
1523 std::string ip_port;
1525
1526 if (proxy_enabled) {
1528 QString ip_port_q = QString::fromStdString(ip_port);
1530 labelProxyIcon->setToolTip(tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
1531 } else {
1532 labelProxyIcon->show();
1533 }
1534 } else {
1535 labelProxyIcon->hide();
1536 }
1537}
1538
1540{
1542#ifdef ENABLE_WALLET
1543 if (walletFrame) {
1545 if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
1547 }
1548 }
1549#endif
1550 if (!m_network_style->getTitleAddText().isEmpty()) {
1552 }
1554}
1555
1557{
1558 if(!clientModel)
1559 return;
1560
1561 if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) && fToggleHidden) {
1562 hide();
1563 } else {
1565 }
1566}
1567
1572
1574{
1576 {
1577 if(rpcConsole)
1578 rpcConsole->hide();
1580 }
1581}
1582
1584{
1585 if (nProgress == 0) {
1586 progressDialog = new QProgressDialog(title, QString(), 0, 100);
1588 progressDialog->setWindowModality(Qt::ApplicationModal);
1589 progressDialog->setAutoClose(false);
1590 progressDialog->setValue(0);
1591 } else if (nProgress == 100) {
1592 if (progressDialog) {
1593 progressDialog->close();
1594 progressDialog->deleteLater();
1595 progressDialog = nullptr;
1596 }
1597 } else if (progressDialog) {
1598 progressDialog->setValue(nProgress);
1599 }
1600}
1601
1607
1608[[nodiscard]] static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, unsigned int style)
1609{
1611 // The SECURE flag has no effect in the Qt GUI.
1612 // bool secure = (style & CClientUIInterface::SECURE);
1613 style &= ~CClientUIInterface::SECURE;
1614 bool ret = false;
1615
1616 QString detailed_message; // This is original message, in English, for googling and referencing.
1617 if (message.original != message.translated) {
1618 detailed_message = BitcoinGUI::tr("Original message:") + "\n" + QString::fromStdString(message.original);
1619 }
1620 // The title is empty for node messages. The fallback title is usually set
1621 // by `style`.
1622 const QString title{};
1623
1624 // In case of modal message, use blocking connection to wait for user to click a button
1625 bool invoked = QMetaObject::invokeMethod(gui, "message",
1626 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1627 Q_ARG(QString, title),
1628 Q_ARG(QString, QString::fromStdString(message.translated)),
1629 Q_ARG(unsigned int, style),
1630 Q_ARG(bool*, &ret),
1632 assert(invoked);
1633 return ret;
1634}
1635
1637{
1638 // Connect signals to client
1641 });
1642 m_handler_question = m_node.handleQuestion([this](const bilingual_str& message, const std::string& /*non_interactive_message*/, unsigned int style) {
1643 return ThreadSafeMessageBox(this, message, style);
1644 });
1645}
1646
1648{
1649 // Disconnect signals from client
1650 m_handler_message_box->disconnect();
1651 m_handler_question->disconnect();
1652}
1653
1655{
1657 return m_mask_values_action->isChecked();
1658}
1659
1661 : m_platform_style{platformStyle}
1662{
1664 setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1666 int max_width = 0;
1667 const QFontMetrics fm(font());
1668 for (const BitcoinUnit unit : units) {
1670 }
1672 setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1673 setStyleSheet(QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name()));
1674}
1675
1681
1683{
1684 if (e->type() == QEvent::PaletteChange) {
1685 QString style = QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name());
1686 if (style != styleSheet()) {
1688 }
1689 }
1690
1691 QLabel::changeEvent(e);
1692}
1693
1696{
1697 menu = new QMenu(this);
1698 for (const BitcoinUnit u : BitcoinUnits::availableUnits()) {
1699 menu->addAction(BitcoinUnits::longName(u))->setData(QVariant::fromValue(u));
1700 }
1701 connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection);
1702}
1703
1706{
1707 if (_optionsModel)
1708 {
1710
1711 // be aware of a display unit change reported by the OptionsModel object.
1713
1714 // initialize the display units label with the current value in the model.
1715 updateDisplayUnit(_optionsModel->getDisplayUnit());
1716 }
1717}
1718
1724
1731
1740
1741#include <moc_bitcoingui.cpp>
int64_t CAmount
Amount in satoshis (Can be negative)
Definition amount.h:12
int ret
node::NodeContext m_node
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const bilingual_str &message, 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.
const CChainParams & Params()
Return the currently selected parameters.
#define Assume(val)
Assume is the identity function.
Definition check.h:131
Bitcoin GUI main class.
Definition bitcoingui.h:68
void updateHeadersPresyncProgressLabel(int64_t height, const QDateTime &blockDate)
GUIUtil::ClickableProgressBar * progressBar
Definition bitcoingui.h:131
QAction * m_close_all_wallets_action
Definition bitcoingui.h:161
void showEvent(QShowEvent *event) override
QLabel * progressBarLabel
Definition bitcoingui.h:130
QAction * m_open_wallet_action
Definition bitcoingui.h:157
static const std::string DEFAULT_UIPLATFORM
Definition bitcoingui.h:72
QAction * m_export_watchonly_action
Definition bitcoingui.h:169
QAction * openAction
Definition bitcoingui.h:154
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.
GUIUtil::ClickableLabel * connectionsControl
Definition bitcoingui.h:128
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
ModalOverlay * modalOverlay
Definition bitcoingui.h:179
GUIUtil::ThemedLabel * labelWalletEncryptionIcon
Definition bitcoingui.h:125
QAction * changePassphraseAction
Definition bitcoingui.h:151
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:188
QAction * openRPCConsoleAction
Definition bitcoingui.h:153
const NetworkStyle *const m_network_style
Definition bitcoingui.h:192
void changeEvent(QEvent *e) override
GUIUtil::ClickableLabel * labelProxyIcon
Definition bitcoingui.h:127
void optionsClicked()
Show configuration dialog.
QAction * historyAction
Definition bitcoingui.h:137
bool eventFilter(QObject *object, QEvent *event) override
QMenu * m_open_wallet_menu
Definition bitcoingui.h:158
void createTrayIcon()
Create system tray icon and notification.
QAction * m_load_psbt_clipboard_action
Definition bitcoingui.h:145
QAction * quitAction
Definition bitcoingui.h:138
void setNetworkActive(bool network_active)
Set network state shown in the UI.
void setPrivacy(bool privacy)
QProgressDialog * progressDialog
Definition bitcoingui.h:132
BitcoinGUI(interfaces::Node &node, const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent=nullptr)
std::unique_ptr< interfaces::Handler > m_handler_message_box
Definition bitcoingui.h:119
WalletFrame * walletFrame
Definition bitcoingui.h:122
void updateProxyIcon()
Set the proxy-enabled icon as shown in the UI.
QAction * m_restore_wallet_action
Definition bitcoingui.h:159
QAction * receiveCoinsAction
Definition bitcoingui.h:147
const std::unique_ptr< QMenu > trayIconMenu
Definition bitcoingui.h:175
QAction * usedSendingAddressesAction
Definition bitcoingui.h:140
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
void closeEvent(QCloseEvent *event) override
QAction * verifyMessageAction
Definition bitcoingui.h:143
QAction * m_migrate_wallet_action
Definition bitcoingui.h:167
void createTrayIconMenu()
Create system tray menu (or setup the dock menu)
HelpMessageDialog * helpMessageDialog
Definition bitcoingui.h:178
void aboutClicked()
Show about dialog.
void toggleHidden()
Simply calls showNormalIfMinimized(true)
QAction * encryptWalletAction
Definition bitcoingui.h:149
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:166
int spinnerFrame
Definition bitcoingui.h:189
QAction * aboutAction
Definition bitcoingui.h:146
void consoleShown(RPCConsole *console)
Signal raised when RPC console shown.
bool isPrivacyModeActivated() const
QMenu * m_migrate_wallet_menu
Definition bitcoingui.h:168
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:141
void subscribeToCoreSignals()
Connect core signals to GUI client.
void createToolBars()
Create the toolbars.
UnitDisplayStatusBarControl * unitDisplayControl
Definition bitcoingui.h:124
QAction * optionsAction
Definition bitcoingui.h:148
void updateWindowTitle()
void setWalletActionsEnabled(bool enabled)
Enable or disable all wallet-related actions.
const PlatformStyle * platformStyle
Definition bitcoingui.h:191
void dragEnterEvent(QDragEnterEvent *event) override
QAction * m_close_wallet_action
Definition bitcoingui.h:160
QAction * overviewAction
Definition bitcoingui.h:136
GUIUtil::ClickableLabel * labelBlocksIcon
Definition bitcoingui.h:129
interfaces::Node & m_node
Definition bitcoingui.h:115
QAction * m_create_wallet_action
Definition bitcoingui.h:156
QAction * m_load_psbt_action
Definition bitcoingui.h:144
void detectShutdown()
called by a timer to check if shutdown has been requested
bool enableWallet
Definition bitcoingui.h:94
RPCConsole * rpcConsole
Definition bitcoingui.h:177
QMenu * m_network_context_menu
Definition bitcoingui.h:181
QAction * backupWalletAction
Definition bitcoingui.h:150
QAction * showHelpMessageAction
Definition bitcoingui.h:155
QAction * aboutQtAction
Definition bitcoingui.h:152
void showNormalIfMinimized()
Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHid...
Definition bitcoingui.h:315
ClientModel * clientModel
Definition bitcoingui.h:121
void updateHeadersSyncProgressLabel()
void createMenuBar()
Create the menu bar and sub-menus.
QSystemTrayIcon * trayIcon
Definition bitcoingui.h:174
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:139
void quitRequested()
QToolBar * appToolBar
Definition bitcoingui.h:135
void setNumConnections(int count)
Set number of connections shown in the UI.
QAction * signMessageAction
Definition bitcoingui.h:142
GUIUtil::ThemedLabel * labelWalletHDStatusIcon
Definition bitcoingui.h:126
void showModalOverlay()
Notificator * notificator
Definition bitcoingui.h:176
std::unique_ptr< interfaces::Handler > m_handler_question
Definition bitcoingui.h:120
QMenuBar * appMenuBar
Definition bitcoingui.h:134
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.
const Consensus::Params & GetConsensus() const
Definition chainparams.h:89
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:57
void showProgress(const QString &title, int nProgress)
int getHeaderTipHeight() const
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)
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:850
"Help message" dialog box
macOS-specific Dock icon handler.
static MacDockIconHandler * instance()
void migrated(WalletModel *wallet_model)
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: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.
void quitOnReset()
Interface from Qt to configuration data structure for Bitcoin client.
void displayUnitChanged(BitcoinUnit unit)
void showTrayIconChanged(bool)
bool getMinimizeToTray() const
bool getShowTrayIcon() const
bool getMinimizeOnClose() const
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:44
std::vector< TabTypes > tabs() const
Definition rpcconsole.h:78
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)
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:344
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:346
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 walletRemoved(WalletModel *wallet_model)
A container for embedding all wallet-related controls into BitcoinGUI.
Definition walletframe.h:29
void currentWalletSet()
bool addView(WalletView *walletView)
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)
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)
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
QString getDisplayName() const
static bool isWalletEnabled()
void outOfSyncWarningClicked()
Notify that the out of sync warning icon has been pressed.
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:66
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 util::Result< std::string > exportWatchOnlyWallet(const fs::path &destination)=0
Export a watchonly wallet file. See CWallet::ExportWatchOnlyWallet.
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:183
constexpr int STATUSBAR_ICONSIZE
#define SPINNER_FRAMES
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:399
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
Definition guiutil.cpp:380
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:944
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:426
void PolishProgressDialog(QProgressDialog *dialog)
Definition guiutil.cpp:897
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:355
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition guiutil.cpp:315
ClickableProgressBar ProgressBar
Definition guiutil.h:300
void bringToFront(QWidget *w)
Definition guiutil.cpp:408
bool HasPixmap(const QLabel *label)
Returns true if pixmap has been set.
Definition guiutil.cpp:956
QString formatNiceTimeOffset(qint64 secs)
Definition guiutil.cpp:783
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:911
fs::path QStringToPath(const QString &path)
Convert QString to OS specific boost path through UTF-8.
Definition guiutil.cpp:672
bilingual_str ErrorString(const Result< T > &result)
Definition result.h:93
const char * name
Definition rest.cpp:71
static RPCMethod help()
Definition server.cpp:127
int64_t nPowTargetSpacing
Definition params.h:124
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:46
static int count
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition time.cpp:88
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
assert(!tx.IsCoinBase())
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition validation.h:96