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