19 #include "validation.h" 25 #include <boost/assign/list_of.hpp> 27 #include <QApplication> 30 #include <QDialogButtonBox> 35 #include <QTreeWidget> 36 #include <QTreeWidgetItem> 46 platformStyle(platformStyle)
54 QAction *copyAddressAction =
new QAction(tr(
"Copy address"),
this);
55 QAction *copyLabelAction =
new QAction(tr(
"Copy label"),
this);
56 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
58 lockAction =
new QAction(tr(
"Lock unspent"),
this);
72 connect(
ui->
treeWidget, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showMenu(QPoint)));
73 connect(copyAddressAction, SIGNAL(triggered()),
this, SLOT(
copyAddress()));
74 connect(copyLabelAction, SIGNAL(triggered()),
this, SLOT(
copyLabel()));
75 connect(copyAmountAction, SIGNAL(triggered()),
this, SLOT(
copyAmount()));
81 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
82 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
83 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
84 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
85 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
86 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy dust"),
this);
87 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
89 connect(clipboardQuantityAction, SIGNAL(triggered()),
this, SLOT(
clipboardQuantity()));
90 connect(clipboardAmountAction, SIGNAL(triggered()),
this, SLOT(
clipboardAmount()));
91 connect(clipboardFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardFee()));
92 connect(clipboardAfterFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardAfterFee()));
93 connect(clipboardBytesAction, SIGNAL(triggered()),
this, SLOT(
clipboardBytes()));
94 connect(clipboardLowOutputAction, SIGNAL(triggered()),
this, SLOT(
clipboardLowOutput()));
95 connect(clipboardChangeAction, SIGNAL(triggered()),
this, SLOT(
clipboardChange()));
113 #if QT_VERSION < 0x050000 150 if (
settings.contains(
"nCoinControlMode") && !
settings.value(
"nCoinControlMode").toBool())
152 if (
settings.contains(
"nCoinControlSortColumn") &&
settings.contains(
"nCoinControlSortOrder"))
153 sortView(
settings.value(
"nCoinControlSortColumn").toInt(), ((Qt::SortOrder)
settings.value(
"nCoinControlSortOrder").toInt()));
181 while (s.length() < nPadLength)
190 if (
ui->
buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
191 done(QDialog::Accepted);
197 Qt::CheckState state = Qt::Checked;
198 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
202 state = Qt::Unchecked;
207 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
211 if (state == Qt::Unchecked)
219 QTreeWidgetItem *item;
224 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++){
229 item->setDisabled(
false);
234 item->setDisabled(
true);
235 item->setIcon(
COLUMN_CHECKBOX, QIcon(
":/icons/" + theme +
"/lock_closed"));
244 msgBox.setObjectName(
"lockMessageBox");
246 msgBox.setText(tr(
"Please switch to \"List mode\" to use this function."));
403 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
417 if (checked &&
model)
424 if (checked &&
model)
437 else if (item->isDisabled())
443 QMessageBox::warning(
this, windowTitle(),
444 tr(
"Non-anonymized input selected. <b>PrivateSend will be disabled.</b><br><br>If you still want to use PrivateSend, please deselect all non-nonymized inputs first and then check PrivateSend checkbox again."),
445 QMessageBox::Ok, QMessageBox::Ok);
457 #if QT_VERSION >= 0x050000 469 std::vector<COutPoint> vOutpts;
471 if (vOutpts.size() > 0)
473 ui->
labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
490 nPayAmount += amount;
494 CTxOut txout(amount, (
CScript)std::vector<unsigned char>(24, 0));
495 txDummy.
vout.push_back(txout);
505 unsigned int nBytes = 0;
506 unsigned int nBytesInputs = 0;
507 double dPriority = 0;
508 double dPriorityInputs = 0;
509 unsigned int nQuantity = 0;
510 int nQuantityUncompressed = 0;
511 bool fAllowFree =
false;
513 std::vector<COutPoint> vCoinControl;
514 std::vector<COutput> vOutputs;
533 nAmount +=
out.tx->vout[
out.i].nValue;
536 dPriorityInputs += (double)
out.tx->vout[
out.i].nValue * (
out.nDepth+1);
543 CKeyID *keyid = boost::get<CKeyID>(&address);
548 nQuantityUncompressed++;
553 else nBytesInputs += 148;
568 if (nAmount - nPayAmount == 0)
581 dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29));
583 fAllowFree = (dPriority >= dPriorityNeeded);
591 nChange = nAmount - nPayAmount;
604 CTxOut txout(nChange, (
CScript)std::vector<unsigned char>(24, 0));
622 nAfterFee = nAmount - nPayFee;
632 QLabel *
l1 = dialog->findChild<QLabel *>(
"labelCoinControlQuantity");
633 QLabel *
l2 = dialog->findChild<QLabel *>(
"labelCoinControlAmount");
634 QLabel *l3 = dialog->findChild<QLabel *>(
"labelCoinControlFee");
635 QLabel *l4 = dialog->findChild<QLabel *>(
"labelCoinControlAfterFee");
636 QLabel *l5 = dialog->findChild<QLabel *>(
"labelCoinControlBytes");
637 QLabel *l7 = dialog->findChild<QLabel *>(
"labelCoinControlLowOutput");
638 QLabel *l8 = dialog->findChild<QLabel *>(
"labelCoinControlChange");
641 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0);
642 dialog->findChild<QLabel *>(
"labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0);
643 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
644 dialog->findChild<QLabel *>(
"labelCoinControlChange") ->setEnabled(nPayAmount > 0);
647 l1->setText(QString::number(nQuantity));
651 l5->setText(((nBytes > 0) ?
ASYMP_UTF8 :
"") + QString::number(nBytes));
652 l7->setText(fDust ? tr(
"yes") : tr(
"no"));
663 l7->setStyleSheet((fDust) ?
"color:red;" :
"");
666 QString toolTipDust = tr(
"This label turns red if any recipient receives an amount smaller than the current dust threshold.");
675 QString toolTip4 = tr(
"Can vary +/- %1 duff(s) per input.").arg(dFeeVary);
677 l3->setToolTip(toolTip4);
678 l4->setToolTip(toolTip4);
679 l7->setToolTip(toolTipDust);
680 l8->setToolTip(toolTip4);
681 dialog->findChild<QLabel *>(
"labelCoinControlFeeText") ->setToolTip(l3->toolTip());
682 dialog->findChild<QLabel *>(
"labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip());
683 dialog->findChild<QLabel *>(
"labelCoinControlBytesText") ->setToolTip(l5->toolTip());
684 dialog->findChild<QLabel *>(
"labelCoinControlLowOutputText")->setToolTip(l7->toolTip());
685 dialog->findChild<QLabel *>(
"labelCoinControlChangeText") ->setToolTip(l8->toolTip());
688 QLabel *label = dialog->findChild<QLabel *>(
"labelCoinControlInsuffFunds");
690 label->setVisible(nChange < 0);
704 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
705 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
709 std::map<QString, std::vector<COutput> > mapCoins;
712 BOOST_FOREACH(
const PAIRTYPE(QString, std::vector<COutput>)& coins, mapCoins) {
713 QTreeWidgetItem *itemWalletAddress =
new QTreeWidgetItem();
715 QString sWalletAddress = coins.first;
717 if (sWalletLabel.isEmpty())
718 sWalletLabel = tr(
"(no label)");
725 itemWalletAddress->setFlags(flgTristate);
730 itemWalletAddress->setToolTip(
COLUMN_LABEL, sWalletLabel);
739 BOOST_FOREACH(
const COutput&
out, coins.second) {
740 nSum +=
out.tx->vout[
out.i].nValue;
743 QTreeWidgetItem *itemOutput;
744 if (treeMode) itemOutput =
new QTreeWidgetItem(itemWalletAddress);
746 itemOutput->setFlags(flgCheckbox);
751 QString sAddress =
"";
754 sAddress = QString::fromStdString(
CBitcoinAddress(outputAddress).ToString());
757 if (!treeMode || (!(sAddress == sWalletAddress)))
764 if (!(sAddress == sWalletAddress))
767 itemOutput->setToolTip(
COLUMN_LABEL, tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
773 if (sLabel.isEmpty())
774 sLabel = tr(
"(no label)");
812 itemOutput->setDisabled(
true);
813 itemOutput->setIcon(
COLUMN_CHECKBOX, QIcon(
":/icons/" + theme +
"/lock_closed"));
824 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
834 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
static QList< CAmount > payAmounts
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
void buttonSelectAllClicked()
Ui::CoinControlDialog * ui
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
static void updateLabels(WalletModel *, QDialog *)
bool IsSelected(const COutPoint &output) const
void headerSectionClicked(int)
CFeeRate estimateSmartFee(int nBlocks, int *answerFoundAtBlocks=NULL) const
double AllowFreeThreshold()
void viewItemChanged(QTreeWidgetItem *, int)
QLabel * labelCoinControlLowOutput
void clipboardLowOutput()
double estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks=NULL) const
QDialogButtonBox * buttonBox
void Select(const COutPoint &output)
int getMappedColumn(int column, bool fVisibleColumn=true)
void showMenu(const QPoint &)
QLabel * labelCoinControlAfterFee
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
QRadioButton * radioListMode
void ListSelected(std::vector< COutPoint > &vOutpoints) const
static const CAmount MIN_CHANGE
minimum change amount
void unlockCoin(COutPoint &output)
void copyTransactionHash()
QLabel * labelCoinControlAmount
unsigned int nTxConfirmTarget
bool fSendFreeTransactions
void setClipboard(const QString &str)
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE
Largest (in bytes) free transaction we're willing to create.
QString labelForAddress(const QString &address) const
CAmount nMinimumTotalFee
Minimum absolute fee (not per kilobyte)
uint256 uint256S(const char *str)
CAmount GetFeePerK() const
void sortView(int, Qt::SortOrder)
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool &pool)
void listLockedCoins(std::vector< COutPoint > &vOutpts)
QLabel * labelCoinControlBytes
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string.
OptionsModel * getOptionsModel()
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
void setModel(WalletModel *model)
void buttonBoxClicked(QAbstractButton *)
CoinControlTreeWidget * treeWidget
bool isSpent(const COutPoint &outpoint) const
bool isLockedCoin(uint256 hash, unsigned int n) const
std::vector< CTxOut > vout
CPrivateSendClient privateSendClient
QPushButton * pushButtonToggleLock
static bool fSubtractFeeFromAmount
QPushButton * pushButtonSelectAll
void lockCoin(COutPoint &output)
bool IsDust(const CFeeRate &minRelayTxFee) const
int GetOutpointPrivateSendRounds(const COutPoint &outpoint) const
void UnSelect(const COutPoint &output)
bool IsCompressed() const
Check whether this is a compressed public key.
QLabel * labelCoinControlQuantity
CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
std::string GetHex() const
QLabel * labelCoinControlChange
static CCoinControl * coinControl
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
static QString removeSpaces(QString text)
QTreeWidgetItem * contextMenuItem
QRadioButton * radioTreeMode
static CAmount GetRequiredFee(unsigned int nTxBytes)
QAction * copyTransactionHashAction
void setupUi(QDialog *CoinControlDialog)
AddressTableModel * getAddressTableModel()
QLabel * labelCoinControlFee
CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
QString strPad(QString, int, QString)
void getOutputs(const std::vector< COutPoint > &vOutpoints, std::vector< COutput > &vOutputs)
void buttonToggleLockClicked()
QString dateTimeStr(const QDateTime &date)
void listCoins(std::map< QString, std::vector< COutput > > &mapCoins) const