LCOV - code coverage report
Current view: top level - src/qt - walletview.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 209 0.0 %
Date: 2020-09-26 01:30:44 Functions: 0 26 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2011-2020 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 <qt/walletview.h>
       6             : 
       7             : #include <qt/addressbookpage.h>
       8             : #include <qt/askpassphrasedialog.h>
       9             : #include <qt/clientmodel.h>
      10             : #include <qt/guiutil.h>
      11             : #include <qt/psbtoperationsdialog.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>
      21             : 
      22             : #include <interfaces/node.h>
      23             : #include <node/ui_interface.h>
      24             : #include <psbt.h>
      25             : #include <util/strencodings.h>
      26             : 
      27             : #include <QAction>
      28             : #include <QActionGroup>
      29             : #include <QApplication>
      30             : #include <QClipboard>
      31             : #include <QFileDialog>
      32             : #include <QHBoxLayout>
      33             : #include <QProgressDialog>
      34             : #include <QPushButton>
      35             : #include <QVBoxLayout>
      36             : 
      37           0 : WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent):
      38           0 :     QStackedWidget(parent),
      39           0 :     clientModel(nullptr),
      40           0 :     walletModel(nullptr),
      41           0 :     platformStyle(_platformStyle)
      42           0 : {
      43             :     // Create tabs
      44           0 :     overviewPage = new OverviewPage(platformStyle);
      45             : 
      46           0 :     transactionsPage = new QWidget(this);
      47           0 :     QVBoxLayout *vbox = new QVBoxLayout();
      48           0 :     QHBoxLayout *hbox_buttons = new QHBoxLayout();
      49           0 :     transactionView = new TransactionView(platformStyle, this);
      50           0 :     vbox->addWidget(transactionView);
      51           0 :     QPushButton *exportButton = new QPushButton(tr("&Export"), this);
      52           0 :     exportButton->setToolTip(tr("Export the data in the current tab to a file"));
      53           0 :     if (platformStyle->getImagesOnButtons()) {
      54           0 :         exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
      55           0 :     }
      56           0 :     hbox_buttons->addStretch();
      57           0 :     hbox_buttons->addWidget(exportButton);
      58           0 :     vbox->addLayout(hbox_buttons);
      59           0 :     transactionsPage->setLayout(vbox);
      60             : 
      61           0 :     receiveCoinsPage = new ReceiveCoinsDialog(platformStyle);
      62           0 :     sendCoinsPage = new SendCoinsDialog(platformStyle);
      63             : 
      64           0 :     usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
      65           0 :     usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
      66             : 
      67           0 :     addWidget(overviewPage);
      68           0 :     addWidget(transactionsPage);
      69           0 :     addWidget(receiveCoinsPage);
      70           0 :     addWidget(sendCoinsPage);
      71             : 
      72           0 :     connect(overviewPage, &OverviewPage::transactionClicked, this, &WalletView::transactionClicked);
      73             :     // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
      74           0 :     connect(overviewPage, &OverviewPage::transactionClicked, transactionView, static_cast<void (TransactionView::*)(const QModelIndex&)>(&TransactionView::focusTransaction));
      75             : 
      76           0 :     connect(overviewPage, &OverviewPage::outOfSyncWarningClicked, this, &WalletView::requestedSyncWarningInfo);
      77             : 
      78           0 :     connect(sendCoinsPage, &SendCoinsDialog::coinsSent, this, &WalletView::coinsSent);
      79             :     // Highlight transaction after send
      80           0 :     connect(sendCoinsPage, &SendCoinsDialog::coinsSent, transactionView, static_cast<void (TransactionView::*)(const uint256&)>(&TransactionView::focusTransaction));
      81             : 
      82             :     // Clicking on "Export" allows to export the transaction list
      83           0 :     connect(exportButton, &QPushButton::clicked, transactionView, &TransactionView::exportClicked);
      84             : 
      85             :     // Pass through messages from sendCoinsPage
      86           0 :     connect(sendCoinsPage, &SendCoinsDialog::message, this, &WalletView::message);
      87             :     // Pass through messages from transactionView
      88           0 :     connect(transactionView, &TransactionView::message, this, &WalletView::message);
      89             : 
      90           0 :     connect(this, &WalletView::setPrivacy, overviewPage, &OverviewPage::setPrivacy);
      91           0 : }
      92             : 
      93           0 : WalletView::~WalletView()
      94           0 : {
      95           0 : }
      96             : 
      97           0 : void WalletView::setClientModel(ClientModel *_clientModel)
      98             : {
      99           0 :     this->clientModel = _clientModel;
     100             : 
     101           0 :     overviewPage->setClientModel(_clientModel);
     102           0 :     sendCoinsPage->setClientModel(_clientModel);
     103           0 :     if (walletModel) walletModel->setClientModel(_clientModel);
     104           0 : }
     105             : 
     106           0 : void WalletView::setWalletModel(WalletModel *_walletModel)
     107             : {
     108           0 :     this->walletModel = _walletModel;
     109             : 
     110             :     // Put transaction list in tabs
     111           0 :     transactionView->setModel(_walletModel);
     112           0 :     overviewPage->setWalletModel(_walletModel);
     113           0 :     receiveCoinsPage->setModel(_walletModel);
     114           0 :     sendCoinsPage->setModel(_walletModel);
     115           0 :     usedReceivingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr);
     116           0 :     usedSendingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr);
     117             : 
     118           0 :     if (_walletModel)
     119             :     {
     120             :         // Receive and pass through messages from wallet model
     121           0 :         connect(_walletModel, &WalletModel::message, this, &WalletView::message);
     122             : 
     123             :         // Handle changes in encryption status
     124           0 :         connect(_walletModel, &WalletModel::encryptionStatusChanged, this, &WalletView::encryptionStatusChanged);
     125           0 :         updateEncryptionStatus();
     126             : 
     127             :         // update HD status
     128           0 :         Q_EMIT hdEnabledStatusChanged();
     129             : 
     130             :         // Balloon pop-up for new transaction
     131           0 :         connect(_walletModel->getTransactionTableModel(), &TransactionTableModel::rowsInserted, this, &WalletView::processNewTransaction);
     132             : 
     133             :         // Ask for passphrase if needed
     134           0 :         connect(_walletModel, &WalletModel::requireUnlock, this, &WalletView::unlockWallet);
     135             : 
     136             :         // Show progress dialog
     137           0 :         connect(_walletModel, &WalletModel::showProgress, this, &WalletView::showProgress);
     138           0 :     }
     139           0 : }
     140             : 
     141           0 : void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/)
     142             : {
     143             :     // Prevent balloon-spam when initial block download is in progress
     144           0 :     if (!walletModel || !clientModel || clientModel->node().isInitialBlockDownload())
     145             :         return;
     146             : 
     147           0 :     TransactionTableModel *ttm = walletModel->getTransactionTableModel();
     148           0 :     if (!ttm || ttm->processingQueuedTransactions())
     149           0 :         return;
     150             : 
     151           0 :     QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
     152           0 :     qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
     153           0 :     QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();
     154           0 :     QModelIndex index = ttm->index(start, 0, parent);
     155           0 :     QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
     156           0 :     QString label = GUIUtil::HtmlEscape(ttm->data(index, TransactionTableModel::LabelRole).toString());
     157             : 
     158           0 :     Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label, GUIUtil::HtmlEscape(walletModel->getWalletName()));
     159           0 : }
     160             : 
     161           0 : void WalletView::gotoOverviewPage()
     162             : {
     163           0 :     setCurrentWidget(overviewPage);
     164           0 : }
     165             : 
     166           0 : void WalletView::gotoHistoryPage()
     167             : {
     168           0 :     setCurrentWidget(transactionsPage);
     169           0 : }
     170             : 
     171           0 : void WalletView::gotoReceiveCoinsPage()
     172             : {
     173           0 :     setCurrentWidget(receiveCoinsPage);
     174           0 : }
     175             : 
     176           0 : void WalletView::gotoSendCoinsPage(QString addr)
     177             : {
     178           0 :     setCurrentWidget(sendCoinsPage);
     179             : 
     180           0 :     if (!addr.isEmpty())
     181           0 :         sendCoinsPage->setAddress(addr);
     182           0 : }
     183             : 
     184           0 : void WalletView::gotoSignMessageTab(QString addr)
     185             : {
     186             :     // calls show() in showTab_SM()
     187           0 :     SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
     188           0 :     signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
     189           0 :     signVerifyMessageDialog->setModel(walletModel);
     190           0 :     signVerifyMessageDialog->showTab_SM(true);
     191             : 
     192           0 :     if (!addr.isEmpty())
     193           0 :         signVerifyMessageDialog->setAddress_SM(addr);
     194           0 : }
     195             : 
     196           0 : void WalletView::gotoVerifyMessageTab(QString addr)
     197             : {
     198             :     // calls show() in showTab_VM()
     199           0 :     SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
     200           0 :     signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
     201           0 :     signVerifyMessageDialog->setModel(walletModel);
     202           0 :     signVerifyMessageDialog->showTab_VM(true);
     203             : 
     204           0 :     if (!addr.isEmpty())
     205           0 :         signVerifyMessageDialog->setAddress_VM(addr);
     206           0 : }
     207             : 
     208           0 : void WalletView::gotoLoadPSBT(bool from_clipboard)
     209             : {
     210           0 :     std::string data;
     211             : 
     212           0 :     if (from_clipboard) {
     213           0 :         std::string raw = QApplication::clipboard()->text().toStdString();
     214           0 :         bool invalid;
     215           0 :         data = DecodeBase64(raw, &invalid);
     216           0 :         if (invalid) {
     217           0 :             Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);
     218           0 :             return;
     219             :         }
     220           0 :     } else {
     221           0 :         QString filename = GUIUtil::getOpenFileName(this,
     222           0 :             tr("Load Transaction Data"), QString(),
     223           0 :             tr("Partially Signed Transaction (*.psbt)"), nullptr);
     224           0 :         if (filename.isEmpty()) return;
     225           0 :         if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
     226           0 :             Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
     227           0 :             return;
     228             :         }
     229           0 :         std::ifstream in(filename.toLocal8Bit().data(), std::ios::binary);
     230           0 :         data = std::string(std::istreambuf_iterator<char>{in}, {});
     231           0 :     }
     232             : 
     233           0 :     std::string error;
     234           0 :     PartiallySignedTransaction psbtx;
     235           0 :     if (!DecodeRawPSBT(psbtx, data, error)) {
     236           0 :         Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
     237           0 :         return;
     238             :     }
     239             : 
     240           0 :     PSBTOperationsDialog* dlg = new PSBTOperationsDialog(this, walletModel, clientModel);
     241           0 :     dlg->openWithPSBT(psbtx);
     242           0 :     dlg->setAttribute(Qt::WA_DeleteOnClose);
     243           0 :     dlg->exec();
     244           0 : }
     245             : 
     246           0 : bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
     247             : {
     248           0 :     return sendCoinsPage->handlePaymentRequest(recipient);
     249             : }
     250             : 
     251           0 : void WalletView::showOutOfSyncWarning(bool fShow)
     252             : {
     253           0 :     overviewPage->showOutOfSyncWarning(fShow);
     254           0 : }
     255             : 
     256           0 : void WalletView::updateEncryptionStatus()
     257             : {
     258           0 :     Q_EMIT encryptionStatusChanged();
     259           0 : }
     260             : 
     261           0 : void WalletView::encryptWallet(bool status)
     262             : {
     263           0 :     if(!walletModel)
     264             :         return;
     265           0 :     AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
     266           0 :     dlg.setModel(walletModel);
     267           0 :     dlg.exec();
     268             : 
     269           0 :     updateEncryptionStatus();
     270           0 : }
     271             : 
     272           0 : void WalletView::backupWallet()
     273             : {
     274           0 :     QString filename = GUIUtil::getSaveFileName(this,
     275           0 :         tr("Backup Wallet"), QString(),
     276           0 :         tr("Wallet Data (*.dat)"), nullptr);
     277             : 
     278           0 :     if (filename.isEmpty())
     279           0 :         return;
     280             : 
     281           0 :     if (!walletModel->wallet().backupWallet(filename.toLocal8Bit().data())) {
     282           0 :         Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
     283             :             CClientUIInterface::MSG_ERROR);
     284           0 :         }
     285             :     else {
     286           0 :         Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename),
     287             :             CClientUIInterface::MSG_INFORMATION);
     288             :     }
     289           0 : }
     290             : 
     291           0 : void WalletView::changePassphrase()
     292             : {
     293           0 :     AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
     294           0 :     dlg.setModel(walletModel);
     295           0 :     dlg.exec();
     296           0 : }
     297             : 
     298           0 : void WalletView::unlockWallet()
     299             : {
     300           0 :     if(!walletModel)
     301             :         return;
     302             :     // Unlock wallet when requested by wallet model
     303           0 :     if (walletModel->getEncryptionStatus() == WalletModel::Locked)
     304             :     {
     305           0 :         AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
     306           0 :         dlg.setModel(walletModel);
     307           0 :         dlg.exec();
     308           0 :     }
     309           0 : }
     310             : 
     311           0 : void WalletView::usedSendingAddresses()
     312             : {
     313           0 :     if(!walletModel)
     314             :         return;
     315             : 
     316           0 :     GUIUtil::bringToFront(usedSendingAddressesPage);
     317           0 : }
     318             : 
     319           0 : void WalletView::usedReceivingAddresses()
     320             : {
     321           0 :     if(!walletModel)
     322             :         return;
     323             : 
     324           0 :     GUIUtil::bringToFront(usedReceivingAddressesPage);
     325           0 : }
     326             : 
     327           0 : void WalletView::showProgress(const QString &title, int nProgress)
     328             : {
     329           0 :     if (nProgress == 0) {
     330           0 :         progressDialog = new QProgressDialog(title, tr("Cancel"), 0, 100);
     331           0 :         GUIUtil::PolishProgressDialog(progressDialog);
     332           0 :         progressDialog->setWindowModality(Qt::ApplicationModal);
     333           0 :         progressDialog->setMinimumDuration(0);
     334           0 :         progressDialog->setAutoClose(false);
     335           0 :         progressDialog->setValue(0);
     336           0 :     } else if (nProgress == 100) {
     337           0 :         if (progressDialog) {
     338           0 :             progressDialog->close();
     339           0 :             progressDialog->deleteLater();
     340           0 :             progressDialog = nullptr;
     341           0 :         }
     342           0 :     } else if (progressDialog) {
     343           0 :         if (progressDialog->wasCanceled()) {
     344           0 :             getWalletModel()->wallet().abortRescan();
     345           0 :         } else {
     346           0 :             progressDialog->setValue(nProgress);
     347             :         }
     348             :     }
     349           0 : }
     350             : 
     351           0 : void WalletView::requestedSyncWarningInfo()
     352             : {
     353           0 :     Q_EMIT outOfSyncWarningClicked();
     354           0 : }

Generated by: LCOV version 1.15