1 // Copyright (c) 2011-2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include <qt/walletview.h>
7 #include <qt/addressbookpage.h>
8 #include <qt/askpassphrasedialog.h>
9 #include <qt/bitcoingui.h>
10 #include <qt/clientmodel.h>
11 #include <qt/guiutil.h>
12 #include <qt/optionsmodel.h>
13 #include <qt/overviewpage.h>
14 #include <qt/platformstyle.h>
15 #include <qt/receivecoinsdialog.h>
16 #include <qt/sendcoinsdialog.h>
17 #include <qt/signverifymessagedialog.h>
18 #include <qt/transactiontablemodel.h>
19 #include <qt/transactionview.h>
20 #include <qt/walletmodel.h>
22 #include <ui_interface.h>
25 #include <QActionGroup>
26 #include <QFileDialog>
27 #include <QHBoxLayout>
28 #include <QProgressDialog>
29 #include <QPushButton>
30 #include <QVBoxLayout>
32 WalletView::WalletView(const PlatformStyle
*_platformStyle
, QWidget
*parent
):
33 QStackedWidget(parent
),
36 platformStyle(_platformStyle
)
39 overviewPage
= new OverviewPage(platformStyle
);
41 transactionsPage
= new QWidget(this);
42 QVBoxLayout
*vbox
= new QVBoxLayout();
43 QHBoxLayout
*hbox_buttons
= new QHBoxLayout();
44 transactionView
= new TransactionView(platformStyle
, this);
45 vbox
->addWidget(transactionView
);
46 QPushButton
*exportButton
= new QPushButton(tr("&Export"), this);
47 exportButton
->setToolTip(tr("Export the data in the current tab to a file"));
48 if (platformStyle
->getImagesOnButtons()) {
49 exportButton
->setIcon(platformStyle
->SingleColorIcon(":/icons/export"));
51 hbox_buttons
->addStretch();
52 hbox_buttons
->addWidget(exportButton
);
53 vbox
->addLayout(hbox_buttons
);
54 transactionsPage
->setLayout(vbox
);
56 receiveCoinsPage
= new ReceiveCoinsDialog(platformStyle
);
57 sendCoinsPage
= new SendCoinsDialog(platformStyle
);
59 usedSendingAddressesPage
= new AddressBookPage(platformStyle
, AddressBookPage::ForEditing
, AddressBookPage::SendingTab
, this);
60 usedReceivingAddressesPage
= new AddressBookPage(platformStyle
, AddressBookPage::ForEditing
, AddressBookPage::ReceivingTab
, this);
62 addWidget(overviewPage
);
63 addWidget(transactionsPage
);
64 addWidget(receiveCoinsPage
);
65 addWidget(sendCoinsPage
);
67 // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
68 connect(overviewPage
, SIGNAL(transactionClicked(QModelIndex
)), transactionView
, SLOT(focusTransaction(QModelIndex
)));
69 connect(overviewPage
, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
71 // Double-clicking on a transaction on the transaction history page shows details
72 connect(transactionView
, SIGNAL(doubleClicked(QModelIndex
)), transactionView
, SLOT(showDetails()));
74 // Clicking on "Export" allows to export the transaction list
75 connect(exportButton
, SIGNAL(clicked()), transactionView
, SLOT(exportClicked()));
77 // Pass through messages from sendCoinsPage
78 connect(sendCoinsPage
, SIGNAL(message(QString
,QString
,unsigned int)), this, SIGNAL(message(QString
,QString
,unsigned int)));
79 // Pass through messages from transactionView
80 connect(transactionView
, SIGNAL(message(QString
,QString
,unsigned int)), this, SIGNAL(message(QString
,QString
,unsigned int)));
83 WalletView::~WalletView()
87 void WalletView::setBitcoinGUI(BitcoinGUI
*gui
)
91 // Clicking on a transaction on the overview page simply sends you to transaction history page
92 connect(overviewPage
, SIGNAL(transactionClicked(QModelIndex
)), gui
, SLOT(gotoHistoryPage()));
94 // Receive and report messages
95 connect(this, SIGNAL(message(QString
,QString
,unsigned int)), gui
, SLOT(message(QString
,QString
,unsigned int)));
97 // Pass through encryption status changed signals
98 connect(this, SIGNAL(encryptionStatusChanged(int)), gui
, SLOT(setEncryptionStatus(int)));
100 // Pass through transaction notifications
101 connect(this, SIGNAL(incomingTransaction(QString
,int,CAmount
,QString
,QString
,QString
)), gui
, SLOT(incomingTransaction(QString
,int,CAmount
,QString
,QString
,QString
)));
103 // Connect HD enabled state signal
104 connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui
, SLOT(setHDStatus(int)));
108 void WalletView::setClientModel(ClientModel
*_clientModel
)
110 this->clientModel
= _clientModel
;
112 overviewPage
->setClientModel(_clientModel
);
113 sendCoinsPage
->setClientModel(_clientModel
);
116 void WalletView::setWalletModel(WalletModel
*_walletModel
)
118 this->walletModel
= _walletModel
;
120 // Put transaction list in tabs
121 transactionView
->setModel(_walletModel
);
122 overviewPage
->setWalletModel(_walletModel
);
123 receiveCoinsPage
->setModel(_walletModel
);
124 sendCoinsPage
->setModel(_walletModel
);
125 usedReceivingAddressesPage
->setModel(_walletModel
? _walletModel
->getAddressTableModel() : nullptr);
126 usedSendingAddressesPage
->setModel(_walletModel
? _walletModel
->getAddressTableModel() : nullptr);
130 // Receive and pass through messages from wallet model
131 connect(_walletModel
, SIGNAL(message(QString
,QString
,unsigned int)), this, SIGNAL(message(QString
,QString
,unsigned int)));
133 // Handle changes in encryption status
134 connect(_walletModel
, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
135 updateEncryptionStatus();
138 Q_EMIT
hdEnabledStatusChanged(_walletModel
->hdEnabled());
140 // Balloon pop-up for new transaction
141 connect(_walletModel
->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex
,int,int)),
142 this, SLOT(processNewTransaction(QModelIndex
,int,int)));
144 // Ask for passphrase if needed
145 connect(_walletModel
, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
147 // Show progress dialog
148 connect(_walletModel
, SIGNAL(showProgress(QString
,int)), this, SLOT(showProgress(QString
,int)));
152 void WalletView::processNewTransaction(const QModelIndex
& parent
, int start
, int /*end*/)
154 // Prevent balloon-spam when initial block download is in progress
155 if (!walletModel
|| !clientModel
|| clientModel
->inInitialBlockDownload())
158 TransactionTableModel
*ttm
= walletModel
->getTransactionTableModel();
159 if (!ttm
|| ttm
->processingQueuedTransactions())
162 QString date
= ttm
->index(start
, TransactionTableModel::Date
, parent
).data().toString();
163 qint64 amount
= ttm
->index(start
, TransactionTableModel::Amount
, parent
).data(Qt::EditRole
).toULongLong();
164 QString type
= ttm
->index(start
, TransactionTableModel::Type
, parent
).data().toString();
165 QModelIndex index
= ttm
->index(start
, 0, parent
);
166 QString address
= ttm
->data(index
, TransactionTableModel::AddressRole
).toString();
167 QString label
= ttm
->data(index
, TransactionTableModel::LabelRole
).toString();
169 Q_EMIT
incomingTransaction(date
, walletModel
->getOptionsModel()->getDisplayUnit(), amount
, type
, address
, label
);
172 void WalletView::gotoOverviewPage()
174 setCurrentWidget(overviewPage
);
177 void WalletView::gotoHistoryPage()
179 setCurrentWidget(transactionsPage
);
182 void WalletView::gotoReceiveCoinsPage()
184 setCurrentWidget(receiveCoinsPage
);
187 void WalletView::gotoSendCoinsPage(QString addr
)
189 setCurrentWidget(sendCoinsPage
);
192 sendCoinsPage
->setAddress(addr
);
195 void WalletView::gotoSignMessageTab(QString addr
)
197 // calls show() in showTab_SM()
198 SignVerifyMessageDialog
*signVerifyMessageDialog
= new SignVerifyMessageDialog(platformStyle
, this);
199 signVerifyMessageDialog
->setAttribute(Qt::WA_DeleteOnClose
);
200 signVerifyMessageDialog
->setModel(walletModel
);
201 signVerifyMessageDialog
->showTab_SM(true);
204 signVerifyMessageDialog
->setAddress_SM(addr
);
207 void WalletView::gotoVerifyMessageTab(QString addr
)
209 // calls show() in showTab_VM()
210 SignVerifyMessageDialog
*signVerifyMessageDialog
= new SignVerifyMessageDialog(platformStyle
, this);
211 signVerifyMessageDialog
->setAttribute(Qt::WA_DeleteOnClose
);
212 signVerifyMessageDialog
->setModel(walletModel
);
213 signVerifyMessageDialog
->showTab_VM(true);
216 signVerifyMessageDialog
->setAddress_VM(addr
);
219 bool WalletView::handlePaymentRequest(const SendCoinsRecipient
& recipient
)
221 return sendCoinsPage
->handlePaymentRequest(recipient
);
224 void WalletView::showOutOfSyncWarning(bool fShow
)
226 overviewPage
->showOutOfSyncWarning(fShow
);
229 void WalletView::updateEncryptionStatus()
231 Q_EMIT
encryptionStatusChanged(walletModel
->getEncryptionStatus());
234 void WalletView::encryptWallet(bool status
)
238 AskPassphraseDialog
dlg(status
? AskPassphraseDialog::Encrypt
: AskPassphraseDialog::Decrypt
, this);
239 dlg
.setModel(walletModel
);
242 updateEncryptionStatus();
245 void WalletView::backupWallet()
247 QString filename
= GUIUtil::getSaveFileName(this,
248 tr("Backup Wallet"), QString(),
249 tr("Wallet Data (*.dat)"), nullptr);
251 if (filename
.isEmpty())
254 if (!walletModel
->backupWallet(filename
)) {
255 Q_EMIT
message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename
),
256 CClientUIInterface::MSG_ERROR
);
259 Q_EMIT
message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename
),
260 CClientUIInterface::MSG_INFORMATION
);
264 void WalletView::changePassphrase()
266 AskPassphraseDialog
dlg(AskPassphraseDialog::ChangePass
, this);
267 dlg
.setModel(walletModel
);
271 void WalletView::unlockWallet()
275 // Unlock wallet when requested by wallet model
276 if (walletModel
->getEncryptionStatus() == WalletModel::Locked
)
278 AskPassphraseDialog
dlg(AskPassphraseDialog::Unlock
, this);
279 dlg
.setModel(walletModel
);
284 void WalletView::usedSendingAddresses()
289 usedSendingAddressesPage
->show();
290 usedSendingAddressesPage
->raise();
291 usedSendingAddressesPage
->activateWindow();
294 void WalletView::usedReceivingAddresses()
299 usedReceivingAddressesPage
->show();
300 usedReceivingAddressesPage
->raise();
301 usedReceivingAddressesPage
->activateWindow();
304 void WalletView::showProgress(const QString
&title
, int nProgress
)
308 progressDialog
= new QProgressDialog(title
, "", 0, 100);
309 progressDialog
->setWindowModality(Qt::ApplicationModal
);
310 progressDialog
->setMinimumDuration(0);
311 progressDialog
->setCancelButton(0);
312 progressDialog
->setAutoClose(false);
313 progressDialog
->setValue(0);
315 else if (nProgress
== 100)
319 progressDialog
->close();
320 progressDialog
->deleteLater();
323 else if (progressDialog
)
324 progressDialog
->setValue(nProgress
);
327 void WalletView::requestedSyncWarningInfo()
329 Q_EMIT
outOfSyncWarningClicked();