You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

walletview.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // Copyright (c) 2011-2016 The Starwels 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 "starwelsgui.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. connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
  60. // Double-clicking on a transaction on the transaction history page shows details
  61. connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
  62. // Clicking on "Export" allows to export the transaction list
  63. connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked()));
  64. // Pass through messages from sendCoinsPage
  65. connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
  66. // Pass through messages from transactionView
  67. connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
  68. }
  69. WalletView::~WalletView()
  70. {
  71. }
  72. void WalletView::setStarwelsGUI(StarwelsGUI *gui)
  73. {
  74. if (gui)
  75. {
  76. // Clicking on a transaction on the overview page simply sends you to transaction history page
  77. connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage()));
  78. // Receive and report messages
  79. connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
  80. // Pass through encryption status changed signals
  81. connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
  82. // Pass through transaction notifications
  83. connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
  84. // Connect HD enabled state signal
  85. connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int)));
  86. }
  87. }
  88. void WalletView::setClientModel(ClientModel *_clientModel)
  89. {
  90. this->clientModel = _clientModel;
  91. overviewPage->setClientModel(_clientModel);
  92. sendCoinsPage->setClientModel(_clientModel);
  93. }
  94. void WalletView::setWalletModel(WalletModel *_walletModel)
  95. {
  96. this->walletModel = _walletModel;
  97. // Put transaction list in tabs
  98. transactionView->setModel(_walletModel);
  99. overviewPage->setWalletModel(_walletModel);
  100. receiveCoinsPage->setModel(_walletModel);
  101. sendCoinsPage->setModel(_walletModel);
  102. usedReceivingAddressesPage->setModel(_walletModel->getAddressTableModel());
  103. usedSendingAddressesPage->setModel(_walletModel->getAddressTableModel());
  104. if (_walletModel)
  105. {
  106. // Receive and pass through messages from wallet model
  107. connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
  108. // Handle changes in encryption status
  109. connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
  110. updateEncryptionStatus();
  111. // update HD status
  112. Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled());
  113. // Balloon pop-up for new transaction
  114. connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
  115. this, SLOT(processNewTransaction(QModelIndex,int,int)));
  116. // Ask for passphrase if needed
  117. connect(_walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
  118. // Show progress dialog
  119. connect(_walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
  120. }
  121. }
  122. void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/)
  123. {
  124. // Prevent balloon-spam when initial block download is in progress
  125. if (!walletModel || !clientModel || clientModel->inInitialBlockDownload())
  126. return;
  127. TransactionTableModel *ttm = walletModel->getTransactionTableModel();
  128. if (!ttm || ttm->processingQueuedTransactions())
  129. return;
  130. QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
  131. qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
  132. QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();
  133. QModelIndex index = ttm->index(start, 0, parent);
  134. QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
  135. QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
  136. Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
  137. }
  138. void WalletView::gotoOverviewPage()
  139. {
  140. setCurrentWidget(overviewPage);
  141. }
  142. void WalletView::gotoHistoryPage()
  143. {
  144. setCurrentWidget(transactionsPage);
  145. }
  146. void WalletView::gotoReceiveCoinsPage()
  147. {
  148. setCurrentWidget(receiveCoinsPage);
  149. }
  150. void WalletView::gotoSendCoinsPage(QString addr)
  151. {
  152. setCurrentWidget(sendCoinsPage);
  153. if (!addr.isEmpty())
  154. sendCoinsPage->setAddress(addr);
  155. }
  156. void WalletView::gotoSignMessageTab(QString addr)
  157. {
  158. // calls show() in showTab_SM()
  159. SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
  160. signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
  161. signVerifyMessageDialog->setModel(walletModel);
  162. signVerifyMessageDialog->showTab_SM(true);
  163. if (!addr.isEmpty())
  164. signVerifyMessageDialog->setAddress_SM(addr);
  165. }
  166. void WalletView::gotoVerifyMessageTab(QString addr)
  167. {
  168. // calls show() in showTab_VM()
  169. SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
  170. signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
  171. signVerifyMessageDialog->setModel(walletModel);
  172. signVerifyMessageDialog->showTab_VM(true);
  173. if (!addr.isEmpty())
  174. signVerifyMessageDialog->setAddress_VM(addr);
  175. }
  176. bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
  177. {
  178. return sendCoinsPage->handlePaymentRequest(recipient);
  179. }
  180. void WalletView::showOutOfSyncWarning(bool fShow)
  181. {
  182. overviewPage->showOutOfSyncWarning(fShow);
  183. }
  184. void WalletView::updateEncryptionStatus()
  185. {
  186. Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
  187. }
  188. void WalletView::encryptWallet(bool status)
  189. {
  190. if(!walletModel)
  191. return;
  192. AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
  193. dlg.setModel(walletModel);
  194. dlg.exec();
  195. updateEncryptionStatus();
  196. }
  197. void WalletView::backupWallet()
  198. {
  199. QString filename = GUIUtil::getSaveFileName(this,
  200. tr("Backup Wallet"), QString(),
  201. tr("Wallet Data (*.dat)"), nullptr);
  202. if (filename.isEmpty())
  203. return;
  204. if (!walletModel->backupWallet(filename)) {
  205. Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
  206. CClientUIInterface::MSG_ERROR);
  207. }
  208. else {
  209. Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename),
  210. CClientUIInterface::MSG_INFORMATION);
  211. }
  212. }
  213. void WalletView::changePassphrase()
  214. {
  215. AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
  216. dlg.setModel(walletModel);
  217. dlg.exec();
  218. }
  219. void WalletView::unlockWallet()
  220. {
  221. if(!walletModel)
  222. return;
  223. // Unlock wallet when requested by wallet model
  224. if (walletModel->getEncryptionStatus() == WalletModel::Locked)
  225. {
  226. AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
  227. dlg.setModel(walletModel);
  228. dlg.exec();
  229. }
  230. }
  231. void WalletView::usedSendingAddresses()
  232. {
  233. if(!walletModel)
  234. return;
  235. usedSendingAddressesPage->show();
  236. usedSendingAddressesPage->raise();
  237. usedSendingAddressesPage->activateWindow();
  238. }
  239. void WalletView::usedReceivingAddresses()
  240. {
  241. if(!walletModel)
  242. return;
  243. usedReceivingAddressesPage->show();
  244. usedReceivingAddressesPage->raise();
  245. usedReceivingAddressesPage->activateWindow();
  246. }
  247. void WalletView::showProgress(const QString &title, int nProgress)
  248. {
  249. if (nProgress == 0)
  250. {
  251. progressDialog = new QProgressDialog(title, "", 0, 100);
  252. progressDialog->setWindowModality(Qt::ApplicationModal);
  253. progressDialog->setMinimumDuration(0);
  254. progressDialog->setCancelButton(0);
  255. progressDialog->setAutoClose(false);
  256. progressDialog->setValue(0);
  257. }
  258. else if (nProgress == 100)
  259. {
  260. if (progressDialog)
  261. {
  262. progressDialog->close();
  263. progressDialog->deleteLater();
  264. }
  265. }
  266. else if (progressDialog)
  267. progressDialog->setValue(nProgress);
  268. }
  269. void WalletView::requestedSyncWarningInfo()
  270. {
  271. Q_EMIT outOfSyncWarningClicked();
  272. }