Remove unused variable int64_t nEnd
[bitcoinplatinum.git] / src / qt / bitcoingui.cpp
blob429c18cba85c309fe2cfe8d9268e26741f81fa33
1 // Copyright (c) 2011-2016 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.
5 #if defined(HAVE_CONFIG_H)
6 #include "config/bitcoin-config.h"
7 #endif
9 #include "bitcoingui.h"
11 #include "bitcoinunits.h"
12 #include "clientmodel.h"
13 #include "guiconstants.h"
14 #include "guiutil.h"
15 #include "modaloverlay.h"
16 #include "networkstyle.h"
17 #include "notificator.h"
18 #include "openuridialog.h"
19 #include "optionsdialog.h"
20 #include "optionsmodel.h"
21 #include "platformstyle.h"
22 #include "rpcconsole.h"
23 #include "utilitydialog.h"
25 #ifdef ENABLE_WALLET
26 #include "walletframe.h"
27 #include "walletmodel.h"
28 #endif // ENABLE_WALLET
30 #ifdef Q_OS_MAC
31 #include "macdockiconhandler.h"
32 #endif
34 #include "chainparams.h"
35 #include "init.h"
36 #include "ui_interface.h"
37 #include "util.h"
39 #include <iostream>
41 #include <QAction>
42 #include <QApplication>
43 #include <QDateTime>
44 #include <QDesktopWidget>
45 #include <QDragEnterEvent>
46 #include <QListWidget>
47 #include <QMenuBar>
48 #include <QMessageBox>
49 #include <QMimeData>
50 #include <QProgressDialog>
51 #include <QSettings>
52 #include <QShortcut>
53 #include <QStackedWidget>
54 #include <QStatusBar>
55 #include <QStyle>
56 #include <QTimer>
57 #include <QToolBar>
58 #include <QVBoxLayout>
60 #if QT_VERSION < 0x050000
61 #include <QTextDocument>
62 #include <QUrl>
63 #else
64 #include <QUrlQuery>
65 #endif
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
77 /** Display name for default wallet name. Uses tilde to avoid name
78 * collisions in the future with additional wallets */
79 const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
81 BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
82 QMainWindow(parent),
83 enableWallet(false),
84 clientModel(0),
85 walletFrame(0),
86 unitDisplayControl(0),
87 labelWalletEncryptionIcon(0),
88 labelWalletHDStatusIcon(0),
89 connectionsControl(0),
90 labelBlocksIcon(0),
91 progressBarLabel(0),
92 progressBar(0),
93 progressDialog(0),
94 appMenuBar(0),
95 overviewAction(0),
96 historyAction(0),
97 quitAction(0),
98 sendCoinsAction(0),
99 sendCoinsMenuAction(0),
100 usedSendingAddressesAction(0),
101 usedReceivingAddressesAction(0),
102 signMessageAction(0),
103 verifyMessageAction(0),
104 aboutAction(0),
105 receiveCoinsAction(0),
106 receiveCoinsMenuAction(0),
107 optionsAction(0),
108 toggleHideAction(0),
109 encryptWalletAction(0),
110 backupWalletAction(0),
111 changePassphraseAction(0),
112 aboutQtAction(0),
113 openRPCConsoleAction(0),
114 openAction(0),
115 showHelpMessageAction(0),
116 trayIcon(0),
117 trayIconMenu(0),
118 notificator(0),
119 rpcConsole(0),
120 helpMessageDialog(0),
121 modalOverlay(0),
122 prevBlocks(0),
123 spinnerFrame(0),
124 platformStyle(_platformStyle)
126 GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
128 QString windowTitle = tr(PACKAGE_NAME) + " - ";
129 #ifdef ENABLE_WALLET
130 enableWallet = WalletModel::isWalletEnabled();
131 #endif // ENABLE_WALLET
132 if(enableWallet)
134 windowTitle += tr("Wallet");
135 } else {
136 windowTitle += tr("Node");
138 windowTitle += " " + networkStyle->getTitleAddText();
139 #ifndef Q_OS_MAC
140 QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
141 setWindowIcon(networkStyle->getTrayAndWindowIcon());
142 #else
143 MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon());
144 #endif
145 setWindowTitle(windowTitle);
147 #if defined(Q_OS_MAC) && QT_VERSION < 0x050000
148 // This property is not implemented in Qt 5. Setting it has no effect.
149 // A replacement API (QtMacUnifiedToolBar) is available in QtMacExtras.
150 setUnifiedTitleAndToolBarOnMac(true);
151 #endif
153 rpcConsole = new RPCConsole(_platformStyle, 0);
154 helpMessageDialog = new HelpMessageDialog(this, false);
155 #ifdef ENABLE_WALLET
156 if(enableWallet)
158 /** Create wallet frame and make it the central widget */
159 walletFrame = new WalletFrame(_platformStyle, this);
160 setCentralWidget(walletFrame);
161 } else
162 #endif // ENABLE_WALLET
164 /* When compiled without wallet or -disablewallet is provided,
165 * the central widget is the rpc console.
167 setCentralWidget(rpcConsole);
170 // Accept D&D of URIs
171 setAcceptDrops(true);
173 // Create actions for the toolbar, menu bar and tray/dock icon
174 // Needs walletFrame to be initialized
175 createActions();
177 // Create application menu bar
178 createMenuBar();
180 // Create the toolbars
181 createToolBars();
183 // Create system tray icon and notification
184 createTrayIcon(networkStyle);
186 // Create status bar
187 statusBar();
189 // Disable size grip because it looks ugly and nobody needs it
190 statusBar()->setSizeGripEnabled(false);
192 // Status bar notification icons
193 QFrame *frameBlocks = new QFrame();
194 frameBlocks->setContentsMargins(0,0,0,0);
195 frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
196 QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
197 frameBlocksLayout->setContentsMargins(3,0,3,0);
198 frameBlocksLayout->setSpacing(3);
199 unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
200 labelWalletEncryptionIcon = new QLabel();
201 labelWalletHDStatusIcon = new QLabel();
202 connectionsControl = new GUIUtil::ClickableLabel();
203 labelBlocksIcon = new GUIUtil::ClickableLabel();
204 if(enableWallet)
206 frameBlocksLayout->addStretch();
207 frameBlocksLayout->addWidget(unitDisplayControl);
208 frameBlocksLayout->addStretch();
209 frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
210 frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
212 frameBlocksLayout->addStretch();
213 frameBlocksLayout->addWidget(connectionsControl);
214 frameBlocksLayout->addStretch();
215 frameBlocksLayout->addWidget(labelBlocksIcon);
216 frameBlocksLayout->addStretch();
218 // Progress bar and label for blocks download
219 progressBarLabel = new QLabel();
220 progressBarLabel->setVisible(false);
221 progressBar = new GUIUtil::ProgressBar();
222 progressBar->setAlignment(Qt::AlignCenter);
223 progressBar->setVisible(false);
225 // Override style sheet for progress bar for styles that have a segmented progress bar,
226 // as they make the text unreadable (workaround for issue #1071)
227 // See https://qt-project.org/doc/qt-4.8/gallery.html
228 QString curStyle = QApplication::style()->metaObject()->className();
229 if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
231 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; }");
234 statusBar()->addWidget(progressBarLabel);
235 statusBar()->addWidget(progressBar);
236 statusBar()->addPermanentWidget(frameBlocks);
238 // Install event filter to be able to catch status tip events (QEvent::StatusTip)
239 this->installEventFilter(this);
241 // Initially wallet actions should be disabled
242 setWalletActionsEnabled(false);
244 // Subscribe to notifications from core
245 subscribeToCoreSignals();
247 connect(connectionsControl, SIGNAL(clicked(QPoint)), this, SLOT(toggleNetworkActive()));
249 modalOverlay = new ModalOverlay(this->centralWidget());
250 #ifdef ENABLE_WALLET
251 if(enableWallet) {
252 connect(walletFrame, SIGNAL(requestedSyncWarningInfo()), this, SLOT(showModalOverlay()));
253 connect(labelBlocksIcon, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay()));
254 connect(progressBar, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay()));
256 #endif
259 BitcoinGUI::~BitcoinGUI()
261 // Unsubscribe from notifications from core
262 unsubscribeFromCoreSignals();
264 GUIUtil::saveWindowGeometry("nWindow", this);
265 if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
266 trayIcon->hide();
267 #ifdef Q_OS_MAC
268 delete appMenuBar;
269 MacDockIconHandler::cleanup();
270 #endif
272 delete rpcConsole;
275 void BitcoinGUI::createActions()
277 QActionGroup *tabGroup = new QActionGroup(this);
279 overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
280 overviewAction->setStatusTip(tr("Show general overview of wallet"));
281 overviewAction->setToolTip(overviewAction->statusTip());
282 overviewAction->setCheckable(true);
283 overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
284 tabGroup->addAction(overviewAction);
286 sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
287 sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
288 sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
289 sendCoinsAction->setCheckable(true);
290 sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
291 tabGroup->addAction(sendCoinsAction);
293 sendCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
294 sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
295 sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
297 receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
298 receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
299 receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
300 receiveCoinsAction->setCheckable(true);
301 receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
302 tabGroup->addAction(receiveCoinsAction);
304 receiveCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
305 receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
306 receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
308 historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
309 historyAction->setStatusTip(tr("Browse transaction history"));
310 historyAction->setToolTip(historyAction->statusTip());
311 historyAction->setCheckable(true);
312 historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
313 tabGroup->addAction(historyAction);
315 #ifdef ENABLE_WALLET
316 // These showNormalIfMinimized are needed because Send Coins and Receive Coins
317 // can be triggered from the tray menu, and need to show the GUI to be useful.
318 connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
319 connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
320 connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
321 connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
322 connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
323 connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
324 connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
325 connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
326 connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
327 connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
328 connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
329 connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
330 #endif // ENABLE_WALLET
332 quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this);
333 quitAction->setStatusTip(tr("Quit application"));
334 quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
335 quitAction->setMenuRole(QAction::QuitRole);
336 aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About %1").arg(tr(PACKAGE_NAME)), this);
337 aboutAction->setStatusTip(tr("Show information about %1").arg(tr(PACKAGE_NAME)));
338 aboutAction->setMenuRole(QAction::AboutRole);
339 aboutAction->setEnabled(false);
340 aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
341 aboutQtAction->setStatusTip(tr("Show information about Qt"));
342 aboutQtAction->setMenuRole(QAction::AboutQtRole);
343 optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this);
344 optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(tr(PACKAGE_NAME)));
345 optionsAction->setMenuRole(QAction::PreferencesRole);
346 optionsAction->setEnabled(false);
347 toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
348 toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
350 encryptWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
351 encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
352 encryptWalletAction->setCheckable(true);
353 backupWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
354 backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
355 changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
356 changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
357 signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
358 signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
359 verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
360 verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
362 openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
363 openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
364 // initially disable the debug window menu item
365 openRPCConsoleAction->setEnabled(false);
367 usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
368 usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
369 usedReceivingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
370 usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
372 openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
373 openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
375 showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
376 showHelpMessageAction->setMenuRole(QAction::NoRole);
377 showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(tr(PACKAGE_NAME)));
379 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
380 connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
381 connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
382 connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
383 connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
384 connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
385 connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow()));
386 // prevents an open debug window from becoming stuck/unusable on client shutdown
387 connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
389 #ifdef ENABLE_WALLET
390 if(walletFrame)
392 connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
393 connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
394 connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
395 connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
396 connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
397 connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
398 connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
399 connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
401 #endif // ENABLE_WALLET
403 new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this, SLOT(showDebugWindowActivateConsole()));
404 new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this, SLOT(showDebugWindow()));
407 void BitcoinGUI::createMenuBar()
409 #ifdef Q_OS_MAC
410 // Create a decoupled menu bar on Mac which stays even if the window is closed
411 appMenuBar = new QMenuBar();
412 #else
413 // Get the main window's menu bar on other platforms
414 appMenuBar = menuBar();
415 #endif
417 // Configure the menus
418 QMenu *file = appMenuBar->addMenu(tr("&File"));
419 if(walletFrame)
421 file->addAction(openAction);
422 file->addAction(backupWalletAction);
423 file->addAction(signMessageAction);
424 file->addAction(verifyMessageAction);
425 file->addSeparator();
426 file->addAction(usedSendingAddressesAction);
427 file->addAction(usedReceivingAddressesAction);
428 file->addSeparator();
430 file->addAction(quitAction);
432 QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
433 if(walletFrame)
435 settings->addAction(encryptWalletAction);
436 settings->addAction(changePassphraseAction);
437 settings->addSeparator();
439 settings->addAction(optionsAction);
441 QMenu *help = appMenuBar->addMenu(tr("&Help"));
442 if(walletFrame)
444 help->addAction(openRPCConsoleAction);
446 help->addAction(showHelpMessageAction);
447 help->addSeparator();
448 help->addAction(aboutAction);
449 help->addAction(aboutQtAction);
452 void BitcoinGUI::createToolBars()
454 if(walletFrame)
456 QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
457 toolbar->setMovable(false);
458 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
459 toolbar->addAction(overviewAction);
460 toolbar->addAction(sendCoinsAction);
461 toolbar->addAction(receiveCoinsAction);
462 toolbar->addAction(historyAction);
463 overviewAction->setChecked(true);
467 void BitcoinGUI::setClientModel(ClientModel *_clientModel)
469 this->clientModel = _clientModel;
470 if(_clientModel)
472 // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
473 // while the client has not yet fully loaded
474 createTrayIconMenu();
476 // Keep up to date with client
477 updateNetworkState();
478 connect(_clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
479 connect(_clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool)));
481 modalOverlay->setKnownBestHeight(_clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(_clientModel->getHeaderTipTime()));
482 setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false);
483 connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
485 // Receive and report messages from client model
486 connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
488 // Show progress dialog
489 connect(_clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
491 rpcConsole->setClientModel(_clientModel);
492 #ifdef ENABLE_WALLET
493 if(walletFrame)
495 walletFrame->setClientModel(_clientModel);
497 #endif // ENABLE_WALLET
498 unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
500 OptionsModel* optionsModel = _clientModel->getOptionsModel();
501 if(optionsModel)
503 // be aware of the tray icon disable state change reported by the OptionsModel object.
504 connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool)));
506 // initialize the disable state of the tray icon with the current value in the model.
507 setTrayIconVisible(optionsModel->getHideTrayIcon());
509 } else {
510 // Disable possibility to show main window via action
511 toggleHideAction->setEnabled(false);
512 if(trayIconMenu)
514 // Disable context menu on tray icon
515 trayIconMenu->clear();
517 // Propagate cleared model to child objects
518 rpcConsole->setClientModel(nullptr);
519 #ifdef ENABLE_WALLET
520 if (walletFrame)
522 walletFrame->setClientModel(nullptr);
524 #endif // ENABLE_WALLET
525 unitDisplayControl->setOptionsModel(nullptr);
529 #ifdef ENABLE_WALLET
530 bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
532 if(!walletFrame)
533 return false;
534 setWalletActionsEnabled(true);
535 return walletFrame->addWallet(name, walletModel);
538 bool BitcoinGUI::setCurrentWallet(const QString& name)
540 if(!walletFrame)
541 return false;
542 return walletFrame->setCurrentWallet(name);
545 void BitcoinGUI::removeAllWallets()
547 if(!walletFrame)
548 return;
549 setWalletActionsEnabled(false);
550 walletFrame->removeAllWallets();
552 #endif // ENABLE_WALLET
554 void BitcoinGUI::setWalletActionsEnabled(bool enabled)
556 overviewAction->setEnabled(enabled);
557 sendCoinsAction->setEnabled(enabled);
558 sendCoinsMenuAction->setEnabled(enabled);
559 receiveCoinsAction->setEnabled(enabled);
560 receiveCoinsMenuAction->setEnabled(enabled);
561 historyAction->setEnabled(enabled);
562 encryptWalletAction->setEnabled(enabled);
563 backupWalletAction->setEnabled(enabled);
564 changePassphraseAction->setEnabled(enabled);
565 signMessageAction->setEnabled(enabled);
566 verifyMessageAction->setEnabled(enabled);
567 usedSendingAddressesAction->setEnabled(enabled);
568 usedReceivingAddressesAction->setEnabled(enabled);
569 openAction->setEnabled(enabled);
572 void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
574 #ifndef Q_OS_MAC
575 trayIcon = new QSystemTrayIcon(this);
576 QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText();
577 trayIcon->setToolTip(toolTip);
578 trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
579 trayIcon->hide();
580 #endif
582 notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
585 void BitcoinGUI::createTrayIconMenu()
587 #ifndef Q_OS_MAC
588 // return if trayIcon is unset (only on non-Mac OSes)
589 if (!trayIcon)
590 return;
592 trayIconMenu = new QMenu(this);
593 trayIcon->setContextMenu(trayIconMenu);
595 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
596 this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
597 #else
598 // Note: On Mac, the dock icon is used to provide the tray's functionality.
599 MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
600 dockIconHandler->setMainWindow((QMainWindow *)this);
601 trayIconMenu = dockIconHandler->dockMenu();
602 #endif
604 // Configuration of the tray icon (or dock icon) icon menu
605 trayIconMenu->addAction(toggleHideAction);
606 trayIconMenu->addSeparator();
607 trayIconMenu->addAction(sendCoinsMenuAction);
608 trayIconMenu->addAction(receiveCoinsMenuAction);
609 trayIconMenu->addSeparator();
610 trayIconMenu->addAction(signMessageAction);
611 trayIconMenu->addAction(verifyMessageAction);
612 trayIconMenu->addSeparator();
613 trayIconMenu->addAction(optionsAction);
614 trayIconMenu->addAction(openRPCConsoleAction);
615 #ifndef Q_OS_MAC // This is built-in on Mac
616 trayIconMenu->addSeparator();
617 trayIconMenu->addAction(quitAction);
618 #endif
621 #ifndef Q_OS_MAC
622 void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
624 if(reason == QSystemTrayIcon::Trigger)
626 // Click on system tray icon triggers show/hide of the main window
627 toggleHidden();
630 #endif
632 void BitcoinGUI::optionsClicked()
634 if(!clientModel || !clientModel->getOptionsModel())
635 return;
637 OptionsDialog dlg(this, enableWallet);
638 dlg.setModel(clientModel->getOptionsModel());
639 dlg.exec();
642 void BitcoinGUI::aboutClicked()
644 if(!clientModel)
645 return;
647 HelpMessageDialog dlg(this, true);
648 dlg.exec();
651 void BitcoinGUI::showDebugWindow()
653 rpcConsole->showNormal();
654 rpcConsole->show();
655 rpcConsole->raise();
656 rpcConsole->activateWindow();
659 void BitcoinGUI::showDebugWindowActivateConsole()
661 rpcConsole->setTabFocus(RPCConsole::TAB_CONSOLE);
662 showDebugWindow();
665 void BitcoinGUI::showHelpMessageClicked()
667 helpMessageDialog->show();
670 #ifdef ENABLE_WALLET
671 void BitcoinGUI::openClicked()
673 OpenURIDialog dlg(this);
674 if(dlg.exec())
676 Q_EMIT receivedURI(dlg.getURI());
680 void BitcoinGUI::gotoOverviewPage()
682 overviewAction->setChecked(true);
683 if (walletFrame) walletFrame->gotoOverviewPage();
686 void BitcoinGUI::gotoHistoryPage()
688 historyAction->setChecked(true);
689 if (walletFrame) walletFrame->gotoHistoryPage();
692 void BitcoinGUI::gotoReceiveCoinsPage()
694 receiveCoinsAction->setChecked(true);
695 if (walletFrame) walletFrame->gotoReceiveCoinsPage();
698 void BitcoinGUI::gotoSendCoinsPage(QString addr)
700 sendCoinsAction->setChecked(true);
701 if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
704 void BitcoinGUI::gotoSignMessageTab(QString addr)
706 if (walletFrame) walletFrame->gotoSignMessageTab(addr);
709 void BitcoinGUI::gotoVerifyMessageTab(QString addr)
711 if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
713 #endif // ENABLE_WALLET
715 void BitcoinGUI::updateNetworkState()
717 int count = clientModel->getNumConnections();
718 QString icon;
719 switch(count)
721 case 0: icon = ":/icons/connect_0"; break;
722 case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
723 case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
724 case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
725 default: icon = ":/icons/connect_4"; break;
728 QString tooltip;
730 if (clientModel->getNetworkActive()) {
731 tooltip = tr("%n active connection(s) to Bitcoin network", "", count) + QString(".<br>") + tr("Click to disable network activity.");
732 } else {
733 tooltip = tr("Network activity disabled.") + QString("<br>") + tr("Click to enable network activity again.");
734 icon = ":/icons/network_disabled";
737 // Don't word-wrap this (fixed-width) tooltip
738 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
739 connectionsControl->setToolTip(tooltip);
741 connectionsControl->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
744 void BitcoinGUI::setNumConnections(int count)
746 updateNetworkState();
749 void BitcoinGUI::setNetworkActive(bool networkActive)
751 updateNetworkState();
754 void BitcoinGUI::updateHeadersSyncProgressLabel()
756 int64_t headersTipTime = clientModel->getHeaderTipTime();
757 int headersTipHeight = clientModel->getHeaderTipHeight();
758 int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
759 if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
760 progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
763 void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
765 if (modalOverlay)
767 if (header)
768 modalOverlay->setKnownBestHeight(count, blockDate);
769 else
770 modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
772 if (!clientModel)
773 return;
775 // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
776 statusBar()->clearMessage();
778 // Acquire current block source
779 enum BlockSource blockSource = clientModel->getBlockSource();
780 switch (blockSource) {
781 case BLOCK_SOURCE_NETWORK:
782 if (header) {
783 updateHeadersSyncProgressLabel();
784 return;
786 progressBarLabel->setText(tr("Synchronizing with network..."));
787 updateHeadersSyncProgressLabel();
788 break;
789 case BLOCK_SOURCE_DISK:
790 if (header) {
791 progressBarLabel->setText(tr("Indexing blocks on disk..."));
792 } else {
793 progressBarLabel->setText(tr("Processing blocks on disk..."));
795 break;
796 case BLOCK_SOURCE_REINDEX:
797 progressBarLabel->setText(tr("Reindexing blocks on disk..."));
798 break;
799 case BLOCK_SOURCE_NONE:
800 if (header) {
801 return;
803 progressBarLabel->setText(tr("Connecting to peers..."));
804 break;
807 QString tooltip;
809 QDateTime currentDate = QDateTime::currentDateTime();
810 qint64 secs = blockDate.secsTo(currentDate);
812 tooltip = tr("Processed %n block(s) of transaction history.", "", count);
814 // Set icon state: spinning if catching up, tick otherwise
815 if(secs < 90*60)
817 tooltip = tr("Up to date") + QString(".<br>") + tooltip;
818 labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
820 #ifdef ENABLE_WALLET
821 if(walletFrame)
823 walletFrame->showOutOfSyncWarning(false);
824 modalOverlay->showHide(true, true);
826 #endif // ENABLE_WALLET
828 progressBarLabel->setVisible(false);
829 progressBar->setVisible(false);
831 else
833 QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
835 progressBarLabel->setVisible(true);
836 progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
837 progressBar->setMaximum(1000000000);
838 progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
839 progressBar->setVisible(true);
841 tooltip = tr("Catching up...") + QString("<br>") + tooltip;
842 if(count != prevBlocks)
844 labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
845 ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
846 .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
847 spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
849 prevBlocks = count;
851 #ifdef ENABLE_WALLET
852 if(walletFrame)
854 walletFrame->showOutOfSyncWarning(true);
855 modalOverlay->showHide();
857 #endif // ENABLE_WALLET
859 tooltip += QString("<br>");
860 tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
861 tooltip += QString("<br>");
862 tooltip += tr("Transactions after this will not yet be visible.");
865 // Don't word-wrap this (fixed-width) tooltip
866 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
868 labelBlocksIcon->setToolTip(tooltip);
869 progressBarLabel->setToolTip(tooltip);
870 progressBar->setToolTip(tooltip);
873 void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
875 QString strTitle = tr("Bitcoin"); // default title
876 // Default to information icon
877 int nMBoxIcon = QMessageBox::Information;
878 int nNotifyIcon = Notificator::Information;
880 QString msgType;
882 // Prefer supplied title over style based title
883 if (!title.isEmpty()) {
884 msgType = title;
886 else {
887 switch (style) {
888 case CClientUIInterface::MSG_ERROR:
889 msgType = tr("Error");
890 break;
891 case CClientUIInterface::MSG_WARNING:
892 msgType = tr("Warning");
893 break;
894 case CClientUIInterface::MSG_INFORMATION:
895 msgType = tr("Information");
896 break;
897 default:
898 break;
901 // Append title to "Bitcoin - "
902 if (!msgType.isEmpty())
903 strTitle += " - " + msgType;
905 // Check for error/warning icon
906 if (style & CClientUIInterface::ICON_ERROR) {
907 nMBoxIcon = QMessageBox::Critical;
908 nNotifyIcon = Notificator::Critical;
910 else if (style & CClientUIInterface::ICON_WARNING) {
911 nMBoxIcon = QMessageBox::Warning;
912 nNotifyIcon = Notificator::Warning;
915 // Display message
916 if (style & CClientUIInterface::MODAL) {
917 // Check for buttons, use OK as default, if none was supplied
918 QMessageBox::StandardButton buttons;
919 if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
920 buttons = QMessageBox::Ok;
922 showNormalIfMinimized();
923 QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this);
924 int r = mBox.exec();
925 if (ret != NULL)
926 *ret = r == QMessageBox::Ok;
928 else
929 notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
932 void BitcoinGUI::changeEvent(QEvent *e)
934 QMainWindow::changeEvent(e);
935 #ifndef Q_OS_MAC // Ignored on Mac
936 if(e->type() == QEvent::WindowStateChange)
938 if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray())
940 QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
941 if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
943 QTimer::singleShot(0, this, SLOT(hide()));
944 e->ignore();
948 #endif
951 void BitcoinGUI::closeEvent(QCloseEvent *event)
953 #ifndef Q_OS_MAC // Ignored on Mac
954 if(clientModel && clientModel->getOptionsModel())
956 if(!clientModel->getOptionsModel()->getMinimizeOnClose())
958 // close rpcConsole in case it was open to make some space for the shutdown window
959 rpcConsole->close();
961 QApplication::quit();
963 else
965 QMainWindow::showMinimized();
966 event->ignore();
969 #else
970 QMainWindow::closeEvent(event);
971 #endif
974 void BitcoinGUI::showEvent(QShowEvent *event)
976 // enable the debug window when the main window shows up
977 openRPCConsoleAction->setEnabled(true);
978 aboutAction->setEnabled(true);
979 optionsAction->setEnabled(true);
982 #ifdef ENABLE_WALLET
983 void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
985 // On new transaction, make an info balloon
986 QString msg = tr("Date: %1\n").arg(date) +
987 tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
988 tr("Type: %1\n").arg(type);
989 if (!label.isEmpty())
990 msg += tr("Label: %1\n").arg(label);
991 else if (!address.isEmpty())
992 msg += tr("Address: %1\n").arg(address);
993 message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
994 msg, CClientUIInterface::MSG_INFORMATION);
996 #endif // ENABLE_WALLET
998 void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
1000 // Accept only URIs
1001 if(event->mimeData()->hasUrls())
1002 event->acceptProposedAction();
1005 void BitcoinGUI::dropEvent(QDropEvent *event)
1007 if(event->mimeData()->hasUrls())
1009 for (const QUrl &uri : event->mimeData()->urls())
1011 Q_EMIT receivedURI(uri.toString());
1014 event->acceptProposedAction();
1017 bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
1019 // Catch status tip events
1020 if (event->type() == QEvent::StatusTip)
1022 // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
1023 if (progressBarLabel->isVisible() || progressBar->isVisible())
1024 return true;
1026 return QMainWindow::eventFilter(object, event);
1029 #ifdef ENABLE_WALLET
1030 bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
1032 // URI has to be valid
1033 if (walletFrame && walletFrame->handlePaymentRequest(recipient))
1035 showNormalIfMinimized();
1036 gotoSendCoinsPage();
1037 return true;
1039 return false;
1042 void BitcoinGUI::setHDStatus(int hdEnabled)
1044 labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1045 labelWalletHDStatusIcon->setToolTip(hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
1047 // eventually disable the QLabel to set its opacity to 50%
1048 labelWalletHDStatusIcon->setEnabled(hdEnabled);
1051 void BitcoinGUI::setEncryptionStatus(int status)
1053 switch(status)
1055 case WalletModel::Unencrypted:
1056 labelWalletEncryptionIcon->hide();
1057 encryptWalletAction->setChecked(false);
1058 changePassphraseAction->setEnabled(false);
1059 encryptWalletAction->setEnabled(true);
1060 break;
1061 case WalletModel::Unlocked:
1062 labelWalletEncryptionIcon->show();
1063 labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1064 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1065 encryptWalletAction->setChecked(true);
1066 changePassphraseAction->setEnabled(true);
1067 encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1068 break;
1069 case WalletModel::Locked:
1070 labelWalletEncryptionIcon->show();
1071 labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1072 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1073 encryptWalletAction->setChecked(true);
1074 changePassphraseAction->setEnabled(true);
1075 encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1076 break;
1079 #endif // ENABLE_WALLET
1081 void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
1083 if(!clientModel)
1084 return;
1086 // activateWindow() (sometimes) helps with keyboard focus on Windows
1087 if (isHidden())
1089 show();
1090 activateWindow();
1092 else if (isMinimized())
1094 showNormal();
1095 activateWindow();
1097 else if (GUIUtil::isObscured(this))
1099 raise();
1100 activateWindow();
1102 else if(fToggleHidden)
1103 hide();
1106 void BitcoinGUI::toggleHidden()
1108 showNormalIfMinimized(true);
1111 void BitcoinGUI::detectShutdown()
1113 if (ShutdownRequested())
1115 if(rpcConsole)
1116 rpcConsole->hide();
1117 qApp->quit();
1121 void BitcoinGUI::showProgress(const QString &title, int nProgress)
1123 if (nProgress == 0)
1125 progressDialog = new QProgressDialog(title, "", 0, 100);
1126 progressDialog->setWindowModality(Qt::ApplicationModal);
1127 progressDialog->setMinimumDuration(0);
1128 progressDialog->setCancelButton(0);
1129 progressDialog->setAutoClose(false);
1130 progressDialog->setValue(0);
1132 else if (nProgress == 100)
1134 if (progressDialog)
1136 progressDialog->close();
1137 progressDialog->deleteLater();
1140 else if (progressDialog)
1141 progressDialog->setValue(nProgress);
1144 void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
1146 if (trayIcon)
1148 trayIcon->setVisible(!fHideTrayIcon);
1152 void BitcoinGUI::showModalOverlay()
1154 if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
1155 modalOverlay->toggleVisibility();
1158 static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
1160 bool modal = (style & CClientUIInterface::MODAL);
1161 // The SECURE flag has no effect in the Qt GUI.
1162 // bool secure = (style & CClientUIInterface::SECURE);
1163 style &= ~CClientUIInterface::SECURE;
1164 bool ret = false;
1165 // In case of modal message, use blocking connection to wait for user to click a button
1166 QMetaObject::invokeMethod(gui, "message",
1167 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1168 Q_ARG(QString, QString::fromStdString(caption)),
1169 Q_ARG(QString, QString::fromStdString(message)),
1170 Q_ARG(unsigned int, style),
1171 Q_ARG(bool*, &ret));
1172 return ret;
1175 void BitcoinGUI::subscribeToCoreSignals()
1177 // Connect signals to client
1178 uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1179 uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1182 void BitcoinGUI::unsubscribeFromCoreSignals()
1184 // Disconnect signals from client
1185 uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1186 uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1189 void BitcoinGUI::toggleNetworkActive()
1191 if (clientModel) {
1192 clientModel->setNetworkActive(!clientModel->getNetworkActive());
1196 UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
1197 optionsModel(0),
1198 menu(0)
1200 createContextMenu();
1201 setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1202 QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
1203 int max_width = 0;
1204 const QFontMetrics fm(font());
1205 for (const BitcoinUnits::Unit unit : units)
1207 max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
1209 setMinimumSize(max_width, 0);
1210 setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1211 setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
1214 /** So that it responds to button clicks */
1215 void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
1217 onDisplayUnitsClicked(event->pos());
1220 /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
1221 void UnitDisplayStatusBarControl::createContextMenu()
1223 menu = new QMenu(this);
1224 for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
1226 QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this);
1227 menuAction->setData(QVariant(u));
1228 menu->addAction(menuAction);
1230 connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*)));
1233 /** Lets the control know about the Options Model (and its signals) */
1234 void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
1236 if (_optionsModel)
1238 this->optionsModel = _optionsModel;
1240 // be aware of a display unit change reported by the OptionsModel object.
1241 connect(_optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
1243 // initialize the display units label with the current value in the model.
1244 updateDisplayUnit(_optionsModel->getDisplayUnit());
1248 /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
1249 void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
1251 setText(BitcoinUnits::name(newUnits));
1254 /** Shows context menu with Display Unit options by the mouse coordinates */
1255 void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
1257 QPoint globalPos = mapToGlobal(point);
1258 menu->exec(globalPos);
1261 /** Tells underlying optionsModel to update its current display unit. */
1262 void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
1264 if (action)
1266 optionsModel->setDisplayUnit(action->data());