2018-01-02 18:12:05 +01:00
|
|
|
// Copyright (c) 2011-2017 The Bitcoin Core developers
|
2014-12-13 05:09:33 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-11-04 16:20:43 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2018-01-16 21:11:40 +01:00
|
|
|
#include <wallet/wallet.h>
|
|
|
|
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <qt/receivecoinsdialog.h>
|
2017-08-15 17:31:26 +02:00
|
|
|
#include <qt/forms/ui_receivecoinsdialog.h>
|
2013-10-16 15:14:26 +02:00
|
|
|
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <qt/addressbookpage.h>
|
|
|
|
#include <qt/addresstablemodel.h>
|
|
|
|
#include <qt/bitcoinunits.h>
|
|
|
|
#include <qt/optionsmodel.h>
|
|
|
|
#include <qt/platformstyle.h>
|
|
|
|
#include <qt/receiverequestdialog.h>
|
|
|
|
#include <qt/recentrequeststablemodel.h>
|
|
|
|
#include <qt/walletmodel.h>
|
2013-10-16 15:14:26 +02:00
|
|
|
|
2014-01-26 06:37:17 +01:00
|
|
|
#include <QAction>
|
|
|
|
#include <QCursor>
|
2013-10-16 15:14:26 +02:00
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QScrollBar>
|
2014-05-06 12:52:21 +02:00
|
|
|
#include <QTextDocument>
|
2013-10-16 15:14:26 +02:00
|
|
|
|
2016-09-09 13:43:29 +02:00
|
|
|
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
|
2013-10-16 15:14:26 +02:00
|
|
|
QDialog(parent),
|
|
|
|
ui(new Ui::ReceiveCoinsDialog),
|
2016-11-18 15:47:20 +01:00
|
|
|
columnResizingFixer(0),
|
2015-07-28 15:20:14 +02:00
|
|
|
model(0),
|
2016-09-09 13:43:29 +02:00
|
|
|
platformStyle(_platformStyle)
|
2013-10-16 15:14:26 +02:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
2016-09-09 13:43:29 +02:00
|
|
|
if (!_platformStyle->getImagesOnButtons()) {
|
2015-07-28 15:20:14 +02:00
|
|
|
ui->clearButton->setIcon(QIcon());
|
|
|
|
ui->receiveButton->setIcon(QIcon());
|
|
|
|
ui->showRequestButton->setIcon(QIcon());
|
|
|
|
ui->removeRequestButton->setIcon(QIcon());
|
|
|
|
} else {
|
2016-09-09 13:43:29 +02:00
|
|
|
ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
|
|
|
|
ui->receiveButton->setIcon(_platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
|
|
|
|
ui->showRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/edit"));
|
|
|
|
ui->removeRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
|
2015-07-28 15:20:14 +02:00
|
|
|
}
|
2014-01-26 06:37:17 +01:00
|
|
|
|
|
|
|
// context menu actions
|
2016-10-14 01:27:26 +02:00
|
|
|
QAction *copyURIAction = new QAction(tr("Copy URI"), this);
|
2014-01-26 06:37:17 +01:00
|
|
|
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
|
|
|
|
QAction *copyMessageAction = new QAction(tr("Copy message"), this);
|
|
|
|
QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
|
|
|
|
|
|
|
|
// context menu
|
2016-11-18 15:47:20 +01:00
|
|
|
contextMenu = new QMenu(this);
|
2016-10-14 01:27:26 +02:00
|
|
|
contextMenu->addAction(copyURIAction);
|
2014-01-26 06:37:17 +01:00
|
|
|
contextMenu->addAction(copyLabelAction);
|
|
|
|
contextMenu->addAction(copyMessageAction);
|
|
|
|
contextMenu->addAction(copyAmountAction);
|
|
|
|
|
|
|
|
// context menu signals
|
|
|
|
connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
|
2016-10-14 01:27:26 +02:00
|
|
|
connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI()));
|
2014-01-26 06:37:17 +01:00
|
|
|
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
|
|
|
|
connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
|
|
|
|
connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
|
|
|
|
|
2013-10-16 15:14:26 +02:00
|
|
|
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
|
|
|
}
|
|
|
|
|
2016-09-09 13:43:29 +02:00
|
|
|
void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
2013-10-16 15:14:26 +02:00
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
this->model = _model;
|
2013-10-16 15:14:26 +02:00
|
|
|
|
2016-09-09 13:43:29 +02:00
|
|
|
if(_model && _model->getOptionsModel())
|
2013-10-16 15:14:26 +02:00
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
_model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
|
|
|
|
connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
2014-03-21 06:45:47 +01:00
|
|
|
updateDisplayUnit();
|
|
|
|
|
|
|
|
QTableView* tableView = ui->recentRequestsView;
|
|
|
|
|
|
|
|
tableView->verticalHeader()->hide();
|
|
|
|
tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
2016-09-09 13:43:29 +02:00
|
|
|
tableView->setModel(_model->getRecentRequestsTableModel());
|
2014-03-21 06:45:47 +01:00
|
|
|
tableView->setAlternatingRowColors(true);
|
|
|
|
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
|
|
|
tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
|
|
|
|
tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
|
2016-01-20 14:57:28 +01:00
|
|
|
tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
|
2014-03-21 06:45:47 +01:00
|
|
|
|
2014-03-21 15:04:32 +01:00
|
|
|
connect(tableView->selectionModel(),
|
2014-03-21 09:12:01 +01:00
|
|
|
SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
|
2014-05-06 12:52:21 +02:00
|
|
|
SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
|
2014-03-21 09:12:01 +01:00
|
|
|
// Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
|
2016-11-18 15:47:20 +01:00
|
|
|
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
|
2018-01-17 19:23:26 +01:00
|
|
|
|
|
|
|
// configure bech32 checkbox, disable if launched with legacy as default:
|
2017-04-18 00:56:44 +02:00
|
|
|
if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
|
2018-01-17 19:23:26 +01:00
|
|
|
ui->useBech32->setCheckState(Qt::Checked);
|
|
|
|
} else {
|
|
|
|
ui->useBech32->setCheckState(Qt::Unchecked);
|
|
|
|
}
|
|
|
|
|
2017-04-18 00:56:44 +02:00
|
|
|
ui->useBech32->setVisible(model->wallet().getDefaultAddressType() != OutputType::LEGACY);
|
2013-10-16 15:14:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReceiveCoinsDialog::~ReceiveCoinsDialog()
|
|
|
|
{
|
|
|
|
delete ui;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::clear()
|
|
|
|
{
|
|
|
|
ui->reqAmount->clear();
|
|
|
|
ui->reqLabel->setText("");
|
|
|
|
ui->reqMessage->setText("");
|
|
|
|
updateDisplayUnit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::reject()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::accept()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::updateDisplayUnit()
|
|
|
|
{
|
|
|
|
if(model && model->getOptionsModel())
|
|
|
|
{
|
|
|
|
ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::on_receiveButton_clicked()
|
|
|
|
{
|
2013-11-05 18:03:05 +01:00
|
|
|
if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
|
2013-10-16 15:14:26 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
QString address;
|
|
|
|
QString label = ui->reqLabel->text();
|
2014-02-21 05:43:29 +01:00
|
|
|
/* Generate new receiving address */
|
2017-04-18 00:56:44 +02:00
|
|
|
OutputType address_type = model->wallet().getDefaultAddressType();
|
2018-02-11 03:06:35 +01:00
|
|
|
if (address_type != OutputType::LEGACY) {
|
|
|
|
address_type = ui->useBech32->isChecked() ? OutputType::BECH32 : OutputType::P2SH_SEGWIT;
|
2018-01-16 21:11:40 +01:00
|
|
|
}
|
|
|
|
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
|
2013-10-18 13:45:11 +02:00
|
|
|
SendCoinsRecipient info(address, label,
|
2013-12-03 09:25:24 +01:00
|
|
|
ui->reqAmount->value(), ui->reqMessage->text());
|
2013-10-18 14:25:35 +02:00
|
|
|
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
|
2013-12-03 09:25:24 +01:00
|
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
2018-03-06 06:17:36 +01:00
|
|
|
dialog->setModel(model);
|
2013-10-18 14:25:35 +02:00
|
|
|
dialog->setInfo(info);
|
2013-10-16 15:14:26 +02:00
|
|
|
dialog->show();
|
|
|
|
clear();
|
2013-11-05 18:03:05 +01:00
|
|
|
|
|
|
|
/* Store request for later reference */
|
|
|
|
model->getRecentRequestsTableModel()->addNewRequest(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
|
|
|
|
{
|
|
|
|
const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
|
|
|
|
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
|
2018-03-06 06:17:36 +01:00
|
|
|
dialog->setModel(model);
|
2013-11-05 18:03:05 +01:00
|
|
|
dialog->setInfo(submodel->entry(index.row()).recipient);
|
|
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
dialog->show();
|
|
|
|
}
|
|
|
|
|
2014-05-06 12:52:21 +02:00
|
|
|
void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
2014-03-15 00:41:23 +01:00
|
|
|
{
|
|
|
|
// Enable Show/Remove buttons only if anything is selected.
|
|
|
|
bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
|
|
|
|
ui->showRequestButton->setEnabled(enable);
|
|
|
|
ui->removeRequestButton->setEnabled(enable);
|
|
|
|
}
|
|
|
|
|
2013-11-05 18:03:05 +01:00
|
|
|
void ReceiveCoinsDialog::on_showRequestButton_clicked()
|
|
|
|
{
|
|
|
|
if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
|
|
|
|
return;
|
|
|
|
QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
|
|
|
|
|
2017-06-02 03:25:02 +02:00
|
|
|
for (const QModelIndex& index : selection) {
|
2013-11-05 18:03:05 +01:00
|
|
|
on_recentRequestsView_doubleClicked(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReceiveCoinsDialog::on_removeRequestButton_clicked()
|
|
|
|
{
|
|
|
|
if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
|
|
|
|
return;
|
|
|
|
QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
|
|
|
|
if(selection.empty())
|
|
|
|
return;
|
|
|
|
// correct for selection mode ContiguousSelection
|
|
|
|
QModelIndex firstIndex = selection.at(0);
|
|
|
|
model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
|
2013-10-16 15:14:26 +02:00
|
|
|
}
|
2014-01-26 06:37:17 +01:00
|
|
|
|
2014-03-21 09:12:01 +01:00
|
|
|
// We override the virtual resizeEvent of the QWidget to adjust tables column
|
|
|
|
// sizes as the tables width is proportional to the dialogs width.
|
2014-05-06 12:52:21 +02:00
|
|
|
void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
|
2014-03-21 09:12:01 +01:00
|
|
|
{
|
|
|
|
QWidget::resizeEvent(event);
|
|
|
|
columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
|
2014-03-21 06:45:47 +01:00
|
|
|
}
|
|
|
|
|
2014-01-26 06:37:17 +01:00
|
|
|
void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
|
|
|
|
{
|
|
|
|
if (event->key() == Qt::Key_Return)
|
|
|
|
{
|
|
|
|
// press return -> submit form
|
|
|
|
if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus())
|
|
|
|
{
|
|
|
|
event->ignore();
|
|
|
|
on_receiveButton_clicked();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this->QDialog::keyPressEvent(event);
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:27:26 +02:00
|
|
|
QModelIndex ReceiveCoinsDialog::selectedRow()
|
2014-01-26 06:37:17 +01:00
|
|
|
{
|
|
|
|
if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
|
2016-10-14 01:27:26 +02:00
|
|
|
return QModelIndex();
|
2014-01-26 06:37:17 +01:00
|
|
|
QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
|
|
|
|
if(selection.empty())
|
2016-10-14 01:27:26 +02:00
|
|
|
return QModelIndex();
|
2014-01-26 06:37:17 +01:00
|
|
|
// correct for selection mode ContiguousSelection
|
|
|
|
QModelIndex firstIndex = selection.at(0);
|
2016-10-14 01:27:26 +02:00
|
|
|
return firstIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy column of selected row to clipboard
|
|
|
|
void ReceiveCoinsDialog::copyColumnToClipboard(int column)
|
|
|
|
{
|
|
|
|
QModelIndex firstIndex = selectedRow();
|
|
|
|
if (!firstIndex.isValid()) {
|
|
|
|
return;
|
|
|
|
}
|
2014-01-26 06:37:17 +01:00
|
|
|
GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
// context menu
|
|
|
|
void ReceiveCoinsDialog::showMenu(const QPoint &point)
|
|
|
|
{
|
2016-10-14 01:27:26 +02:00
|
|
|
if (!selectedRow().isValid()) {
|
2014-01-26 06:37:17 +01:00
|
|
|
return;
|
2016-10-14 01:27:26 +02:00
|
|
|
}
|
2014-01-26 06:37:17 +01:00
|
|
|
contextMenu->exec(QCursor::pos());
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:27:26 +02:00
|
|
|
// context menu action: copy URI
|
|
|
|
void ReceiveCoinsDialog::copyURI()
|
|
|
|
{
|
|
|
|
QModelIndex sel = selectedRow();
|
|
|
|
if (!sel.isValid()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel();
|
|
|
|
const QString uri = GUIUtil::formatBitcoinURI(submodel->entry(sel.row()).recipient);
|
|
|
|
GUIUtil::setClipboard(uri);
|
|
|
|
}
|
|
|
|
|
2014-01-26 06:37:17 +01:00
|
|
|
// context menu action: copy label
|
|
|
|
void ReceiveCoinsDialog::copyLabel()
|
|
|
|
{
|
|
|
|
copyColumnToClipboard(RecentRequestsTableModel::Label);
|
|
|
|
}
|
|
|
|
|
|
|
|
// context menu action: copy message
|
|
|
|
void ReceiveCoinsDialog::copyMessage()
|
|
|
|
{
|
|
|
|
copyColumnToClipboard(RecentRequestsTableModel::Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
// context menu action: copy amount
|
|
|
|
void ReceiveCoinsDialog::copyAmount()
|
|
|
|
{
|
|
|
|
copyColumnToClipboard(RecentRequestsTableModel::Amount);
|
|
|
|
}
|