]>
Commit | Line | Data |
---|---|---|
67155d92 EL |
1 | /* |
2 | * Qt4 bitcoin GUI. | |
3 | * | |
4 | * W.J. van der Laan 2011-2012 | |
5 | * The Bitcoin Developers 2011-2013 | |
6 | */ | |
7 | #include "walletview.h" | |
8 | #include "bitcoingui.h" | |
9 | #include "transactiontablemodel.h" | |
10 | #include "addressbookpage.h" | |
11 | #include "sendcoinsdialog.h" | |
12 | #include "signverifymessagedialog.h" | |
67155d92 EL |
13 | #include "clientmodel.h" |
14 | #include "walletmodel.h" | |
67155d92 | 15 | #include "optionsmodel.h" |
67155d92 EL |
16 | #include "transactionview.h" |
17 | #include "overviewpage.h" | |
67155d92 | 18 | #include "askpassphrasedialog.h" |
67155d92 EL |
19 | #include "ui_interface.h" |
20 | ||
46fd626b | 21 | #include <QHBoxLayout> |
67155d92 | 22 | #include <QVBoxLayout> |
67155d92 | 23 | #include <QAction> |
25c0cce7 | 24 | #if QT_VERSION < 0x050000 |
67155d92 | 25 | #include <QDesktopServices> |
25c0cce7 WL |
26 | #else |
27 | #include <QStandardPaths> | |
28 | #endif | |
67155d92 | 29 | #include <QFileDialog> |
45155d30 | 30 | #include <QPushButton> |
67155d92 EL |
31 | |
32 | WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui): | |
33 | QStackedWidget(parent), | |
34 | gui(_gui), | |
35 | clientModel(0), | |
8726de26 | 36 | walletModel(0) |
67155d92 | 37 | { |
67155d92 EL |
38 | // Create tabs |
39 | overviewPage = new OverviewPage(); | |
40 | ||
41 | transactionsPage = new QWidget(this); | |
42 | QVBoxLayout *vbox = new QVBoxLayout(); | |
45155d30 | 43 | QHBoxLayout *hbox_buttons = new QHBoxLayout(); |
67155d92 EL |
44 | transactionView = new TransactionView(this); |
45 | vbox->addWidget(transactionView); | |
46fd626b | 46 | QPushButton *exportButton = new QPushButton(tr("&Export"), this); |
45155d30 WL |
47 | exportButton->setToolTip(tr("Export the data in the current tab to a file")); |
48 | #ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac | |
49 | exportButton->setIcon(QIcon(":/icons/export")); | |
50 | #endif | |
51 | hbox_buttons->addStretch(); | |
52 | hbox_buttons->addWidget(exportButton); | |
53 | vbox->addLayout(hbox_buttons); | |
67155d92 EL |
54 | transactionsPage->setLayout(vbox); |
55 | ||
56 | addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab); | |
57 | ||
58 | receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab); | |
59 | ||
60 | sendCoinsPage = new SendCoinsDialog(gui); | |
61 | ||
62 | signVerifyMessageDialog = new SignVerifyMessageDialog(gui); | |
63 | ||
64 | addWidget(overviewPage); | |
65 | addWidget(transactionsPage); | |
66 | addWidget(addressBookPage); | |
67 | addWidget(receiveCoinsPage); | |
68 | addWidget(sendCoinsPage); | |
69 | ||
70 | // Clicking on a transaction on the overview page simply sends you to transaction history page | |
71 | connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); | |
72 | connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); | |
73 | ||
74 | // Double-clicking on a transaction on the transaction history page shows details | |
75 | connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); | |
76 | ||
abf11f79 PK |
77 | // Clicking on "Send Coins" in the address book sends you to the send coins tab |
78 | connect(addressBookPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString))); | |
79 | // Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog | |
67155d92 | 80 | connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); |
abf11f79 | 81 | // Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog |
67155d92 | 82 | connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString))); |
45155d30 WL |
83 | // Clicking on "Export" allows to export the transaction list |
84 | connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked())); | |
67155d92 EL |
85 | |
86 | gotoOverviewPage(); | |
87 | } | |
88 | ||
89 | WalletView::~WalletView() | |
90 | { | |
91 | } | |
92 | ||
67155d92 EL |
93 | void WalletView::setBitcoinGUI(BitcoinGUI *gui) |
94 | { | |
95 | this->gui = gui; | |
96 | } | |
97 | ||
98 | void WalletView::setClientModel(ClientModel *clientModel) | |
99 | { | |
100 | this->clientModel = clientModel; | |
8726de26 | 101 | if (clientModel) |
67155d92 EL |
102 | { |
103 | overviewPage->setClientModel(clientModel); | |
104 | addressBookPage->setOptionsModel(clientModel->getOptionsModel()); | |
105 | receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel()); | |
106 | } | |
107 | } | |
108 | ||
109 | void WalletView::setWalletModel(WalletModel *walletModel) | |
110 | { | |
111 | this->walletModel = walletModel; | |
8726de26 | 112 | if (walletModel) |
67155d92 EL |
113 | { |
114 | // Receive and report messages from wallet thread | |
115 | connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int))); | |
116 | ||
117 | // Put transaction list in tabs | |
118 | transactionView->setModel(walletModel); | |
119 | overviewPage->setWalletModel(walletModel); | |
120 | addressBookPage->setModel(walletModel->getAddressTableModel()); | |
121 | receiveCoinsPage->setModel(walletModel->getAddressTableModel()); | |
122 | sendCoinsPage->setModel(walletModel); | |
123 | signVerifyMessageDialog->setModel(walletModel); | |
124 | ||
125 | setEncryptionStatus(); | |
126 | connect(walletModel, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int))); | |
127 | ||
128 | // Balloon pop-up for new transaction | |
129 | connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), | |
130 | this, SLOT(incomingTransaction(QModelIndex,int,int))); | |
131 | ||
132 | // Ask for passphrase if needed | |
133 | connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); | |
134 | } | |
135 | } | |
136 | ||
137 | void WalletView::incomingTransaction(const QModelIndex& parent, int start, int /*end*/) | |
138 | { | |
139 | // Prevent balloon-spam when initial block download is in progress | |
140 | if(!walletModel || !clientModel || clientModel->inInitialBlockDownload()) | |
141 | return; | |
142 | ||
143 | TransactionTableModel *ttm = walletModel->getTransactionTableModel(); | |
144 | ||
46fd626b PK |
145 | QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); |
146 | qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); | |
147 | QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString(); | |
148 | QString address = ttm->index(start, TransactionTableModel::ToAddress, parent).data().toString(); | |
67155d92 EL |
149 | |
150 | gui->incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address); | |
151 | } | |
152 | ||
153 | void WalletView::gotoOverviewPage() | |
154 | { | |
8726de26 | 155 | gui->getOverviewAction()->setChecked(true); |
67155d92 | 156 | setCurrentWidget(overviewPage); |
67155d92 EL |
157 | } |
158 | ||
159 | void WalletView::gotoHistoryPage() | |
160 | { | |
8726de26 | 161 | gui->getHistoryAction()->setChecked(true); |
67155d92 | 162 | setCurrentWidget(transactionsPage); |
67155d92 EL |
163 | } |
164 | ||
165 | void WalletView::gotoAddressBookPage() | |
166 | { | |
8726de26 | 167 | gui->getAddressBookAction()->setChecked(true); |
67155d92 | 168 | setCurrentWidget(addressBookPage); |
67155d92 EL |
169 | } |
170 | ||
171 | void WalletView::gotoReceiveCoinsPage() | |
172 | { | |
8726de26 | 173 | gui->getReceiveCoinsAction()->setChecked(true); |
67155d92 | 174 | setCurrentWidget(receiveCoinsPage); |
67155d92 EL |
175 | } |
176 | ||
abf11f79 | 177 | void WalletView::gotoSendCoinsPage(QString addr) |
67155d92 | 178 | { |
8726de26 | 179 | gui->getSendCoinsAction()->setChecked(true); |
67155d92 EL |
180 | setCurrentWidget(sendCoinsPage); |
181 | ||
8726de26 | 182 | if (!addr.isEmpty()) |
abf11f79 | 183 | sendCoinsPage->setAddress(addr); |
67155d92 EL |
184 | } |
185 | ||
186 | void WalletView::gotoSignMessageTab(QString addr) | |
187 | { | |
188 | // call show() in showTab_SM() | |
189 | signVerifyMessageDialog->showTab_SM(true); | |
190 | ||
8726de26 | 191 | if (!addr.isEmpty()) |
67155d92 EL |
192 | signVerifyMessageDialog->setAddress_SM(addr); |
193 | } | |
194 | ||
195 | void WalletView::gotoVerifyMessageTab(QString addr) | |
196 | { | |
197 | // call show() in showTab_VM() | |
198 | signVerifyMessageDialog->showTab_VM(true); | |
199 | ||
8726de26 | 200 | if (!addr.isEmpty()) |
67155d92 EL |
201 | signVerifyMessageDialog->setAddress_VM(addr); |
202 | } | |
203 | ||
a41d5fe0 | 204 | bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient) |
67155d92 EL |
205 | { |
206 | // URI has to be valid | |
a41d5fe0 | 207 | if (sendCoinsPage->handlePaymentRequest(recipient)) |
67155d92 EL |
208 | { |
209 | gotoSendCoinsPage(); | |
210 | return true; | |
211 | } | |
212 | else | |
213 | return false; | |
214 | } | |
215 | ||
216 | void WalletView::showOutOfSyncWarning(bool fShow) | |
217 | { | |
218 | overviewPage->showOutOfSyncWarning(fShow); | |
219 | } | |
220 | ||
221 | void WalletView::setEncryptionStatus() | |
222 | { | |
223 | gui->setEncryptionStatus(walletModel->getEncryptionStatus()); | |
224 | } | |
225 | ||
226 | void WalletView::encryptWallet(bool status) | |
227 | { | |
228 | if(!walletModel) | |
229 | return; | |
46fd626b | 230 | AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this); |
67155d92 EL |
231 | dlg.setModel(walletModel); |
232 | dlg.exec(); | |
233 | ||
234 | setEncryptionStatus(); | |
235 | } | |
236 | ||
237 | void WalletView::backupWallet() | |
238 | { | |
25c0cce7 | 239 | #if QT_VERSION < 0x050000 |
67155d92 | 240 | QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); |
25c0cce7 WL |
241 | #else |
242 | QString saveDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); | |
243 | #endif | |
67155d92 | 244 | QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); |
8726de26 PK |
245 | if (!filename.isEmpty()) { |
246 | if (!walletModel->backupWallet(filename)) { | |
67155d92 EL |
247 | gui->message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."), |
248 | CClientUIInterface::MSG_ERROR); | |
249 | } | |
250 | else | |
251 | gui->message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."), | |
252 | CClientUIInterface::MSG_INFORMATION); | |
253 | } | |
254 | } | |
255 | ||
256 | void WalletView::changePassphrase() | |
257 | { | |
258 | AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this); | |
259 | dlg.setModel(walletModel); | |
260 | dlg.exec(); | |
261 | } | |
262 | ||
263 | void WalletView::unlockWallet() | |
264 | { | |
265 | if(!walletModel) | |
266 | return; | |
267 | // Unlock wallet when requested by wallet model | |
8726de26 | 268 | if (walletModel->getEncryptionStatus() == WalletModel::Locked) |
67155d92 EL |
269 | { |
270 | AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); | |
271 | dlg.setModel(walletModel); | |
272 | dlg.exec(); | |
273 | } | |
274 | } |