Bitcoin ABC  0.24.7
P2P Digital Currency
sendcoinsdialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 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)
6 #include <config/bitcoin-config.h>
7 #endif
8 
9 #include <qt/forms/ui_sendcoinsdialog.h>
10 #include <qt/sendcoinsdialog.h>
11 
12 #include <chainparams.h>
13 #include <interfaces/node.h>
14 #include <key_io.h>
15 #include <node/ui_interface.h>
16 #include <qt/addresstablemodel.h>
17 #include <qt/bitcoinunits.h>
18 #include <qt/clientmodel.h>
19 #include <qt/coincontroldialog.h>
20 #include <qt/guiutil.h>
21 #include <qt/optionsmodel.h>
22 #include <qt/platformstyle.h>
23 #include <qt/sendcoinsentry.h>
24 #include <txmempool.h>
25 #include <wallet/coincontrol.h>
26 #include <wallet/fees.h>
27 #include <wallet/wallet.h>
28 
29 #include <validation.h>
30 
31 #include <QScrollBar>
32 #include <QSettings>
33 #include <QTextDocument>
34 
36  WalletModel *_model, QWidget *parent)
37  : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(nullptr),
38  model(_model), m_coin_control(new CCoinControl),
39  fNewRecipientAllowed(true), fFeeMinimized(true),
40  platformStyle(_platformStyle) {
41  ui->setupUi(this);
42 
43  if (!_platformStyle->getImagesOnButtons()) {
44  ui->addButton->setIcon(QIcon());
45  ui->clearButton->setIcon(QIcon());
46  ui->sendButton->setIcon(QIcon());
47  } else {
48  ui->addButton->setIcon(_platformStyle->SingleColorIcon(":/icons/add"));
49  ui->clearButton->setIcon(
50  _platformStyle->SingleColorIcon(":/icons/remove"));
51  ui->sendButton->setIcon(
52  _platformStyle->SingleColorIcon(":/icons/send"));
53  }
54 
55  GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
56 
57  addEntry();
58 
59  connect(ui->addButton, &QPushButton::clicked, this,
61  connect(ui->clearButton, &QPushButton::clicked, this,
63 
64  // Coin Control
65  connect(ui->pushButtonCoinControl, &QPushButton::clicked, this,
67  connect(ui->checkBoxCoinControlChange, &QCheckBox::stateChanged, this,
69  connect(ui->lineEditCoinControlChange, &QValidatedLineEdit::textEdited,
71 
72  // Coin Control: clipboard actions
73  QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
74  QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
75  QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
76  QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
77  QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
78  QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this);
79  QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
80  connect(clipboardQuantityAction, &QAction::triggered, this,
82  connect(clipboardAmountAction, &QAction::triggered, this,
84  connect(clipboardFeeAction, &QAction::triggered, this,
86  connect(clipboardAfterFeeAction, &QAction::triggered, this,
88  connect(clipboardBytesAction, &QAction::triggered, this,
90  connect(clipboardLowOutputAction, &QAction::triggered, this,
92  connect(clipboardChangeAction, &QAction::triggered, this,
94  ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
95  ui->labelCoinControlAmount->addAction(clipboardAmountAction);
96  ui->labelCoinControlFee->addAction(clipboardFeeAction);
97  ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
98  ui->labelCoinControlBytes->addAction(clipboardBytesAction);
99  ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
100  ui->labelCoinControlChange->addAction(clipboardChangeAction);
101 
102  // init transaction fee section
103  QSettings settings;
104  if (!settings.contains("fFeeSectionMinimized")) {
105  settings.setValue("fFeeSectionMinimized", true);
106  }
107  // compatibility
108  if (!settings.contains("nFeeRadio") &&
109  settings.contains("nTransactionFee") &&
110  settings.value("nTransactionFee").toLongLong() > 0) {
111  // custom
112  settings.setValue("nFeeRadio", 1);
113  }
114  if (!settings.contains("nFeeRadio")) {
115  // recommended
116  settings.setValue("nFeeRadio", 0);
117  }
118  if (!settings.contains("nTransactionFee")) {
119  settings.setValue("nTransactionFee",
120  qint64(DEFAULT_PAY_TX_FEE / SATOSHI));
121  }
122  ui->groupFee->setId(ui->radioSmartFee, 0);
123  ui->groupFee->setId(ui->radioCustomFee, 1);
124  ui->groupFee
125  ->button(
126  std::max<int>(0, std::min(1, settings.value("nFeeRadio").toInt())))
127  ->setChecked(true);
128  ui->customFee->SetAllowEmpty(false);
129  ui->customFee->setValue(
130  int64_t(settings.value("nTransactionFee").toLongLong()) * SATOSHI);
131  minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
132 
133  // Set the model properly.
134  setModel(model);
135 }
136 
138  this->clientModel = _clientModel;
139 
140  if (_clientModel) {
141  connect(_clientModel, &ClientModel::numBlocksChanged, this,
143  }
144 }
145 
147  this->model = _model;
148 
149  if (_model && _model->getOptionsModel()) {
150  for (int i = 0; i < ui->entries->count(); ++i) {
151  SendCoinsEntry *entry = qobject_cast<SendCoinsEntry *>(
152  ui->entries->itemAt(i)->widget());
153  if (entry) {
154  entry->setModel(_model);
155  }
156  }
157 
158  interfaces::WalletBalances balances = _model->wallet().getBalances();
159  setBalance(balances);
160  connect(_model, &WalletModel::balanceChanged, this,
165 
166  // Coin Control
169  connect(_model->getOptionsModel(),
172  ui->frameCoinControl->setVisible(
175 
176  // fee section
177 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
178  const auto buttonClickedEvent =
179  QOverload<int>::of(&QButtonGroup::idClicked);
180 #else
181  /* QOverload in introduced from Qt 5.7, but we support down to 5.5.1 */
182  const auto buttonClickedEvent =
183  static_cast<void (QButtonGroup::*)(int)>(
184  &QButtonGroup::buttonClicked);
185 #endif
186  connect(ui->groupFee, buttonClickedEvent, this,
188  connect(ui->groupFee, buttonClickedEvent, this,
190  connect(ui->customFee, &BitcoinAmountField::valueChanged, this,
192  Amount requiredFee = model->wallet().getRequiredFee(1000);
193  ui->customFee->SetMinValue(requiredFee);
194  if (ui->customFee->value() < requiredFee) {
195  ui->customFee->setValue(requiredFee);
196  }
197  ui->customFee->setSingleStep(requiredFee);
200 
201  if (model->wallet().privateKeysDisabled()) {
202  ui->sendButton->setText(tr("Cr&eate Unsigned"));
203  ui->sendButton->setToolTip(
204  tr("Creates a Partially Signed Bitcoin Transaction (PSBT) for "
205  "use with e.g. an offline %1 wallet, or a PSBT-compatible "
206  "hardware wallet.")
207  .arg(PACKAGE_NAME));
208  }
209  }
210 }
211 
213  QSettings settings;
214  settings.setValue("fFeeSectionMinimized", fFeeMinimized);
215  settings.setValue("nFeeRadio", ui->groupFee->checkedId());
216  settings.setValue("nTransactionFee",
217  qint64(ui->customFee->value() / SATOSHI));
218 
219  delete ui;
220 }
221 
222 bool SendCoinsDialog::PrepareSendText(QString &question_string,
223  QString &informative_text,
224  QString &detailed_text) {
225  QList<SendCoinsRecipient> recipients;
226  bool valid = true;
227 
228  for (int i = 0; i < ui->entries->count(); ++i) {
229  SendCoinsEntry *entry =
230  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(i)->widget());
231  if (entry) {
232  if (entry->validate(model->node())) {
233  recipients.append(entry->getValue());
234  } else if (valid) {
235  ui->scrollArea->ensureWidgetVisible(entry);
236  valid = false;
237  }
238  }
239  }
240 
241  if (!valid || recipients.isEmpty()) {
242  return false;
243  }
244 
245  fNewRecipientAllowed = false;
247  if (!ctx.isValid()) {
248  // Unlock wallet was cancelled
249  fNewRecipientAllowed = true;
250  return false;
251  }
252 
253  // prepare transaction for getting txFee earlier
255  std::make_unique<WalletModelTransaction>(recipients);
256  WalletModel::SendCoinsReturn prepareStatus;
257 
259 
260  prepareStatus =
262 
263  // process prepareStatus and on error generate message shown to user
264  processSendCoinsReturn(prepareStatus,
267  m_current_transaction->getTransactionFee()));
268 
269  if (prepareStatus.status != WalletModel::OK) {
270  fNewRecipientAllowed = true;
271  return false;
272  }
273 
274  Amount txFee = m_current_transaction->getTransactionFee();
275  QStringList formatted;
276  for (const SendCoinsRecipient &rcp :
277  m_current_transaction->getRecipients()) {
278  // generate amount string with wallet name in case of multiwallet
279  QString amount = BitcoinUnits::formatWithUnit(
280  model->getOptionsModel()->getDisplayUnit(), rcp.amount);
281  if (model->isMultiwallet()) {
282  amount.append(
283  tr(" from wallet '%1'")
285  }
286  // generate address string
287  QString address = rcp.address;
288 
289  QString recipientElement;
290 
291 #ifdef ENABLE_BIP70
292  // normal payment
293  if (!rcp.paymentRequest.IsInitialized())
294 #endif
295  {
296  if (rcp.label.length() > 0) {
297  // label with address
298  recipientElement.append(
299  tr("%1 to '%2'")
300  .arg(amount, GUIUtil::HtmlEscape(rcp.label)));
301  recipientElement.append(QString(" (%1)").arg(address));
302  } else {
303  // just address
304  recipientElement.append(tr("%1 to %2").arg(amount, address));
305  }
306  }
307 #ifdef ENABLE_BIP70
308  // authenticated payment request
309  else if (!rcp.authenticatedMerchant.isEmpty()) {
310  recipientElement.append(
311  tr("%1 to '%2'").arg(amount, rcp.authenticatedMerchant));
312  } else {
313  // unauthenticated payment request
314  recipientElement.append(tr("%1 to %2").arg(amount, address));
315  }
316 #endif
317 
318  formatted.append(recipientElement);
319  }
320 
321  if (model->wallet().privateKeysDisabled()) {
322  question_string.append(tr("Do you want to draft this transaction?"));
323  } else {
324  question_string.append(tr("Are you sure you want to send?"));
325  }
326 
327  question_string.append("<br /><span style='font-size:10pt;'>");
328  if (model->wallet().privateKeysDisabled()) {
329  question_string.append(
330  tr("Please, review your transaction proposal. This will produce a "
331  "Partially Signed Bitcoin Transaction (PSBT) which you can save "
332  "or copy and then sign with e.g. an offline %1 wallet, or a "
333  "PSBT-compatible hardware wallet.")
334  .arg(PACKAGE_NAME));
335  } else {
336  question_string.append(tr("Please, review your transaction."));
337  }
338  question_string.append("</span>%1");
339 
340  if (txFee > Amount::zero()) {
341  // append fee string if a fee is required
342  question_string.append("<hr /><b>");
343  question_string.append(tr("Transaction fee"));
344  question_string.append("</b>");
345 
346  // append transaction size
347  question_string.append(
348  " (" +
349  QString::number(
350  (double)m_current_transaction->getTransactionSize() / 1000) +
351  " kB): ");
352 
353  // append transaction fee value
354  question_string.append(
355  "<span style='color:#aa0000; font-weight:bold;'>");
356  question_string.append(BitcoinUnits::formatHtmlWithUnit(
357  model->getOptionsModel()->getDisplayUnit(), txFee));
358  question_string.append("</span><br />");
359  }
360 
361  // add total amount in all subdivision units
362  question_string.append("<hr />");
363  Amount totalAmount =
364  m_current_transaction->getTotalTransactionAmount() + txFee;
365  QStringList alternativeUnits;
367  if (u != model->getOptionsModel()->getDisplayUnit()) {
368  alternativeUnits.append(
369  BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
370  }
371  }
372  question_string.append(
373  QString("<b>%1</b>: <b>%2</b>")
374  .arg(tr("Total Amount"))
376  model->getOptionsModel()->getDisplayUnit(), totalAmount)));
377  question_string.append(
378  QString("<br /><span style='font-size:10pt; "
379  "font-weight:normal;'>(=%1)</span>")
380  .arg(alternativeUnits.join(" " + tr("or") + " ")));
381 
382  if (formatted.size() > 1) {
383  question_string = question_string.arg("");
384  informative_text =
385  tr("To review recipient list click \"Show Details...\"");
386  detailed_text = formatted.join("\n\n");
387  } else {
388  question_string = question_string.arg("<br /><br />" + formatted.at(0));
389  }
390 
391  return true;
392 }
393 
395  if (!model || !model->getOptionsModel()) {
396  return;
397  }
398 
399  QString question_string, informative_text, detailed_text;
400  if (!PrepareSendText(question_string, informative_text, detailed_text)) {
401  return;
402  }
403  assert(m_current_transaction);
404 
405  const QString confirmation = model->wallet().privateKeysDisabled()
406  ? tr("Confirm transaction proposal")
407  : tr("Confirm send coins");
408  const QString confirmButtonText = model->wallet().privateKeysDisabled()
409  ? tr("Create Unsigned")
410  : tr("Send");
411  SendConfirmationDialog confirmationDialog(
412  confirmation, question_string, informative_text, detailed_text,
413  SEND_CONFIRM_DELAY, confirmButtonText, this);
414  confirmationDialog.exec();
415  QMessageBox::StandardButton retval =
416  static_cast<QMessageBox::StandardButton>(confirmationDialog.result());
417 
418  if (retval != QMessageBox::Yes) {
419  fNewRecipientAllowed = true;
420  return;
421  }
422 
423  bool send_failure = false;
424  if (model->wallet().privateKeysDisabled()) {
425  CMutableTransaction mtx =
427  PartiallySignedTransaction psbtx(mtx);
428  bool complete = false;
429  const TransactionError err = model->wallet().fillPSBT(
430  SigHashType().withForkId(), false /* sign */,
431  true /* bip32derivs */, psbtx, complete);
432  assert(!complete);
433  assert(err == TransactionError::OK);
434  // Serialize the PSBT
436  ssTx << psbtx;
437  GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
438  QMessageBox msgBox;
439  msgBox.setText("Unsigned Transaction");
440  msgBox.setInformativeText(
441  "The PSBT has been copied to the clipboard. You can also save it.");
442  msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
443  msgBox.setDefaultButton(QMessageBox::Discard);
444  switch (msgBox.exec()) {
445  case QMessageBox::Save: {
446  QString selectedFilter;
447  QString fileNameSuggestion = "";
448  bool first = true;
449  for (const SendCoinsRecipient &rcp :
450  m_current_transaction->getRecipients()) {
451  if (!first) {
452  fileNameSuggestion.append(" - ");
453  }
454  QString labelOrAddress =
455  rcp.label.isEmpty() ? rcp.address : rcp.label;
456  QString amount = BitcoinUnits::formatWithUnit(
457  model->getOptionsModel()->getDisplayUnit(), rcp.amount);
458  fileNameSuggestion.append(labelOrAddress + "-" + amount);
459  first = false;
460  }
461  fileNameSuggestion.append(".psbt");
462  QString filename = GUIUtil::getSaveFileName(
463  this, tr("Save Transaction Data"), fileNameSuggestion,
464  tr("Partially Signed Transaction (Binary) (*.psbt)"),
465  &selectedFilter);
466  if (filename.isEmpty()) {
467  return;
468  }
469  std::ofstream out(filename.toLocal8Bit().data());
470  out << ssTx.str();
471  out.close();
472  Q_EMIT message(tr("PSBT saved"), "PSBT saved to disk",
474  break;
475  }
476  case QMessageBox::Discard:
477  break;
478  default:
479  assert(false);
480  }
481  } else {
482  // now send the prepared transaction
483  WalletModel::SendCoinsReturn sendStatus =
485  // process sendStatus and on error generate message shown to user
486  processSendCoinsReturn(sendStatus);
487 
488  if (sendStatus.status == WalletModel::OK) {
489  Q_EMIT coinsSent(m_current_transaction->getWtx()->GetId());
490  } else {
491  send_failure = true;
492  }
493  }
494  if (!send_failure) {
495  accept();
496  m_coin_control->UnSelectAll();
498  }
499  fNewRecipientAllowed = true;
500  m_current_transaction.reset();
501 }
502 
504  m_current_transaction.reset();
505 
506  // Clear coin control settings
507  m_coin_control->UnSelectAll();
508  ui->checkBoxCoinControlChange->setChecked(false);
509  ui->lineEditCoinControlChange->clear();
511 
512  // Remove entries until only one left
513  while (ui->entries->count()) {
514  ui->entries->takeAt(0)->widget()->deleteLater();
515  }
516  addEntry();
517 
519 }
520 
522  clear();
523 }
524 
526  clear();
527 }
528 
530  SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, model, this);
531  ui->entries->addWidget(entry);
532  connect(entry, &SendCoinsEntry::removeEntry, this,
534  connect(entry, &SendCoinsEntry::useAvailableBalance, this,
536  connect(entry, &SendCoinsEntry::payAmountChanged, this,
538  connect(entry, &SendCoinsEntry::subtractFeeFromAmountChanged, this,
540 
541  // Focus the field, so that entry can start immediately
542  entry->clear();
543  entry->setFocus();
544  ui->scrollAreaWidgetContents->resize(
545  ui->scrollAreaWidgetContents->sizeHint());
546  qApp->processEvents();
547  QScrollBar *bar = ui->scrollArea->verticalScrollBar();
548  if (bar) {
549  bar->setSliderPosition(bar->maximum());
550  }
551 
553  return entry;
554 }
555 
557  setupTabChain(nullptr);
559 }
560 
562  entry->hide();
563 
564  // If the last entry is about to be removed add an empty one
565  if (ui->entries->count() == 1) {
566  addEntry();
567  }
568 
569  entry->deleteLater();
570 
572 }
573 
574 QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) {
575  for (int i = 0; i < ui->entries->count(); ++i) {
576  SendCoinsEntry *entry =
577  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(i)->widget());
578  if (entry) {
579  prev = entry->setupTabChain(prev);
580  }
581  }
582  QWidget::setTabOrder(prev, ui->sendButton);
583  QWidget::setTabOrder(ui->sendButton, ui->clearButton);
584  QWidget::setTabOrder(ui->clearButton, ui->addButton);
585  return ui->addButton;
586 }
587 
588 void SendCoinsDialog::setAddress(const QString &address) {
589  SendCoinsEntry *entry = nullptr;
590  // Replace the first entry if it is still unused
591  if (ui->entries->count() == 1) {
592  SendCoinsEntry *first =
593  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(0)->widget());
594  if (first->isClear()) {
595  entry = first;
596  }
597  }
598  if (!entry) {
599  entry = addEntry();
600  }
601 
602  entry->setAddress(address);
603 }
604 
606  if (!fNewRecipientAllowed) {
607  return;
608  }
609 
610  SendCoinsEntry *entry = nullptr;
611  // Replace the first entry if it is still unused
612  if (ui->entries->count() == 1) {
613  SendCoinsEntry *first =
614  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(0)->widget());
615  if (first->isClear()) {
616  entry = first;
617  }
618  }
619  if (!entry) {
620  entry = addEntry();
621  }
622 
623  entry->setValue(rv);
625 }
626 
628  // Just paste the entry, all pre-checks are done in paymentserver.cpp.
629  pasteEntry(rv);
630  return true;
631 }
632 
634  if (model && model->getOptionsModel()) {
635  Amount balance = balances.balance;
636  if (model->wallet().privateKeysDisabled()) {
637  balance = balances.watch_only_balance;
638  ui->labelBalanceName->setText(tr("Watch-only balance:"));
639  }
640  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(
642  }
643 }
644 
647  ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
649 }
650 
652  const WalletModel::SendCoinsReturn &sendCoinsReturn,
653  const QString &msgArg) {
654  QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
655  // Default to a warning message, override if error message is needed
656  msgParams.second = CClientUIInterface::MSG_WARNING;
657 
658  // This comment is specific to SendCoinsDialog usage of
659  // WalletModel::SendCoinsReturn.
660  // All status values are used only in WalletModel::prepareTransaction()
661  switch (sendCoinsReturn.status) {
663  msgParams.first =
664  tr("The recipient address is not valid. Please recheck.");
665  break;
667  msgParams.first = tr("The amount to pay must be larger than 0.");
668  break;
670  msgParams.first = tr("The amount exceeds your balance.");
671  break;
673  msgParams.first = tr("The total exceeds your balance when the %1 "
674  "transaction fee is included.")
675  .arg(msgArg);
676  break;
678  msgParams.first = tr("Duplicate address found: addresses should "
679  "only be used once each.");
680  break;
682  msgParams.first = tr("Transaction creation failed!");
683  msgParams.second = CClientUIInterface::MSG_ERROR;
684  break;
686  msgParams.first =
687  tr("A fee higher than %1 is considered an absurdly high fee.")
691  break;
693  msgParams.first = tr("Payment request expired.");
694  msgParams.second = CClientUIInterface::MSG_ERROR;
695  break;
696  // included to prevent a compiler warning.
697  case WalletModel::OK:
698  default:
699  return;
700  }
701 
702  Q_EMIT message(tr("Send Coins"), msgParams.first, msgParams.second);
703 }
704 
706  ui->labelFeeMinimized->setVisible(fMinimize);
707  ui->buttonChooseFee->setVisible(fMinimize);
708  ui->buttonMinimizeFee->setVisible(!fMinimize);
709  ui->frameFeeSelection->setVisible(!fMinimize);
710  ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0,
711  0);
712  fFeeMinimized = fMinimize;
713 }
714 
716  minimizeFeeSection(false);
717 }
718 
721  minimizeFeeSection(true);
722 }
723 
725  // Include watch-only for wallets without private key
726  m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled();
727 
728  // Calculate available amount to send.
730  for (int i = 0; i < ui->entries->count(); ++i) {
731  SendCoinsEntry *e =
732  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(i)->widget());
733  if (e && !e->isHidden() && e != entry) {
734  amount -= e->getValue().amount;
735  }
736  }
737 
738  if (amount > Amount::zero()) {
740  entry->setAmount(amount);
741  } else {
742  entry->setAmount(Amount::zero());
743  }
744 }
745 
747  ui->labelSmartFee->setEnabled(ui->radioSmartFee->isChecked());
748  ui->labelSmartFee2->setEnabled(ui->radioSmartFee->isChecked());
749  ui->labelFeeEstimation->setEnabled(ui->radioSmartFee->isChecked());
750  ui->labelCustomFeeWarning->setEnabled(ui->radioCustomFee->isChecked());
751  ui->labelCustomPerKilobyte->setEnabled(ui->radioCustomFee->isChecked());
752  ui->customFee->setEnabled(ui->radioCustomFee->isChecked());
753 }
754 
756  if (!model || !model->getOptionsModel()) {
757  return;
758  }
759 
760  if (ui->radioSmartFee->isChecked()) {
761  ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
762  } else {
763  ui->labelFeeMinimized->setText(
766  ui->customFee->value()) +
767  "/kB");
768  }
769 }
770 
772  if (ui->radioCustomFee->isChecked()) {
773  ctrl.m_feerate = CFeeRate(ui->customFee->value());
774  } else {
775  ctrl.m_feerate.reset();
776  }
777  // Include watch-only for wallets without private key
779 }
780 
782  const QDateTime &blockDate,
783  double nVerificationProgress,
784  bool headers,
785  SynchronizationState sync_state) {
786  if (sync_state == SynchronizationState::POST_INIT) {
788  }
789 }
790 
792  if (!model || !model->getOptionsModel()) {
793  return;
794  }
795 
797  // Explicitly use only fee estimation rate for smart fee labels
798  m_coin_control->m_feerate.reset();
799  CFeeRate feeRate(model->wallet().getMinimumFee(1000, *m_coin_control));
800 
801  ui->labelSmartFee->setText(
803  feeRate.GetFeePerK()) +
804  "/kB");
805  // not enough data => minfee
806  if (feeRate <= CFeeRate(Amount::zero())) {
807  // (Smart fee not initialized yet. This usually takes a few blocks...)
808  ui->labelSmartFee2->show();
809  ui->labelFeeEstimation->setText("");
810  } else {
811  ui->labelSmartFee2->hide();
812  ui->labelFeeEstimation->setText(
813  tr("Estimated to begin confirmation by next block."));
814  }
815 
817 }
818 
819 // Coin Control: copy label "Quantity" to clipboard
821  GUIUtil::setClipboard(ui->labelCoinControlQuantity->text());
822 }
823 
824 // Coin Control: copy label "Amount" to clipboard
826  GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(
827  ui->labelCoinControlAmount->text().indexOf(" ")));
828 }
829 
830 // Coin Control: copy label "Fee" to clipboard
833  ui->labelCoinControlFee->text()
834  .left(ui->labelCoinControlFee->text().indexOf(" "))
835  .replace(ASYMP_UTF8, ""));
836 }
837 
838 // Coin Control: copy label "After fee" to clipboard
841  ui->labelCoinControlAfterFee->text()
842  .left(ui->labelCoinControlAfterFee->text().indexOf(" "))
843  .replace(ASYMP_UTF8, ""));
844 }
845 
846 // Coin Control: copy label "Bytes" to clipboard
849  ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
850 }
851 
852 // Coin Control: copy label "Dust" to clipboard
854  GUIUtil::setClipboard(ui->labelCoinControlLowOutput->text());
855 }
856 
857 // Coin Control: copy label "Change" to clipboard
860  ui->labelCoinControlChange->text()
861  .left(ui->labelCoinControlChange->text().indexOf(" "))
862  .replace(ASYMP_UTF8, ""));
863 }
864 
865 // Coin Control: settings menu - coin control enabled/disabled by user
867  ui->frameCoinControl->setVisible(checked);
868 
869  // coin control features disabled
870  if (!checked && model) {
871  m_coin_control->SetNull();
872  }
873 
875 }
876 
877 // Coin Control: button inputs -> show actual coin control dialog
880  dlg.exec();
882 }
883 
884 // Coin Control: checkbox custom change address
886  if (state == Qt::Unchecked) {
887  m_coin_control->destChange = CNoDestination();
888  ui->labelCoinControlChangeLabel->clear();
889  } else {
890  // use this to re-validate an already entered address
891  coinControlChangeEdited(ui->lineEditCoinControlChange->text());
892  }
893 
894  ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked));
895 }
896 
897 // Coin Control: custom change address changed
898 void SendCoinsDialog::coinControlChangeEdited(const QString &text) {
899  if (model && model->getAddressTableModel()) {
900  // Default to no change address until verified
901  m_coin_control->destChange = CNoDestination();
902  ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}");
903 
904  const CTxDestination dest =
905  DecodeDestination(text.toStdString(), model->getChainParams());
906 
907  if (text.isEmpty()) {
908  // Nothing entered
909  ui->labelCoinControlChangeLabel->setText("");
910  } else if (!IsValidDestination(dest)) {
911  // Invalid address
912  ui->labelCoinControlChangeLabel->setText(
913  tr("Warning: Invalid Bitcoin address"));
914  } else {
915  // Valid address
916  if (!model->wallet().isSpendable(dest)) {
917  ui->labelCoinControlChangeLabel->setText(
918  tr("Warning: Unknown change address"));
919 
920  // confirmation dialog
921  QMessageBox::StandardButton btnRetVal = QMessageBox::question(
922  this, tr("Confirm custom change address"),
923  tr("The address you selected for change is not part of "
924  "this wallet. Any or all funds in your wallet may be "
925  "sent to this address. Are you sure?"),
926  QMessageBox::Yes | QMessageBox::Cancel,
927  QMessageBox::Cancel);
928 
929  if (btnRetVal == QMessageBox::Yes) {
930  m_coin_control->destChange = dest;
931  } else {
932  ui->lineEditCoinControlChange->setText("");
933  ui->labelCoinControlChangeLabel->setStyleSheet(
934  "QLabel{color:black;}");
935  ui->labelCoinControlChangeLabel->setText("");
936  }
937  } else {
938  // Known change address
939  ui->labelCoinControlChangeLabel->setStyleSheet(
940  "QLabel{color:black;}");
941 
942  // Query label
943  QString associatedLabel =
945  if (!associatedLabel.isEmpty()) {
946  ui->labelCoinControlChangeLabel->setText(associatedLabel);
947  } else {
948  ui->labelCoinControlChangeLabel->setText(tr("(no label)"));
949  }
950 
951  m_coin_control->destChange = dest;
952  }
953  }
954  }
955 }
956 
957 // Coin Control: update labels
959  if (!model || !model->getOptionsModel()) {
960  return;
961  }
962 
964 
965  // set pay amounts
968  for (int i = 0; i < ui->entries->count(); ++i) {
969  SendCoinsEntry *entry =
970  qobject_cast<SendCoinsEntry *>(ui->entries->itemAt(i)->widget());
971  if (entry && !entry->isHidden()) {
972  SendCoinsRecipient rcp = entry->getValue();
974  if (rcp.fSubtractFeeFromAmount) {
976  }
977  }
978  }
979 
980  if (m_coin_control->HasSelected()) {
981  // actual coin control calculation
983 
984  // show coin control stats
985  ui->labelCoinControlAutomaticallySelected->hide();
986  ui->widgetCoinControl->show();
987  } else {
988  // hide coin control stats
989  ui->labelCoinControlAutomaticallySelected->show();
990  ui->widgetCoinControl->hide();
991  ui->labelCoinControlInsuffFunds->hide();
992  }
993 }
994 
996  const QString &title, const QString &text, const QString &informative_text,
997  const QString &detailed_text, int _secDelay,
998  const QString &_confirmButtonText, QWidget *parent)
999  : QMessageBox(parent), secDelay(_secDelay),
1000  confirmButtonText(_confirmButtonText) {
1001  setIcon(QMessageBox::Question);
1002  // On macOS, the window title is ignored (as required by the macOS
1003  // Guidelines).
1004  setWindowTitle(title);
1005  setText(text);
1006  setInformativeText(informative_text);
1007  setDetailedText(detailed_text);
1008  setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
1009  setDefaultButton(QMessageBox::Cancel);
1010  yesButton = button(QMessageBox::Yes);
1011  updateYesButton();
1012  connect(&countDownTimer, &QTimer::timeout, this,
1014 }
1015 
1017  updateYesButton();
1018  countDownTimer.start(1000);
1019  return QMessageBox::exec();
1020 }
1021 
1023  secDelay--;
1024  updateYesButton();
1025 
1026  if (secDelay <= 0) {
1027  countDownTimer.stop();
1028  }
1029 }
1030 
1032  if (secDelay > 0) {
1033  yesButton->setEnabled(false);
1034  yesButton->setText(confirmButtonText + " (" +
1035  QString::number(secDelay) + ")");
1036  } else {
1037  yesButton->setEnabled(true);
1038  yesButton->setText(confirmButtonText);
1039  }
1040 }
interfaces::WalletBalances::watch_only_balance
Amount watch_only_balance
Definition: wallet.h:356
ASYMP_UTF8
#define ASYMP_UTF8
Definition: coincontroldialog.h:29
BitcoinUnits::formatHtmlWithUnit
static QString formatHtmlWithUnit(int unit, const Amount amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as HTML string (with unit)
Definition: bitcoinunits.cpp:167
ClientModel::numBlocksChanged
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, bool header, SynchronizationState sync_state)
SendCoinsDialog::coinControlClipboardAmount
void coinControlClipboardAmount()
Definition: sendcoinsdialog.cpp:825
SendCoinsDialog::on_buttonChooseFee_clicked
void on_buttonChooseFee_clicked()
Definition: sendcoinsdialog.cpp:715
CClientUIInterface::MSG_INFORMATION
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
Definition: ui_interface.h:71
interfaces::Wallet::fillPSBT
virtual TransactionError fillPSBT(SigHashType sighash_type, bool sign, bool bip32derivs, PartiallySignedTransaction &psbtx, bool &complete) const =0
Fill PSBT.
WalletModel::getOptionsModel
OptionsModel * getOptionsModel()
Definition: walletmodel.cpp:315
SendCoinsEntry::setAddress
void setAddress(const QString &address)
Definition: sendcoinsentry.cpp:266
SendCoinsDialog::updateCoinControlState
void updateCoinControlState(CCoinControl &ctrl)
Definition: sendcoinsdialog.cpp:771
SendCoinsDialog::fNewRecipientAllowed
bool fNewRecipientAllowed
Definition: sendcoinsdialog.h:70
count
static int count
Definition: tests.c:41
SendConfirmationDialog
Definition: sendcoinsdialog.h:121
SendCoinsDialog::coinsSent
void coinsSent(const uint256 &txid)
wallet.h
WalletModel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:47
SendCoinsRecipient::amount
Amount amount
Definition: sendcoinsrecipient.h:41
SendCoinsEntry::payAmountChanged
void payAmountChanged()
SEND_CONFIRM_DELAY
#define SEND_CONFIRM_DELAY
Definition: sendcoinsdialog.h:119
SendCoinsEntry::setValue
void setValue(const SendCoinsRecipient &value)
Definition: sendcoinsentry.cpp:220
BitcoinAmountField::valueChanged
void valueChanged()
key_io.h
PlatformStyle::SingleColorIcon
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
Definition: platformstyle.cpp:97
WalletModel::TransactionCreationFailed
@ TransactionCreationFailed
Definition: walletmodel.h:66
sendcoinsdialog.h
WalletModel::getAddressTableModel
AddressTableModel * getAddressTableModel()
Definition: walletmodel.cpp:319
SendCoinsEntry::setFocus
void setFocus()
Definition: sendcoinsentry.cpp:280
AddressTableModel::labelForAddress
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
Definition: addresstablemodel.cpp:386
WalletModel::DuplicateAddress
@ DuplicateAddress
Definition: walletmodel.h:64
CCoinControl
Coin Control Features.
Definition: coincontrol.h:21
WalletModel::sendCoins
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
Definition: walletmodel.cpp:248
WalletModel::AmountWithFeeExceedsBalance
@ AmountWithFeeExceedsBalance
Definition: walletmodel.h:63
CoinControlDialog
Definition: coincontroldialog.h:41
SendCoinsDialog::updateNumberOfBlocks
void updateNumberOfBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, bool headers, SynchronizationState sync_state)
Definition: sendcoinsdialog.cpp:781
node.h
WalletModel::AbsurdFee
@ AbsurdFee
Definition: walletmodel.h:67
SendCoinsDialog::coinControlFeatureChanged
void coinControlFeatureChanged(bool)
Definition: sendcoinsdialog.cpp:866
interfaces::Wallet::getMinimumFee
virtual Amount getMinimumFee(unsigned int tx_bytes, const CCoinControl &coin_control)=0
Get minimum fee.
SendCoinsEntry::setupTabChain
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
Definition: sendcoinsentry.cpp:208
WalletModel::isMultiwallet
bool isMultiwallet()
Definition: walletmodel.cpp:527
SendCoinsDialog::coinControlButtonClicked
void coinControlButtonClicked()
Definition: sendcoinsdialog.cpp:878
OptionsModel::displayUnitChanged
void displayUnitChanged(int unit)
interfaces::WalletBalances::balance
Amount balance
Definition: wallet.h:352
SendConfirmationDialog::SendConfirmationDialog
SendConfirmationDialog(const QString &title, const QString &text, const QString &informative_text="", const QString &detailed_text="", int secDelay=SEND_CONFIRM_DELAY, const QString &confirmText="Send", QWidget *parent=nullptr)
Definition: sendcoinsdialog.cpp:995
CCoinControl::m_feerate
std::optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
Definition: coincontrol.h:36
SendCoinsDialog::on_sendButton_clicked
void on_sendButton_clicked()
Definition: sendcoinsdialog.cpp:394
SendCoinsDialog::addEntry
SendCoinsEntry * addEntry()
Definition: sendcoinsdialog.cpp:529
SendCoinsDialog::useAvailableBalance
void useAvailableBalance(SendCoinsEntry *entry)
Definition: sendcoinsdialog.cpp:724
CoinControlDialog::updateLabels
static void updateLabels(CCoinControl &m_coin_control, WalletModel *, QDialog *)
Definition: coincontroldialog.cpp:442
chainparams.h
SendCoinsDialog::~SendCoinsDialog
~SendCoinsDialog()
Definition: sendcoinsdialog.cpp:212
WalletModel::requestUnlock
UnlockContext requestUnlock()
Definition: walletmodel.cpp:465
WalletModel::prepareTransaction
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl)
Definition: walletmodel.cpp:133
CFeeRate
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
SendCoinsDialog::clientModel
ClientModel * clientModel
Definition: sendcoinsdialog.h:66
SendCoinsDialog::updateDisplayUnit
void updateDisplayUnit()
Definition: sendcoinsdialog.cpp:645
GUIUtil::setClipboard
void setClipboard(const QString &str)
Definition: guiutil.cpp:766
balance
static Amount balance
Definition: coinselector_tests.cpp:37
Amount::zero
static constexpr Amount zero()
Definition: amount.h:42
txmempool.h
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:165
SendCoinsDialog::coinControlClipboardAfterFee
void coinControlClipboardAfterFee()
Definition: sendcoinsdialog.cpp:839
WalletModel::node
interfaces::Node & node() const
Definition: walletmodel.h:149
CoinControlDialog::fSubtractFeeFromAmount
static bool fSubtractFeeFromAmount
Definition: coincontroldialog.h:55
SendCoinsEntry::clear
void clear()
Definition: sendcoinsentry.cpp:114
SATOSHI
static constexpr Amount SATOSHI
Definition: amount.h:153
fsbridge::ofstream
fs::ofstream ofstream
Definition: fs.h:99
SendCoinsRecipient
Definition: sendcoinsrecipient.h:23
CFeeRate::GetFeePerK
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:54
fees.h
SendCoinsDialog::updateFeeMinimizedLabel
void updateFeeMinimizedLabel()
Definition: sendcoinsdialog.cpp:755
TransactionError
TransactionError
Definition: error.h:22
WalletModel::wallet
interfaces::Wallet & wallet() const
Definition: walletmodel.h:150
BitcoinUnits::availableUnits
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
Definition: bitcoinunits.cpp:49
CCoinControl::fAllowWatchOnly
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
Definition: coincontrol.h:32
interfaces::WalletBalances
Collection of wallet balances.
Definition: wallet.h:351
WalletModel::AmountExceedsBalance
@ AmountExceedsBalance
Definition: walletmodel.h:62
SendConfirmationDialog::confirmButtonText
QString confirmButtonText
Definition: sendcoinsdialog.h:141
IsValidDestination
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:263
sendcoinsentry.h
WalletModel::SendCoinsReturn::status
StatusCode status
Definition: walletmodel.h:95
PlatformStyle::getImagesOnButtons
bool getImagesOnButtons() const
Definition: platformstyle.h:20
SendCoinsDialog::handlePaymentRequest
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: sendcoinsdialog.cpp:627
OptionsModel::getCoinControlFeatures
bool getCoinControlFeatures() const
Definition: optionsmodel.h:100
CClientUIInterface::MSG_WARNING
@ MSG_WARNING
Definition: ui_interface.h:72
WalletModel::getChainParams
const CChainParams & getChainParams() const
Definition: walletmodel.cpp:531
SendCoinsEntry::isClear
bool isClear()
Return whether the entry is still empty and unedited.
Definition: sendcoinsentry.cpp:275
BitcoinUnits::formatWithUnit
static QString formatWithUnit(int unit, const Amount amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as string (with unit)
Definition: bitcoinunits.cpp:161
SendCoinsDialog::m_current_transaction
std::unique_ptr< WalletModelTransaction > m_current_transaction
Definition: sendcoinsdialog.h:69
SigHashType
Signature hash type wrapper class.
Definition: sighashtype.h:37
SendCoinsDialog
Dialog for sending bitcoins.
Definition: sendcoinsdialog.h:31
guiutil.h
WalletModel::getWalletName
QString getWalletName() const
Definition: walletmodel.cpp:518
SendConfirmationDialog::secDelay
int secDelay
Definition: sendcoinsdialog.h:140
SendCoinsDialog::minimizeFeeSection
void minimizeFeeSection(bool fMinimize)
Definition: sendcoinsdialog.cpp:705
SendCoinsDialog::setBalance
void setBalance(const interfaces::WalletBalances &balances)
Definition: sendcoinsdialog.cpp:633
SendCoinsDialog::setAddress
void setAddress(const QString &address)
Definition: sendcoinsdialog.cpp:588
interfaces::Wallet::getDefaultMaxTxFee
virtual Amount getDefaultMaxTxFee()=0
Get max tx fee.
SendCoinsDialog::setupTabChain
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
Definition: sendcoinsdialog.cpp:574
interfaces::Wallet::getBalances
virtual WalletBalances getBalances()=0
Get balances.
SendCoinsEntry::validate
bool validate(interfaces::Node &node)
Definition: sendcoinsentry.cpp:148
Amount
Definition: amount.h:19
SendCoinsEntry::setAmount
void setAmount(const Amount amount)
Definition: sendcoinsentry.cpp:271
SendCoinsDialog::platformStyle
const PlatformStyle * platformStyle
Definition: sendcoinsdialog.h:72
CNoDestination
Definition: standard.h:96
SendCoinsDialog::PrepareSendText
bool PrepareSendText(QString &question_string, QString &informative_text, QString &detailed_text)
Definition: sendcoinsdialog.cpp:222
SendCoinsDialog::coinControlClipboardBytes
void coinControlClipboardBytes()
Definition: sendcoinsdialog.cpp:847
SendCoinsDialog::ui
Ui::SendCoinsDialog * ui
Definition: sendcoinsdialog.h:65
DEFAULT_PAY_TX_FEE
constexpr Amount DEFAULT_PAY_TX_FEE
-paytxfee default
Definition: wallet.h:81
SendCoinsDialog::updateTabsAndLabels
void updateTabsAndLabels()
Definition: sendcoinsdialog.cpp:556
SendCoinsEntry::setModel
void setModel(WalletModel *model)
Definition: sendcoinsentry.cpp:94
ui_interface.h
ctx
secp256k1_context * ctx
Definition: bench_multiset.c:12
GUIUtil::getSaveFileName
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition: guiutil.cpp:283
SendCoinsDialog::m_coin_control
std::unique_ptr< CCoinControl > m_coin_control
Definition: sendcoinsdialog.h:68
platformstyle.h
SendCoinsDialog::coinControlClipboardChange
void coinControlClipboardChange()
Definition: sendcoinsdialog.cpp:858
CClientUIInterface::MSG_ERROR
@ MSG_ERROR
Definition: ui_interface.h:73
SendCoinsEntry::useAvailableBalance
void useAvailableBalance(SendCoinsEntry *entry)
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:36
Ui
Definition: addressbookpage.h:14
WalletModel::OK
@ OK
Definition: walletmodel.h:59
SendConfirmationDialog::countDown
void countDown()
Definition: sendcoinsdialog.cpp:1022
GUIUtil::HtmlEscape
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:240
SendCoinsDialog::pasteEntry
void pasteEntry(const SendCoinsRecipient &rv)
Definition: sendcoinsdialog.cpp:605
interfaces::Wallet::getAvailableBalance
virtual Amount getAvailableBalance(const CCoinControl &coin_control)=0
Get available balance.
SendConfirmationDialog::exec
int exec() override
Definition: sendcoinsdialog.cpp:1016
SendCoinsDialog::model
WalletModel * model
Definition: sendcoinsdialog.h:67
WalletModel::UnlockContext
Definition: walletmodel.h:115
CoinControlDialog::payAmounts
static QList< Amount > payAmounts
Definition: coincontroldialog.h:54
WalletModel::InvalidAmount
@ InvalidAmount
Definition: walletmodel.h:60
interfaces::Wallet::getRequiredFee
virtual Amount getRequiredFee(unsigned int tx_bytes)=0
Get required fee.
OptionsModel::getDisplayUnit
int getDisplayUnit() const
Definition: optionsmodel.h:97
SendCoinsDialog::setClientModel
void setClientModel(ClientModel *clientModel)
Definition: sendcoinsdialog.cpp:137
PartiallySignedTransaction
A version of CTransaction with the PSBT format.
Definition: psbt.h:335
WalletModel::InvalidAddress
@ InvalidAddress
Definition: walletmodel.h:61
TransactionError::OK
@ OK
No error.
SendCoinsEntry::removeEntry
void removeEntry(SendCoinsEntry *entry)
SendCoinsDialog::coinControlClipboardLowOutput
void coinControlClipboardLowOutput()
Definition: sendcoinsdialog.cpp:853
SendConfirmationDialog::updateYesButton
void updateYesButton()
Definition: sendcoinsdialog.cpp:1031
BitcoinUnits::Unit
Unit
Currency units Please add only sensible ones.
Definition: bitcoinunits.h:42
SendCoinsDialog::setModel
void setModel(WalletModel *model)
Definition: sendcoinsdialog.cpp:146
coincontroldialog.h
SendCoinsDialog::SendCoinsDialog
SendCoinsDialog(const PlatformStyle *platformStyle, WalletModel *model, QWidget *parent=nullptr)
Definition: sendcoinsdialog.cpp:35
SendConfirmationDialog::yesButton
QAbstractButton * yesButton
Definition: sendcoinsdialog.h:138
SendCoinsDialog::coinControlChangeChecked
void coinControlChangeChecked(int)
Definition: sendcoinsdialog.cpp:885
WalletModel::SendCoinsReturn
Definition: walletmodel.h:91
SendCoinsEntry::checkSubtractFeeFromAmount
void checkSubtractFeeFromAmount()
Definition: sendcoinsentry.cpp:136
bitcoinunits.h
SendCoinsDialog::message
void message(const QString &title, const QString &message, unsigned int style)
SendCoinsDialog::updateFeeSectionControls
void updateFeeSectionControls()
Definition: sendcoinsdialog.cpp:746
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:197
SendCoinsDialog::coinControlClipboardFee
void coinControlClipboardFee()
Definition: sendcoinsdialog.cpp:831
SendCoinsDialog::coinControlChangeEdited
void coinControlChangeEdited(const QString &)
Definition: sendcoinsdialog.cpp:898
SendCoinsEntry
A single entry in the dialog for sending bitcoins.
Definition: sendcoinsentry.h:28
SendCoinsDialog::coinControlUpdateLabels
void coinControlUpdateLabels()
Definition: sendcoinsdialog.cpp:958
SendCoinsDialog::removeEntry
void removeEntry(SendCoinsEntry *entry)
Definition: sendcoinsdialog.cpp:561
SendCoinsDialog::fFeeMinimized
bool fFeeMinimized
Definition: sendcoinsdialog.h:71
SynchronizationState
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:130
SendCoinsEntry::subtractFeeFromAmountChanged
void subtractFeeFromAmountChanged()
SendCoinsDialog::clear
void clear()
Definition: sendcoinsdialog.cpp:503
EncodeBase64
std::string EncodeBase64(Span< const uint8_t > input)
Definition: strencodings.cpp:137
optionsmodel.h
WalletModel::PaymentRequestExpired
@ PaymentRequestExpired
Definition: walletmodel.h:68
interfaces::Wallet::isSpendable
virtual bool isSpendable(const CTxDestination &dest)=0
Return whether wallet has private key.
SendCoinsDialog::accept
void accept() override
Definition: sendcoinsdialog.cpp:525
coincontrol.h
WalletModel::balanceChanged
void balanceChanged(const interfaces::WalletBalances &balances)
PlatformStyle
Definition: platformstyle.h:13
DecodeDestination
CTxDestination DecodeDestination(const std::string &addr, const CChainParams &params)
Definition: key_io.cpp:177
CDataStream::str
std::string str() const
Definition: streams.h:271
GUIUtil::setupAddressWidget
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:119
interfaces::Wallet::privateKeysDisabled
virtual bool privateKeysDisabled()=0
addresstablemodel.h
CTxDestination
boost::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:132
SendCoinsDialog::processSendCoinsReturn
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg=QString())
Definition: sendcoinsdialog.cpp:651
SendCoinsDialog::updateSmartFeeLabel
void updateSmartFeeLabel()
Definition: sendcoinsdialog.cpp:791
SynchronizationState::POST_INIT
@ POST_INIT
SendCoinsDialog::coinControlClipboardQuantity
void coinControlClipboardQuantity()
Definition: sendcoinsdialog.cpp:820
clientmodel.h
OptionsModel::coinControlFeaturesChanged
void coinControlFeaturesChanged(bool)
SendCoinsRecipient::fSubtractFeeFromAmount
bool fSubtractFeeFromAmount
Definition: sendcoinsrecipient.h:57
SendCoinsEntry::getValue
SendCoinsRecipient getValue()
Definition: sendcoinsentry.cpp:189
SendCoinsDialog::on_buttonMinimizeFee_clicked
void on_buttonMinimizeFee_clicked()
Definition: sendcoinsdialog.cpp:719
CMutableTransaction
A mutable version of CTransaction.
Definition: transaction.h:278
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11
SendConfirmationDialog::countDownTimer
QTimer countDownTimer
Definition: sendcoinsdialog.h:139
SendCoinsDialog::reject
void reject() override
Definition: sendcoinsdialog.cpp:521