Bitcoin Core  0.21.0rc5
P2P Digital Currency
sendcoinsentry.cpp
Go to the documentation of this file.
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 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <qt/sendcoinsentry.h>
11 
12 #include <qt/addressbookpage.h>
13 #include <qt/addresstablemodel.h>
14 #include <qt/guiutil.h>
15 #include <qt/optionsmodel.h>
16 #include <qt/platformstyle.h>
17 #include <qt/walletmodel.h>
18 
19 #include <QApplication>
20 #include <QClipboard>
21 
22 SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) :
23  QStackedWidget(parent),
24  ui(new Ui::SendCoinsEntry),
25  model(nullptr),
26  platformStyle(_platformStyle)
27 {
28  ui->setupUi(this);
29 
30  ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
31  ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
32  ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
33  ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
34  ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
35 
36  setCurrentWidget(ui->SendCoins);
37 
39  ui->payToLayout->setSpacing(4);
40 
41  // normal bitcoin address field
43  // just a label for displaying bitcoin address(es)
44  ui->payTo_is->setFont(GUIUtil::fixedPitchFont());
45 
46  // Connect signals
49  connect(ui->deleteButton, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
50  connect(ui->deleteButton_is, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
51  connect(ui->deleteButton_s, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
52  connect(ui->useAvailableBalanceButton, &QPushButton::clicked, this, &SendCoinsEntry::useAvailableBalanceClicked);
53 }
54 
56 {
57  delete ui;
58 }
59 
61 {
62  // Paste text from clipboard into recipient field
63  ui->payTo->setText(QApplication::clipboard()->text());
64 }
65 
67 {
68  if(!model)
69  return;
72  if(dlg.exec())
73  {
74  ui->payTo->setText(dlg.getReturnValue());
75  ui->payAmount->setFocus();
76  }
77 }
78 
79 void SendCoinsEntry::on_payTo_textChanged(const QString &address)
80 {
81  updateLabel(address);
82 }
83 
85 {
86  this->model = _model;
87 
88  if (_model && _model->getOptionsModel())
90 
91  clear();
92 }
93 
95 {
96  // clear UI elements for normal payment
97  ui->payTo->clear();
98  ui->addAsLabel->clear();
99  ui->payAmount->clear();
100  ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
101  ui->messageTextLabel->clear();
102  ui->messageTextLabel->hide();
103  ui->messageLabel->hide();
104  // clear UI elements for unauthenticated payment request
105  ui->payTo_is->clear();
106  ui->memoTextLabel_is->clear();
107  ui->payAmount_is->clear();
108  // clear UI elements for authenticated payment request
109  ui->payTo_s->clear();
110  ui->memoTextLabel_s->clear();
111  ui->payAmount_s->clear();
112 
113  // update the display unit, to not use the default ("BTC")
115 }
116 
118 {
119  ui->checkboxSubtractFeeFromAmount->setChecked(true);
120 }
121 
123 {
124  Q_EMIT removeEntry(this);
125 }
126 
128 {
129  Q_EMIT useAvailableBalance(this);
130 }
131 
133 {
134  if (!model)
135  return false;
136 
137  // Check input validity
138  bool retval = true;
139 
140  if (!model->validateAddress(ui->payTo->text()))
141  {
142  ui->payTo->setValid(false);
143  retval = false;
144  }
145 
146  if (!ui->payAmount->validate())
147  {
148  retval = false;
149  }
150 
151  // Sending a zero amount is invalid
152  if (ui->payAmount->value(nullptr) <= 0)
153  {
154  ui->payAmount->setValid(false);
155  retval = false;
156  }
157 
158  // Reject dust outputs:
159  if (retval && GUIUtil::isDust(node, ui->payTo->text(), ui->payAmount->value())) {
160  ui->payAmount->setValid(false);
161  retval = false;
162  }
163 
164  return retval;
165 }
166 
168 {
169  recipient.address = ui->payTo->text();
170  recipient.label = ui->addAsLabel->text();
173  recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
174 
175  return recipient;
176 }
177 
178 QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
179 {
180  QWidget::setTabOrder(prev, ui->payTo);
181  QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
182  QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
183  QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
184  QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
185  QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
186  QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
187  return ui->deleteButton;
188 }
189 
191 {
192  recipient = value;
193  {
194  // message
196  ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
197  ui->messageLabel->setVisible(!recipient.message.isEmpty());
198 
199  ui->addAsLabel->clear();
200  ui->payTo->setText(recipient.address); // this may set a label from addressbook
201  if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, don't overwrite with an empty label
202  ui->addAsLabel->setText(recipient.label);
204  }
205 }
206 
207 void SendCoinsEntry::setAddress(const QString &address)
208 {
209  ui->payTo->setText(address);
210  ui->payAmount->setFocus();
211 }
212 
214 {
215  ui->payAmount->setValue(amount);
216 }
217 
219 {
220  return ui->payTo->text().isEmpty() && ui->payTo_is->text().isEmpty() && ui->payTo_s->text().isEmpty();
221 }
222 
224 {
225  ui->payTo->setFocus();
226 }
227 
229 {
230  if(model && model->getOptionsModel())
231  {
232  // Update payAmount with the current unit
236  }
237 }
238 
239 bool SendCoinsEntry::updateLabel(const QString &address)
240 {
241  if(!model)
242  return false;
243 
244  // Fill in label from address book, if address has an associated label
245  QString associatedLabel = model->getAddressTableModel()->labelForAddress(address);
246  if(!associatedLabel.isEmpty())
247  {
248  ui->addAsLabel->setText(associatedLabel);
249  return true;
250  }
251 
252  return false;
253 }
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Widget that shows a list of sending or receiving addresses.
@ ForSelection
Open address book to pick address.
void setModel(AddressTableModel *model)
const QString & getReturnValue() const
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
void setDisplayUnit(int unit)
Change unit used to display amount.
void clear()
Make field empty and ready for new input.
bool validate()
Perform input validation, mark field as invalid if entered value is not valid.
QWidget * setupTabChain(QWidget *prev)
Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project....
void setValid(bool valid)
Mark current value as invalid in UI.
void setValue(const CAmount &value)
int getDisplayUnit() const
Definition: optionsmodel.h:84
void displayUnitChanged(int unit)
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
bool getUseExtraSpacing() const
Definition: platformstyle.h:22
void setValid(bool valid)
A single entry in the dialog for sending bitcoins.
WalletModel * model
void setFocus()
bool updateLabel(const QString &address)
void setAddress(const QString &address)
bool isClear()
Return whether the entry is still empty and unedited.
void subtractFeeFromAmountChanged()
void useAvailableBalance(SendCoinsEntry *entry)
~SendCoinsEntry()
SendCoinsRecipient recipient
void setValue(const SendCoinsRecipient &value)
void updateDisplayUnit()
void on_payTo_textChanged(const QString &address)
void on_pasteButton_clicked()
SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
void setModel(WalletModel *model)
void useAvailableBalanceClicked()
void removeEntry(SendCoinsEntry *entry)
void payAmountChanged()
void setAmount(const CAmount &amount)
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
const PlatformStyle * platformStyle
void deleteClicked()
void clear()
void on_addressBookButton_clicked()
bool validate(interfaces::Node &node)
Ui::SendCoinsEntry * ui
void checkSubtractFeeFromAmount()
SendCoinsRecipient getValue()
QToolButton * deleteButton_is
QValidatedLineEdit * payTo
QLineEdit * addAsLabel
QLabel * memoTextLabel_s
BitcoinAmountField * payAmount_is
QPushButton * useAvailableBalanceButton
QLabel * memoTextLabel_is
QToolButton * pasteButton
BitcoinAmountField * payAmount_s
QLabel * messageTextLabel
QLabel * payTo_s
QFrame * SendCoins
QCheckBox * checkboxSubtractFeeFromAmount
QLabel * payTo_is
void setupUi(QStackedWidget *SendCoinsEntry)
QHBoxLayout * payToLayout
QToolButton * deleteButton
QToolButton * addressBookButton
QToolButton * deleteButton_s
BitcoinAmountField * payAmount
QLabel * messageLabel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:52
bool validateAddress(const QString &address)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:53
bool isDust(interfaces::Node &node, const QString &address, const CAmount &amount)
Definition: guiutil.cpp:207
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:101
QFont fixedPitchFont()
Definition: guiutil.cpp:78