Dash Core  0.12.2.1
P2P Digital Currency
bitcoingui.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2017 The Dash Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "bitcoingui.h"
7 
8 #include "bitcoinunits.h"
9 #include "clientmodel.h"
10 #include "guiconstants.h"
11 #include "guiutil.h"
12 #include "modaloverlay.h"
13 #include "networkstyle.h"
14 #include "notificator.h"
15 #include "openuridialog.h"
16 #include "optionsdialog.h"
17 #include "optionsmodel.h"
18 #include "platformstyle.h"
19 #include "rpcconsole.h"
20 #include "utilitydialog.h"
21 
22 #ifdef ENABLE_WALLET
23 #include "walletframe.h"
24 #include "walletmodel.h"
25 #endif // ENABLE_WALLET
26 
27 #ifdef Q_OS_MAC
28 #include "macdockiconhandler.h"
29 #endif
30 
31 #include "chainparams.h"
32 #include "init.h"
33 #include "ui_interface.h"
34 #include "util.h"
35 #include "masternode-sync.h"
36 #include "masternodelist.h"
37 
38 #include <iostream>
39 
40 #include <QAction>
41 #include <QApplication>
42 #include <QDateTime>
43 #include <QDesktopWidget>
44 #include <QDragEnterEvent>
45 #include <QListWidget>
46 #include <QMenuBar>
47 #include <QMessageBox>
48 #include <QMimeData>
49 #include <QProgressDialog>
50 #include <QSettings>
51 #include <QShortcut>
52 #include <QStackedWidget>
53 #include <QStatusBar>
54 #include <QStyle>
55 #include <QTimer>
56 #include <QToolBar>
57 #include <QVBoxLayout>
58 
59 #if QT_VERSION < 0x050000
60 #include <QTextDocument>
61 #include <QUrl>
62 #else
63 #include <QUrlQuery>
64 #endif
65 
66 const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
67 #if defined(Q_OS_MAC)
68  "macosx"
69 #elif defined(Q_OS_WIN)
70  "windows"
71 #else
72  "other"
73 #endif
74  ;
75 
76 const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
77 
78 BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
79  QMainWindow(parent),
80  clientModel(0),
81  walletFrame(0),
82  unitDisplayControl(0),
83  labelEncryptionIcon(0),
84  labelWalletHDStatusIcon(0),
85  labelConnectionsIcon(0),
86  labelBlocksIcon(0),
87  progressBarLabel(0),
88  progressBar(0),
89  progressDialog(0),
90  appMenuBar(0),
91  overviewAction(0),
92  historyAction(0),
93  masternodeAction(0),
94  quitAction(0),
95  sendCoinsAction(0),
96  sendCoinsMenuAction(0),
97  usedSendingAddressesAction(0),
98  usedReceivingAddressesAction(0),
99  signMessageAction(0),
100  verifyMessageAction(0),
101  aboutAction(0),
102  receiveCoinsAction(0),
103  receiveCoinsMenuAction(0),
104  optionsAction(0),
105  toggleHideAction(0),
106  encryptWalletAction(0),
107  backupWalletAction(0),
108  changePassphraseAction(0),
109  aboutQtAction(0),
110  openRPCConsoleAction(0),
111  openAction(0),
112  showHelpMessageAction(0),
113  showPrivateSendHelpAction(0),
114  trayIcon(0),
115  trayIconMenu(0),
116  dockIconMenu(0),
117  notificator(0),
118  rpcConsole(0),
119  helpMessageDialog(0),
120  modalOverlay(0),
121  prevBlocks(0),
122  spinnerFrame(0),
123  platformStyle(platformStyle)
124 {
125  /* Open CSS when configured */
126  this->setStyleSheet(GUIUtil::loadStyleSheet());
127 
128  GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
129 
130  QString windowTitle = tr("Dash Core") + " - ";
131 #ifdef ENABLE_WALLET
132  /* if compiled with wallet support, -disablewallet can still disable the wallet */
133  enableWallet = !GetBoolArg("-disablewallet", false);
134 #else
135  enableWallet = false;
136 #endif // ENABLE_WALLET
137  if(enableWallet)
138  {
139  windowTitle += tr("Wallet");
140  } else {
141  windowTitle += tr("Node");
142  }
143  QString userWindowTitle = QString::fromStdString(GetArg("-windowtitle", ""));
144  if(!userWindowTitle.isEmpty()) windowTitle += " - " + userWindowTitle;
145  windowTitle += " " + networkStyle->getTitleAddText();
146 #ifndef Q_OS_MAC
147  QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
148  setWindowIcon(networkStyle->getTrayAndWindowIcon());
149 #else
150  MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon());
151 #endif
152  setWindowTitle(windowTitle);
153 
154 #if defined(Q_OS_MAC) && QT_VERSION < 0x050000
155  // This property is not implemented in Qt 5. Setting it has no effect.
156  // A replacement API (QtMacUnifiedToolBar) is available in QtMacExtras.
157  setUnifiedTitleAndToolBarOnMac(true);
158 #endif
159 
162 #ifdef ENABLE_WALLET
163  if(enableWallet)
164  {
167  } else
168 #endif // ENABLE_WALLET
169  {
170  /* When compiled without wallet or -disablewallet is provided,
171  * the central widget is the rpc console.
172  */
173  setCentralWidget(rpcConsole);
174  }
175 
176  // Accept D&D of URIs
177  setAcceptDrops(true);
178 
179  // Create actions for the toolbar, menu bar and tray/dock icon
180  // Needs walletFrame to be initialized
181  createActions();
182 
183  // Create application menu bar
184  createMenuBar();
185 
186  // Create the toolbars
187  createToolBars();
188 
189  // Create system tray icon and notification
190  createTrayIcon(networkStyle);
191 
192  // Create status bar
193  statusBar();
194 
195  // Disable size grip because it looks ugly and nobody needs it
196  statusBar()->setSizeGripEnabled(false);
197 
198  // Status bar notification icons
199  QFrame *frameBlocks = new QFrame();
200  frameBlocks->setContentsMargins(0,0,0,0);
201  frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
202  QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
203  frameBlocksLayout->setContentsMargins(3,0,3,0);
204  frameBlocksLayout->setSpacing(3);
206  labelEncryptionIcon = new QLabel();
207  labelWalletHDStatusIcon = new QLabel();
209 
211  if(enableWallet)
212  {
213  frameBlocksLayout->addStretch();
214  frameBlocksLayout->addWidget(unitDisplayControl);
215  frameBlocksLayout->addStretch();
216  frameBlocksLayout->addWidget(labelEncryptionIcon);
217  frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
218  }
219  frameBlocksLayout->addStretch();
220  frameBlocksLayout->addWidget(labelConnectionsIcon);
221  frameBlocksLayout->addStretch();
222  frameBlocksLayout->addWidget(labelBlocksIcon);
223  frameBlocksLayout->addStretch();
224 
225  // Progress bar and label for blocks download
226  progressBarLabel = new QLabel();
227  progressBarLabel->setVisible(true);
229  progressBar->setAlignment(Qt::AlignCenter);
230  progressBar->setVisible(true);
231 
232  // Override style sheet for progress bar for styles that have a segmented progress bar,
233  // as they make the text unreadable (workaround for issue #1071)
234  // See https://qt-project.org/doc/qt-4.8/gallery.html
235  QString curStyle = QApplication::style()->metaObject()->className();
236  if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
237  {
238  progressBar->setStyleSheet("QProgressBar { background-color: #F8F8F8; 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 #00CCFF, stop: 1 #33CCFF); border-radius: 7px; margin: 0px; }");
239  }
240 
241  statusBar()->addWidget(progressBarLabel);
242  statusBar()->addWidget(progressBar);
243  statusBar()->addPermanentWidget(frameBlocks);
244 
245  // Install event filter to be able to catch status tip events (QEvent::StatusTip)
246  this->installEventFilter(this);
247 
248  // Initially wallet actions should be disabled
250 
251  // Subscribe to notifications from core
253 
254  // Jump to peers tab by clicking on connections icon
255  connect(labelConnectionsIcon, SIGNAL(clicked(QPoint)), this, SLOT(showPeers()));
256 
257  modalOverlay = new ModalOverlay(this->centralWidget());
258 #ifdef ENABLE_WALLET
259  if(enableWallet) {
260  connect(walletFrame, SIGNAL(requestedSyncWarningInfo()), this, SLOT(showModalOverlay()));
261  connect(labelBlocksIcon, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay()));
262  connect(progressBar, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay()));
263  }
264 #endif
265 }
266 
268 {
269  // Unsubscribe from notifications from core
271 
272  GUIUtil::saveWindowGeometry("nWindow", this);
273  if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
274  trayIcon->hide();
275 #ifdef Q_OS_MAC
276  delete appMenuBar;
278 #endif
279 
280  delete rpcConsole;
281 }
282 
284 {
285  QActionGroup *tabGroup = new QActionGroup(this);
286 
287  QString theme = GUIUtil::getThemeName();
288  overviewAction = new QAction(QIcon(":/icons/" + theme + "/overview"), tr("&Overview"), this);
289  overviewAction->setStatusTip(tr("Show general overview of wallet"));
290  overviewAction->setToolTip(overviewAction->statusTip());
291  overviewAction->setCheckable(true);
292 #ifdef Q_OS_MAC
293  overviewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_1));
294 #else
295  overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
296 #endif
297  tabGroup->addAction(overviewAction);
298 
299  sendCoinsAction = new QAction(QIcon(":/icons/" + theme + "/send"), tr("&Send"), this);
300  sendCoinsAction->setStatusTip(tr("Send coins to a Dash address"));
301  sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
302  sendCoinsAction->setCheckable(true);
303 #ifdef Q_OS_MAC
304  sendCoinsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_2));
305 #else
306  sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
307 #endif
308  tabGroup->addAction(sendCoinsAction);
309 
310  sendCoinsMenuAction = new QAction(QIcon(":/icons/" + theme + "/send"), sendCoinsAction->text(), this);
311  sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
312  sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
313 
314  receiveCoinsAction = new QAction(QIcon(":/icons/" + theme + "/receiving_addresses"), tr("&Receive"), this);
315  receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and dash: URIs)"));
316  receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
317  receiveCoinsAction->setCheckable(true);
318 #ifdef Q_OS_MAC
319  receiveCoinsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_3));
320 #else
321  receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
322 #endif
323  tabGroup->addAction(receiveCoinsAction);
324 
325  receiveCoinsMenuAction = new QAction(QIcon(":/icons/" + theme + "/receiving_addresses"), receiveCoinsAction->text(), this);
326  receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
327  receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
328 
329  historyAction = new QAction(QIcon(":/icons/" + theme + "/history"), tr("&Transactions"), this);
330  historyAction->setStatusTip(tr("Browse transaction history"));
331  historyAction->setToolTip(historyAction->statusTip());
332  historyAction->setCheckable(true);
333 #ifdef Q_OS_MAC
334  historyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_4));
335 #else
336  historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
337 #endif
338  tabGroup->addAction(historyAction);
339 
340 #ifdef ENABLE_WALLET
341  QSettings settings;
342  if (settings.value("fShowMasternodesTab").toBool()) {
343  masternodeAction = new QAction(QIcon(":/icons/" + theme + "/masternodes"), tr("&Masternodes"), this);
344  masternodeAction->setStatusTip(tr("Browse masternodes"));
345  masternodeAction->setToolTip(masternodeAction->statusTip());
346  masternodeAction->setCheckable(true);
347 #ifdef Q_OS_MAC
348  masternodeAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_5));
349 #else
350  masternodeAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
351 #endif
352  tabGroup->addAction(masternodeAction);
353  connect(masternodeAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
354  connect(masternodeAction, SIGNAL(triggered()), this, SLOT(gotoMasternodePage()));
355  }
356 
357  // These showNormalIfMinimized are needed because Send Coins and Receive Coins
358  // can be triggered from the tray menu, and need to show the GUI to be useful.
359  connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
360  connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
361  connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
362  connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
363  connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
364  connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
365  connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
366  connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
367  connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
368  connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
369  connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
370  connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
371 #endif // ENABLE_WALLET
372 
373  quitAction = new QAction(QIcon(":/icons/" + theme + "/quit"), tr("E&xit"), this);
374  quitAction->setStatusTip(tr("Quit application"));
375  quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
376  quitAction->setMenuRole(QAction::QuitRole);
377  aboutAction = new QAction(QIcon(":/icons/" + theme + "/about"), tr("&About Dash Core"), this);
378  aboutAction->setStatusTip(tr("Show information about Dash Core"));
379  aboutAction->setMenuRole(QAction::AboutRole);
380  aboutAction->setEnabled(false);
381  aboutQtAction = new QAction(QIcon(":/icons/" + theme + "/about_qt"), tr("About &Qt"), this);
382  aboutQtAction->setStatusTip(tr("Show information about Qt"));
383  aboutQtAction->setMenuRole(QAction::AboutQtRole);
384  optionsAction = new QAction(QIcon(":/icons/" + theme + "/options"), tr("&Options..."), this);
385  optionsAction->setStatusTip(tr("Modify configuration options for Dash Core"));
386  optionsAction->setMenuRole(QAction::PreferencesRole);
387  optionsAction->setEnabled(false);
388  toggleHideAction = new QAction(QIcon(":/icons/" + theme + "/about"), tr("&Show / Hide"), this);
389  toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
390 
391  encryptWalletAction = new QAction(QIcon(":/icons/" + theme + "/lock_closed"), tr("&Encrypt Wallet..."), this);
392  encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
393  encryptWalletAction->setCheckable(true);
394  backupWalletAction = new QAction(QIcon(":/icons/" + theme + "/filesave"), tr("&Backup Wallet..."), this);
395  backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
396  changePassphraseAction = new QAction(QIcon(":/icons/" + theme + "/key"), tr("&Change Passphrase..."), this);
397  changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
398  unlockWalletAction = new QAction(tr("&Unlock Wallet..."), this);
399  unlockWalletAction->setToolTip(tr("Unlock wallet"));
400  lockWalletAction = new QAction(tr("&Lock Wallet"), this);
401  signMessageAction = new QAction(QIcon(":/icons/" + theme + "/edit"), tr("Sign &message..."), this);
402  signMessageAction->setStatusTip(tr("Sign messages with your Dash addresses to prove you own them"));
403  verifyMessageAction = new QAction(QIcon(":/icons/" + theme + "/transaction_0"), tr("&Verify message..."), this);
404  verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Dash addresses"));
405 
406  openInfoAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Information"), this);
407  openInfoAction->setStatusTip(tr("Show diagnostic information"));
408  openRPCConsoleAction = new QAction(QIcon(":/icons/" + theme + "/debugwindow"), tr("&Debug console"), this);
409  openRPCConsoleAction->setStatusTip(tr("Open debugging console"));
410  openGraphAction = new QAction(QIcon(":/icons/" + theme + "/connect_4"), tr("&Network Monitor"), this);
411  openGraphAction->setStatusTip(tr("Show network monitor"));
412  openPeersAction = new QAction(QIcon(":/icons/" + theme + "/connect_4"), tr("&Peers list"), this);
413  openPeersAction->setStatusTip(tr("Show peers info"));
414  openRepairAction = new QAction(QIcon(":/icons/" + theme + "/options"), tr("Wallet &Repair"), this);
415  openRepairAction->setStatusTip(tr("Show wallet repair options"));
416  openConfEditorAction = new QAction(QIcon(":/icons/" + theme + "/edit"), tr("Open Wallet &Configuration File"), this);
417  openConfEditorAction->setStatusTip(tr("Open configuration file"));
418  openMNConfEditorAction = new QAction(QIcon(":/icons/" + theme + "/edit"), tr("Open &Masternode Configuration File"), this);
419  openMNConfEditorAction->setStatusTip(tr("Open Masternode configuration file"));
420  showBackupsAction = new QAction(QIcon(":/icons/" + theme + "/browse"), tr("Show Automatic &Backups"), this);
421  showBackupsAction->setStatusTip(tr("Show automatically created wallet backups"));
422  // initially disable the debug window menu items
423  openInfoAction->setEnabled(false);
424  openRPCConsoleAction->setEnabled(false);
425  openGraphAction->setEnabled(false);
426  openPeersAction->setEnabled(false);
427  openRepairAction->setEnabled(false);
428 
429  usedSendingAddressesAction = new QAction(QIcon(":/icons/" + theme + "/address-book"), tr("&Sending addresses..."), this);
430  usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
431  usedReceivingAddressesAction = new QAction(QIcon(":/icons/" + theme + "/address-book"), tr("&Receiving addresses..."), this);
432  usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
433 
434  openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_DirOpenIcon), tr("Open &URI..."), this);
435  openAction->setStatusTip(tr("Open a dash: URI or payment request"));
436 
437  showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this);
438  showHelpMessageAction->setMenuRole(QAction::NoRole);
439  showHelpMessageAction->setStatusTip(tr("Show the Dash Core help message to get a list with possible Dash Core command-line options"));
440 
441  showPrivateSendHelpAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&PrivateSend information"), this);
442  showPrivateSendHelpAction->setMenuRole(QAction::NoRole);
443  showPrivateSendHelpAction->setStatusTip(tr("Show the PrivateSend basic information"));
444 
445  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
446  connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
447  connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
448  connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
449  connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
450  connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
451  connect(showPrivateSendHelpAction, SIGNAL(triggered()), this, SLOT(showPrivateSendHelpClicked()));
452 
453  // Jump directly to tabs in RPC-console
454  connect(openInfoAction, SIGNAL(triggered()), this, SLOT(showInfo()));
455  connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showConsole()));
456  connect(openGraphAction, SIGNAL(triggered()), this, SLOT(showGraph()));
457  connect(openPeersAction, SIGNAL(triggered()), this, SLOT(showPeers()));
458  connect(openRepairAction, SIGNAL(triggered()), this, SLOT(showRepair()));
459 
460  // Open configs and backup folder from menu
461  connect(openConfEditorAction, SIGNAL(triggered()), this, SLOT(showConfEditor()));
462  connect(openMNConfEditorAction, SIGNAL(triggered()), this, SLOT(showMNConfEditor()));
463  connect(showBackupsAction, SIGNAL(triggered()), this, SLOT(showBackups()));
464 
465  // Get restart command-line parameters and handle restart
466  connect(rpcConsole, SIGNAL(handleRestart(QStringList)), this, SLOT(handleRestart(QStringList)));
467 
468  // prevents an open debug window from becoming stuck/unusable on client shutdown
469  connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
470 
471 #ifdef ENABLE_WALLET
472  if(walletFrame)
473  {
474  connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
475  connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
476  connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
477  connect(unlockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(unlockWallet()));
478  connect(lockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(lockWallet()));
479  connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
480  connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
481  connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
482  connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
483  connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
484  }
485 #endif // ENABLE_WALLET
486 
487  new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I), this, SLOT(showInfo()));
488  new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this, SLOT(showConsole()));
489  new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_G), this, SLOT(showGraph()));
490  new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_P), this, SLOT(showPeers()));
491  new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R), this, SLOT(showRepair()));
492 }
493 
495 {
496 #ifdef Q_OS_MAC
497  // Create a decoupled menu bar on Mac which stays even if the window is closed
498  appMenuBar = new QMenuBar();
499 #else
500  // Get the main window's menu bar on other platforms
501  appMenuBar = menuBar();
502 #endif
503 
504  // Configure the menus
505  QMenu *file = appMenuBar->addMenu(tr("&File"));
506  if(walletFrame)
507  {
508  file->addAction(openAction);
509  file->addAction(backupWalletAction);
510  file->addAction(signMessageAction);
511  file->addAction(verifyMessageAction);
512  file->addSeparator();
513  file->addAction(usedSendingAddressesAction);
515  file->addSeparator();
516  }
517  file->addAction(quitAction);
518 
519  QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
520  if(walletFrame)
521  {
522  settings->addAction(encryptWalletAction);
523  settings->addAction(changePassphraseAction);
524  settings->addAction(unlockWalletAction);
525  settings->addAction(lockWalletAction);
526  settings->addSeparator();
527  }
528  settings->addAction(optionsAction);
529 
530  if(walletFrame)
531  {
532  QMenu *tools = appMenuBar->addMenu(tr("&Tools"));
533  tools->addAction(openInfoAction);
534  tools->addAction(openRPCConsoleAction);
535  tools->addAction(openGraphAction);
536  tools->addAction(openPeersAction);
537  tools->addAction(openRepairAction);
538  tools->addSeparator();
539  tools->addAction(openConfEditorAction);
540  tools->addAction(openMNConfEditorAction);
541  tools->addAction(showBackupsAction);
542  }
543 
544  QMenu *help = appMenuBar->addMenu(tr("&Help"));
545  help->addAction(showHelpMessageAction);
546  help->addAction(showPrivateSendHelpAction);
547  help->addSeparator();
548  help->addAction(aboutAction);
549  help->addAction(aboutQtAction);
550 }
551 
553 {
554  if(walletFrame)
555  {
556  QToolBar *toolbar = new QToolBar(tr("Tabs toolbar"));
557  toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
558  toolbar->addAction(overviewAction);
559  toolbar->addAction(sendCoinsAction);
560  toolbar->addAction(receiveCoinsAction);
561  toolbar->addAction(historyAction);
562  QSettings settings;
563  if (settings.value("fShowMasternodesTab").toBool())
564  {
565  toolbar->addAction(masternodeAction);
566  }
567  toolbar->setMovable(false); // remove unused icon in upper left corner
568  overviewAction->setChecked(true);
569 
573  QVBoxLayout *layout = new QVBoxLayout;
574  layout->addWidget(toolbar);
575  layout->addWidget(walletFrame);
576  layout->setSpacing(0);
577  layout->setContentsMargins(QMargins());
578  QWidget *containerWidget = new QWidget();
579  containerWidget->setLayout(layout);
580  setCentralWidget(containerWidget);
581  }
582 }
583 
585 {
586  this->clientModel = clientModel;
587  if(clientModel)
588  {
589  // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
590  // while the client has not yet fully loaded
591  if (trayIcon) {
592  // do so only if trayIcon is already set
593  trayIconMenu = new QMenu(this);
594  trayIcon->setContextMenu(trayIconMenu);
596 
597 #ifndef Q_OS_MAC
598  // Show main window on tray icon click
599  // Note: ignore this on Mac - this is not the way tray should work there
600  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
601  this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
602 #else
603  // Note: On Mac, the dock icon is also used to provide menu functionality
604  // similar to one for tray icon
606  dockIconHandler->setMainWindow((QMainWindow *)this);
607  dockIconMenu = dockIconHandler->dockMenu();
608 
610 #endif
611  }
612 
613  // Keep up to date with client
615  connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
616  connect(clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool)));
617 
620  connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
621 
622  connect(clientModel, SIGNAL(additionalDataSyncProgressChanged(double)), this, SLOT(setAdditionalDataSyncProgress(double)));
623 
624  // Receive and report messages from client model
625  connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
626 
627  // Show progress dialog
628  connect(clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
629 
631 #ifdef ENABLE_WALLET
632  if(walletFrame)
633  {
635  }
636 #endif // ENABLE_WALLET
638 
639  OptionsModel* optionsModel = clientModel->getOptionsModel();
640  if(optionsModel)
641  {
642  // be aware of the tray icon disable state change reported by the OptionsModel object.
643  connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool)));
644 
645  // initialize the disable state of the tray icon with the current value in the model.
646  setTrayIconVisible(optionsModel->getHideTrayIcon());
647  }
648  } else {
649  // Disable possibility to show main window via action
650  toggleHideAction->setEnabled(false);
651  if(trayIconMenu)
652  {
653  // Disable context menu on tray icon
654  trayIconMenu->clear();
655  }
656  // Propagate cleared model to child objects
657  rpcConsole->setClientModel(nullptr);
658 #ifdef ENABLE_WALLET
659  walletFrame->setClientModel(nullptr);
660 #endif // ENABLE_WALLET
662 
663 #ifdef Q_OS_MAC
664  if(dockIconMenu)
665  {
666  // Disable context menu on dock icon
667  dockIconMenu->clear();
668  }
669 #endif
670  }
671 }
672 
673 #ifdef ENABLE_WALLET
674 bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
675 {
676  if(!walletFrame)
677  return false;
679  return walletFrame->addWallet(name, walletModel);
680 }
681 
682 bool BitcoinGUI::setCurrentWallet(const QString& name)
683 {
684  if(!walletFrame)
685  return false;
687 }
688 
689 void BitcoinGUI::removeAllWallets()
690 {
691  if(!walletFrame)
692  return;
695 }
696 #endif // ENABLE_WALLET
697 
699 {
700  overviewAction->setEnabled(enabled);
701  sendCoinsAction->setEnabled(enabled);
702  sendCoinsMenuAction->setEnabled(enabled);
703  receiveCoinsAction->setEnabled(enabled);
704  receiveCoinsMenuAction->setEnabled(enabled);
705  historyAction->setEnabled(enabled);
706  QSettings settings;
707  if (settings.value("fShowMasternodesTab").toBool() && masternodeAction) {
708  masternodeAction->setEnabled(enabled);
709  }
710  encryptWalletAction->setEnabled(enabled);
711  backupWalletAction->setEnabled(enabled);
712  changePassphraseAction->setEnabled(enabled);
713  signMessageAction->setEnabled(enabled);
714  verifyMessageAction->setEnabled(enabled);
715  usedSendingAddressesAction->setEnabled(enabled);
716  usedReceivingAddressesAction->setEnabled(enabled);
717  openAction->setEnabled(enabled);
718 }
719 
720 void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
721 {
722  trayIcon = new QSystemTrayIcon(this);
723  QString toolTip = tr("Dash Core client") + " " + networkStyle->getTitleAddText();
724  trayIcon->setToolTip(toolTip);
725  trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
726  trayIcon->hide();
727  notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
728 }
729 
730 void BitcoinGUI::createIconMenu(QMenu *pmenu)
731 {
732  // Configuration of the tray icon (or dock icon) icon menu
733  pmenu->addAction(toggleHideAction);
734  pmenu->addSeparator();
735  pmenu->addAction(sendCoinsMenuAction);
736  pmenu->addAction(receiveCoinsMenuAction);
737  pmenu->addSeparator();
738  pmenu->addAction(signMessageAction);
739  pmenu->addAction(verifyMessageAction);
740  pmenu->addSeparator();
741  pmenu->addAction(optionsAction);
742  pmenu->addAction(openInfoAction);
743  pmenu->addAction(openRPCConsoleAction);
744  pmenu->addAction(openGraphAction);
745  pmenu->addAction(openPeersAction);
746  pmenu->addAction(openRepairAction);
747  pmenu->addSeparator();
748  pmenu->addAction(openConfEditorAction);
749  pmenu->addAction(openMNConfEditorAction);
750  pmenu->addAction(showBackupsAction);
751 #ifndef Q_OS_MAC // This is built-in on Mac
752  pmenu->addSeparator();
753  pmenu->addAction(quitAction);
754 #endif
755 }
756 
757 #ifndef Q_OS_MAC
758 void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
759 {
760  if(reason == QSystemTrayIcon::Trigger)
761  {
762  // Click on system tray icon triggers show/hide of the main window
763  toggleHidden();
764  }
765 }
766 #endif
767 
769 {
771  return;
772 
773  OptionsDialog dlg(this, enableWallet);
775  dlg.exec();
776 }
777 
779 {
780  if(!clientModel)
781  return;
782 
784  dlg.exec();
785 }
786 
788 {
789  rpcConsole->showNormal();
790  rpcConsole->show();
791  rpcConsole->raise();
792  rpcConsole->activateWindow();
793 }
794 
796 {
798  showDebugWindow();
799 }
800 
802 {
804  showDebugWindow();
805 }
806 
808 {
810  showDebugWindow();
811 }
812 
814 {
816  showDebugWindow();
817 }
818 
820 {
822  showDebugWindow();
823 }
824 
826 {
828 }
829 
831 {
833 }
834 
836 {
838 }
839 
841 {
842  helpMessageDialog->show();
843 }
844 
846 {
847  if(!clientModel)
848  return;
849 
851  dlg.exec();
852 }
853 
854 #ifdef ENABLE_WALLET
855 void BitcoinGUI::openClicked()
856 {
857  OpenURIDialog dlg(this);
858  if(dlg.exec())
859  {
860  Q_EMIT receivedURI(dlg.getURI());
861  }
862 }
863 
864 void BitcoinGUI::gotoOverviewPage()
865 {
866  overviewAction->setChecked(true);
868 }
869 
870 void BitcoinGUI::gotoHistoryPage()
871 {
872  historyAction->setChecked(true);
874 }
875 
876 void BitcoinGUI::gotoMasternodePage()
877 {
878  QSettings settings;
879  if (settings.value("fShowMasternodesTab").toBool()) {
880  masternodeAction->setChecked(true);
882  }
883 }
884 
885 void BitcoinGUI::gotoReceiveCoinsPage()
886 {
887  receiveCoinsAction->setChecked(true);
889 }
890 
891 void BitcoinGUI::gotoSendCoinsPage(QString addr)
892 {
893  sendCoinsAction->setChecked(true);
895 }
896 
897 void BitcoinGUI::gotoSignMessageTab(QString addr)
898 {
900 }
901 
902 void BitcoinGUI::gotoVerifyMessageTab(QString addr)
903 {
905 }
906 #endif // ENABLE_WALLET
907 
909 {
911  QString icon;
912  QString theme = GUIUtil::getThemeName();
913  switch(count)
914  {
915  case 0: icon = ":/icons/" + theme + "/connect_0"; break;
916  case 1: case 2: case 3: icon = ":/icons/" + theme + "/connect_1"; break;
917  case 4: case 5: case 6: icon = ":/icons/" + theme + "/connect_2"; break;
918  case 7: case 8: case 9: icon = ":/icons/" + theme + "/connect_3"; break;
919  default: icon = ":/icons/" + theme + "/connect_4"; break;
920  }
921 
922  if (clientModel->getNetworkActive()) {
923  labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Dash network", "", count));
924  } else {
925  labelConnectionsIcon->setToolTip(tr("Network activity disabled"));
926  icon = ":/icons/" + theme + "/network_disabled";
927  }
928 
930 }
931 
933 {
935 }
936 
937 void BitcoinGUI::setNetworkActive(bool networkActive)
938 {
940 }
941 
943 {
944  int64_t headersTipTime = clientModel->getHeaderTipTime();
945  int headersTipHeight = clientModel->getHeaderTipHeight();
946  int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
947  if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
948  progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
949 }
950 
951 void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
952 {
953  if (modalOverlay)
954  {
955  if (header)
957  else
958  modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
959  }
960  if (!clientModel)
961  return;
962 
963  // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text)
964  statusBar()->clearMessage();
965 
966  // Acquire current block source
967  enum BlockSource blockSource = clientModel->getBlockSource();
968  switch (blockSource) {
970  if (header) {
972  return;
973  }
974  progressBarLabel->setText(tr("Synchronizing with network..."));
976  break;
977  case BLOCK_SOURCE_DISK:
978  if (header) {
979  progressBarLabel->setText(tr("Indexing blocks on disk..."));
980  } else {
981  progressBarLabel->setText(tr("Processing blocks on disk..."));
982  }
983  break;
985  progressBarLabel->setText(tr("Reindexing blocks on disk..."));
986  break;
987  case BLOCK_SOURCE_NONE:
988  if (header) {
989  return;
990  }
991  progressBarLabel->setText(tr("Connecting to peers..."));
992  break;
993  }
994 
995  QString tooltip;
996 
997  QDateTime currentDate = QDateTime::currentDateTime();
998  qint64 secs = blockDate.secsTo(currentDate);
999 
1000  tooltip = tr("Processed %n block(s) of transaction history.", "", count);
1001 
1002  // Set icon state: spinning if catching up, tick otherwise
1003  QString theme = GUIUtil::getThemeName();
1004 
1005 #ifdef ENABLE_WALLET
1006  if (walletFrame)
1007  {
1008  if(secs < 25*60) // 90*60 in bitcoin
1009  {
1010  modalOverlay->showHide(true, true);
1011  // TODO instead of hiding it forever, we should add meaningful information about MN sync to the overlay
1013  }
1014  else
1015  {
1017  }
1018  }
1019 #endif // ENABLE_WALLET
1020 
1022  {
1023  QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
1024 
1025  progressBarLabel->setVisible(true);
1026  progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
1027  progressBar->setMaximum(1000000000);
1028  progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
1029  progressBar->setVisible(true);
1030 
1031  tooltip = tr("Catching up...") + QString("<br>") + tooltip;
1032  if(count != prevBlocks)
1033  {
1034  labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
1035  ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
1038  }
1039  prevBlocks = count;
1040 
1041 #ifdef ENABLE_WALLET
1042  if(walletFrame)
1043  {
1045  }
1046 #endif // ENABLE_WALLET
1047 
1048  tooltip += QString("<br>");
1049  tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
1050  tooltip += QString("<br>");
1051  tooltip += tr("Transactions after this will not yet be visible.");
1052  }
1053 
1054  // Don't word-wrap this (fixed-width) tooltip
1055  tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1056 
1057  labelBlocksIcon->setToolTip(tooltip);
1058  progressBarLabel->setToolTip(tooltip);
1059  progressBar->setToolTip(tooltip);
1060 }
1061 
1063 {
1064  if(!clientModel)
1065  return;
1066 
1067  // No additional data sync should be happening while blockchain is not synced, nothing to update
1069  return;
1070 
1071  // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text)
1072  statusBar()->clearMessage();
1073 
1074  QString tooltip;
1075 
1076  // Set icon state: spinning if catching up, tick otherwise
1077  QString theme = GUIUtil::getThemeName();
1078 
1079  QString strSyncStatus;
1080  tooltip = tr("Up to date") + QString(".<br>") + tooltip;
1081 
1082  if(masternodeSync.IsSynced()) {
1083  progressBarLabel->setVisible(false);
1084  progressBar->setVisible(false);
1085  labelBlocksIcon->setPixmap(QIcon(":/icons/" + theme + "/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1086  } else {
1087 
1088  labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
1089  ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
1092 
1093 #ifdef ENABLE_WALLET
1094  if(walletFrame)
1096 #endif // ENABLE_WALLET
1097 
1098  progressBar->setFormat(tr("Synchronizing additional data: %p%"));
1099  progressBar->setMaximum(1000000000);
1100  progressBar->setValue(nSyncProgress * 1000000000.0 + 0.5);
1101  }
1102 
1103  strSyncStatus = QString(masternodeSync.GetSyncStatus().c_str());
1104  progressBarLabel->setText(strSyncStatus);
1105  tooltip = strSyncStatus + QString("<br>") + tooltip;
1106 
1107  // Don't word-wrap this (fixed-width) tooltip
1108  tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
1109 
1110  labelBlocksIcon->setToolTip(tooltip);
1111  progressBarLabel->setToolTip(tooltip);
1112  progressBar->setToolTip(tooltip);
1113 }
1114 
1115 void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
1116 {
1117  QString strTitle = tr("Dash Core"); // default title
1118  // Default to information icon
1119  int nMBoxIcon = QMessageBox::Information;
1120  int nNotifyIcon = Notificator::Information;
1121 
1122  QString msgType;
1123 
1124  // Prefer supplied title over style based title
1125  if (!title.isEmpty()) {
1126  msgType = title;
1127  }
1128  else {
1129  switch (style) {
1131  msgType = tr("Error");
1132  break;
1134  msgType = tr("Warning");
1135  break;
1137  msgType = tr("Information");
1138  break;
1139  default:
1140  break;
1141  }
1142  }
1143  // Append title to "Dash Core - "
1144  if (!msgType.isEmpty())
1145  strTitle += " - " + msgType;
1146 
1147  // Check for error/warning icon
1148  if (style & CClientUIInterface::ICON_ERROR) {
1149  nMBoxIcon = QMessageBox::Critical;
1150  nNotifyIcon = Notificator::Critical;
1151  }
1152  else if (style & CClientUIInterface::ICON_WARNING) {
1153  nMBoxIcon = QMessageBox::Warning;
1154  nNotifyIcon = Notificator::Warning;
1155  }
1156 
1157  // Display message
1158  if (style & CClientUIInterface::MODAL) {
1159  // Check for buttons, use OK as default, if none was supplied
1160  QMessageBox::StandardButton buttons;
1161  if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
1162  buttons = QMessageBox::Ok;
1163 
1165  QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this);
1166  int r = mBox.exec();
1167  if (ret != NULL)
1168  *ret = r == QMessageBox::Ok;
1169  }
1170  else
1171  notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
1172 }
1173 
1175 {
1176  QMainWindow::changeEvent(e);
1177 #ifndef Q_OS_MAC // Ignored on Mac
1178  if(e->type() == QEvent::WindowStateChange)
1179  {
1181  {
1182  QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
1183  if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
1184  {
1185  QTimer::singleShot(0, this, SLOT(hide()));
1186  e->ignore();
1187  }
1188  }
1189  }
1190 #endif
1191 }
1192 
1193 void BitcoinGUI::closeEvent(QCloseEvent *event)
1194 {
1195 #ifndef Q_OS_MAC // Ignored on Mac
1197  {
1199  {
1200  // close rpcConsole in case it was open to make some space for the shutdown window
1201  rpcConsole->close();
1202 
1203  QApplication::quit();
1204  }
1205  }
1206 #endif
1207  QMainWindow::closeEvent(event);
1208 }
1209 
1210 void BitcoinGUI::showEvent(QShowEvent *event)
1211 {
1212  // enable the debug window when the main window shows up
1213  openInfoAction->setEnabled(true);
1214  openRPCConsoleAction->setEnabled(true);
1215  openGraphAction->setEnabled(true);
1216  openPeersAction->setEnabled(true);
1217  openRepairAction->setEnabled(true);
1218  aboutAction->setEnabled(true);
1219  optionsAction->setEnabled(true);
1220 }
1221 
1222 #ifdef ENABLE_WALLET
1223 void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
1224 {
1225  // On new transaction, make an info balloon
1226  QString msg = tr("Date: %1\n").arg(date) +
1227  tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
1228  tr("Type: %1\n").arg(type);
1229  if (!label.isEmpty())
1230  msg += tr("Label: %1\n").arg(label);
1231  else if (!address.isEmpty())
1232  msg += tr("Address: %1\n").arg(address);
1233  message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
1235 }
1236 #endif // ENABLE_WALLET
1237 
1238 void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
1239 {
1240  // Accept only URIs
1241  if(event->mimeData()->hasUrls())
1242  event->acceptProposedAction();
1243 }
1244 
1245 void BitcoinGUI::dropEvent(QDropEvent *event)
1246 {
1247  if(event->mimeData()->hasUrls())
1248  {
1249  Q_FOREACH(const QUrl &uri, event->mimeData()->urls())
1250  {
1251  Q_EMIT receivedURI(uri.toString());
1252  }
1253  }
1254  event->acceptProposedAction();
1255 }
1256 
1257 bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
1258 {
1259  // Catch status tip events
1260  if (event->type() == QEvent::StatusTip)
1261  {
1262  // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
1263  if (progressBarLabel->isVisible() || progressBar->isVisible())
1264  return true;
1265  }
1266  return QMainWindow::eventFilter(object, event);
1267 }
1268 
1269 #ifdef ENABLE_WALLET
1270 bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
1271 {
1272  // URI has to be valid
1273  if (walletFrame && walletFrame->handlePaymentRequest(recipient))
1274  {
1276  gotoSendCoinsPage();
1277  return true;
1278  }
1279  return false;
1280 }
1281 
1282 void BitcoinGUI::setHDStatus(int hdEnabled)
1283 {
1284  QString theme = GUIUtil::getThemeName();
1285 
1286  labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(hdEnabled ? ":/icons/" + theme + "/hd_enabled" : ":/icons/" + theme + "/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1287  labelWalletHDStatusIcon->setToolTip(hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
1288 
1289  // eventually disable the QLabel to set its opacity to 50%
1290  labelWalletHDStatusIcon->setEnabled(hdEnabled);
1291 }
1292 
1293 void BitcoinGUI::setEncryptionStatus(int status)
1294 {
1295  QString theme = GUIUtil::getThemeName();
1296  switch(status)
1297  {
1299  labelEncryptionIcon->hide();
1300  encryptWalletAction->setChecked(false);
1301  changePassphraseAction->setEnabled(false);
1302  unlockWalletAction->setVisible(false);
1303  lockWalletAction->setVisible(false);
1304  encryptWalletAction->setEnabled(true);
1305  break;
1306  case WalletModel::Unlocked:
1307  labelEncryptionIcon->show();
1308  labelEncryptionIcon->setPixmap(QIcon(":/icons/" + theme + "/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1309  labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
1310  encryptWalletAction->setChecked(true);
1311  changePassphraseAction->setEnabled(true);
1312  unlockWalletAction->setVisible(false);
1313  lockWalletAction->setVisible(true);
1314  encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1315  break;
1317  labelEncryptionIcon->show();
1318  labelEncryptionIcon->setPixmap(QIcon(":/icons/" + theme + "/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1319  labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b> for mixing only"));
1320  encryptWalletAction->setChecked(true);
1321  changePassphraseAction->setEnabled(true);
1322  unlockWalletAction->setVisible(true);
1323  lockWalletAction->setVisible(true);
1324  encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1325  break;
1326  case WalletModel::Locked:
1327  labelEncryptionIcon->show();
1328  labelEncryptionIcon->setPixmap(QIcon(":/icons/" + theme + "/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
1329  labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
1330  encryptWalletAction->setChecked(true);
1331  changePassphraseAction->setEnabled(true);
1332  unlockWalletAction->setVisible(true);
1333  lockWalletAction->setVisible(false);
1334  encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
1335  break;
1336  }
1337 }
1338 #endif // ENABLE_WALLET
1339 
1340 void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
1341 {
1342  if(!clientModel)
1343  return;
1344 
1345  // activateWindow() (sometimes) helps with keyboard focus on Windows
1346  if (isHidden())
1347  {
1348  show();
1349  activateWindow();
1350  }
1351  else if (isMinimized())
1352  {
1353  showNormal();
1354  activateWindow();
1355  }
1356  else if (GUIUtil::isObscured(this))
1357  {
1358  raise();
1359  activateWindow();
1360  }
1361  else if(fToggleHidden)
1362  hide();
1363 }
1364 
1366 {
1367  showNormalIfMinimized(true);
1368 }
1369 
1371 {
1372  if (ShutdownRequested())
1373  {
1374  if(rpcConsole)
1375  rpcConsole->hide();
1376  qApp->quit();
1377  }
1378 }
1379 
1380 void BitcoinGUI::showProgress(const QString &title, int nProgress)
1381 {
1382  if (nProgress == 0)
1383  {
1384  progressDialog = new QProgressDialog(title, "", 0, 100);
1385  progressDialog->setWindowModality(Qt::ApplicationModal);
1386  progressDialog->setMinimumDuration(0);
1387  progressDialog->setCancelButton(0);
1388  progressDialog->setAutoClose(false);
1389  progressDialog->setValue(0);
1390  }
1391  else if (nProgress == 100)
1392  {
1393  if (progressDialog)
1394  {
1395  progressDialog->close();
1396  progressDialog->deleteLater();
1397  }
1398  }
1399  else if (progressDialog)
1400  progressDialog->setValue(nProgress);
1401 }
1402 
1403 void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
1404 {
1405  if (trayIcon)
1406  {
1407  trayIcon->setVisible(!fHideTrayIcon);
1408  }
1409 }
1410 
1412 {
1413  if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
1415 }
1416 
1417 static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
1418 {
1419  bool modal = (style & CClientUIInterface::MODAL);
1420  // The SECURE flag has no effect in the Qt GUI.
1421  // bool secure = (style & CClientUIInterface::SECURE);
1422  style &= ~CClientUIInterface::SECURE;
1423  bool ret = false;
1424  // In case of modal message, use blocking connection to wait for user to click a button
1425  QMetaObject::invokeMethod(gui, "message",
1426  modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
1427  Q_ARG(QString, QString::fromStdString(caption)),
1428  Q_ARG(QString, QString::fromStdString(message)),
1429  Q_ARG(unsigned int, style),
1430  Q_ARG(bool*, &ret));
1431  return ret;
1432 }
1433 
1435 {
1436  // Connect signals to client
1437  uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1438  uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1439 }
1440 
1442 {
1443  // Disconnect signals from client
1444  uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
1445  uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
1446 }
1447 
1449 {
1450  if (clientModel) {
1452  }
1453 }
1454 
1456 void BitcoinGUI::handleRestart(QStringList args)
1457 {
1458  if (!ShutdownRequested())
1459  Q_EMIT requestedRestart(args);
1460 }
1461 
1463  optionsModel(0),
1464  menu(0)
1465 {
1467  setToolTip(tr("Unit to show amounts in. Click to select another unit."));
1468  QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
1469  int max_width = 0;
1470  const QFontMetrics fm(font());
1471  Q_FOREACH (const BitcoinUnits::Unit unit, units)
1472  {
1473  max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
1474  }
1475  setMinimumSize(max_width, 0);
1476  setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1477  setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
1478 }
1479 
1482 {
1483  onDisplayUnitsClicked(event->pos());
1484 }
1485 
1488 {
1489  menu = new QMenu(this);
1491  {
1492  QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this);
1493  menuAction->setData(QVariant(u));
1494  menu->addAction(menuAction);
1495  }
1496  connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*)));
1497 }
1498 
1501 {
1502  if (optionsModel)
1503  {
1504  this->optionsModel = optionsModel;
1505 
1506  // be aware of a display unit change reported by the OptionsModel object.
1507  connect(optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
1508 
1509  // initialize the display units label with the current value in the model.
1511  }
1512 }
1513 
1516 {
1517  setText(BitcoinUnits::name(newUnits));
1518 }
1519 
1522 {
1523  QPoint globalPos = mapToGlobal(point);
1524  menu->exec(globalPos);
1525 }
1526 
1529 {
1530  if (action)
1531  {
1532  optionsModel->setDisplayUnit(action->data());
1533  }
1534 }
const QIcon & getTrayAndWindowIcon() const
Definition: networkstyle.h:23
RPCConsole * rpcConsole
Definition: bitcoingui.h:134
QString loadStyleSheet()
Definition: guiutil.cpp:914
bool getHideTrayIcon()
Definition: optionsmodel.h:70
QAction * sendCoinsMenuAction
Definition: bitcoingui.h:102
bool enableWallet
Definition: bitcoingui.h:73
void gotoMasternodePage()
QLabel * labelConnectionsIcon
Definition: bitcoingui.h:90
CMasternodeSync masternodeSync
QSystemTrayIcon * trayIcon
Definition: bitcoingui.h:130
QAction * aboutQtAction
Definition: bitcoingui.h:117
QAction * verifyMessageAction
Definition: bitcoingui.h:106
QLabel * labelEncryptionIcon
Definition: bitcoingui.h:88
void showEvent(QShowEvent *event)
QAction * usedSendingAddressesAction
Definition: bitcoingui.h:103
void hideForever()
bool isObscured(QWidget *w)
Definition: guiutil.cpp:405
void createActions()
Definition: bitcoingui.cpp:283
void setAdditionalDataSyncProgress(double nSyncProgress)
void setKnownBestHeight(int count, const QDateTime &blockDate)
bool setCurrentWallet(const QString &name)
Definition: walletframe.cpp:65
bool ShutdownRequested()
Definition: init.cpp:168
void gotoOverviewPage()
void optionsClicked()
Definition: bitcoingui.cpp:768
void requestedRestart(QStringList args)
void setClientModel(ClientModel *clientModel)
Definition: walletframe.cpp:36
void setTabFocus(enum TabTypes tabType)
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:55
OptionsModel * optionsModel
Definition: bitcoingui.h:299
enum BlockSource getBlockSource() const
Returns enum BlockSource of the current importing/syncing state.
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string &message, const std::string &caption, unsigned int style)
ClientModel * clientModel
Definition: bitcoingui.h:84
void showHelpMessageClicked()
Definition: bitcoingui.cpp:840
QAction * openAction
Definition: bitcoingui.h:126
static constexpr int HEADER_HEIGHT_DELTA_SYNC
The required delta of headers to the estimated number of available headers until we show the IBD prog...
Definition: modaloverlay.h:12
void unsubscribeFromCoreSignals()
int64_t getHeaderTipTime() const
void createIconMenu(QMenu *pmenu)
Definition: bitcoingui.cpp:730
void createToolBars()
Definition: bitcoingui.cpp:552
void createTrayIcon(const NetworkStyle *networkStyle)
Definition: bitcoingui.cpp:720
void createMenuBar()
Definition: bitcoingui.cpp:494
void saveWindowGeometry(const QString &strSetting, QWidget *parent)
Definition: guiutil.cpp:875
QAction * openPeersAction
Definition: bitcoingui.h:121
void detectShutdown()
QIcon SingleColorIcon(const QString &filename) const
void handleRestart(QStringList args)
void openMNConfigfile()
Definition: guiutil.cpp:432
void message(const QString &title, const QString &message, unsigned int style, bool *ret=NULL)
QMenuBar * appMenuBar
Definition: bitcoingui.h:96
void aboutClicked()
Definition: bitcoingui.cpp:778
QProgressDialog * progressDialog
Definition: bitcoingui.h:94
void notify(Class cls, const QString &title, const QString &text, const QIcon &icon=QIcon(), int millisTimeout=10000)
int getNumBlocks() const
Definition: clientmodel.cpp:94
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: walletframe.cpp:94
void showConsole()
Definition: bitcoingui.cpp:801
void toggleVisibility()
bool eventFilter(QObject *object, QEvent *event)
ModalOverlay * modalOverlay
Definition: bitcoingui.h:136
QAction * openRepairAction
Definition: bitcoingui.h:122
Qt::ConnectionType blockingGUIThreadConnection()
Definition: guiutil.cpp:386
void setNetworkActive(bool active)
Toggle network activity state in core.
void setNetworkActive(bool networkActive)
Definition: bitcoingui.cpp:937
void gotoVerifyMessageTab(QString addr="")
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
UnitDisplayStatusBarControl(const PlatformStyle *platformStyle)
void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize, QWidget *parent)
Definition: guiutil.cpp:882
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Definition: ui_interface.h:77
void changeEvent(QEvent *e)
void toggleHidden()
QAction * historyAction
Definition: bitcoingui.h:98
dictionary settings
void openConfigfile()
Definition: guiutil.cpp:423
QAction * unlockWalletAction
Definition: bitcoingui.h:115
void setClientModel(ClientModel *clientModel)
Definition: bitcoingui.cpp:584
static const QString DEFAULT_WALLET
Definition: bitcoingui.h:53
void setClientModel(ClientModel *model)
Definition: rpcconsole.cpp:368
boost::signals2::signal< bool(const std::string &message, const std::string &noninteractive_message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeQuestion
Definition: ui_interface.h:80
QAction * openRPCConsoleAction
Definition: bitcoingui.h:119
void setTrayIconVisible(bool)
int64_t CAmount
Definition: amount.h:14
void showConfEditor()
Definition: bitcoingui.cpp:825
QLabel * labelWalletHDStatusIcon
Definition: bitcoingui.h:89
void removeAllWallets()
Definition: walletframe.cpp:86
bool addWallet(const QString &name, WalletModel *walletModel)
Definition: walletframe.cpp:41
void mousePressEvent(QMouseEvent *event)
const PlatformStyle * platformStyle
Definition: bitcoingui.h:142
static MacDockIconHandler * instance()
QColor SingleColor() const
Definition: platformstyle.h:25
bool getMinimizeToTray()
Definition: optionsmodel.h:71
bool GetBoolArg(const std::string &strArg, bool fDefault)
Definition: util.cpp:455
QAction * toggleHideAction
Definition: bitcoingui.h:111
BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent=0)
Definition: bitcoingui.cpp:78
bool getMinimizeOnClose()
Definition: optionsmodel.h:72
void showBackups()
Definition: bitcoingui.cpp:835
void updateNetworkState()
Definition: bitcoingui.cpp:908
const QString & getTitleAddText() const
Definition: networkstyle.h:24
void setDisplayUnit(const QVariant &value)
void showPrivateSendHelpClicked()
Definition: bitcoingui.cpp:845
QAction * backupWalletAction
Definition: bitcoingui.h:113
std::string GetSyncStatus()
void setNumBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, bool headers)
Definition: bitcoingui.cpp:951
QAction * lockWalletAction
Definition: bitcoingui.h:116
void updateDisplayUnit(int newUnits)
void setIcon(const QIcon &icon)
const char * name
Definition: rest.cpp:37
QAction * showBackupsAction
Definition: bitcoingui.h:125
BlockSource
Definition: clientmodel.h:27
QLabel * progressBarLabel
Definition: bitcoingui.h:92
QAction * changePassphraseAction
Definition: bitcoingui.h:114
ClickableProgressBar ProgressBar
Definition: guiutil.h:260
void trayIconActivated(QSystemTrayIcon::ActivationReason reason)
Definition: bitcoingui.cpp:758
void showNormalIfMinimized(bool fToggleHidden=false)
CClientUIInterface uiInterface
Definition: init.cpp:130
QAction * optionsAction
Definition: bitcoingui.h:110
void showHide(bool hide=false, bool userRequested=false)
QAction * usedReceivingAddressesAction
Definition: bitcoingui.h:104
int64_t nPowTargetSpacing
Definition: params.h:80
void gotoSendCoinsPage(QString addr="")
void setWalletActionsEnabled(bool enabled)
Definition: bitcoingui.cpp:698
void closeEvent(QCloseEvent *event)
void setNumConnections(int count)
Definition: bitcoingui.cpp:932
QAction * encryptWalletAction
Definition: bitcoingui.h:112
int getHeaderTipHeight() const
void gotoSignMessageTab(QString addr="")
QProgressBar * progressBar
Definition: bitcoingui.h:93
UnitDisplayStatusBarControl * unitDisplayControl
Definition: bitcoingui.h:87
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:1028
void setMainWindow(QMainWindow *window)
static const int STATUSBAR_ICONSIZE
Definition: guiconstants.h:16
void updateHeadersSyncProgressLabel()
Definition: bitcoingui.cpp:942
void showPeers()
Definition: bitcoingui.cpp:813
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:54
void showOutOfSyncWarning(bool fShow)
void toggleNetworkActive()
QAction * signMessageAction
Definition: bitcoingui.h:105
void showGraph()
Definition: bitcoingui.cpp:807
QAction * openMNConfEditorAction
Definition: bitcoingui.h:124
void setOptionsModel(OptionsModel *optionsModel)
bool getNetworkActive() const
Return true if network activity in core is enabled.
QAction * showHelpMessageAction
Definition: bitcoingui.h:127
void showDebugWindow()
Definition: bitcoingui.cpp:787
int spinnerFrame
Definition: bitcoingui.h:140
void showInfo()
Definition: bitcoingui.cpp:795
void showModalOverlay()
const CChainParams & Params()
void showMNConfEditor()
Definition: bitcoingui.cpp:830
QString getThemeName()
Definition: guiutil.cpp:902
void dropEvent(QDropEvent *event)
QMenu * trayIconMenu
Definition: bitcoingui.h:131
void onDisplayUnitsClicked(const QPoint &point)
bool IsBlockchainSynced()
WalletFrame * walletFrame
Definition: bitcoingui.h:85
QAction * aboutAction
Definition: bitcoingui.h:107
QLabel * labelBlocksIcon
Definition: bitcoingui.h:91
static int count
Definition: tests.c:41
void receivedURI(const QString &uri)
void onMenuSelection(QAction *action)
QAction * masternodeAction
Definition: bitcoingui.h:99
static QString name(int unit)
Short name.
void dragEnterEvent(QDragEnterEvent *event)
void subscribeToCoreSignals()
bool isLayerVisible()
Definition: modaloverlay.h:36
void showBackups()
Definition: guiutil.cpp:441
QAction * showPrivateSendHelpAction
Definition: bitcoingui.h:128
double getVerificationProgress(const CBlockIndex *tip) const
int getDisplayUnit()
Definition: optionsmodel.h:73
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Definition: util.cpp:441
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
QAction * openInfoAction
Definition: bitcoingui.h:118
QAction * receiveCoinsMenuAction
Definition: bitcoingui.h:109
void showRepair()
Definition: bitcoingui.cpp:819
QAction * quitAction
Definition: bitcoingui.h:100
void gotoReceiveCoinsPage()
QAction * receiveCoinsAction
Definition: bitcoingui.h:108
int prevBlocks
Definition: bitcoingui.h:139
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
QAction * openGraphAction
Definition: bitcoingui.h:120
Notificator * notificator
Definition: bitcoingui.h:133
void tipUpdate(int count, const QDateTime &blockDate, double nVerificationProgress)
HelpMessageDialog * helpMessageDialog
Definition: bitcoingui.h:135
void showProgress(const QString &title, int nProgress)
void setModel(OptionsModel *model)
QAction * overviewAction
Definition: bitcoingui.h:97
QAction * openConfEditorAction
Definition: bitcoingui.h:123
QDateTime getLastBlockDate() const
void gotoHistoryPage()
OptionsModel * getOptionsModel()
QAction * sendCoinsAction
Definition: bitcoingui.h:101
UniValue help(const UniValue &params, bool fHelp)
Definition: server.cpp:220
QMenu * dockIconMenu
Definition: bitcoingui.h:132
const QIcon & getAppIcon() const
Definition: networkstyle.h:21
#define SPINNER_FRAMES
Definition: guiconstants.h:50
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:66