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