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