5 #if defined(HAVE_CONFIG_H) 10 #include <qt/forms/ui_coincontroldialog.h> 26 #include <validation.h> 30 #include <QApplication> 33 #include <QDialogButtonBox> 37 #include <QTreeWidget> 43 int column = treeWidget()->sortColumn();
45 return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong();
53 platformStyle(_platformStyle)
58 QAction *copyAddressAction =
new QAction(tr(
"Copy address"),
this);
59 QAction *copyLabelAction =
new QAction(tr(
"Copy label"),
this);
60 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
62 lockAction =
new QAction(tr(
"Lock unspent"),
this);
85 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
86 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
87 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
88 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
89 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
90 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy dust"),
this);
91 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
101 ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
102 ui->labelCoinControlAmount->addAction(clipboardAmountAction);
103 ui->labelCoinControlFee->addAction(clipboardFeeAction);
104 ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
105 ui->labelCoinControlBytes->addAction(clipboardBytesAction);
106 ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
107 ui->labelCoinControlChange->addAction(clipboardChangeAction);
117 ui->treeWidget->header()->setSectionsClickable(
true);
140 if (settings.contains(
"nCoinControlMode") && !settings.value(
"nCoinControlMode").toBool())
141 ui->radioTreeMode->click();
142 if (settings.contains(
"nCoinControlSortColumn") && settings.contains(
"nCoinControlSortOrder"))
143 sortView(settings.value(
"nCoinControlSortColumn").toInt(), (
static_cast<Qt::SortOrder
>(settings.value(
"nCoinControlSortOrder").toInt())));
149 settings.setValue(
"nCoinControlMode",
ui->radioListMode->isChecked());
150 settings.setValue(
"nCoinControlSortColumn",
sortColumn);
151 settings.setValue(
"nCoinControlSortOrder", (
int)
sortOrder);
158 this->
model = _model;
171 if (
ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
172 done(QDialog::Accepted);
178 Qt::CheckState state = Qt::Checked;
179 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
181 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) != Qt::Unchecked)
183 state = Qt::Unchecked;
187 ui->treeWidget->setEnabled(
false);
188 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
191 ui->treeWidget->setEnabled(
true);
192 if (state == Qt::Unchecked)
200 QTreeWidgetItem *item =
ui->treeWidget->itemAt(point);
332 ui->treeWidget->sortItems(column, order);
346 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
360 if (checked &&
model)
367 if (checked &&
model)
380 else if (item->isDisabled())
386 if (
ui->treeWidget->isEnabled())
402 std::vector<COutPoint> vOutpts;
404 if (vOutpts.size() > 0)
406 ui->labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
407 ui->labelLocked->setVisible(
true);
409 else ui->labelLocked->setVisible(
false);
423 nPayAmount += amount;
427 CTxOut txout(amount, static_cast<CScript>(std::vector<unsigned char>(24, 0)));
428 txDummy.
vout.push_back(txout);
437 unsigned int nBytes = 0;
438 unsigned int nBytesInputs = 0;
439 unsigned int nQuantity = 0;
440 bool fWitness =
false;
442 std::vector<COutPoint> vCoinControl;
447 if (out.depth_in_main_chain < 0)
continue;
451 const COutPoint& outpt = vCoinControl[i++];
462 nAmount += out.txout.nValue;
466 int witnessversion = 0;
467 std::vector<unsigned char> witnessprogram;
468 if (out.txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram))
470 nBytesInputs += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
476 CKeyID *keyid = boost::get<CKeyID>(&address);
484 else nBytesInputs += 148;
503 if (nAmount - nPayAmount == 0)
511 nChange = nAmount - nPayAmount;
516 if (nChange > 0 && nChange < MIN_CHANGE)
518 CTxOut txout(nChange, static_cast<CScript>(std::vector<unsigned char>(24, 0)));
533 nAfterFee = std::max<CAmount>(nAmount - nPayFee, 0);
541 QLabel *l1 = dialog->findChild<QLabel *>(
"labelCoinControlQuantity");
542 QLabel *l2 = dialog->findChild<QLabel *>(
"labelCoinControlAmount");
543 QLabel *l3 = dialog->findChild<QLabel *>(
"labelCoinControlFee");
544 QLabel *l4 = dialog->findChild<QLabel *>(
"labelCoinControlAfterFee");
545 QLabel *l5 = dialog->findChild<QLabel *>(
"labelCoinControlBytes");
546 QLabel *l7 = dialog->findChild<QLabel *>(
"labelCoinControlLowOutput");
547 QLabel *l8 = dialog->findChild<QLabel *>(
"labelCoinControlChange");
550 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0);
551 dialog->findChild<QLabel *>(
"labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0);
552 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
553 dialog->findChild<QLabel *>(
"labelCoinControlChange") ->setEnabled(nPayAmount > 0);
556 l1->setText(QString::number(nQuantity));
560 l5->setText(((nBytes > 0) ?
ASYMP_UTF8 :
"") + QString::number(nBytes));
561 l7->setText(fDust ? tr(
"yes") : tr(
"no"));
572 l7->setStyleSheet((fDust) ?
"color:red;" :
"");
575 QString toolTipDust = tr(
"This label turns red if any recipient receives an amount smaller than the current dust threshold.");
578 double dFeeVary = (nBytes != 0) ? (
double)nPayFee / nBytes : 0;
580 QString toolTip4 = tr(
"Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
582 l3->setToolTip(toolTip4);
583 l4->setToolTip(toolTip4);
584 l7->setToolTip(toolTipDust);
585 l8->setToolTip(toolTip4);
586 dialog->findChild<QLabel *>(
"labelCoinControlFeeText") ->setToolTip(l3->toolTip());
587 dialog->findChild<QLabel *>(
"labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip());
588 dialog->findChild<QLabel *>(
"labelCoinControlBytesText") ->setToolTip(l5->toolTip());
589 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setToolTip(l7->toolTip());
590 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setToolTip(l8->toolTip());
593 QLabel *label = dialog->findChild<QLabel *>(
"labelCoinControlInsuffFunds");
595 label->setVisible(nChange < 0);
601 return &coin_control;
609 bool treeMode =
ui->radioTreeMode->isChecked();
611 ui->treeWidget->clear();
612 ui->treeWidget->setEnabled(
false);
613 ui->treeWidget->setAlternatingRowColors(!treeMode);
614 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
615 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
624 if (sWalletLabel.isEmpty())
625 sWalletLabel = tr(
"(no label)");
630 ui->treeWidget->addTopLevelItem(itemWalletAddress);
632 itemWalletAddress->setFlags(flgTristate);
644 for (
const auto& outpair : coins.second) {
645 const COutPoint& output = std::get<0>(outpair);
653 itemOutput->setFlags(flgCheckbox);
658 QString sAddress =
"";
664 if (!treeMode || (!(sAddress == sWalletAddress)))
669 if (!(sAddress == sWalletAddress))
672 itemOutput->setToolTip(
COLUMN_LABEL, tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
678 if (sLabel.isEmpty())
679 sLabel = tr(
"(no label)");
685 itemOutput->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.txout.nValue));
689 itemOutput->setData(
COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.time));
693 itemOutput->setData(
COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.depth_in_main_chain));
705 itemOutput->setDisabled(
true);
717 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
719 itemWalletAddress->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum));
726 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
727 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) == Qt::PartiallyChecked)
728 ui->treeWidget->topLevelItem(i)->setExpanded(
true);
733 ui->treeWidget->setEnabled(
true);
const PlatformStyle * platformStyle
void viewItemChanged(QTreeWidgetItem *, int)
virtual CoinsList listCoins()=0
interfaces::Wallet & wallet() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
void buttonSelectAllClicked()
void clipboardLowOutput()
void headerSectionClicked(int)
void copyTransactionHash()
void ListSelected(std::vector< COutPoint > &vOutpoints) const
QString dateTimeStr(const QDateTime &date)
CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
virtual void lockCoin(const COutPoint &output)=0
Lock coin.
AddressTableModel * getAddressTableModel()
void UnSelect(const COutPoint &output)
virtual CFeeRate getDustRelayFee()=0
Get dust relay fee.
int getDisplayUnit() const
int64_t CAmount
Amount in satoshis (Can be negative)
static QList< CAmount > payAmounts
QAction * copyTransactionHashAction
virtual void unlockCoin(const COutPoint &output)=0
Unlock coin.
Ui::CoinControlDialog * ui
void setClipboard(const QString &str)
boost::variant< CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
void Select(const COutPoint &output)
uint256 uint256S(const char *str)
An encapsulated public key.
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
virtual CAmount getMinimumFee(unsigned int tx_bytes, const CCoinControl &coin_control, int *returned_target, FeeReason *reason)=0
Get minimum fee.
static void updateLabels(WalletModel *, QDialog *)
friend class CCoinControlWidgetItem
An output of a transaction.
An outpoint - a combination of a transaction hash and an index n into its vout.
interfaces::Node & node() const
std::vector< CTxOut > vout
virtual std::vector< WalletTxOut > getCoins(const std::vector< COutPoint > &outputs)=0
Return wallet transaction output information.
bool operator<(const CNetAddr &a, const CNetAddr &b)
void setModel(WalletModel *model)
static bool fSubtractFeeFromAmount
QTreeWidgetItem * contextMenuItem
virtual void listLockedCoins(std::vector< COutPoint > &outputs)=0
List locked coins.
Interface to Bitcoin wallet from Qt view code.
bool IsSelected(const COutPoint &output) const
static QString removeSpaces(QString text)
A reference to a CKey: the Hash360 of its serialized public key.
std::string GetHex() const
void sortView(int, Qt::SortOrder)
virtual bool getPubKey(const CKeyID &address, CPubKey &pub_key)=0
Get public key.
virtual bool isLockedCoin(const COutPoint &output)=0
Return whether coin is locked.
std::string EncodeDestination(const CTxDestination &dest)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
A mutable version of CTransaction.
void buttonBoxClicked(QAbstractButton *)
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
void showMenu(const QPoint &)
Wallet transaction output.
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string.
OptionsModel * getOptionsModel()
static CCoinControl * coinControl()
bool IsCompressed() const
Check whether this is a compressed public key.