6 #include <qt/forms/ui_coincontroldialog.h>
22 #include <QApplication>
25 #include <QDialogButtonBox>
29 #include <QTreeWidget>
37 int column = treeWidget()->sortColumn();
39 return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong();
46 m_coin_control(coin_control),
48 platformStyle(_platformStyle)
64 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
65 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
66 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
67 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
68 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
69 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
78 ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
79 ui->labelCoinControlAmount->addAction(clipboardAmountAction);
80 ui->labelCoinControlFee->addAction(clipboardFeeAction);
81 ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
82 ui->labelCoinControlBytes->addAction(clipboardBytesAction);
83 ui->labelCoinControlChange->addAction(clipboardChangeAction);
93 ui->treeWidget->header()->setSectionsClickable(
true);
114 if (settings.contains(
"nCoinControlMode") && !settings.value(
"nCoinControlMode").toBool())
115 ui->radioTreeMode->click();
116 if (settings.contains(
"nCoinControlSortColumn") && settings.contains(
"nCoinControlSortOrder"))
117 sortView(settings.value(
"nCoinControlSortColumn").toInt(), (
static_cast<Qt::SortOrder
>(settings.value(
"nCoinControlSortOrder").toInt())));
132 settings.setValue(
"nCoinControlMode",
ui->radioListMode->isChecked());
133 settings.setValue(
"nCoinControlSortColumn",
sortColumn);
134 settings.setValue(
"nCoinControlSortOrder", (
int)
sortOrder);
142 if (
ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
143 done(QDialog::Accepted);
149 Qt::CheckState state = Qt::Checked;
150 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
152 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) != Qt::Unchecked)
154 state = Qt::Unchecked;
158 ui->treeWidget->setEnabled(
false);
159 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
162 ui->treeWidget->setEnabled(
true);
163 if (state == Qt::Unchecked)
171 QTreeWidgetItem *item =
ui->treeWidget->itemAt(point);
232 const QString outpoint = QString(
"%1:%2").arg(address).arg(vout);
301 ui->treeWidget->sortItems(column, order);
315 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
329 if (checked &&
model)
336 if (checked &&
model)
349 else if (item->isDisabled())
355 if (
ui->treeWidget->isEnabled())
363 std::vector<COutPoint> vOutpts;
365 if (vOutpts.size() > 0)
367 ui->labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
368 ui->labelLocked->setVisible(
true);
370 else ui->labelLocked->setVisible(
false);
381 nPayAmount += amount;
388 unsigned int nBytes = 0;
389 unsigned int nBytesInputs = 0;
390 unsigned int nQuantity = 0;
391 bool fWitness =
false;
397 if (
out.depth_in_main_chain < 0)
continue;
401 const COutPoint& outpt = vCoinControl[i++];
412 nAmount +=
out.txout.nValue;
416 int witnessversion = 0;
417 std::vector<unsigned char> witnessprogram;
418 if (
out.txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram))
421 nBytesInputs += (32 + 4 + 1 + 4);
423 if (witnessversion == 0) {
426 }
else if (witnessversion == 1) {
431 throw std::runtime_error(
"Trying to spend future segwit version script");
438 PKHash* pkhash = std::get_if<PKHash>(&address);
446 else nBytesInputs += 148;
465 if (nAmount - nPayAmount == 0)
473 nChange = nAmount - nPayAmount;
479 CTxOut txout(nChange,
CScript() << std::vector<unsigned char>(24, 0));
495 nAfterFee = std::max<CAmount>(nAmount - nPayFee, 0);
503 QLabel *l1 = dialog->findChild<QLabel *>(
"labelCoinControlQuantity");
504 QLabel *l2 = dialog->findChild<QLabel *>(
"labelCoinControlAmount");
505 QLabel *l3 = dialog->findChild<QLabel *>(
"labelCoinControlFee");
506 QLabel *l4 = dialog->findChild<QLabel *>(
"labelCoinControlAfterFee");
507 QLabel *l5 = dialog->findChild<QLabel *>(
"labelCoinControlBytes");
508 QLabel *l8 = dialog->findChild<QLabel *>(
"labelCoinControlChange");
511 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
512 dialog->findChild<QLabel *>(
"labelCoinControlChange") ->setEnabled(nPayAmount > 0);
515 l1->setText(QString::number(nQuantity));
519 l5->setText(((nBytes > 0) ?
ASYMP_UTF8 :
"") + QString::number(nBytes));
530 double dFeeVary = (nBytes != 0) ? (
double)nPayFee / nBytes : 0;
532 QString toolTip4 = tr(
"Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
534 l3->setToolTip(toolTip4);
535 l4->setToolTip(toolTip4);
536 l8->setToolTip(toolTip4);
537 dialog->findChild<QLabel *>(
"labelCoinControlFeeText") ->setToolTip(l3->toolTip());
538 dialog->findChild<QLabel *>(
"labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip());
539 dialog->findChild<QLabel *>(
"labelCoinControlBytesText") ->setToolTip(l5->toolTip());
540 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setToolTip(l8->toolTip());
543 QLabel *label = dialog->findChild<QLabel *>(
"labelCoinControlInsuffFunds");
545 label->setVisible(nChange < 0);
550 if (e->type() == QEvent::PaletteChange) {
554 QDialog::changeEvent(e);
562 bool treeMode =
ui->radioTreeMode->isChecked();
564 ui->treeWidget->clear();
565 ui->treeWidget->setEnabled(
false);
566 ui->treeWidget->setAlternatingRowColors(!treeMode);
567 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
568 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate;
576 if (sWalletLabel.isEmpty())
577 sWalletLabel = tr(
"(no label)");
584 itemWalletAddress->setFlags(flgTristate);
596 for (
const auto& outpair : coins.second) {
597 const COutPoint& output = std::get<0>(outpair);
599 nSum +=
out.txout.nValue;
605 itemOutput->setFlags(flgCheckbox);
610 QString sAddress =
"";
616 if (!treeMode || (!(sAddress == sWalletAddress)))
621 if (!(sAddress == sWalletAddress))
624 itemOutput->setToolTip(
COLUMN_LABEL, tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
630 if (sLabel.isEmpty())
631 sLabel = tr(
"(no label)");
637 itemOutput->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)
out.txout.nValue));
641 itemOutput->setData(
COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)
out.time));
657 itemOutput->setDisabled(
true);
669 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
671 itemWalletAddress->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum));
678 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
679 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) == Qt::PartiallyChecked)
680 ui->treeWidget->topLevelItem(i)->setExpanded(
true);
685 ui->treeWidget->setEnabled(
true);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
int64_t CAmount
Amount in satoshis (Can be negative)
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
static QString format(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
static QString removeSpaces(QString text)
static QString formatWithUnit(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD)
Format as string (with unit)
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
Serialized script, used inside transaction inputs and outputs.
An output of a transaction.
void headerSectionClicked(int)
QTreeWidgetItem * contextMenuItem
friend class CCoinControlWidgetItem
CoinControlDialog(wallet::CCoinControl &coin_control, WalletModel *model, const PlatformStyle *platformStyle, QWidget *parent=nullptr)
void copyTransactionOutpoint()
const PlatformStyle * platformStyle
void changeEvent(QEvent *e) override
Ui::CoinControlDialog * ui
void sortView(int, Qt::SortOrder)
void showMenu(const QPoint &)
void viewItemChanged(QTreeWidgetItem *, int)
wallet::CCoinControl & m_coin_control
void buttonSelectAllClicked()
QAction * m_copy_transaction_outpoint_action
static QList< CAmount > payAmounts
static void updateLabels(wallet::CCoinControl &m_coin_control, WalletModel *, QDialog *)
static bool fSubtractFeeFromAmount
void buttonBoxClicked(QAbstractButton *)
BitcoinUnit getDisplayUnit() const
Interface to Bitcoin wallet from Qt view code.
AddressTableModel * getAddressTableModel() const
interfaces::Wallet & wallet() const
OptionsModel * getOptionsModel() const
interfaces::Node & node() const
virtual CFeeRate getDustRelayFee()=0
Get dust relay fee.
virtual bool unlockCoin(const COutPoint &output)=0
Unlock coin.
virtual CoinsList listCoins()=0
virtual bool getPubKey(const CScript &script, const CKeyID &address, CPubKey &pub_key)=0
Get public key.
virtual std::vector< WalletTxOut > getCoins(const std::vector< COutPoint > &outputs)=0
Return wallet transaction output information.
virtual bool isLockedCoin(const COutPoint &output)=0
Return whether coin is locked.
virtual void listLockedCoins(std::vector< COutPoint > &outputs)=0
List locked coins.
virtual bool lockCoin(const COutPoint &output, const bool write_to_db)=0
Lock coin.
virtual CAmount getMinimumFee(unsigned int tx_bytes, const wallet::CCoinControl &coin_control, int *returned_target, FeeReason *reason)=0
Get minimum fee.
std::string GetHex() const
constexpr const std::byte * data() const
bool IsSelected(const COutPoint &outpoint) const
Returns true if the given output is pre-selected.
void UnSelectAll()
Unselects all outputs.
void UnSelect(const COutPoint &outpoint)
Unselects the given output.
PreselectedInput & Select(const COutPoint &outpoint)
Lock-in the given output for spending.
std::vector< COutPoint > ListSelected() const
List the selected inputs.
static const int WITNESS_SCALE_FACTOR
std::string EncodeDestination(const CTxDestination &dest)
Utility functions used by the Bitcoin Qt UI.
void handleCloseWindowShortcut(QWidget *w)
QString dateTimeStr(const QDateTime &date)
constexpr auto dialog_flags
void setClipboard(const QString &str)
bool operator<(const CNetAddr &a, const CNetAddr &b)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Wallet transaction output.
Txid TxidFromString(std::string_view str)