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

          Line data    Source code
       1             : // Copyright (c) 2011-2019 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 <wallet/wallet.h>
       6             : 
       7             : #include <qt/receivecoinsdialog.h>
       8             : #include <qt/forms/ui_receivecoinsdialog.h>
       9             : 
      10             : #include <qt/addresstablemodel.h>
      11             : #include <qt/optionsmodel.h>
      12             : #include <qt/platformstyle.h>
      13             : #include <qt/receiverequestdialog.h>
      14             : #include <qt/recentrequeststablemodel.h>
      15             : #include <qt/walletmodel.h>
      16             : 
      17             : #include <QAction>
      18             : #include <QCursor>
      19             : #include <QMessageBox>
      20             : #include <QScrollBar>
      21             : #include <QTextDocument>
      22             : 
      23           0 : ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
      24           0 :     QDialog(parent),
      25           0 :     ui(new Ui::ReceiveCoinsDialog),
      26           0 :     columnResizingFixer(nullptr),
      27           0 :     model(nullptr),
      28           0 :     platformStyle(_platformStyle)
      29           0 : {
      30           0 :     ui->setupUi(this);
      31             : 
      32           0 :     if (!_platformStyle->getImagesOnButtons()) {
      33           0 :         ui->clearButton->setIcon(QIcon());
      34           0 :         ui->receiveButton->setIcon(QIcon());
      35           0 :         ui->showRequestButton->setIcon(QIcon());
      36           0 :         ui->removeRequestButton->setIcon(QIcon());
      37           0 :     } else {
      38           0 :         ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
      39           0 :         ui->receiveButton->setIcon(_platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
      40           0 :         ui->showRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/edit"));
      41           0 :         ui->removeRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
      42             :     }
      43             : 
      44             :     // context menu actions
      45           0 :     QAction *copyURIAction = new QAction(tr("Copy URI"), this);
      46           0 :     QAction *copyLabelAction = new QAction(tr("Copy label"), this);
      47           0 :     QAction *copyMessageAction = new QAction(tr("Copy message"), this);
      48           0 :     QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
      49             : 
      50             :     // context menu
      51           0 :     contextMenu = new QMenu(this);
      52           0 :     contextMenu->addAction(copyURIAction);
      53           0 :     contextMenu->addAction(copyLabelAction);
      54           0 :     contextMenu->addAction(copyMessageAction);
      55           0 :     contextMenu->addAction(copyAmountAction);
      56             : 
      57             :     // context menu signals
      58           0 :     connect(ui->recentRequestsView, &QWidget::customContextMenuRequested, this, &ReceiveCoinsDialog::showMenu);
      59           0 :     connect(copyURIAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyURI);
      60           0 :     connect(copyLabelAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyLabel);
      61           0 :     connect(copyMessageAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyMessage);
      62           0 :     connect(copyAmountAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyAmount);
      63             : 
      64           0 :     connect(ui->clearButton, &QPushButton::clicked, this, &ReceiveCoinsDialog::clear);
      65           0 : }
      66             : 
      67           0 : void ReceiveCoinsDialog::setModel(WalletModel *_model)
      68             : {
      69           0 :     this->model = _model;
      70             : 
      71           0 :     if(_model && _model->getOptionsModel())
      72             :     {
      73           0 :         _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
      74           0 :         connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveCoinsDialog::updateDisplayUnit);
      75           0 :         updateDisplayUnit();
      76             : 
      77           0 :         QTableView* tableView = ui->recentRequestsView;
      78             : 
      79           0 :         tableView->verticalHeader()->hide();
      80           0 :         tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
      81           0 :         tableView->setModel(_model->getRecentRequestsTableModel());
      82           0 :         tableView->setAlternatingRowColors(true);
      83           0 :         tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
      84           0 :         tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
      85           0 :         tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
      86           0 :         tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
      87           0 :         tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
      88             : 
      89           0 :         connect(tableView->selectionModel(),
      90             :             &QItemSelectionModel::selectionChanged, this,
      91             :             &ReceiveCoinsDialog::recentRequestsView_selectionChanged);
      92             :         // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
      93           0 :         columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
      94             : 
      95           0 :         if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
      96           0 :             ui->useBech32->setCheckState(Qt::Checked);
      97           0 :         } else {
      98           0 :             ui->useBech32->setCheckState(Qt::Unchecked);
      99             :         }
     100             : 
     101             :         // Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
     102           0 :         ui->receiveButton->setEnabled(model->wallet().canGetAddresses());
     103             : 
     104             :         // Enable/disable the receive button if the wallet is now able/unable to give out new addresses.
     105           0 :         connect(model, &WalletModel::canGetAddressesChanged, [this] {
     106           0 :             ui->receiveButton->setEnabled(model->wallet().canGetAddresses());
     107           0 :         });
     108           0 :     }
     109           0 : }
     110             : 
     111           0 : ReceiveCoinsDialog::~ReceiveCoinsDialog()
     112           0 : {
     113           0 :     delete ui;
     114           0 : }
     115             : 
     116           0 : void ReceiveCoinsDialog::clear()
     117             : {
     118           0 :     ui->reqAmount->clear();
     119           0 :     ui->reqLabel->setText("");
     120           0 :     ui->reqMessage->setText("");
     121           0 :     updateDisplayUnit();
     122           0 : }
     123             : 
     124           0 : void ReceiveCoinsDialog::reject()
     125             : {
     126           0 :     clear();
     127           0 : }
     128             : 
     129           0 : void ReceiveCoinsDialog::accept()
     130             : {
     131           0 :     clear();
     132           0 : }
     133             : 
     134           0 : void ReceiveCoinsDialog::updateDisplayUnit()
     135             : {
     136           0 :     if(model && model->getOptionsModel())
     137             :     {
     138           0 :         ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
     139           0 :     }
     140           0 : }
     141             : 
     142           0 : void ReceiveCoinsDialog::on_receiveButton_clicked()
     143             : {
     144           0 :     if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
     145             :         return;
     146             : 
     147           0 :     QString address;
     148           0 :     QString label = ui->reqLabel->text();
     149             :     /* Generate new receiving address */
     150             :     OutputType address_type;
     151           0 :     if (ui->useBech32->isChecked()) {
     152             :         address_type = OutputType::BECH32;
     153           0 :     } else {
     154           0 :         address_type = model->wallet().getDefaultAddressType();
     155           0 :         if (address_type == OutputType::BECH32) {
     156             :             address_type = OutputType::P2SH_SEGWIT;
     157             :         }
     158             :     }
     159           0 :     address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
     160             : 
     161           0 :     switch(model->getAddressTableModel()->getEditStatus())
     162             :     {
     163             :     case AddressTableModel::EditStatus::OK: {
     164             :         // Success
     165           0 :         SendCoinsRecipient info(address, label,
     166           0 :             ui->reqAmount->value(), ui->reqMessage->text());
     167           0 :         ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
     168           0 :         dialog->setAttribute(Qt::WA_DeleteOnClose);
     169           0 :         dialog->setModel(model);
     170           0 :         dialog->setInfo(info);
     171           0 :         dialog->show();
     172             : 
     173             :         /* Store request for later reference */
     174           0 :         model->getRecentRequestsTableModel()->addNewRequest(info);
     175             :         break;
     176           0 :     }
     177             :     case AddressTableModel::EditStatus::WALLET_UNLOCK_FAILURE:
     178           0 :         QMessageBox::critical(this, windowTitle(),
     179           0 :             tr("Could not unlock wallet."),
     180             :             QMessageBox::Ok, QMessageBox::Ok);
     181           0 :         break;
     182             :     case AddressTableModel::EditStatus::KEY_GENERATION_FAILURE:
     183           0 :         QMessageBox::critical(this, windowTitle(),
     184           0 :             tr("Could not generate new %1 address").arg(QString::fromStdString(FormatOutputType(address_type))),
     185             :             QMessageBox::Ok, QMessageBox::Ok);
     186           0 :         break;
     187             :     // These aren't valid return values for our action
     188             :     case AddressTableModel::EditStatus::INVALID_ADDRESS:
     189             :     case AddressTableModel::EditStatus::DUPLICATE_ADDRESS:
     190             :     case AddressTableModel::EditStatus::NO_CHANGES:
     191           0 :         assert(false);
     192             :     }
     193           0 :     clear();
     194           0 : }
     195             : 
     196           0 : void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
     197             : {
     198           0 :     const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
     199           0 :     ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
     200           0 :     dialog->setModel(model);
     201           0 :     dialog->setInfo(submodel->entry(index.row()).recipient);
     202           0 :     dialog->setAttribute(Qt::WA_DeleteOnClose);
     203           0 :     dialog->show();
     204           0 : }
     205             : 
     206           0 : void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
     207             : {
     208             :     // Enable Show/Remove buttons only if anything is selected.
     209           0 :     bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
     210           0 :     ui->showRequestButton->setEnabled(enable);
     211           0 :     ui->removeRequestButton->setEnabled(enable);
     212           0 : }
     213             : 
     214           0 : void ReceiveCoinsDialog::on_showRequestButton_clicked()
     215             : {
     216           0 :     if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
     217             :         return;
     218           0 :     QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
     219             : 
     220           0 :     for (const QModelIndex& index : selection) {
     221           0 :         on_recentRequestsView_doubleClicked(index);
     222           0 :     }
     223           0 : }
     224             : 
     225           0 : void ReceiveCoinsDialog::on_removeRequestButton_clicked()
     226             : {
     227           0 :     if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
     228             :         return;
     229           0 :     QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
     230           0 :     if(selection.empty())
     231           0 :         return;
     232             :     // correct for selection mode ContiguousSelection
     233           0 :     QModelIndex firstIndex = selection.at(0);
     234           0 :     model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
     235           0 : }
     236             : 
     237             : // We override the virtual resizeEvent of the QWidget to adjust tables column
     238             : // sizes as the tables width is proportional to the dialogs width.
     239           0 : void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
     240             : {
     241           0 :     QWidget::resizeEvent(event);
     242           0 :     columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
     243           0 : }
     244             : 
     245           0 : QModelIndex ReceiveCoinsDialog::selectedRow()
     246             : {
     247           0 :     if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
     248           0 :         return QModelIndex();
     249           0 :     QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
     250           0 :     if(selection.empty())
     251           0 :         return QModelIndex();
     252             :     // correct for selection mode ContiguousSelection
     253           0 :     QModelIndex firstIndex = selection.at(0);
     254           0 :     return firstIndex;
     255           0 : }
     256             : 
     257             : // copy column of selected row to clipboard
     258           0 : void ReceiveCoinsDialog::copyColumnToClipboard(int column)
     259             : {
     260           0 :     QModelIndex firstIndex = selectedRow();
     261           0 :     if (!firstIndex.isValid()) {
     262           0 :         return;
     263             :     }
     264           0 :     GUIUtil::setClipboard(model->getRecentRequestsTableModel()->index(firstIndex.row(), column).data(Qt::EditRole).toString());
     265           0 : }
     266             : 
     267             : // context menu
     268           0 : void ReceiveCoinsDialog::showMenu(const QPoint &point)
     269             : {
     270           0 :     if (!selectedRow().isValid()) {
     271             :         return;
     272             :     }
     273           0 :     contextMenu->exec(QCursor::pos());
     274           0 : }
     275             : 
     276             : // context menu action: copy URI
     277           0 : void ReceiveCoinsDialog::copyURI()
     278             : {
     279           0 :     QModelIndex sel = selectedRow();
     280           0 :     if (!sel.isValid()) {
     281           0 :         return;
     282             :     }
     283             : 
     284           0 :     const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel();
     285           0 :     const QString uri = GUIUtil::formatBitcoinURI(submodel->entry(sel.row()).recipient);
     286           0 :     GUIUtil::setClipboard(uri);
     287           0 : }
     288             : 
     289             : // context menu action: copy label
     290           0 : void ReceiveCoinsDialog::copyLabel()
     291             : {
     292           0 :     copyColumnToClipboard(RecentRequestsTableModel::Label);
     293           0 : }
     294             : 
     295             : // context menu action: copy message
     296           0 : void ReceiveCoinsDialog::copyMessage()
     297             : {
     298           0 :     copyColumnToClipboard(RecentRequestsTableModel::Message);
     299           0 : }
     300             : 
     301             : // context menu action: copy amount
     302           0 : void ReceiveCoinsDialog::copyAmount()
     303             : {
     304           0 :     copyColumnToClipboard(RecentRequestsTableModel::Amount);
     305           0 : }

Generated by: LCOV version 1.15