5#include <bitcoin-build-config.h>
8#include <qt/forms/ui_sendcoinsdialog.h>
19#include <chainparams.h>
26#include <validation.h>
36#include <QFontMetrics>
39#include <QTextDocument>
44static constexpr std::array
confTargets{2, 4, 6, 12, 24, 48, 144, 504, 1008};
46 if (index+1 >
static_cast<int>(
confTargets.size())) {
55 for (
unsigned int i = 0; i <
confTargets.size(); i++) {
67 platformStyle(_platformStyle)
72 ui->addButton->setIcon(QIcon());
73 ui->clearButton->setIcon(QIcon());
74 ui->sendButton->setIcon(QIcon());
90#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
98 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
99 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
100 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
101 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
102 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
103 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
110 ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
111 ui->labelCoinControlAmount->addAction(clipboardAmountAction);
112 ui->labelCoinControlFee->addAction(clipboardFeeAction);
113 ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
114 ui->labelCoinControlBytes->addAction(clipboardBytesAction);
115 ui->labelCoinControlChange->addAction(clipboardChangeAction);
119 if (!settings.contains(
"fFeeSectionMinimized"))
120 settings.setValue(
"fFeeSectionMinimized",
true);
121 if (!settings.contains(
"nFeeRadio") && settings.contains(
"nTransactionFee") && settings.value(
"nTransactionFee").toLongLong() > 0)
122 settings.setValue(
"nFeeRadio", 1);
123 if (!settings.contains(
"nFeeRadio"))
124 settings.setValue(
"nFeeRadio", 0);
125 if (!settings.contains(
"nSmartFeeSliderPosition"))
126 settings.setValue(
"nSmartFeeSliderPosition", 0);
127 ui->groupFee->setId(
ui->radioSmartFee, 0);
128 ui->groupFee->setId(
ui->radioCustomFee, 1);
129 ui->groupFee->button((
int)std::max(0, std::min(1, settings.value(
"nFeeRadio").toInt())))->setChecked(
true);
130 ui->customFee->SetAllowEmpty(
false);
131 ui->customFee->setValue(settings.value(
"nTransactionFee").toLongLong());
148 this->
model = _model;
152 for(
int i = 0; i <
ui->entries->count(); ++i)
154 SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(i)->widget());
183 ui->customFee->SetMinValue(requiredFee);
184 if (
ui->customFee->value() < requiredFee) {
185 ui->customFee->setValue(requiredFee);
187 ui->customFee->setSingleStep(requiredFee);
193 ui->sendButton->setText(tr(
"Sign on device"));
195 ui->sendButton->setEnabled(
true);
196 ui->sendButton->setToolTip(tr(
"Connect your hardware wallet first."));
198 ui->sendButton->setEnabled(
false);
200 ui->sendButton->setToolTip(tr(
"Set external signer script path in Options -> Wallet"));
203 ui->sendButton->setText(tr(
"Cr&eate Unsigned"));
204 ui->sendButton->setToolTip(tr(
"Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.").arg(CLIENT_NAME));
209 if (settings.value(
"nSmartFeeSliderPosition").toInt() != 0) {
212 int nConfirmTarget = 25 - settings.value(
"nSmartFeeSliderPosition").toInt();
213 settings.setValue(
"nConfTarget", nConfirmTarget);
214 settings.remove(
"nSmartFeeSliderPosition");
216 if (settings.value(
"nConfTarget").toInt() == 0)
227 settings.setValue(
"nFeeRadio",
ui->groupFee->checkedId());
229 settings.setValue(
"nTransactionFee", (qint64)
ui->customFee->value());
236 QList<SendCoinsRecipient> recipients;
239 for(
int i = 0; i <
ui->entries->count(); ++i)
241 SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(i)->widget());
246 recipients.append(entry->
getValue());
250 ui->scrollArea->ensureWidgetVisible(entry);
256 if(!valid || recipients.isEmpty())
290 QStringList formatted;
300 QString address = rcp.address;
302 QString recipientElement;
305 if(rcp.label.length() > 0)
308 recipientElement.append(QString(
" (%1)").arg(address));
312 recipientElement.append(tr(
"%1 to %2").arg(amount, address));
315 formatted.append(recipientElement);
320 question_string.append(tr(
"Do you want to create this transaction?"));
321 question_string.append(
"<br /><span style='font-size:10pt;'>");
326 question_string.append(tr(
"Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.").arg(CLIENT_NAME));
331 question_string.append(tr(
"Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet.").arg(CLIENT_NAME));
334 question_string.append(tr(
"Please, review your transaction."));
336 question_string.append(
"</span>%1");
341 question_string.append(
"<hr /><b>");
342 question_string.append(tr(
"Transaction fee"));
343 question_string.append(
"</b>");
347 question_string.append(
" (" + tr(
"%1 kvB",
"PSBT transaction creation").arg((
double)
m_current_transaction->getTransactionSize() / 1000, 0,
'g', 3) +
"): ");
350 question_string.append(
"<span style='color:#aa0000; font-weight:bold;'>");
352 question_string.append(
"</span><br />");
356 question_string.append(
"<span style='font-size:10pt; font-weight:normal;'>");
357 question_string.append(tr(
"You can increase the fee later."));
360 question_string.append(
"<hr />");
362 QStringList alternativeUnits;
367 question_string.append(QString(
"<b>%1</b>: <b>%2</b>").arg(tr(
"Total Amount"))
369 question_string.append(QString(
"<br /><span style='font-size:10pt; font-weight:normal;'>(=%1)</span>")
370 .arg(alternativeUnits.join(
" " + tr(
"or") +
" ")));
372 if (formatted.size() > 1) {
373 question_string = question_string.arg(
"");
374 informative_text = tr(
"To review recipient list click \"Show Details…\"");
375 detailed_text = formatted.join(
"\n\n");
377 question_string = question_string.arg(
"<br /><br />" + formatted.at(0));
389 QMessageBox msgBox(
this);
391 msgBox.setText(tr(
"Unsigned Transaction",
"PSBT copied"));
392 msgBox.setInformativeText(tr(
"The PSBT has been copied to the clipboard. You can also save it."));
393 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
394 msgBox.setDefaultButton(QMessageBox::Discard);
395 msgBox.setObjectName(
"psbt_copied_message");
396 switch (msgBox.exec()) {
397 case QMessageBox::Save: {
398 QString selectedFilter;
399 QString fileNameSuggestion =
"";
403 fileNameSuggestion.append(
" - ");
405 QString labelOrAddress = rcp.label.isEmpty() ? rcp.address : rcp.label;
407 fileNameSuggestion.append(labelOrAddress +
"-" + amount);
410 fileNameSuggestion.append(
".psbt");
412 tr(
"Save Transaction Data"), fileNameSuggestion,
414 tr(
"Partially Signed Transaction (Binary)") + QLatin1String(
" (*.psbt)"), &selectedFilter);
415 if (filename.isEmpty()) {
425 case QMessageBox::Discard:
433 std::optional<PSBTError> err;
435 err =
model->
wallet().
fillPSBT({.sign =
true, .bip32_derivs =
true},
nullptr, psbtx, complete);
436 }
catch (
const std::runtime_error& e) {
437 QMessageBox::critical(
nullptr, tr(
"Sign failed"), e.what());
440 if (err == PSBTError::EXTERNAL_SIGNER_NOT_FOUND) {
442 const QString
msg = tr(
"External signer not found");
443 QMessageBox::critical(
nullptr,
msg,
msg);
446 if (err == PSBTError::EXTERNAL_SIGNER_FAILED) {
448 const QString
msg = tr(
"External signer failure");
449 QMessageBox::critical(
nullptr,
msg,
msg);
453 qWarning() <<
"Failed to sign PSBT";
467 QString question_string, informative_text, detailed_text;
468 if (!
PrepareSendText(question_string, informative_text, detailed_text))
return;
471 const QString confirmation = tr(
"Confirm send coins");
475 confirmationDialog->setAttribute(Qt::WA_DeleteOnClose);
477 const auto retval =
static_cast<QMessageBox::StandardButton
>(confirmationDialog->exec());
479 if(retval != QMessageBox::Yes && retval != QMessageBox::Save)
485 bool send_failure =
false;
486 if (retval == QMessageBox::Save) {
490 bool complete =
false;
492 const auto err{
model->
wallet().
fillPSBT({.sign =
false, .bip32_derivs =
true},
nullptr, psbtx, complete)};
501 bool broadcast =
true;
505 bool complete =
false;
508 const auto err{
model->
wallet().
fillPSBT({.sign =
false, .bip32_derivs =
true},
nullptr, psbtx, complete)};
513 broadcast = complete && !send_failure;
550 ui->checkBoxCoinControlChange->setChecked(
false);
551 ui->lineEditCoinControlChange->clear();
555 while(
ui->entries->count())
557 ui->entries->takeAt(0)->widget()->deleteLater();
578 ui->entries->addWidget(entry);
587 ui->scrollAreaWidgetContents->resize(
ui->scrollAreaWidgetContents->sizeHint());
592 QMetaObject::invokeMethod(
ui->scrollArea, [
this] {
593 if (ui->scrollArea->verticalScrollBar()) {
594 ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
596 }, Qt::QueuedConnection);
598 updateTabsAndLabels();
613 if (
ui->entries->count() == 1)
616 entry->deleteLater();
623 for(
int i = 0; i <
ui->entries->count(); ++i)
625 SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(i)->widget());
631 QWidget::setTabOrder(prev,
ui->sendButton);
632 QWidget::setTabOrder(
ui->sendButton,
ui->clearButton);
633 QWidget::setTabOrder(
ui->clearButton,
ui->addButton);
634 return ui->addButton;
641 if(
ui->entries->count() == 1)
643 SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(0)->widget());
664 if(
ui->entries->count() == 1)
666 SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(0)->widget());
695 ui->labelBalanceName->setText(tr(
"External balance:"));
710 QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
716 switch(sendCoinsReturn.
status)
719 msgParams.first = tr(
"The recipient address is not valid. Please recheck.");
722 msgParams.first = tr(
"The amount to pay must be larger than 0.");
725 msgParams.first = tr(
"The amount exceeds your balance.");
728 msgParams.first = tr(
"Duplicate address found: addresses should only be used once each.");
731 msgParams.first = tr(
"Transaction creation failed!");
740 Q_EMIT
message(tr(
"Send Coins"), msgParams.first, msgParams.second);
745 ui->labelFeeMinimized->setVisible(fMinimize);
746 ui->buttonChooseFee ->setVisible(fMinimize);
747 ui->buttonMinimizeFee->setVisible(!fMinimize);
748 ui->frameFeeSelection->setVisible(!fMinimize);
749 ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0, 0);
773 for (
int i = 0; i <
ui->entries->count(); ++i) {
774 SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(i)->widget());
775 if (e && !e->isHidden() && e != entry) {
790 ui->confTargetSelector ->setEnabled(
ui->radioSmartFee->isChecked());
791 ui->labelSmartFee ->setEnabled(
ui->radioSmartFee->isChecked());
792 ui->labelSmartFee2 ->setEnabled(
ui->radioSmartFee->isChecked());
793 ui->labelSmartFee3 ->setEnabled(
ui->radioSmartFee->isChecked());
794 ui->labelFeeEstimation ->setEnabled(
ui->radioSmartFee->isChecked());
795 ui->labelCustomFeeWarning ->setEnabled(
ui->radioCustomFee->isChecked());
796 ui->labelCustomPerKilobyte ->setEnabled(
ui->radioCustomFee->isChecked());
797 ui->customFee ->setEnabled(
ui->radioCustomFee->isChecked());
805 if (
ui->radioSmartFee->isChecked())
806 ui->labelFeeMinimized->setText(
ui->labelSmartFee->text());
814 if (
ui->radioCustomFee->isChecked()) {
847 ui->labelSmartFee2->show();
848 ui->labelFeeEstimation->setText(
"");
849 ui->fallbackFeeWarningLabel->setVisible(
true);
850 int lightness =
ui->fallbackFeeWarningLabel->palette().color(QPalette::WindowText).lightness();
851 QColor warning_colour(255 - (lightness / 5), 176 - (lightness / 3), 48 - (lightness / 14));
852 ui->fallbackFeeWarningLabel->setStyleSheet(
"QLabel { color: " + warning_colour.name() +
"; }");
853 ui->fallbackFeeWarningLabel->setIndent(
GUIUtil::TextWidth(QFontMetrics(
ui->fallbackFeeWarningLabel->font()),
"x"));
857 ui->labelSmartFee2->hide();
858 ui->labelFeeEstimation->setText(tr(
"Estimated to begin confirmation within %n block(s).",
"", returned_target));
859 ui->fallbackFeeWarningLabel->setVisible(
false);
904 ui->frameCoinControl->setVisible(checked);
906 if (!checked &&
model) {
922#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
928 if (state == Qt::Unchecked)
931 ui->labelCoinControlChangeLabel->clear();
935 coinControlChangeEdited(ui->lineEditCoinControlChange->text());
937 ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked));
947 ui->labelCoinControlChangeLabel->setStyleSheet(
"QLabel{color:red;}");
953 ui->labelCoinControlChangeLabel->setText(
"");
957 ui->labelCoinControlChangeLabel->setText(tr(
"Warning: Invalid Bitcoin address"));
962 ui->labelCoinControlChangeLabel->setText(tr(
"Warning: Unknown change address"));
965 QMessageBox::StandardButton btnRetVal = QMessageBox::question(
this, tr(
"Confirm custom change address"), tr(
"The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?"),
966 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
968 if(btnRetVal == QMessageBox::Yes)
972 ui->lineEditCoinControlChange->setText(
"");
973 ui->labelCoinControlChangeLabel->setStyleSheet(
"QLabel{color:black;}");
974 ui->labelCoinControlChangeLabel->setText(
"");
979 ui->labelCoinControlChangeLabel->setStyleSheet(
"QLabel{color:black;}");
983 if (!associatedLabel.isEmpty())
984 ui->labelCoinControlChangeLabel->setText(associatedLabel);
986 ui->labelCoinControlChangeLabel->setText(tr(
"(no label)"));
1006 for(
int i = 0; i <
ui->entries->count(); ++i)
1008 SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(
ui->entries->itemAt(i)->widget());
1009 if(entry && !entry->isHidden())
1024 ui->labelCoinControlAutomaticallySelected->hide();
1025 ui->widgetCoinControl->show();
1030 ui->labelCoinControlAutomaticallySelected->show();
1031 ui->widgetCoinControl->hide();
1032 ui->labelCoinControlInsuffFunds->hide();
1037 : QMessageBox(parent), secDelay(_secDelay), m_enable_send(enable_send)
1039 setIcon(QMessageBox::Question);
1040 setWindowTitle(title);
1042 setInformativeText(informative_text);
1043 setDetailedText(detailed_text);
1044 setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
1045 if (always_show_unsigned || !enable_send) addButton(QMessageBox::Save);
1046 setDefaultButton(QMessageBox::Cancel);
1060 return QMessageBox::exec();
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
int64_t CAmount
Amount in satoshis (Can be negative)
const CChainParams & Params()
Return the currently selected parameters.
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
static QString formatHtmlWithUnit(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as HTML string (with unit)
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
static QString formatWithUnit(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as string (with unit)
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
Model for Bitcoin network client.
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state)
static QList< CAmount > payAmounts
static void updateLabels(wallet::CCoinControl &m_coin_control, WalletModel *, QDialog *)
static bool fSubtractFeeFromAmount
Double ended buffer combining vector and stream-like interfaces.
bool getCoinControlFeatures() const
bool getEnablePSBTControls() const
void coinControlFeaturesChanged(bool)
void displayUnitChanged(BitcoinUnit unit)
BitcoinUnit getDisplayUnit() const
bool hasSigner()
Whether -signer was set or not.
A version of CTransaction with the PSBT format.
Dialog for sending bitcoins.
void useAvailableBalance(SendCoinsEntry *entry)
void presentPSBT(PartiallySignedTransaction &psbt)
ClientModel * clientModel
void coinControlChangeEdited(const QString &)
void coinControlClipboardFee()
void on_buttonChooseFee_clicked()
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg=QString())
void setClientModel(ClientModel *clientModel)
void updateTabsAndLabels()
void updateFeeSectionControls()
SendCoinsEntry * addEntry()
void updateNumberOfBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state)
void pasteEntry(const SendCoinsRecipient &rv)
void updateFeeMinimizedLabel()
const PlatformStyle * platformStyle
std::unique_ptr< wallet::CCoinControl > m_coin_control
void coinControlClipboardQuantity()
void coinControlButtonClicked()
void coinControlClipboardAfterFee()
bool signWithExternalSigner(PartiallySignedTransaction &psbt, CMutableTransaction &mtx, bool &complete)
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
bool PrepareSendText(QString &question_string, QString &informative_text, QString &detailed_text)
void sendButtonClicked(bool checked)
void setModel(WalletModel *model)
void coinControlChangeChecked(Qt::CheckState)
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
void setBalance(const interfaces::WalletBalances &balances)
void coinControlClipboardAmount()
void setAddress(const QString &address)
void coinsSent(const Txid &txid)
void coinControlClipboardChange()
std::unique_ptr< WalletModelTransaction > m_current_transaction
bool fNewRecipientAllowed
void removeEntry(SendCoinsEntry *entry)
void updateSmartFeeLabel()
void updateCoinControlState()
void coinControlClipboardBytes()
void message(const QString &title, const QString &message, unsigned int style)
SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
void on_buttonMinimizeFee_clicked()
void coinControlUpdateLabels()
void coinControlFeatureChanged(bool)
void minimizeFeeSection(bool fMinimize)
A single entry in the dialog for sending bitcoins.
void setAddress(const QString &address)
bool isClear()
Return whether the entry is still empty and unedited.
void subtractFeeFromAmountChanged()
void useAvailableBalance(SendCoinsEntry *entry)
void setValue(const SendCoinsRecipient &value)
void setModel(WalletModel *model)
void removeEntry(SendCoinsEntry *entry)
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://...
bool validate(interfaces::Node &node)
void checkSubtractFeeFromAmount()
SendCoinsRecipient getValue()
bool fSubtractFeeFromAmount
QString m_psbt_button_text
SendConfirmationDialog(const QString &title, const QString &text, const QString &informative_text="", const QString &detailed_text="", int secDelay=SEND_CONFIRM_DELAY, bool enable_send=true, bool always_show_unsigned=true, QWidget *parent=nullptr)
QAbstractButton * m_psbt_button
QAbstractButton * yesButton
QString confirmButtonText
Interface to Bitcoin wallet from Qt view code.
interfaces::Node & node() const
AddressTableModel * getAddressTableModel() const
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const wallet::CCoinControl &coinControl)
void sendCoins(WalletModelTransaction &transaction)
CAmount getAvailableBalance(const wallet::CCoinControl *control)
bool isMultiwallet() const
interfaces::Wallet & wallet() const
OptionsModel * getOptionsModel() const
UnlockContext requestUnlock()
void balanceChanged(const interfaces::WalletBalances &balances)
interfaces::WalletBalances getCachedBalance() const
QString getWalletName() const
@ TransactionCreationFailed
virtual CAmount getRequiredFee(unsigned int tx_bytes)=0
Get required fee.
virtual unsigned int getConfirmTarget()=0
Get tx confirm target.
virtual bool hasExternalSigner()=0
virtual CAmount getDefaultMaxTxFee()=0
Get max tx fee.
virtual bool isSpendable(const CTxDestination &dest)=0
Return whether wallet has private key.
virtual std::optional< common::PSBTError > fillPSBT(const common::PSBTFillOptions &options, size_t *n_signed, PartiallySignedTransaction &psbtx, bool &complete)=0
Fill PSBT.
virtual bool privateKeysDisabled()=0
virtual CAmount getMinimumFee(unsigned int tx_bytes, const wallet::CCoinControl &coin_control, int *returned_target, FeeReason *reason)=0
Get minimum fee.
bool HasSelected() const
Returns true if there are pre-selected inputs.
bool m_allow_other_inputs
If true, the selection process can add extra unselected inputs from the wallet while requires all sel...
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Utility functions used by the Bitcoin Qt UI.
QString HtmlEscape(const QString &str, bool fMultiLine)
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
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 ...
QString formatNiceTimeOffset(qint64 secs)
constexpr auto dialog_flags
auto ExceptionSafeConnect(Sender sender, Signal signal, Receiver receiver, Slot method, Qt::ConnectionType type=Qt::AutoConnection)
A drop-in replacement of QObject::connect function (see: https://doc.qt.io/qt-5/qobject....
int TextWidth(const QFontMetrics &fm, const QString &text)
Returns the distance in pixels appropriate for drawing a subsequent character after text.
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
void setClipboard(const QString &str)
is a home for public enum and struct type definitions that are used internally by node code,...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
int getConfTargetForIndex(int index)
int getIndexForConfTarget(int target)
static constexpr std::array confTargets
#define SEND_CONFIRM_DELAY
A mutable version of CTransaction.
Collection of wallet balances.
std::string EncodeBase64(std::span< const unsigned char > input)
SynchronizationState
Current sync state passed to tip changed callbacks.