95646b1df14281059d638decec8441e8b0060cb9
[novacoin.git] / src / qt / bitcoingui.cpp
1 /*
2  * Qt4 bitcoin GUI.
3  *
4  * W.J. van der Laan 2011
5  */
6 #include "bitcoingui.h"
7 #include "transactiontablemodel.h"
8 #include "addressbookpage.h"
9 #include "sendcoinsdialog.h"
10 #include "optionsdialog.h"
11 #include "aboutdialog.h"
12 #include "clientmodel.h"
13 #include "walletmodel.h"
14 #include "editaddressdialog.h"
15 #include "optionsmodel.h"
16 #include "transactiondescdialog.h"
17 #include "addresstablemodel.h"
18 #include "transactionview.h"
19 #include "overviewpage.h"
20 #include "bitcoinunits.h"
21 #include "guiconstants.h"
22 #include "askpassphrasedialog.h"
23 #include "notificator.h"
24
25 #include <QApplication>
26 #include <QMainWindow>
27 #include <QMenuBar>
28 #include <QMenu>
29 #include <QIcon>
30 #include <QTabWidget>
31 #include <QVBoxLayout>
32 #include <QToolBar>
33 #include <QStatusBar>
34 #include <QLabel>
35 #include <QLineEdit>
36 #include <QPushButton>
37 #include <QLocale>
38 #include <QMessageBox>
39 #include <QProgressBar>
40 #include <QStackedWidget>
41 #include <QDateTime>
42 #include <QMovie>
43
44 #include <QDragEnterEvent>
45 #include <QUrl>
46
47 #include <iostream>
48
49 BitcoinGUI::BitcoinGUI(QWidget *parent):
50     QMainWindow(parent),
51     clientModel(0),
52     walletModel(0),
53     encryptWalletAction(0),
54     changePassphraseAction(0),
55     trayIcon(0),
56     notificator(0)
57 {
58     resize(850, 550);
59     setWindowTitle(tr("Bitcoin Wallet"));
60     setWindowIcon(QIcon(":icons/bitcoin"));
61     // Accept D&D of URIs
62     setAcceptDrops(true);
63
64     createActions();
65
66     // Menus
67     QMenu *file = menuBar()->addMenu(tr("&File"));
68     file->addAction(sendCoinsAction);
69     file->addAction(receiveCoinsAction);
70     file->addSeparator();
71     file->addAction(quitAction);
72     
73     QMenu *settings = menuBar()->addMenu(tr("&Settings"));
74     settings->addAction(encryptWalletAction);
75     settings->addAction(changePassphraseAction);
76     settings->addSeparator();
77     settings->addAction(optionsAction);
78
79     QMenu *help = menuBar()->addMenu(tr("&Help"));
80     help->addAction(aboutAction);
81     
82     // Toolbars
83     QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
84     toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
85     toolbar->addAction(overviewAction);
86     toolbar->addAction(sendCoinsAction);
87     toolbar->addAction(receiveCoinsAction);
88     toolbar->addAction(historyAction);
89     toolbar->addAction(addressBookAction);
90
91     QToolBar *toolbar2 = addToolBar(tr("Actions toolbar"));
92     toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
93     toolbar2->addAction(exportAction);
94
95     // Create tabs
96     overviewPage = new OverviewPage();
97
98     transactionsPage = new QWidget(this);
99     QVBoxLayout *vbox = new QVBoxLayout();
100     transactionView = new TransactionView(this);
101     vbox->addWidget(transactionView);
102     transactionsPage->setLayout(vbox);
103
104     addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab);
105
106     receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
107
108     sendCoinsPage = new SendCoinsDialog(this);
109
110     centralWidget = new QStackedWidget(this);
111     centralWidget->addWidget(overviewPage);
112     centralWidget->addWidget(transactionsPage);
113     centralWidget->addWidget(addressBookPage);
114     centralWidget->addWidget(receiveCoinsPage);
115     centralWidget->addWidget(sendCoinsPage);
116     setCentralWidget(centralWidget);
117
118     // Create status bar
119     statusBar();
120
121     // Status bar notification icons
122     QFrame *frameBlocks = new QFrame();
123     //frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken);
124     frameBlocks->setContentsMargins(0,0,0,0);
125     frameBlocks->setMinimumWidth(56);
126     frameBlocks->setMaximumWidth(56);
127     QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
128     frameBlocksLayout->setContentsMargins(3,0,3,0);
129     frameBlocksLayout->setSpacing(3);
130     labelEncryptionIcon = new QLabel();
131     labelConnectionsIcon = new QLabel();
132     labelBlocksIcon = new QLabel();
133     frameBlocksLayout->addStretch();
134     frameBlocksLayout->addWidget(labelEncryptionIcon);
135     frameBlocksLayout->addStretch();
136     frameBlocksLayout->addWidget(labelConnectionsIcon);
137     frameBlocksLayout->addStretch();
138     frameBlocksLayout->addWidget(labelBlocksIcon);
139     frameBlocksLayout->addStretch();
140
141     // Progress bar for blocks download
142     progressBarLabel = new QLabel(tr("Synchronizing with network..."));
143     progressBarLabel->setVisible(false);
144     progressBar = new QProgressBar();
145     progressBar->setToolTip(tr("Block chain synchronization in progress"));
146     progressBar->setVisible(false);
147
148     statusBar()->addWidget(progressBarLabel);
149     statusBar()->addWidget(progressBar);
150     statusBar()->addPermanentWidget(frameBlocks);
151
152     createTrayIcon();
153
154     syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
155
156     // Clicking on a transaction on the overview page simply sends you to transaction history page
157     connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
158
159     // Doubleclicking on a transaction on the transaction history page shows details
160     connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
161
162     gotoOverviewPage();
163 }
164
165 void BitcoinGUI::createActions()
166 {
167     QActionGroup *tabGroup = new QActionGroup(this);
168
169     overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this);
170     overviewAction->setToolTip(tr("Show general overview of wallet"));
171     overviewAction->setCheckable(true);
172     tabGroup->addAction(overviewAction);
173
174     historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this);
175     historyAction->setToolTip(tr("Browse transaction history"));
176     historyAction->setCheckable(true);
177     tabGroup->addAction(historyAction);
178
179     addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this);
180     addressBookAction->setToolTip(tr("Edit the list of stored addresses and labels"));
181     addressBookAction->setCheckable(true);
182     tabGroup->addAction(addressBookAction);
183
184     receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this);
185     receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments"));
186     receiveCoinsAction->setCheckable(true);
187     tabGroup->addAction(receiveCoinsAction);
188
189     sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this);
190     sendCoinsAction->setToolTip(tr("Send coins to a bitcoin address"));
191     sendCoinsAction->setCheckable(true);
192     tabGroup->addAction(sendCoinsAction);
193
194     connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
195     connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
196     connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
197     connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
198     connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
199
200     quitAction = new QAction(QIcon(":/icons/quit"), tr("&Exit"), this);
201     quitAction->setToolTip(tr("Quit application"));
202     aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About"), this);
203     aboutAction->setToolTip(tr("Show information about Bitcoin"));
204     optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
205     optionsAction->setToolTip(tr("Modify configuration options for bitcoin"));
206     openBitcoinAction = new QAction(QIcon(":/icons/bitcoin"), tr("Open &Bitcoin"), this);
207     openBitcoinAction->setToolTip(tr("Show the Bitcoin window"));
208     exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
209     exportAction->setToolTip(tr("Export the current view to a file"));
210     encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this);
211     encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
212     encryptWalletAction->setCheckable(true);
213     changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
214     changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
215
216     connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
217     connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
218     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
219     connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(show()));
220     connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
221     connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
222 }
223
224 void BitcoinGUI::setClientModel(ClientModel *clientModel)
225 {
226     this->clientModel = clientModel;
227
228     if(clientModel->isTestNet())
229     {
230         QString title_testnet = windowTitle() + QString(" ") + tr("[testnet]");
231         setWindowTitle(title_testnet);
232         setWindowIcon(QIcon(":icons/bitcoin_testnet"));
233         if(trayIcon)
234         {
235             trayIcon->setToolTip(title_testnet);
236             trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
237         }
238     }
239
240     // Keep up to date with client
241     setNumConnections(clientModel->getNumConnections());
242     connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
243
244     setNumBlocks(clientModel->getNumBlocks());
245     connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
246
247     // Report errors from network/worker thread
248     connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
249 }
250
251 void BitcoinGUI::setWalletModel(WalletModel *walletModel)
252 {
253     this->walletModel = walletModel;
254
255     // Report errors from wallet thread
256     connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
257
258     // Put transaction list in tabs
259     transactionView->setModel(walletModel);
260
261     overviewPage->setModel(walletModel);
262     addressBookPage->setModel(walletModel->getAddressTableModel());
263     receiveCoinsPage->setModel(walletModel->getAddressTableModel());
264     sendCoinsPage->setModel(walletModel);
265
266     setEncryptionStatus(walletModel->getEncryptionStatus());
267     connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
268
269     // Balloon popup for new transaction
270     connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
271             this, SLOT(incomingTransaction(QModelIndex,int,int)));
272
273     // Ask for passphrase if needed
274     connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
275 }
276
277 void BitcoinGUI::createTrayIcon()
278 {
279     QMenu *trayIconMenu = new QMenu(this);
280     trayIconMenu->addAction(openBitcoinAction);
281     trayIconMenu->addAction(optionsAction);
282     trayIconMenu->addSeparator();
283     trayIconMenu->addAction(quitAction);
284
285     trayIcon = new QSystemTrayIcon(this);
286     trayIcon->setContextMenu(trayIconMenu);
287     trayIcon->setToolTip("Bitcoin client");
288     trayIcon->setIcon(QIcon(":/icons/toolbar"));
289     connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
290             this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
291     trayIcon->show();
292
293     notificator = new Notificator(tr("bitcoin-qt"), trayIcon);
294 }
295
296 void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
297 {
298     if(reason == QSystemTrayIcon::Trigger)
299     {
300         // Doubleclick on system tray icon triggers "open bitcoin"
301         openBitcoinAction->trigger();
302     }
303 }
304
305 void BitcoinGUI::optionsClicked()
306 {
307     OptionsDialog dlg;
308     dlg.setModel(clientModel->getOptionsModel());
309     dlg.exec();
310 }
311
312 void BitcoinGUI::aboutClicked()
313 {
314     AboutDialog dlg;
315     dlg.setModel(clientModel);
316     dlg.exec();
317 }
318
319 void BitcoinGUI::setNumConnections(int count)
320 {
321     QString icon;
322     switch(count)
323     {
324     case 0: icon = ":/icons/connect_0"; break;
325     case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
326     case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
327     case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
328     default: icon = ":/icons/connect_4"; break;
329     }
330     labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
331     labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
332 }
333
334 void BitcoinGUI::setNumBlocks(int count)
335 {
336     int total = clientModel->getTotalBlocksEstimate();
337     QString tooltip;
338
339     if(count < total)
340     {
341         progressBarLabel->setVisible(true);
342         progressBar->setVisible(true);
343         progressBar->setMaximum(total);
344         progressBar->setValue(count);
345         tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total);
346     }
347     else
348     {
349         progressBarLabel->setVisible(false);
350         progressBar->setVisible(false);
351         tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count);
352     }
353
354     QDateTime now = QDateTime::currentDateTime();
355     QDateTime lastBlockDate = clientModel->getLastBlockDate();
356     int secs = lastBlockDate.secsTo(now);
357     QString text;
358
359     // Represent time from last generated block in human readable text
360     if(secs < 60)
361     {
362         text = tr("%n second(s) ago","",secs);
363     }
364     else if(secs < 60*60)
365     {
366         text = tr("%n minute(s) ago","",secs/60);
367     }
368     else if(secs < 24*60*60)
369     {
370         text = tr("%n hour(s) ago","",secs/(60*60));
371     }
372     else
373     {
374         text = tr("%n day(s) ago","",secs/(60*60*24));
375     }
376
377     // Set icon state: spinning if catching up, tick otherwise
378     if(secs < 30*60)
379     {
380         tooltip = tr("Up to date") + QString("\n") + tooltip;
381         labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
382     }
383     else
384     {
385         tooltip = tr("Catching up...") + QString("\n") + tooltip;
386         labelBlocksIcon->setMovie(syncIconMovie);
387         syncIconMovie->start();
388     }
389
390     tooltip += QString("\n");
391     tooltip += tr("Last received block was generated %1.").arg(text);
392
393     labelBlocksIcon->setToolTip(tooltip);
394     progressBarLabel->setToolTip(tooltip);
395     progressBar->setToolTip(tooltip);
396 }
397
398 void BitcoinGUI::error(const QString &title, const QString &message)
399 {
400     // Report errors from network/worker thread
401     notificator->notify(Notificator::Critical, title, message);
402 }
403
404 void BitcoinGUI::changeEvent(QEvent *e)
405 {
406     if (e->type() == QEvent::WindowStateChange)
407     {
408         if(clientModel->getOptionsModel()->getMinimizeToTray())
409         {
410             if (isMinimized())
411             {
412                 hide();
413                 e->ignore();
414             }
415             else
416             {
417                 e->accept();
418             }
419         }
420     }
421     QMainWindow::changeEvent(e);
422 }
423
424 void BitcoinGUI::closeEvent(QCloseEvent *event)
425 {
426     if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
427        !clientModel->getOptionsModel()->getMinimizeOnClose())
428     {
429         qApp->quit();
430     }
431     QMainWindow::closeEvent(event);
432 }
433
434 void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
435 {
436     QString strMessage =
437         tr("This transaction is over the size limit.  You can still send it for a fee of %1, "
438           "which goes to the nodes that process your transaction and helps to support the network.  "
439           "Do you want to pay the fee?").arg(
440                 BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired));
441     QMessageBox::StandardButton retval = QMessageBox::question(
442           this, tr("Sending..."), strMessage,
443           QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
444     *payFee = (retval == QMessageBox::Yes);
445 }
446
447 void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end)
448 {
449     TransactionTableModel *ttm = walletModel->getTransactionTableModel();
450     qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
451                     .data(Qt::EditRole).toULongLong();
452     if(!clientModel->inInitialBlockDownload())
453     {
454         // On new transaction, make an info balloon
455         // Unless the initial block download is in progress, to prevent balloon-spam
456         QString date = ttm->index(start, TransactionTableModel::Date, parent)
457                         .data().toString();
458         QString type = ttm->index(start, TransactionTableModel::Type, parent)
459                         .data().toString();
460         QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
461                         .data().toString();
462         QIcon icon = qvariant_cast<QIcon>(ttm->index(start,
463                             TransactionTableModel::ToAddress, parent)
464                         .data(Qt::DecorationRole));
465
466         notificator->notify(Notificator::Information,
467                             (amount)<0 ? tr("Sent transaction") :
468                                          tr("Incoming transaction"),
469                               tr("Date: %1\n"
470                                  "Amount: %2\n"
471                                  "Type: %3\n"
472                                  "Address: %4\n")
473                               .arg(date)
474                               .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
475                               .arg(type)
476                               .arg(address), icon);
477     }
478 }
479
480 void BitcoinGUI::gotoOverviewPage()
481 {
482     overviewAction->setChecked(true);
483     centralWidget->setCurrentWidget(overviewPage);
484
485     exportAction->setEnabled(false);
486     disconnect(exportAction, SIGNAL(triggered()), 0, 0);
487 }
488
489 void BitcoinGUI::gotoHistoryPage()
490 {
491     historyAction->setChecked(true);
492     centralWidget->setCurrentWidget(transactionsPage);
493
494     exportAction->setEnabled(true);
495     disconnect(exportAction, SIGNAL(triggered()), 0, 0);
496     connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
497 }
498
499 void BitcoinGUI::gotoAddressBookPage()
500 {
501     addressBookAction->setChecked(true);
502     centralWidget->setCurrentWidget(addressBookPage);
503
504     exportAction->setEnabled(true);
505     disconnect(exportAction, SIGNAL(triggered()), 0, 0);
506     connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
507 }
508
509 void BitcoinGUI::gotoReceiveCoinsPage()
510 {
511     receiveCoinsAction->setChecked(true);
512     centralWidget->setCurrentWidget(receiveCoinsPage);
513
514     exportAction->setEnabled(true);
515     disconnect(exportAction, SIGNAL(triggered()), 0, 0);
516     connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
517 }
518
519 void BitcoinGUI::gotoSendCoinsPage()
520 {
521     sendCoinsAction->setChecked(true);
522     if(centralWidget->currentWidget() != sendCoinsPage)
523     {
524         // Clear the current contents if we arrived from another tab
525         sendCoinsPage->clear();
526     }
527     centralWidget->setCurrentWidget(sendCoinsPage);
528
529     exportAction->setEnabled(false);
530     disconnect(exportAction, SIGNAL(triggered()), 0, 0);
531 }
532
533 void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
534 {
535     // Accept only URLs
536     if(event->mimeData()->hasUrls())
537         event->acceptProposedAction();
538 }
539
540 void BitcoinGUI::dropEvent(QDropEvent *event)
541 {
542     if(event->mimeData()->hasUrls())
543     {
544         gotoSendCoinsPage();
545         QList<QUrl> urls = event->mimeData()->urls();
546         foreach(const QUrl &url, urls)
547         {
548             sendCoinsPage->handleURL(&url);
549         }
550     }
551
552     event->acceptProposedAction();
553 }
554
555 void BitcoinGUI::setEncryptionStatus(int status)
556 {
557     switch(status)
558     {
559     case WalletModel::Unencrypted:
560         labelEncryptionIcon->hide();
561         encryptWalletAction->setChecked(false);
562         changePassphraseAction->setEnabled(false);
563         encryptWalletAction->setEnabled(true);
564         break;
565     case WalletModel::Unlocked:
566         labelEncryptionIcon->show();
567         labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
568         labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
569         encryptWalletAction->setChecked(true);
570         changePassphraseAction->setEnabled(true);
571         encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
572         break;
573     case WalletModel::Locked:
574         labelEncryptionIcon->show();
575         labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
576         labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
577         encryptWalletAction->setChecked(true);
578         changePassphraseAction->setEnabled(true);
579         encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
580         break;
581     }
582 }
583
584 void BitcoinGUI::encryptWallet(bool status)
585 {
586     AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
587                                      AskPassphraseDialog::Decrypt, this);
588     dlg.setModel(walletModel);
589     dlg.exec();
590
591     setEncryptionStatus(walletModel->getEncryptionStatus());
592 }
593
594 void BitcoinGUI::changePassphrase()
595 {
596     AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
597     dlg.setModel(walletModel);
598     dlg.exec();
599 }
600
601 void BitcoinGUI::unlockWallet()
602 {
603     // Unlock wallet when requested by wallet model
604     if(walletModel->getEncryptionStatus() == WalletModel::Locked)
605     {
606         AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
607         dlg.setModel(walletModel);
608         dlg.exec();
609     }
610 }