7 #include "ui_coincontroldialog.h" 21 #include "validation.h" 25 #include <QApplication> 28 #include <QDialogButtonBox> 33 #include <QTreeWidget> 34 #include <QTreeWidgetItem> 41 int column = treeWidget()->sortColumn();
43 return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong();
51 platformStyle(_platformStyle)
56 QAction *copyAddressAction =
new QAction(tr(
"Copy address"),
this);
57 QAction *copyLabelAction =
new QAction(tr(
"Copy label"),
this);
58 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
60 lockAction =
new QAction(tr(
"Lock unspent"),
this);
74 connect(
ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showMenu(QPoint)));
75 connect(copyAddressAction, SIGNAL(triggered()),
this, SLOT(
copyAddress()));
76 connect(copyLabelAction, SIGNAL(triggered()),
this, SLOT(
copyLabel()));
77 connect(copyAmountAction, SIGNAL(triggered()),
this, SLOT(
copyAmount()));
83 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
84 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
85 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
86 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
87 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
88 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy dust"),
this);
89 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
91 connect(clipboardQuantityAction, SIGNAL(triggered()),
this, SLOT(
clipboardQuantity()));
92 connect(clipboardAmountAction, SIGNAL(triggered()),
this, SLOT(
clipboardAmount()));
93 connect(clipboardFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardFee()));
94 connect(clipboardAfterFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardAfterFee()));
95 connect(clipboardBytesAction, SIGNAL(triggered()),
this, SLOT(
clipboardBytes()));
96 connect(clipboardLowOutputAction, SIGNAL(triggered()),
this, SLOT(
clipboardLowOutput()));
97 connect(clipboardChangeAction, SIGNAL(triggered()),
this, SLOT(
clipboardChange()));
99 ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
100 ui->labelCoinControlAmount->addAction(clipboardAmountAction);
101 ui->labelCoinControlFee->addAction(clipboardFeeAction);
102 ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
103 ui->labelCoinControlBytes->addAction(clipboardBytesAction);
104 ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
105 ui->labelCoinControlChange->addAction(clipboardChangeAction);
108 connect(
ui->radioTreeMode, SIGNAL(toggled(
bool)),
this, SLOT(
radioTreeMode(
bool)));
109 connect(
ui->radioListMode, SIGNAL(toggled(
bool)),
this, SLOT(
radioListMode(
bool)));
112 connect(
ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,
int)),
this, SLOT(
viewItemChanged(QTreeWidgetItem*,
int)));
115 #if QT_VERSION < 0x050000 116 ui->treeWidget->header()->setClickable(
true);
118 ui->treeWidget->header()->setSectionsClickable(
true);
123 connect(
ui->buttonBox, SIGNAL(clicked( QAbstractButton*)),
this, SLOT(
buttonBoxClicked(QAbstractButton*)));
146 if (settings.contains(
"nCoinControlMode") && !settings.value(
"nCoinControlMode").toBool())
147 ui->radioTreeMode->click();
148 if (settings.contains(
"nCoinControlSortColumn") && settings.contains(
"nCoinControlSortOrder"))
149 sortView(settings.value(
"nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value(
"nCoinControlSortOrder").toInt()));
155 settings.setValue(
"nCoinControlMode",
ui->radioListMode->isChecked());
156 settings.setValue(
"nCoinControlSortColumn",
sortColumn);
157 settings.setValue(
"nCoinControlSortOrder", (
int)
sortOrder);
164 this->
model = _model;
177 if (
ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
178 done(QDialog::Accepted);
184 Qt::CheckState state = Qt::Checked;
185 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
187 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) != Qt::Unchecked)
189 state = Qt::Unchecked;
193 ui->treeWidget->setEnabled(
false);
194 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
197 ui->treeWidget->setEnabled(
true);
198 if (state == Qt::Unchecked)
206 QTreeWidgetItem *item =
ui->treeWidget->itemAt(point);
338 ui->treeWidget->sortItems(column, order);
352 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
366 if (checked &&
model)
373 if (checked &&
model)
386 else if (item->isDisabled())
392 if (
ui->treeWidget->isEnabled())
398 #if QT_VERSION >= 0x050000 410 std::vector<COutPoint> vOutpts;
412 if (vOutpts.size() > 0)
414 ui->labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
415 ui->labelLocked->setVisible(
true);
417 else ui->labelLocked->setVisible(
false);
431 nPayAmount += amount;
435 CTxOut txout(amount, (
CScript)std::vector<unsigned char>(24, 0));
436 txDummy.
vout.push_back(txout);
445 unsigned int nBytes = 0;
446 unsigned int nBytesInputs = 0;
447 unsigned int nQuantity = 0;
448 bool fWitness =
false;
450 std::vector<COutPoint> vCoinControl;
451 std::vector<COutput> vOutputs;
455 for (
const COutput& out : vOutputs) {
458 uint256 txhash = out.tx->GetHash();
470 nAmount += out.tx->tx->vout[out.i].nValue;
474 int witnessversion = 0;
475 std::vector<unsigned char> witnessprogram;
476 if (out.tx->tx->vout[out.i].scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram))
478 nBytesInputs += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
484 CKeyID *keyid = boost::get<CKeyID>(&address);
485 if (keyid && model->
getPubKey(*keyid, pubkey))
492 else nBytesInputs += 148;
498 nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10;
510 if (nAmount - nPayAmount == 0)
518 nChange = nAmount - nPayAmount;
523 if (nChange > 0 && nChange < MIN_CHANGE)
525 CTxOut txout(nChange, (
CScript)std::vector<unsigned char>(24, 0));
540 nAfterFee = std::max<CAmount>(nAmount - nPayFee, 0);
548 QLabel *l1 = dialog->findChild<QLabel *>(
"labelCoinControlQuantity");
549 QLabel *l2 = dialog->findChild<QLabel *>(
"labelCoinControlAmount");
550 QLabel *l3 = dialog->findChild<QLabel *>(
"labelCoinControlFee");
551 QLabel *l4 = dialog->findChild<QLabel *>(
"labelCoinControlAfterFee");
552 QLabel *l5 = dialog->findChild<QLabel *>(
"labelCoinControlBytes");
553 QLabel *l7 = dialog->findChild<QLabel *>(
"labelCoinControlLowOutput");
554 QLabel *l8 = dialog->findChild<QLabel *>(
"labelCoinControlChange");
557 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0);
558 dialog->findChild<QLabel *>(
"labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0);
559 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
560 dialog->findChild<QLabel *>(
"labelCoinControlChange") ->setEnabled(nPayAmount > 0);
563 l1->setText(QString::number(nQuantity));
567 l5->setText(((nBytes > 0) ?
ASYMP_UTF8 :
"") + QString::number(nBytes));
568 l7->setText(fDust ? tr(
"yes") : tr(
"no"));
579 l7->setStyleSheet((fDust) ?
"color:red;" :
"");
582 QString toolTipDust = tr(
"This label turns red if any recipient receives an amount smaller than the current dust threshold.");
585 double dFeeVary = (nBytes != 0) ? (
double)nPayFee / nBytes : 0;
587 QString toolTip4 = tr(
"Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
589 l3->setToolTip(toolTip4);
590 l4->setToolTip(toolTip4);
591 l7->setToolTip(toolTipDust);
592 l8->setToolTip(toolTip4);
593 dialog->findChild<QLabel *>(
"labelCoinControlFeeText") ->setToolTip(l3->toolTip());
594 dialog->findChild<QLabel *>(
"labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip());
595 dialog->findChild<QLabel *>(
"labelCoinControlBytesText") ->setToolTip(l5->toolTip());
596 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setToolTip(l7->toolTip());
597 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setToolTip(l8->toolTip());
600 QLabel *label = dialog->findChild<QLabel *>(
"labelCoinControlInsuffFunds");
602 label->setVisible(nChange < 0);
610 bool treeMode =
ui->radioTreeMode->isChecked();
612 ui->treeWidget->clear();
613 ui->treeWidget->setEnabled(
false);
614 ui->treeWidget->setAlternatingRowColors(!treeMode);
615 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
616 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
620 std::map<QString, std::vector<COutput> > mapCoins;
623 for (
const std::pair<QString, std::vector<COutput>>& coins : mapCoins) {
626 QString sWalletAddress = coins.first;
628 if (sWalletLabel.isEmpty())
629 sWalletLabel = tr(
"(no label)");
634 ui->treeWidget->addTopLevelItem(itemWalletAddress);
636 itemWalletAddress->setFlags(flgTristate);
648 for (
const COutput& out : coins.second) {
649 nSum += out.
tx->
tx->vout[out.
i].nValue;
655 itemOutput->setFlags(flgCheckbox);
660 QString sAddress =
"";
666 if (!treeMode || (!(sAddress == sWalletAddress)))
671 if (!(sAddress == sWalletAddress))
674 itemOutput->setToolTip(
COLUMN_LABEL, tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
680 if (sLabel.isEmpty())
681 sLabel = tr(
"(no label)");
687 itemOutput->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.
tx->
tx->vout[out.
i].nValue));
709 itemOutput->setDisabled(
true);
721 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
723 itemWalletAddress->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum));
730 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
731 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) == Qt::PartiallyChecked)
732 ui->treeWidget->topLevelItem(i)->setExpanded(
true);
737 ui->treeWidget->setEnabled(
true);
bool isLockedCoin(uint256 hash, unsigned int n) const
RVN END.
void listCoins(std::map< QString, std::vector< COutput > > &mapCoins) const
const PlatformStyle * platformStyle
void viewItemChanged(QTreeWidgetItem *, int)
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard, const int nAssetUnit=MIN_ASSET_UNITS - 1)
Format as string.
void getOutputs(const std::vector< COutPoint > &vOutpoints, std::vector< COutput > &vOutputs)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
void lockCoin(COutPoint &output)
void buttonSelectAllClicked()
void clipboardLowOutput()
void headerSectionClicked(int)
static CCoinControl * coinControl
void copyTransactionHash()
const uint256 & GetHash() const
void ListSelected(std::vector< COutPoint > &vOutpoints) const
QString dateTimeStr(const QDateTime &date)
CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
AddressTableModel * getAddressTableModel()
void UnSelect(const COutPoint &output)
int getDisplayUnit() const
int64_t CAmount
Amount in corbies (Can be negative)
CBlockPolicyEstimator feeEstimator
static QList< CAmount > payAmounts
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
QAction * copyTransactionHashAction
Ui::CoinControlDialog * ui
void setClipboard(const QString &str)
void Select(const COutPoint &output)
uint256 uint256S(const char *str)
An encapsulated public key.
static QString removeSpaces(QString text)
QString labelForAddress(const QString &address) const
bool isSpent(const COutPoint &outpoint) const
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.
std::vector< CTxOut > vout
bool operator<(const CNetAddr &a, const CNetAddr &b)
void setModel(WalletModel *model)
static bool fSubtractFeeFromAmount
QTreeWidgetItem * contextMenuItem
std::string EncodeDestination(const CTxDestination &dest)
void listLockedCoins(std::vector< COutPoint > &vOutpts)
int64_t GetTxTime() const
Serialized script, used inside transaction inputs and outputs.
Interface to Raven wallet from Qt view code.
bool IsSelected(const COutPoint &output) const
void unlockCoin(COutPoint &output)
A reference to a CKey: the Hash160 of its serialized public key.
std::string GetHex() const
void sortView(int, Qt::SortOrder)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
A mutable version of CTransaction.
void buttonBoxClicked(QAbstractButton *)
void showMenu(const QPoint &)
CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl &coin_control, const CTxMemPool &pool, const CBlockPolicyEstimator &estimator, FeeCalculation *feeCalc)
Estimate the minimum fee considering user set parameters and the required fee.
OptionsModel * getOptionsModel()
bool IsCompressed() const
Check whether this is a compressed public key.