Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bitcoingui.cpp
Go to the documentation of this file.
1 /*
2  * Qt4 bitcoin GUI.
3  *
4  * W.J. van der Laan 2011-2012
5  * The Bitcoin Developers 2011-2012
6  */
7 
8 #include <QApplication>
9 
10 #include "bitcoingui.h"
11 
12 #include "transactiontablemodel.h"
13 #include "optionsdialog.h"
14 #include "aboutdialog.h"
15 #include "clientmodel.h"
16 #include "walletmodel.h"
17 #include "walletframe.h"
18 #include "optionsmodel.h"
19 #include "transactiondescdialog.h"
20 #include "bitcoinunits.h"
21 #include "guiconstants.h"
22 #include "notificator.h"
23 #include "guiutil.h"
24 #include "rpcconsole.h"
25 #include "ui_interface.h"
26 #include "wallet.h"
27 #include "init.h"
28 
29 #ifdef Q_OS_MAC
30 #include "macdockiconhandler.h"
31 #endif
32 
33 #include <QMenuBar>
34 #include <QMenu>
35 #include <QIcon>
36 #include <QVBoxLayout>
37 #include <QToolBar>
38 #include <QStatusBar>
39 #include <QLabel>
40 #include <QMessageBox>
41 #include <QProgressBar>
42 #include <QStackedWidget>
43 #include <QDateTime>
44 #include <QMovie>
45 #include <QTimer>
46 #include <QDragEnterEvent>
47 #if QT_VERSION < 0x050000
48 #include <QUrl>
49 #endif
50 #include <QMimeData>
51 #include <QStyle>
52 #include <QSettings>
53 #include <QDesktopWidget>
54 #include <QListWidget>
55 
56 #include <iostream>
57 
58 const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
59 
60 BitcoinGUI::BitcoinGUI(QWidget *parent) :
61  QMainWindow(parent),
62  clientModel(0),
63  encryptWalletAction(0),
64  changePassphraseAction(0),
65  aboutQtAction(0),
66  trayIcon(0),
67  notificator(0),
68  rpcConsole(0),
69  prevBlocks(0)
70 {
72  setWindowTitle(tr("Feathercoin") + " - " + tr("Wallet"));
73 #ifndef Q_OS_MAC
74  QApplication::setWindowIcon(QIcon(":icons/bitcoin"));
75  setWindowIcon(QIcon(":icons/bitcoin"));
76 #else
77  setUnifiedTitleAndToolBarOnMac(true);
78  QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
79 #endif
80  // Create wallet frame and make it the central widget
81  walletFrame = new WalletFrame(this);
82  setCentralWidget(walletFrame);
83 
84  // Accept D&D of URIs
85  setAcceptDrops(true);
86 
87  // Create actions for the toolbar, menu bar and tray/dock icon
88  // Needs walletFrame to be initialized
89  createActions();
90 
91  // Create application menu bar
92  createMenuBar();
93 
94  // Create the toolbars
96 
97  // Create system tray icon and notification
99 
100  // Create status bar
101  statusBar();
102 
103  // Status bar notification icons
104  QFrame *frameBlocks = new QFrame();
105  frameBlocks->setContentsMargins(0,0,0,0);
106  frameBlocks->setMinimumWidth(56);
107  frameBlocks->setMaximumWidth(56);
108  QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
109  frameBlocksLayout->setContentsMargins(3,0,3,0);
110  frameBlocksLayout->setSpacing(3);
111  labelEncryptionIcon = new QLabel();
112  labelConnectionsIcon = new QLabel();
113  labelBlocksIcon = new QLabel();
114  frameBlocksLayout->addStretch();
115  frameBlocksLayout->addWidget(labelEncryptionIcon);
116  frameBlocksLayout->addStretch();
117  frameBlocksLayout->addWidget(labelConnectionsIcon);
118  frameBlocksLayout->addStretch();
119  frameBlocksLayout->addWidget(labelBlocksIcon);
120  frameBlocksLayout->addStretch();
121 
122  // Progress bar and label for blocks download
123  progressBarLabel = new QLabel();
124  progressBarLabel->setVisible(false);
125  progressBar = new QProgressBar();
126  progressBar->setAlignment(Qt::AlignCenter);
127  progressBar->setVisible(false);
128 
129  // Override style sheet for progress bar for styles that have a segmented progress bar,
130  // as they make the text unreadable (workaround for issue #1071)
131  // See https://qt-project.org/doc/qt-4.8/gallery.html
132  QString curStyle = QApplication::style()->metaObject()->className();
133  if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
134  {
135  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; }");
136  }
137 
138  statusBar()->addWidget(progressBarLabel);
139  statusBar()->addWidget(progressBar);
140  statusBar()->addPermanentWidget(frameBlocks);
141 
142  syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
143 
144  rpcConsole = new RPCConsole(this);
145  connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
146 
147  // Install event filter to be able to catch status tip events (QEvent::StatusTip)
148  this->installEventFilter(this);
149 
150  // Initially wallet actions should be disabled
152 }
153 
155 {
157  if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
158  trayIcon->hide();
159 #ifdef Q_OS_MAC
160  delete appMenuBar;
162 #endif
163 }
164 
166 {
167  QActionGroup *tabGroup = new QActionGroup(this);
168 
169  overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this);
170  overviewAction->setStatusTip(tr("Show general overview of wallet"));
171  overviewAction->setToolTip(overviewAction->statusTip());
172  overviewAction->setCheckable(true);
173  overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
174  tabGroup->addAction(overviewAction);
175 
176  sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send"), this);
177  sendCoinsAction->setStatusTip(tr("Send coins to a Feathercoin address"));
178  sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
179  sendCoinsAction->setCheckable(true);
180  sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
181  tabGroup->addAction(sendCoinsAction);
182 
183  receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
184  receiveCoinsAction->setStatusTip(tr("Show the list of addresses for receiving payments"));
185  receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
186  receiveCoinsAction->setCheckable(true);
187  receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
188  tabGroup->addAction(receiveCoinsAction);
189 
190  historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this);
191  historyAction->setStatusTip(tr("Browse transaction history"));
192  historyAction->setToolTip(historyAction->statusTip());
193  historyAction->setCheckable(true);
194  historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
195  tabGroup->addAction(historyAction);
196 
197  addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Addresses"), this);
198  addressBookAction->setStatusTip(tr("Edit the list of stored addresses and labels"));
199  addressBookAction->setToolTip(addressBookAction->statusTip());
200  addressBookAction->setCheckable(true);
201  addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
202  tabGroup->addAction(addressBookAction);
203 
204  connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
205  connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
206  connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
207  connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
208  connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
209  connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
210  connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
211  connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
212  connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
213  connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
214 
215  quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
216  quitAction->setStatusTip(tr("Quit application"));
217  quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
218  quitAction->setMenuRole(QAction::QuitRole);
219  aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About Feathercoin"), this);
220  aboutAction->setStatusTip(tr("Show information about Feathercoin"));
221  aboutAction->setMenuRole(QAction::AboutRole);
222  aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this);
223  aboutQtAction->setStatusTip(tr("Show information about Qt"));
224  aboutQtAction->setMenuRole(QAction::AboutQtRole);
225  optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
226  optionsAction->setStatusTip(tr("Modify configuration options for Feathercoin"));
227  optionsAction->setMenuRole(QAction::PreferencesRole);
228  toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this);
229  toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
230 
231  encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
232  encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
233  encryptWalletAction->setCheckable(true);
234  backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
235  backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
236  changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
237  changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
238  signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
239  signMessageAction->setStatusTip(tr("Sign messages with your Feathercoin addresses to prove you own them"));
240  verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
241  verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Feathercoin addresses"));
242 
243  openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this);
244  openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
245 
246  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
247  connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
248  connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
249  connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
250  connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
251  connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
252  connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
253  connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
254  connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
255  connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
256 }
257 
259 {
260 #ifdef Q_OS_MAC
261  // Create a decoupled menu bar on Mac which stays even if the window is closed
262  appMenuBar = new QMenuBar();
263 #else
264  // Get the main window's menu bar on other platforms
265  appMenuBar = menuBar();
266 #endif
267 
268  // Configure the menus
269  QMenu *file = appMenuBar->addMenu(tr("&File"));
270  file->addAction(backupWalletAction);
271  file->addAction(signMessageAction);
272  file->addAction(verifyMessageAction);
273  file->addSeparator();
274  file->addAction(quitAction);
275 
276  QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
277  settings->addAction(encryptWalletAction);
278  settings->addAction(changePassphraseAction);
279  settings->addSeparator();
280  settings->addAction(optionsAction);
281 
282  QMenu *help = appMenuBar->addMenu(tr("&Help"));
283  help->addAction(openRPCConsoleAction);
284  help->addSeparator();
285  help->addAction(aboutAction);
286  help->addAction(aboutQtAction);
287 }
288 
290 {
291  QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
292  toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
293  toolbar->addAction(overviewAction);
294  toolbar->addAction(sendCoinsAction);
295  toolbar->addAction(receiveCoinsAction);
296  toolbar->addAction(historyAction);
297  toolbar->addAction(addressBookAction);
298 }
299 
301 {
302  this->clientModel = clientModel;
303  if(clientModel)
304  {
305  // Replace some strings and icons, when using the testnet
306  if(clientModel->isTestNet())
307  {
308  setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]"));
309 #ifndef Q_OS_MAC
310  QApplication::setWindowIcon(QIcon(":icons/bitcoin_testnet"));
311  setWindowIcon(QIcon(":icons/bitcoin_testnet"));
312 #else
313  MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet"));
314 #endif
315  if(trayIcon)
316  {
317  // Just attach " [testnet]" to the existing tooltip
318  trayIcon->setToolTip(trayIcon->toolTip() + QString(" ") + tr("[testnet]"));
319  trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
320  }
321 
322  toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet"));
323  aboutAction->setIcon(QIcon(":/icons/toolbar_testnet"));
324  }
325 
326  // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
327  // while the client has not yet fully loaded
329 
330  // Keep up to date with client
331  setNumConnections(clientModel->getNumConnections());
332  connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
333 
334  setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers());
335  connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));
336 
337  // Receive and report messages from network/worker thread
338  connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
339 
340  rpcConsole->setClientModel(clientModel);
341  walletFrame->setClientModel(clientModel);
342  }
343 }
344 
345 bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
346 {
348  return walletFrame->addWallet(name, walletModel);
349 }
350 
351 bool BitcoinGUI::setCurrentWallet(const QString& name)
352 {
353  return walletFrame->setCurrentWallet(name);
354 }
355 
357 {
360 }
361 
363 {
364  overviewAction->setEnabled(enabled);
365  sendCoinsAction->setEnabled(enabled);
366  receiveCoinsAction->setEnabled(enabled);
367  historyAction->setEnabled(enabled);
368  encryptWalletAction->setEnabled(enabled);
369  backupWalletAction->setEnabled(enabled);
370  changePassphraseAction->setEnabled(enabled);
371  signMessageAction->setEnabled(enabled);
372  verifyMessageAction->setEnabled(enabled);
373  addressBookAction->setEnabled(enabled);
374 }
375 
377 {
378 #ifndef Q_OS_MAC
379  trayIcon = new QSystemTrayIcon(this);
380 
381  trayIcon->setToolTip(tr("Feathercoin client"));
382  trayIcon->setIcon(QIcon(":/icons/toolbar"));
383  trayIcon->show();
384 #endif
385 
386  notificator = new Notificator(QApplication::applicationName(), trayIcon);
387 }
388 
390 {
391  QMenu *trayIconMenu;
392 #ifndef Q_OS_MAC
393  // return if trayIcon is unset (only on non-Mac OSes)
394  if (!trayIcon)
395  return;
396 
397  trayIconMenu = new QMenu(this);
398  trayIcon->setContextMenu(trayIconMenu);
399 
400  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
401  this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
402 #else
403  // Note: On Mac, the dock icon is used to provide the tray's functionality.
405  dockIconHandler->setMainWindow((QMainWindow *)this);
406  trayIconMenu = dockIconHandler->dockMenu();
407 #endif
408 
409  // Configuration of the tray icon (or dock icon) icon menu
410  trayIconMenu->addAction(toggleHideAction);
411  trayIconMenu->addSeparator();
412  trayIconMenu->addAction(sendCoinsAction);
413  trayIconMenu->addAction(receiveCoinsAction);
414  trayIconMenu->addSeparator();
415  trayIconMenu->addAction(signMessageAction);
416  trayIconMenu->addAction(verifyMessageAction);
417  trayIconMenu->addSeparator();
418  trayIconMenu->addAction(optionsAction);
419  trayIconMenu->addAction(openRPCConsoleAction);
420 #ifndef Q_OS_MAC // This is built-in on Mac
421  trayIconMenu->addSeparator();
422  trayIconMenu->addAction(quitAction);
423 #endif
424 }
425 
426 #ifndef Q_OS_MAC
427 void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
428 {
429  if(reason == QSystemTrayIcon::Trigger)
430  {
431  // Click on system tray icon triggers show/hide of the main window
432  toggleHideAction->trigger();
433  }
434 }
435 #endif
436 
438 {
439  QSettings settings;
440  settings.setValue("nWindowPos", pos());
441  settings.setValue("nWindowSize", size());
442 }
443 
445 {
446  QSettings settings;
447  QPoint pos = settings.value("nWindowPos").toPoint();
448  QSize size = settings.value("nWindowSize", QSize(850, 550)).toSize();
449  if (!pos.x() && !pos.y())
450  {
451  QRect screen = QApplication::desktop()->screenGeometry();
452  pos.setX((screen.width()-size.width())/2);
453  pos.setY((screen.height()-size.height())/2);
454  }
455  resize(size);
456  move(pos);
457 }
458 
460 {
462  return;
463  OptionsDialog dlg;
465  dlg.exec();
466 }
467 
469 {
470  AboutDialog dlg;
471  dlg.setModel(clientModel);
472  dlg.exec();
473 }
474 
476 {
478 }
479 
481 {
483 }
484 
486 {
488 }
489 
491 {
493 }
494 
496 {
498 }
499 
501 {
503 }
504 
506 {
508 }
509 
511 {
512  QString icon;
513  switch(count)
514  {
515  case 0: icon = ":/icons/connect_0"; break;
516  case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
517  case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
518  case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
519  default: icon = ":/icons/connect_4"; break;
520  }
521  labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
522  labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Feathercoin network", "", count));
523 }
524 
525 void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
526 {
527  // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text)
528  statusBar()->clearMessage();
529 
530  // Acquire current block source
531  enum BlockSource blockSource = clientModel->getBlockSource();
532  switch (blockSource) {
534  progressBarLabel->setText(tr("Synchronizing with network..."));
535  break;
536  case BLOCK_SOURCE_DISK:
537  progressBarLabel->setText(tr("Importing blocks from disk..."));
538  break;
540  progressBarLabel->setText(tr("Reindexing blocks on disk..."));
541  break;
542  case BLOCK_SOURCE_NONE:
543  // Case: not Importing, not Reindexing and no network connection
544  progressBarLabel->setText(tr("No block source available..."));
545  break;
546  }
547 
548  QString tooltip;
549 
550  QDateTime lastBlockDate = clientModel->getLastBlockDate();
551  QDateTime currentDate = QDateTime::currentDateTime();
552  int secs = lastBlockDate.secsTo(currentDate);
553 
554  if(count < nTotalBlocks)
555  {
556  tooltip = tr("Processed %1 of %2 (estimated) blocks of transaction history.").arg(count).arg(nTotalBlocks);
557  }
558  else
559  {
560  tooltip = tr("Processed %1 blocks of transaction history.").arg(count);
561  }
562 
563  // Set icon state: spinning if catching up, tick otherwise
564  if(secs < 90*60 && count >= nTotalBlocks)
565  {
566  tooltip = tr("Up to date") + QString(".<br>") + tooltip;
567  labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
568 
570 
571  progressBarLabel->setVisible(false);
572  progressBar->setVisible(false);
573  }
574  else
575  {
576  // Represent time from last generated block in human readable text
577  QString timeBehindText;
578  if(secs < 48*60*60)
579  {
580  timeBehindText = tr("%n hour(s)","",secs/(60*60));
581  }
582  else if(secs < 14*24*60*60)
583  {
584  timeBehindText = tr("%n day(s)","",secs/(24*60*60));
585  }
586  else
587  {
588  timeBehindText = tr("%n week(s)","",secs/(7*24*60*60));
589  }
590 
591  progressBarLabel->setVisible(true);
592  progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
593  progressBar->setMaximum(1000000000);
594  progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5);
595  progressBar->setVisible(true);
596 
597  tooltip = tr("Catching up...") + QString("<br>") + tooltip;
598  labelBlocksIcon->setMovie(syncIconMovie);
599  if(count != prevBlocks)
600  syncIconMovie->jumpToNextFrame();
601  prevBlocks = count;
602 
604 
605  tooltip += QString("<br>");
606  tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
607  tooltip += QString("<br>");
608  tooltip += tr("Transactions after this will not yet be visible.");
609  }
610 
611  // Don't word-wrap this (fixed-width) tooltip
612  tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
613 
614  labelBlocksIcon->setToolTip(tooltip);
615  progressBarLabel->setToolTip(tooltip);
616  progressBar->setToolTip(tooltip);
617 }
618 
619 void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
620 {
621  QString strTitle = tr("Feathercoin"); // default title
622  // Default to information icon
623  int nMBoxIcon = QMessageBox::Information;
624  int nNotifyIcon = Notificator::Information;
625 
626  // Override title based on style
627  QString msgType;
628  switch (style) {
630  msgType = tr("Error");
631  break;
633  msgType = tr("Warning");
634  break;
636  msgType = tr("Information");
637  break;
638  default:
639  msgType = title; // Use supplied title
640  }
641  if (!msgType.isEmpty())
642  strTitle += " - " + msgType;
643 
644  // Check for error/warning icon
645  if (style & CClientUIInterface::ICON_ERROR) {
646  nMBoxIcon = QMessageBox::Critical;
647  nNotifyIcon = Notificator::Critical;
648  }
649  else if (style & CClientUIInterface::ICON_WARNING) {
650  nMBoxIcon = QMessageBox::Warning;
651  nNotifyIcon = Notificator::Warning;
652  }
653 
654  // Display message
655  if (style & CClientUIInterface::MODAL) {
656  // Check for buttons, use OK as default, if none was supplied
657  QMessageBox::StandardButton buttons;
658  if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
659  buttons = QMessageBox::Ok;
660 
661  QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons);
662  int r = mBox.exec();
663  if (ret != NULL)
664  *ret = r == QMessageBox::Ok;
665  }
666  else
667  notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
668 }
669 
670 void BitcoinGUI::changeEvent(QEvent *e)
671 {
672  QMainWindow::changeEvent(e);
673 #ifndef Q_OS_MAC // Ignored on Mac
674  if(e->type() == QEvent::WindowStateChange)
675  {
677  {
678  QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
679  if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
680  {
681  QTimer::singleShot(0, this, SLOT(hide()));
682  e->ignore();
683  }
684  }
685  }
686 #endif
687 }
688 
689 void BitcoinGUI::closeEvent(QCloseEvent *event)
690 {
691  if(clientModel)
692  {
693 #ifndef Q_OS_MAC // Ignored on Mac
696  {
697  QApplication::quit();
698  }
699 #endif
700  }
701  QMainWindow::closeEvent(event);
702 }
703 
704 void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
705 {
706  QString strMessage = tr("This transaction is over the size limit. You can still send it for a fee of %1, "
707  "which goes to the nodes that process your transaction and helps to support the network. "
708  "Do you want to pay the fee?").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired));
709  QMessageBox::StandardButton retval = QMessageBox::question(
710  this, tr("Confirm transaction fee"), strMessage,
711  QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
712  *payFee = (retval == QMessageBox::Yes);
713 }
714 
715 void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address)
716 {
717  // On new transaction, make an info balloon
718  message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
719  tr("Date: %1\n"
720  "Amount: %2\n"
721  "Type: %3\n"
722  "Address: %4\n")
723  .arg(date)
724  .arg(BitcoinUnits::formatWithUnit(unit, amount, true))
725  .arg(type)
727 }
728 
729 void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
730 {
731  // Accept only URIs
732  if(event->mimeData()->hasUrls())
733  event->acceptProposedAction();
734 }
735 
736 void BitcoinGUI::dropEvent(QDropEvent *event)
737 {
738  if(event->mimeData()->hasUrls())
739  {
740  int nValidUrisFound = 0;
741  QList<QUrl> uris = event->mimeData()->urls();
742  foreach(const QUrl &uri, uris)
743  {
744  if (walletFrame->handleURI(uri.toString()))
745  nValidUrisFound++;
746  }
747 
748  // if valid URIs were found
749  if (nValidUrisFound)
751  else
752  message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Feathercoin address or malformed URI parameters."),
754  }
755 
756  event->acceptProposedAction();
757 }
758 
759 bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
760 {
761  // Catch status tip events
762  if (event->type() == QEvent::StatusTip)
763  {
764  // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
765  if (progressBarLabel->isVisible() || progressBar->isVisible())
766  return true;
767  }
768  return QMainWindow::eventFilter(object, event);
769 }
770 
771 void BitcoinGUI::handleURI(QString strURI)
772 {
773  // URI has to be valid
774  if (!walletFrame->handleURI(strURI))
775  message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Feathercoin address or malformed URI parameters."),
777 }
778 
780 {
781  switch(status)
782  {
784  labelEncryptionIcon->hide();
785  encryptWalletAction->setChecked(false);
786  changePassphraseAction->setEnabled(false);
787  encryptWalletAction->setEnabled(true);
788  break;
790  labelEncryptionIcon->show();
791  labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
792  labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
793  encryptWalletAction->setChecked(true);
794  changePassphraseAction->setEnabled(true);
795  encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
796  break;
797  case WalletModel::Locked:
798  labelEncryptionIcon->show();
799  labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
800  labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
801  encryptWalletAction->setChecked(true);
802  changePassphraseAction->setEnabled(true);
803  encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
804  break;
805  }
806 }
807 
808 void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
809 {
810  // activateWindow() (sometimes) helps with keyboard focus on Windows
811  if (isHidden())
812  {
813  show();
814  activateWindow();
815  }
816  else if (isMinimized())
817  {
818  showNormal();
819  activateWindow();
820  }
821  else if (GUIUtil::isObscured(this))
822  {
823  raise();
824  activateWindow();
825  }
826  else if(fToggleHidden)
827  hide();
828 }
829 
831 {
832  showNormalIfMinimized(true);
833 }
834 
836 {
837  if (ShutdownRequested())
838  QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
839 }
bool setCurrentWallet(const QString &name)
Definition: walletframe.cpp:49
bool getMinimizeOnClose()
Definition: optionsmodel.h:49
QAction * receiveCoinsAction
Definition: bitcoingui.h:97
Local Bitcoin RPC console.
Definition: rpcconsole.h:12
QMenuBar * appMenuBar
Definition: bitcoingui.h:88
static const QString DEFAULT_WALLET
Definition: bitcoingui.h:44
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
Definition: bitcoingui.cpp:495
QAction * signMessageAction
Definition: bitcoingui.h:94
bool handleURI(const QString &uri)
Definition: walletframe.cpp:61
QAction * aboutAction
Definition: bitcoingui.h:96
void showNormalIfMinimized(bool fToggleHidden=false)
Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHid...
Definition: bitcoingui.cpp:808
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false)
Format as string (with unit)
void handleURI(QString strURI)
Definition: bitcoingui.cpp:771
void createTrayIcon()
Create system tray icon and notification.
Definition: bitcoingui.cpp:376
Value help(const Array &params, bool fHelp)
Definition: bitcoinrpc.cpp:165
bool setCurrentWallet(const QString &name)
Definition: bitcoingui.cpp:351
bool ShutdownRequested()
Definition: init.cpp:86
ClientModel * clientModel
Definition: bitcoingui.h:79
void createToolBars()
Create the toolbars.
Definition: bitcoingui.cpp:289
void createTrayIconMenu()
Create system tray menu (or setup the dock menu)
Definition: bitcoingui.cpp:389
RPCConsole * rpcConsole
Definition: bitcoingui.h:109
QAction * overviewAction
Definition: bitcoingui.h:89
QAction * verifyMessageAction
Definition: bitcoingui.h:95
QAction * quitAction
Definition: bitcoingui.h:91
void dropEvent(QDropEvent *event)
Definition: bitcoingui.cpp:736
QAction * historyAction
Definition: bitcoingui.h:90
void setWalletActionsEnabled(bool enabled)
Enable or disable all wallet-related actions.
Definition: bitcoingui.cpp:362
void gotoAddressBookPage()
Switch to address book page.
Definition: walletframe.cpp:91
QAction * aboutQtAction
Definition: bitcoingui.h:103
OptionsModel * getOptionsModel()
Macintosh-specific dock icon handler.
Mask of all available buttons in CClientUIInterface::MessageBoxFlags This needs to be updated...
Definition: ui_interface.h:58
QLabel * progressBarLabel
Definition: bitcoingui.h:85
QSystemTrayIcon * trayIcon
Definition: bitcoingui.h:106
int getNumBlocksOfPeers() const
Return conservative estimate of total number of blocks, or 0 if unknown.
QMovie * syncIconMovie
Definition: bitcoingui.h:111
Notify user of potential problem.
Definition: notificator.h:30
void removeAllWallets()
Definition: walletframe.cpp:56
QAction * backupWalletAction
Definition: bitcoingui.h:101
QLabel * labelConnectionsIcon
Definition: bitcoingui.h:83
void saveWindowGeometry()
Save window size and position.
Definition: bitcoingui.cpp:437
Force blocking, modal message box dialog (not just OS notification)
Definition: ui_interface.h:62
void showOutOfSyncWarning(bool fShow)
Definition: walletframe.cpp:70
void setIcon(const QIcon &icon)
void setClientModel(ClientModel *model)
Definition: rpcconsole.cpp:252
void gotoHistoryPage()
Switch to history (transactions) page.
Definition: walletframe.cpp:86
void gotoOverviewPage()
Switch to overview (home) page.
Definition: bitcoingui.cpp:475
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: bitcoingui.cpp:300
int getNumConnections() const
Definition: clientmodel.cpp:37
void gotoOverviewPage()
Switch to overview (home) page.
Definition: walletframe.cpp:81
QAction * toggleHideAction
Definition: bitcoingui.h:99
double getVerificationProgress() const
Definition: clientmodel.cpp:63
static MacDockIconHandler * instance()
QAction * addressBookAction
Definition: bitcoingui.h:93
void setClientModel(ClientModel *clientModel)
Definition: walletframe.cpp:38
void setMainWindow(QMainWindow *window)
bool isObscured(QWidget *w)
Definition: guiutil.cpp:259
"About" dialog box
Definition: aboutdialog.h:12
void optionsClicked()
Show configuration dialog.
Definition: bitcoingui.cpp:459
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
void notify(Class cls, const QString &title, const QString &text, const QIcon &icon=QIcon(), int millisTimeout=10000)
Show notification message.
bool eventFilter(QObject *object, QEvent *event)
Definition: bitcoingui.cpp:759
QLabel * labelBlocksIcon
Definition: bitcoingui.h:84
bool addWallet(const QString &name, WalletModel *walletModel)
Definition: walletframe.cpp:44
QDateTime getLastBlockDate() const
Definition: clientmodel.cpp:53
BlockSource
Definition: clientmodel.h:16
WalletFrame * walletFrame
Definition: bitcoingui.h:80
void incomingTransaction(const QString &date, int unit, qint64 amount, const QString &type, const QString &address)
Show incoming transaction notification for new transactions.
Definition: bitcoingui.cpp:715
void setModel(OptionsModel *model)
QAction * openRPCConsoleAction
Definition: bitcoingui.h:104
void detectShutdown()
called by a timer to check if fRequestShutdown has been set
Definition: bitcoingui.cpp:835
Cross-platform desktop notification client.
Definition: notificator.h:15
bool addWallet(const QString &name, WalletModel *walletModel)
Set the wallet model.
Definition: bitcoingui.cpp:345
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
Definition: bitcoingui.cpp:500
void gotoReceiveCoinsPage()
Switch to receive coins page.
Definition: bitcoingui.cpp:490
Informational message.
Definition: notificator.h:29
BitcoinGUI(QWidget *parent=0)
Definition: bitcoingui.cpp:60
void dragEnterEvent(QDragEnterEvent *event)
Definition: bitcoingui.cpp:729
Notificator * notificator
Definition: bitcoingui.h:107
Model for Bitcoin network client.
Definition: clientmodel.h:24
An error occurred.
Definition: notificator.h:31
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
QAction * sendCoinsAction
Definition: bitcoingui.h:92
int getNumBlocks() const
Definition: clientmodel.cpp:42
void gotoAddressBookPage()
Switch to address book page.
Definition: bitcoingui.cpp:485
void trayIconActivated(QSystemTrayIcon::ActivationReason reason)
Handle tray icon clicked.
Definition: bitcoingui.cpp:427
QAction * changePassphraseAction
Definition: bitcoingui.h:102
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
void gotoReceiveCoinsPage()
Switch to receive coins page.
Definition: walletframe.cpp:98
void closeEvent(QCloseEvent *event)
Definition: bitcoingui.cpp:689
void setEncryptionStatus(int status)
Set the encryption status as shown in the UI.
Definition: bitcoingui.cpp:779
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:36
void changeEvent(QEvent *e)
Definition: bitcoingui.cpp:670
bool isTestNet() const
Return true if client connected to testnet.
int prevBlocks
Keep track of previous number of blocks, to detect progress.
Definition: bitcoingui.h:113
void toggleHidden()
Simply calls showNormalIfMinimized(true) for use in SLOT() macro.
Definition: bitcoingui.cpp:830
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Definition: bitcoingui.cpp:505
QProgressBar * progressBar
Definition: bitcoingui.h:86
void setNumConnections(int count)
Set number of connections shown in the UI.
Definition: bitcoingui.cpp:510
Preferences dialog.
Definition: optionsdialog.h:14
void createActions()
Create the main UI actions.
Definition: bitcoingui.cpp:165
QAction * optionsAction
Definition: bitcoingui.h:98
QAction * encryptWalletAction
Definition: bitcoingui.h:100
void aboutClicked()
Show about dialog.
Definition: bitcoingui.cpp:468
void message(const QString &title, const QString &message, unsigned int style, bool *ret=NULL)
Notify the user of an event from the core network or transaction handling code.
Definition: bitcoingui.cpp:619
void restoreWindowGeometry()
Restore window size and position.
Definition: bitcoingui.cpp:444
bool getMinimizeToTray()
Definition: optionsmodel.h:48
QLabel * labelEncryptionIcon
Definition: bitcoingui.h:82
void askFee(qint64 nFeeRequired, bool *payFee)
Asks the user whether to pay the transaction fee or to cancel the transaction.
Definition: bitcoingui.cpp:704
enum BlockSource getBlockSource() const
Return true if core is importing blocks.
void gotoHistoryPage()
Switch to history (transactions) page.
Definition: bitcoingui.cpp:480
void * arg
Definition: env_posix.cc:716
void createMenuBar()
Create the menu bar and sub-menus.
Definition: bitcoingui.cpp:258
void removeAllWallets()
Definition: bitcoingui.cpp:356
const char * name
Definition: testharness.cc:18
Predefined combinations for certain default usage cases.
Definition: ui_interface.h:65
void setModel(ClientModel *model)
Definition: aboutdialog.cpp:21
void setNumBlocks(int count, int nTotalBlocks)
Set number of blocks shown in the UI.
Definition: bitcoingui.cpp:525