Line data Source code
1 : // Copyright (c) 2011-2013 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.
4 :
5 : #include "walletview.h"
6 :
7 : #include "addressbookpage.h"
8 : #include "askpassphrasedialog.h"
9 : #include "bitcoingui.h"
10 : #include "clientmodel.h"
11 : #include "guiutil.h"
12 : #include "optionsmodel.h"
13 : #include "overviewpage.h"
14 : #include "platformstyle.h"
15 : #include "receivecoinsdialog.h"
16 : #include "sendcoinsdialog.h"
17 : #include "signverifymessagedialog.h"
18 : #include "transactiontablemodel.h"
19 : #include "transactionview.h"
20 : #include "walletmodel.h"
21 :
22 : #include "ui_interface.h"
23 :
24 : #include <QAction>
25 : #include <QActionGroup>
26 : #include <QFileDialog>
27 : #include <QHBoxLayout>
28 : #include <QProgressDialog>
29 : #include <QPushButton>
30 : #include <QVBoxLayout>
31 :
32 0 : WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
33 : QStackedWidget(parent),
34 : clientModel(0),
35 : walletModel(0),
36 0 : platformStyle(platformStyle)
37 : {
38 : // Create tabs
39 0 : overviewPage = new OverviewPage(platformStyle);
40 :
41 0 : transactionsPage = new QWidget(this);
42 0 : QVBoxLayout *vbox = new QVBoxLayout();
43 0 : QHBoxLayout *hbox_buttons = new QHBoxLayout();
44 0 : transactionView = new TransactionView(platformStyle, this);
45 0 : vbox->addWidget(transactionView);
46 0 : QPushButton *exportButton = new QPushButton(tr("&Export"), this);
47 0 : exportButton->setToolTip(tr("Export the data in the current tab to a file"));
48 0 : if (platformStyle->getImagesOnButtons()) {
49 0 : exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
50 : }
51 0 : hbox_buttons->addStretch();
52 0 : hbox_buttons->addWidget(exportButton);
53 0 : vbox->addLayout(hbox_buttons);
54 0 : transactionsPage->setLayout(vbox);
55 :
56 0 : receiveCoinsPage = new ReceiveCoinsDialog(platformStyle);
57 0 : sendCoinsPage = new SendCoinsDialog(platformStyle);
58 :
59 0 : usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
60 0 : usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
61 :
62 0 : addWidget(overviewPage);
63 0 : addWidget(transactionsPage);
64 0 : addWidget(receiveCoinsPage);
65 0 : addWidget(sendCoinsPage);
66 :
67 : // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
68 0 : connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
69 :
70 : // Double-clicking on a transaction on the transaction history page shows details
71 0 : connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
72 :
73 : // Clicking on "Export" allows to export the transaction list
74 0 : connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked()));
75 :
76 : // Pass through messages from sendCoinsPage
77 0 : connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
78 : // Pass through messages from transactionView
79 0 : connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
80 0 : }
81 :
82 0 : WalletView::~WalletView()
83 : {
84 0 : }
85 :
86 0 : void WalletView::setBitcoinGUI(BitcoinGUI *gui)
87 : {
88 0 : if (gui)
89 : {
90 : // Clicking on a transaction on the overview page simply sends you to transaction history page
91 0 : connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage()));
92 :
93 : // Receive and report messages
94 0 : connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
95 :
96 : // Pass through encryption status changed signals
97 0 : connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
98 :
99 : // Pass through transaction notifications
100 0 : connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
101 : }
102 0 : }
103 :
104 0 : void WalletView::setClientModel(ClientModel *clientModel)
105 : {
106 0 : this->clientModel = clientModel;
107 :
108 0 : overviewPage->setClientModel(clientModel);
109 0 : sendCoinsPage->setClientModel(clientModel);
110 0 : }
111 :
112 0 : void WalletView::setWalletModel(WalletModel *walletModel)
113 : {
114 0 : this->walletModel = walletModel;
115 :
116 : // Put transaction list in tabs
117 0 : transactionView->setModel(walletModel);
118 0 : overviewPage->setWalletModel(walletModel);
119 0 : receiveCoinsPage->setModel(walletModel);
120 0 : sendCoinsPage->setModel(walletModel);
121 0 : usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel());
122 0 : usedSendingAddressesPage->setModel(walletModel->getAddressTableModel());
123 :
124 0 : if (walletModel)
125 : {
126 : // Receive and pass through messages from wallet model
127 0 : connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
128 :
129 : // Handle changes in encryption status
130 0 : connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
131 0 : updateEncryptionStatus();
132 :
133 : // Balloon pop-up for new transaction
134 0 : connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
135 0 : this, SLOT(processNewTransaction(QModelIndex,int,int)));
136 :
137 : // Ask for passphrase if needed
138 0 : connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
139 :
140 : // Show progress dialog
141 0 : connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
142 : }
143 0 : }
144 :
145 0 : void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/)
146 : {
147 : // Prevent balloon-spam when initial block download is in progress
148 0 : if (!walletModel || !clientModel || clientModel->inInitialBlockDownload())
149 0 : return;
150 :
151 0 : TransactionTableModel *ttm = walletModel->getTransactionTableModel();
152 0 : if (!ttm || ttm->processingQueuedTransactions())
153 : return;
154 :
155 0 : QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
156 0 : qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
157 0 : QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();
158 0 : QModelIndex index = ttm->index(start, 0, parent);
159 0 : QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
160 0 : QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
161 :
162 0 : Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
163 : }
164 :
165 0 : void WalletView::gotoOverviewPage()
166 : {
167 0 : setCurrentWidget(overviewPage);
168 0 : }
169 :
170 0 : void WalletView::gotoHistoryPage()
171 : {
172 0 : setCurrentWidget(transactionsPage);
173 0 : }
174 :
175 0 : void WalletView::gotoReceiveCoinsPage()
176 : {
177 0 : setCurrentWidget(receiveCoinsPage);
178 0 : }
179 :
180 0 : void WalletView::gotoSendCoinsPage(QString addr)
181 : {
182 0 : setCurrentWidget(sendCoinsPage);
183 :
184 0 : if (!addr.isEmpty())
185 0 : sendCoinsPage->setAddress(addr);
186 0 : }
187 :
188 0 : void WalletView::gotoSignMessageTab(QString addr)
189 : {
190 : // calls show() in showTab_SM()
191 0 : SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
192 0 : signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
193 0 : signVerifyMessageDialog->setModel(walletModel);
194 0 : signVerifyMessageDialog->showTab_SM(true);
195 :
196 0 : if (!addr.isEmpty())
197 0 : signVerifyMessageDialog->setAddress_SM(addr);
198 0 : }
199 :
200 0 : void WalletView::gotoVerifyMessageTab(QString addr)
201 : {
202 : // calls show() in showTab_VM()
203 0 : SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
204 0 : signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
205 0 : signVerifyMessageDialog->setModel(walletModel);
206 0 : signVerifyMessageDialog->showTab_VM(true);
207 :
208 0 : if (!addr.isEmpty())
209 0 : signVerifyMessageDialog->setAddress_VM(addr);
210 0 : }
211 :
212 0 : bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
213 : {
214 0 : return sendCoinsPage->handlePaymentRequest(recipient);
215 : }
216 :
217 0 : void WalletView::showOutOfSyncWarning(bool fShow)
218 : {
219 0 : overviewPage->showOutOfSyncWarning(fShow);
220 0 : }
221 :
222 0 : void WalletView::updateEncryptionStatus()
223 : {
224 0 : Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
225 0 : }
226 :
227 0 : void WalletView::encryptWallet(bool status)
228 : {
229 0 : if(!walletModel)
230 0 : return;
231 0 : AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
232 0 : dlg.setModel(walletModel);
233 0 : dlg.exec();
234 :
235 0 : updateEncryptionStatus();
236 : }
237 :
238 0 : void WalletView::backupWallet()
239 : {
240 : QString filename = GUIUtil::getSaveFileName(this,
241 : tr("Backup Wallet"), QString(),
242 0 : tr("Wallet Data (*.dat)"), NULL);
243 :
244 0 : if (filename.isEmpty())
245 0 : return;
246 :
247 0 : if (!walletModel->backupWallet(filename)) {
248 : Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
249 0 : CClientUIInterface::MSG_ERROR);
250 : }
251 : else {
252 : Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename),
253 0 : CClientUIInterface::MSG_INFORMATION);
254 0 : }
255 : }
256 :
257 0 : void WalletView::changePassphrase()
258 : {
259 0 : AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
260 0 : dlg.setModel(walletModel);
261 0 : dlg.exec();
262 0 : }
263 :
264 0 : void WalletView::unlockWallet()
265 : {
266 0 : if(!walletModel)
267 0 : return;
268 : // Unlock wallet when requested by wallet model
269 0 : if (walletModel->getEncryptionStatus() == WalletModel::Locked)
270 : {
271 0 : AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
272 0 : dlg.setModel(walletModel);
273 0 : dlg.exec();
274 : }
275 : }
276 :
277 0 : void WalletView::usedSendingAddresses()
278 : {
279 0 : if(!walletModel)
280 0 : return;
281 :
282 0 : usedSendingAddressesPage->show();
283 0 : usedSendingAddressesPage->raise();
284 0 : usedSendingAddressesPage->activateWindow();
285 : }
286 :
287 0 : void WalletView::usedReceivingAddresses()
288 : {
289 0 : if(!walletModel)
290 0 : return;
291 :
292 0 : usedReceivingAddressesPage->show();
293 0 : usedReceivingAddressesPage->raise();
294 0 : usedReceivingAddressesPage->activateWindow();
295 : }
296 :
297 0 : void WalletView::showProgress(const QString &title, int nProgress)
298 : {
299 0 : if (nProgress == 0)
300 : {
301 0 : progressDialog = new QProgressDialog(title, "", 0, 100);
302 0 : progressDialog->setWindowModality(Qt::ApplicationModal);
303 0 : progressDialog->setMinimumDuration(0);
304 0 : progressDialog->setCancelButton(0);
305 0 : progressDialog->setAutoClose(false);
306 0 : progressDialog->setValue(0);
307 : }
308 0 : else if (nProgress == 100)
309 : {
310 0 : if (progressDialog)
311 : {
312 0 : progressDialog->close();
313 0 : progressDialog->deleteLater();
314 : }
315 : }
316 0 : else if (progressDialog)
317 0 : progressDialog->setValue(nProgress);
318 0 : }
|