Fix parameter naming inconsistencies between .h and .cpp files
[bitcoinplatinum.git] / src / qt / bitcoingui.cpp
blobbe79a67990e5bb2ce248d0581f112c8a125b314c
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 setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false);
482 connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
484 // Receive and report messages from client model
485 connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
487 // Show progress dialog
488 connect(_clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
490 rpcConsole->setClientModel(_clientModel);
491 #ifdef ENABLE_WALLET
492 if(walletFrame)
494 walletFrame->setClientModel(_clientModel);
496 #endif // ENABLE_WALLET
497 unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
499 OptionsModel* optionsModel = _clientModel->getOptionsModel();
500 if(optionsModel)
502 // be aware of the tray icon disable state change reported by the OptionsModel object.
503 connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool)));
505 // initialize the disable state of the tray icon with the current value in the model.
506 setTrayIconVisible(optionsModel->getHideTrayIcon());
509 modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime()));
510 } else {
511 // Disable possibility to show main window via action
512 toggleHideAction->setEnabled(false);
513 if(trayIconMenu)
515 // Disable context menu on tray icon
516 trayIconMenu->clear();
518 // Propagate cleared model to child objects
519 rpcConsole->setClientModel(nullptr);
520 #ifdef ENABLE_WALLET
521 if (walletFrame)
523 walletFrame->setClientModel(nullptr);
525 #endif // ENABLE_WALLET
526 unitDisplayControl->setOptionsModel(nullptr);
530 #ifdef ENABLE_WALLET
531 bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
533 if(!walletFrame)
534 return false;
535 setWalletActionsEnabled(true);
536 return walletFrame->addWallet(name, walletModel);
539 bool BitcoinGUI::setCurrentWallet(const QString& name)
541 if(!walletFrame)
542 return false;
543 return walletFrame->setCurrentWallet(name);
546 void BitcoinGUI::removeAllWallets()
548 if(!walletFrame)
549 return;
550 setWalletActionsEnabled(false);
551 walletFrame->removeAllWallets();
553 #endif // ENABLE_WALLET
555 void BitcoinGUI::setWalletActionsEnabled(bool enabled)
557 overviewAction->setEnabled(enabled);
558 sendCoinsAction->setEnabled(enabled);
559 sendCoinsMenuAction->setEnabled(enabled);
560 receiveCoinsAction->setEnabled(enabled);
561 receiveCoinsMenuAction->setEnabled(enabled);
562 historyAction->setEnabled(enabled);
563 encryptWalletAction->setEnabled(enabled);
564 backupWalletAction->setEnabled(enabled);
565 changePassphraseAction->setEnabled(enabled);
566 signMessageAction->setEnabled(enabled);
567 verifyMessageAction->setEnabled(enabled);
568 usedSendingAddressesAction->setEnabled(enabled);
569 usedReceivingAddressesAction->setEnabled(enabled);
570 openAction->setEnabled(enabled);
573 void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
575 #ifndef Q_OS_MAC
576 trayIcon = new QSystemTrayIcon(this);
577 QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText();
578 trayIcon->setToolTip(toolTip);
579 trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
580 trayIcon->hide();
581 #endif
583 notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
586 void BitcoinGUI::createTrayIconMenu()
588 #ifndef Q_OS_MAC
589 // return if trayIcon is unset (only on non-Mac OSes)
590 if (!trayIcon)
591 return;
593 trayIconMenu = new QMenu(this);
594 trayIcon->setContextMenu(trayIconMenu);
596 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
597 this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
598 #else
599 // Note: On Mac, the dock icon is used to provide the tray's functionality.
600 MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
601 dockIconHandler->setMainWindow((QMainWindow *)this);
602 trayIconMenu = dockIconHandler->dockMenu();
603 #endif
605 // Configuration of the tray icon (or dock icon) icon menu
606 trayIconMenu->addAction(toggleHideAction);
607 trayIconMenu->addSeparator();
608 trayIconMenu->addAction(sendCoinsMenuAction);
609 trayIconMenu->addAction(receiveCoinsMenuAction);
610 trayIconMenu->addSeparator();
611 trayIconMenu->addAction(signMessageAction);
612 trayIconMenu->addAction(verifyMessageAction);
613 trayIconMenu->addSeparator();
614 trayIconMenu->addAction(optionsAction);
615 trayIconMenu->addAction(openRPCConsoleAction);
616 #ifndef Q_OS_MAC // This is built-in on Mac
617 trayIconMenu->addSeparator();
618 trayIconMenu->addAction(quitAction);
619 #endif
622 #ifndef Q_OS_MAC
623 void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
625 if(reason == QSystemTrayIcon::Trigger)
627 // Click on system tray icon triggers show/hide of the main window
628 toggleHidden();
631 #endif
633 void BitcoinGUI::optionsClicked()
635 if(!clientModel || !clientModel->getOptionsModel())
636 return;
638 OptionsDialog dlg(this, enableWallet);
639 dlg.setModel(clientModel->getOptionsModel());
640 dlg.exec();
643 void BitcoinGUI::aboutClicked()
645 if(!clientModel)
646 return;
648 HelpMessageDialog dlg(this, true);
649 dlg.exec();
652 void BitcoinGUI::showDebugWindow()
654 rpcConsole->showNormal();
655 rpcConsole->show();
656 rpcConsole->raise();
657 rpcConsole->activateWindow();
660 void BitcoinGUI::showDebugWindowActivateConsole()
662 rpcConsole->setTabFocus(RPCConsole::TAB_CONSOLE);
663 showDebugWindow();
666 void BitcoinGUI::showHelpMessageClicked()
668 helpMessageDialog->show();
671 #ifdef ENABLE_WALLET
672 void BitcoinGUI::openClicked()
674 OpenURIDialog dlg(this);
675 if(dlg.exec())
677 Q_EMIT receivedURI(dlg.getURI());
681 void BitcoinGUI::gotoOverviewPage()
683 overviewAction->setChecked(true);
684 if (walletFrame) walletFrame->gotoOverviewPage();
687 void BitcoinGUI::gotoHistoryPage()
689 historyAction->setChecked(true);
690 if (walletFrame) walletFrame->gotoHistoryPage();
693 void BitcoinGUI::gotoReceiveCoinsPage()
695 receiveCoinsAction->setChecked(true);
696 if (walletFrame) walletFrame->gotoReceiveCoinsPage();
699 void BitcoinGUI::gotoSendCoinsPage(QString addr)
701 sendCoinsAction->setChecked(true);
702 if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
705 void BitcoinGUI::gotoSignMessageTab(QString addr)
707 if (walletFrame) walletFrame->gotoSignMessageTab(addr);
710 void BitcoinGUI::gotoVerifyMessageTab(QString addr)
712 if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
714 #endif // ENABLE_WALLET
716 void BitcoinGUI::updateNetworkState()
718 int count = clientModel->getNumConnections();
719 QString icon;
720 switch(count)
722 case 0: icon = ":/icons/connect_0"; break;
723 case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
724 case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
725 case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
726 default: icon = ":/icons/connect_4"; break;
729 QString tooltip;
731 if (clientModel->getNetworkActive()) {
732 tooltip = tr("%n active connection(s) to Bitcoin network", "", count) + QString(".<br>") + tr("Click to disable network activity.");
733 } else {
734 tooltip = tr("Network activity disabled.") + QString("<br>") + tr("Click to enable network activity again.");
735 icon = ":/icons/network_disabled";
738 // Don't word-wrap this (fixed-width) tooltip
739 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
740 connectionsControl->setToolTip(tooltip);
742 connectionsControl->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
745 void BitcoinGUI::setNumConnections(int count)
747 updateNetworkState();
750 void BitcoinGUI::setNetworkActive(bool networkActive)
752 updateNetworkState();
755 void BitcoinGUI::updateHeadersSyncProgressLabel()
757 int64_t headersTipTime = clientModel->getHeaderTipTime();
758 int headersTipHeight = clientModel->getHeaderTipHeight();
759 int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
760 if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
761 progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
764 void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
766 if (modalOverlay)
768 if (header)
769 modalOverlay->setKnownBestHeight(count, blockDate);
770 else
771 modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
773 if (!clientModel)
774 return;
776 // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
777 statusBar()->clearMessage();
779 // Acquire current block source
780 enum BlockSource blockSource = clientModel->getBlockSource();
781 switch (blockSource) {
782 case BLOCK_SOURCE_NETWORK:
783 if (header) {
784 updateHeadersSyncProgressLabel();
785 return;
787 progressBarLabel->setText(tr("Synchronizing with network..."));
788 updateHeadersSyncProgressLabel();
789 break;
790 case BLOCK_SOURCE_DISK:
791 if (header) {
792 progressBarLabel->setText(tr("Indexing blocks on disk..."));
793 } else {
794 progressBarLabel->setText(tr("Processing blocks on disk..."));
796 break;
797 case BLOCK_SOURCE_REINDEX:
798 progressBarLabel->setText(tr("Reindexing blocks on disk..."));
799 break;
800 case BLOCK_SOURCE_NONE:
801 if (header) {
802 return;
804 progressBarLabel->setText(tr("Connecting to peers..."));
805 break;
808 QString tooltip;
810 QDateTime currentDate = QDateTime::currentDateTime();
811 qint64 secs = blockDate.secsTo(currentDate);
813 tooltip = tr("Processed %n block(s) of transaction history.", "", count);
815 // Set icon state: spinning if catching up, tick otherwise
816 if(secs < 90*60)
818 tooltip = tr("Up to date") + QString(".<br>") + tooltip;
819 labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
821 #ifdef ENABLE_WALLET
822 if(walletFrame)
824 walletFrame->showOutOfSyncWarning(false);
825 modalOverlay->showHide(true, true);
827 #endif // ENABLE_WALLET
829 progressBarLabel->setVisible(false);
830 progressBar->setVisible(false);
832 else
834 QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
836 progressBarLabel->setVisible(true);
837 progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
838 progressBar->setMaximum(1000000000);
839 progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
840 progressBar->setVisible(true);
842 tooltip = tr("Catching up...") + QString("<br>") + tooltip;
843 if(count != prevBlocks)
845 labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
846 ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
847 .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
848 spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
850 prevBlocks = count;
852 #ifdef ENABLE_WALLET
853 if(walletFrame)
855 walletFrame->showOutOfSyncWarning(true);
856 modalOverlay->showHide();
858 #endif // ENABLE_WALLET
860 tooltip += QString("<br>");
861 tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
862 tooltip += QString("<br>");
863 tooltip += tr("Transactions after this will not yet be visible.");
866 // Don't word-wrap this (fixed-width) tooltip
867 tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
869 labelBlocksIcon->setToolTip(tooltip);
870 progressBarLabel->setToolTip(tooltip);
871 progressBar->setToolTip(tooltip);
874 void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
876 QString strTitle = tr("Bitcoin"); // default title
877 // Default to information icon
878 int nMBoxIcon = QMessageBox::Information;
879 int nNotifyIcon = Notificator::Information;
881 QString msgType;
883 // Prefer supplied title over style based title
884 if (!title.isEmpty()) {
885 msgType = title;
887 else {
888 switch (style) {
889 case CClientUIInterface::MSG_ERROR:
890 msgType = tr("Error");
891 break;
892 case CClientUIInterface::MSG_WARNING:
893 msgType = tr("Warning");
894 break;
895 case CClientUIInterface::MSG_INFORMATION:
896 msgType = tr("Information");
897 break;
898 default:
899 break;
902 // Append title to "Bitcoin - "
903 if (!msgType.isEmpty())
904 strTitle += " - " + msgType;
906 // Check for error/warning icon
907 if (style & CClientUIInterface::ICON_ERROR) {
908 nMBoxIcon = QMessageBox::Critical;
909 nNotifyIcon = Notificator::Critical;
911 else if (style & CClientUIInterface::ICON_WARNING) {
912 nMBoxIcon = QMessageBox::Warning;
913 nNotifyIcon = Notificator::Warning;
916 // Display message
917 if (style & CClientUIInterface::MODAL) {
918 // Check for buttons, use OK as default, if none was supplied
919 QMessageBox::StandardButton buttons;
920 if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
921 buttons = QMessageBox::Ok;
923 showNormalIfMinimized();
924 QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this);
925 int r = mBox.exec();
926 if (ret != NULL)
927 *ret = r == QMessageBox::Ok;
929 else
930 notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
933 void BitcoinGUI::changeEvent(QEvent *e)
935 QMainWindow::changeEvent(e);
936 #ifndef Q_OS_MAC // Ignored on Mac
937 if(e->type() == QEvent::WindowStateChange)
939 if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray())
941 QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
942 if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
944 QTimer::singleShot(0, this, SLOT(hide()));
945 e->ignore();
949 #endif
952 void BitcoinGUI::closeEvent(QCloseEvent *event)
954 #ifndef Q_OS_MAC // Ignored on Mac
955 if(clientModel && clientModel->getOptionsModel())
957 if(!clientModel->getOptionsModel()->getMinimizeOnClose())
959 // close rpcConsole in case it was open to make some space for the shutdown window
960 rpcConsole->close();
962 QApplication::quit();
964 else
966 QMainWindow::showMinimized();
967 event->ignore();
970 #else
971 QMainWindow::closeEvent(event);
972 #endif
975 void BitcoinGUI::showEvent(QShowEvent *event)
977 // enable the debug window when the main window shows up
978 openRPCConsoleAction->setEnabled(true);
979 aboutAction->setEnabled(true);
980 optionsAction->setEnabled(true);
983 #ifdef ENABLE_WALLET
984 void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
986 // On new transaction, make an info balloon
987 QString msg = tr("Date: %1\n").arg(date) +
988 tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
989 tr("Type: %1\n").arg(type);
990 if (!label.isEmpty())
991 msg += tr("Label: %1\n").arg(label);
992 else if (!address.isEmpty())
993 msg += tr("Address: %1\n").arg(address);
994 message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
995 msg, CClientUIInterface::MSG_INFORMATION);
997 #endif // ENABLE_WALLET
999 void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
1001 // Accept only URIs
1002 if(event->mimeData()->hasUrls())
1003 event->acceptProposedAction();
1006 void BitcoinGUI::dropEvent(QDropEvent *event)
1008 if(event->mimeData()->hasUrls())
1010 Q_FOREACH(const QUrl &uri, event->mimeData()->urls())
1012 Q_EMIT receivedURI(uri.toString());
1015 event->acceptProposedAction();
1018 bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
1020 // Catch status tip events
1021 if (event->type() == QEvent::StatusTip)
1023 // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
1024 if (progressBarLabel->isVisible() || progressBar->isVisible())
1025 return true;
1027 return QMainWindow::eventFilter(object, event);
1030 #ifdef ENABLE_WALLET
1031 bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
1033 // URI has to be valid
1034 if (walletFrame && walletFrame->handlePaymentRequest(recipient))
1036 showNormalIfMinimized();
1037 gotoSendCoinsPage();
1038 return true;
1040 return false;
1043 void BitcoinGUI::setHDStatus(int hdEnabled)
1045 labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1046 labelWalletHDStatusIcon->setToolTip(hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
1048 // eventually disable the QLabel to set its opacity to 50%
1049 labelWalletHDStatusIcon->setEnabled(hdEnabled);
1052 void BitcoinGUI::setEncryptionStatus(int status)
1054 switch(status)
1056 case WalletModel::Unencrypted:
1057 labelWalletEncryptionIcon->hide();
1058 encryptWalletAction->setChecked(false);
1059 changePassphraseAction->setEnabled(false);
1060 encryptWalletAction->setEnabled(true);
1061 break;
1062 case WalletModel::Unlocked:
1063 labelWalletEncryptionIcon->show();
1064 labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1065 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1066 encryptWalletAction->setChecked(true);
1067 changePassphraseAction->setEnabled(true);
1068 encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1069 break;
1070 case WalletModel::Locked:
1071 labelWalletEncryptionIcon->show();
1072 labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1073 labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1074 encryptWalletAction->setChecked(true);
1075 changePassphraseAction->setEnabled(true);
1076 encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1077 break;
1080 #endif // ENABLE_WALLET
1082 void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
1084 if(!clientModel)
1085 return;
1087 // activateWindow() (sometimes) helps with keyboard focus on Windows
1088 if (isHidden())
1090 show();
1091 activateWindow();
1093 else if (isMinimized())
1095 showNormal();
1096 activateWindow();
1098 else if (GUIUtil::isObscured(this))
1100 raise();
1101 activateWindow();
1103 else if(fToggleHidden)
1104 hide();
1107 void BitcoinGUI::toggleHidden()
1109 showNormalIfMinimized(true);
1112 void BitcoinGUI::detectShutdown()
1114 if (ShutdownRequested())
1116 if(rpcConsole)
1117 rpcConsole->hide();
1118 qApp->quit();
1122 void BitcoinGUI::showProgress(const QString &title, int nProgress)
1124 if (nProgress == 0)
1126 progressDialog = new QProgressDialog(title, "", 0, 100);
1127 progressDialog->setWindowModality(Qt::ApplicationModal);
1128 progressDialog->setMinimumDuration(0);
1129 progressDialog->setCancelButton(0);
1130 progressDialog->setAutoClose(false);
1131 progressDialog->setValue(0);
1133 else if (nProgress == 100)
1135 if (progressDialog)
1137 progressDialog->close();
1138 progressDialog->deleteLater();
1141 else if (progressDialog)
1142 progressDialog->setValue(nProgress);
1145 void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
1147 if (trayIcon)
1149 trayIcon->setVisible(!fHideTrayIcon);
1153 void BitcoinGUI::showModalOverlay()
1155 if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
1156 modalOverlay->toggleVisibility();
1159 static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
1161 bool modal = (style & CClientUIInterface::MODAL);
1162 // The SECURE flag has no effect in the Qt GUI.
1163 // bool secure = (style & CClientUIInterface::SECURE);
1164 style &= ~CClientUIInterface::SECURE;
1165 bool ret = false;
1166 // In case of modal message, use blocking connection to wait for user to click a button
1167 QMetaObject::invokeMethod(gui, "message",
1168 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1169 Q_ARG(QString, QString::fromStdString(caption)),
1170 Q_ARG(QString, QString::fromStdString(message)),
1171 Q_ARG(unsigned int, style),
1172 Q_ARG(bool*, &ret));
1173 return ret;
1176 void BitcoinGUI::subscribeToCoreSignals()
1178 // Connect signals to client
1179 uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1180 uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1183 void BitcoinGUI::unsubscribeFromCoreSignals()
1185 // Disconnect signals from client
1186 uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1187 uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1190 void BitcoinGUI::toggleNetworkActive()
1192 if (clientModel) {
1193 clientModel->setNetworkActive(!clientModel->getNetworkActive());
1197 UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
1198 optionsModel(0),
1199 menu(0)
1201 createContextMenu();
1202 setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1203 QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
1204 int max_width = 0;
1205 const QFontMetrics fm(font());
1206 Q_FOREACH (const BitcoinUnits::Unit unit, units)
1208 max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
1210 setMinimumSize(max_width, 0);
1211 setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1212 setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
1215 /** So that it responds to button clicks */
1216 void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
1218 onDisplayUnitsClicked(event->pos());
1221 /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
1222 void UnitDisplayStatusBarControl::createContextMenu()
1224 menu = new QMenu(this);
1225 Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
1227 QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this);
1228 menuAction->setData(QVariant(u));
1229 menu->addAction(menuAction);
1231 connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*)));
1234 /** Lets the control know about the Options Model (and its signals) */
1235 void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
1237 if (_optionsModel)
1239 this->optionsModel = _optionsModel;
1241 // be aware of a display unit change reported by the OptionsModel object.
1242 connect(_optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
1244 // initialize the display units label with the current value in the model.
1245 updateDisplayUnit(_optionsModel->getDisplayUnit());
1249 /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
1250 void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
1252 setText(BitcoinUnits::name(newUnits));
1255 /** Shows context menu with Display Unit options by the mouse coordinates */
1256 void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
1258 QPoint globalPos = mapToGlobal(point);
1259 menu->exec(globalPos);
1262 /** Tells underlying optionsModel to update its current display unit. */
1263 void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
1265 if (action)
1267 optionsModel->setDisplayUnit(action->data());