PageRenderTime 83ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/qt/walletview.cpp

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