19 #include <QApplication>
22 #include <QDialogButtonBox>
26 #include <QTreeWidget>
27 #include <QTreeWidgetItem>
41 QAction *copyAddressAction =
new QAction(tr(
"Copy address"),
this);
42 QAction *copyLabelAction =
new QAction(tr(
"Copy label"),
this);
43 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
45 lockAction =
new QAction(tr(
"Lock unspent"),
this);
59 connect(
ui->
treeWidget, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showMenu(QPoint)));
60 connect(copyAddressAction, SIGNAL(triggered()),
this, SLOT(
copyAddress()));
61 connect(copyLabelAction, SIGNAL(triggered()),
this, SLOT(
copyLabel()));
62 connect(copyAmountAction, SIGNAL(triggered()),
this, SLOT(
copyAmount()));
68 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
69 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
70 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
71 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
72 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
73 QAction *clipboardPriorityAction =
new QAction(tr(
"Copy priority"),
this);
74 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy low output"),
this);
75 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
77 connect(clipboardQuantityAction, SIGNAL(triggered()),
this, SLOT(
clipboardQuantity()));
78 connect(clipboardAmountAction, SIGNAL(triggered()),
this, SLOT(
clipboardAmount()));
79 connect(clipboardFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardFee()));
80 connect(clipboardAfterFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardAfterFee()));
81 connect(clipboardBytesAction, SIGNAL(triggered()),
this, SLOT(
clipboardBytes()));
82 connect(clipboardPriorityAction, SIGNAL(triggered()),
this, SLOT(
clipboardPriority()));
83 connect(clipboardLowOutputAction, SIGNAL(triggered()),
this, SLOT(
clipboardLowOutput()));
84 connect(clipboardChangeAction, SIGNAL(triggered()),
this, SLOT(
clipboardChange()));
103 #if QT_VERSION < 0x050000
153 while (s.length() < nPadLength)
162 if (
ui->
buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
163 done(QDialog::Accepted);
169 Qt::CheckState state = Qt::Checked;
170 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
174 state = Qt::Unchecked;
179 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
183 if (state == Qt::Unchecked)
345 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
359 if (checked &&
model)
366 if (checked &&
model)
379 else if (item->isDisabled())
393 #if QT_VERSION >= 0x050000
407 if (
AllowFree(dPriority / 1000000))
return tr(
"highest");
408 else if (
AllowFree(dPriority / 100000))
return tr(
"higher");
409 else if (
AllowFree(dPriority / 10000))
return tr(
"high");
410 else if (
AllowFree(dPriority / 1000))
return tr(
"medium-high");
411 else return tr(
"medium");
415 if (
AllowFree(dPriority * 10))
return tr(
"low-medium");
416 else if (
AllowFree(dPriority * 100))
return tr(
"low");
417 else if (
AllowFree(dPriority * 1000))
return tr(
"lower");
418 else return tr(
"lowest");
425 vector<COutPoint> vOutpts;
427 if (vOutpts.size() > 0)
429 ui->
labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
441 qint64 nPayAmount = 0;
442 bool fLowOutput =
false;
447 nPayAmount += amount;
455 txDummy.
vout.push_back(txout);
461 QString sPriorityLabel = tr(
"none");
464 int64_t nAfterFee = 0;
466 unsigned int nBytes = 0;
467 unsigned int nBytesInputs = 0;
468 double dPriority = 0;
469 double dPriorityInputs = 0;
470 unsigned int nQuantity = 0;
471 int nQuantityUncompressed = 0;
473 vector<COutPoint> vCoinControl;
474 vector<COutput> vOutputs;
478 BOOST_FOREACH(
const COutput& out, vOutputs)
494 nAmount += out.
tx->
vout[out.
i].nValue;
497 dPriorityInputs += (double)out.
tx->
vout[out.
i].nValue * (out.
nDepth+1);
504 CKeyID *keyid = boost::get<CKeyID>(&address);
505 if (keyid && model->
getPubKey(*keyid, pubkey))
509 nQuantityUncompressed++;
514 else nBytesInputs += 148;
524 dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29));
533 nPayFee = max(nFee, nMinFee);
537 nChange = nAmount - nPayFee - nPayAmount;
540 if (nPayFee < CTransaction::nMinTxFee && nChange > 0 && nChange <
CENT)
555 if (nChange > 0 && nChange <
CENT)
557 CTxOut txout(nChange, (
CScript)vector<unsigned char>(24, 0));
570 nAfterFee = nAmount - nPayFee;
580 QLabel *l1 = dialog->findChild<
QLabel *>(
"labelCoinControlQuantity");
581 QLabel *l2 = dialog->findChild<
QLabel *>(
"labelCoinControlAmount");
582 QLabel *l3 = dialog->findChild<
QLabel *>(
"labelCoinControlFee");
583 QLabel *l4 = dialog->findChild<
QLabel *>(
"labelCoinControlAfterFee");
584 QLabel *l5 = dialog->findChild<
QLabel *>(
"labelCoinControlBytes");
585 QLabel *l6 = dialog->findChild<
QLabel *>(
"labelCoinControlPriority");
586 QLabel *l7 = dialog->findChild<
QLabel *>(
"labelCoinControlLowOutput");
587 QLabel *l8 = dialog->findChild<
QLabel *>(
"labelCoinControlChange");
590 dialog->findChild<
QLabel *>(
"labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0);
591 dialog->findChild<
QLabel *>(
"labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0);
592 dialog->findChild<
QLabel *>(
"labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
593 dialog->findChild<
QLabel *>(
"labelCoinControlChange") ->setEnabled(nPayAmount > 0);
596 l1->setText(QString::number(nQuantity));
600 l5->setText(((nBytes > 0) ?
"~" :
"") + QString::number(nBytes));
601 l6->setText(sPriorityLabel);
602 l7->setText((fLowOutput ? (fDust ? tr(
"Dust") : tr(
"yes")) : tr(
"no")));
606 l5->setStyleSheet((nBytes >= 1000) ?
"color:red;" :
"");
607 l6->setStyleSheet((dPriority > 0 && !
AllowFree(dPriority)) ?
"color:red;" :
"");
608 l7->setStyleSheet((fLowOutput) ?
"color:red;" :
"");
609 l8->setStyleSheet((nChange > 0 && nChange <
CENT) ?
"color:red;" :
"");
612 QString toolTip1 = tr(
"This label turns red, if the transaction size is greater than 1000 bytes.") +
"<br /><br />";
614 toolTip1 += tr(
"Can vary +/- 1 byte per input.");
616 QString toolTip2 = tr(
"Transactions with higher priority are more likely to get included into a block.") +
"<br /><br />";
617 toolTip2 += tr(
"This label turns red, if the priority is smaller than \"medium\".") +
"<br /><br />";
620 QString toolTip3 = tr(
"This label turns red, if any recipient receives an amount smaller than %1.").arg(
BitcoinUnits::formatWithUnit(nDisplayUnit,
CENT)) +
"<br /><br />";
622 toolTip3 += tr(
"Amounts below 0.546 times the minimum relay fee are shown as dust.");
627 l5->setToolTip(toolTip1);
628 l6->setToolTip(toolTip2);
629 l7->setToolTip(toolTip3);
630 l8->setToolTip(toolTip4);
631 dialog->findChild<
QLabel *>(
"labelCoinControlBytesText") ->setToolTip(l5->toolTip());
632 dialog->findChild<
QLabel *>(
"labelCoinControlPriorityText") ->setToolTip(l6->toolTip());
633 dialog->findChild<
QLabel *>(
"labelCoinControlLowOutputText")->setToolTip(l7->toolTip());
634 dialog->findChild<
QLabel *>(
"labelCoinControlChangeText") ->setToolTip(l8->toolTip());
637 QLabel *label = dialog->findChild<
QLabel *>(
"labelCoinControlInsuffFunds");
639 label->setVisible(nChange < 0);
652 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
653 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
657 map<QString, vector<COutput> > mapCoins;
660 BOOST_FOREACH(
PAIRTYPE(QString, vector<COutput>) coins, mapCoins)
662 QTreeWidgetItem *itemWalletAddress =
new QTreeWidgetItem();
664 QString sWalletAddress = coins.first;
666 if (sWalletLabel.isEmpty())
667 sWalletLabel = tr(
"(no label)");
674 itemWalletAddress->setFlags(flgTristate);
685 double dPrioritySum = 0;
688 BOOST_FOREACH(
const COutput& out, coins.second)
691 nSum += out.
tx->
vout[out.
i].nValue;
694 QTreeWidgetItem *itemOutput;
695 if (treeMode) itemOutput =
new QTreeWidgetItem(itemWalletAddress);
697 itemOutput->setFlags(flgCheckbox);
702 QString sAddress =
"";
708 if (!treeMode || (!(sAddress == sWalletAddress)))
712 CKeyID *keyid = boost::get<CKeyID>(&outputAddress);
718 if (!(sAddress == sWalletAddress))
721 itemOutput->setToolTip(
COLUMN_LABEL, tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
727 if (sLabel.isEmpty())
728 sLabel = tr(
"(no label)");
744 double dPriority = ((double)out.
tx->
vout[out.
i].nValue / (nInputSize + 78)) * (out.
nDepth+1);
747 dPrioritySum += (double)out.
tx->
vout[out.
i].nValue * (out.
nDepth+1);
748 nInputSum += nInputSize;
762 itemOutput->setDisabled(
true);
774 dPrioritySum = dPrioritySum / (nInputSum + 78);
775 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
786 for (
int i = 0; i <
ui->
treeWidget->topLevelItemCount(); i++)
void viewItemChanged(QTreeWidgetItem *, int)
bool IsDust(int64_t nMinRelayTxFee) const
void getOutputs(const std::vector< COutPoint > &vOutpoints, std::vector< COutput > &vOutputs)
void lockCoin(COutPoint &output)
void buttonSelectAllClicked()
void clipboardLowOutput()
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false)
Format as string (with unit)
void headerSectionClicked(int)
static CCoinControl * coinControl
void copyTransactionHash()
int getMappedColumn(int column, bool fVisibleColumn=true)
QRadioButton * radioTreeMode
void setupUi(QDialog *CoinControlDialog)
bool isLockedCoin(uint256 hash, unsigned int n) const
QString dateTimeStr(const QDateTime &date)
bool IsSelected(const uint256 &hash, unsigned int n) const
int64_t GetMinFee(const CTransaction &tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
base58-encoded Bitcoin addresses.
bool AllowFree(double dPriority)
AddressTableModel * getAddressTableModel()
static int64_t nMinTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) ...
QLabel * labelCoinControlPriority
QLabel * labelCoinControlChange
QPushButton * pushButtonSelectAll
QAction * copyTransactionHashAction
bool isSpent(const COutPoint &outpoint) const
Ui::CoinControlDialog * ui
void setClipboard(const QString &str)
std::vector< CTxOut > vout
CoinControlTreeWidget * treeWidget
An encapsulated public key.
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
static QString getPriorityLabel(double)
CoinControlDialog(QWidget *parent=0)
std::string ToString() const
static void updateLabels(WalletModel *, QDialog *)
An output of a transaction.
QLabel * labelCoinControlQuantity
An outpoint - a combination of a transaction hash and an index n into its vout.
std::string GetHex() const
QLabel * labelCoinControlLowOutput
int64_t GetTxTime() const
bool IsCompressed() const
QLabel * labelCoinControlAmount
void setModel(WalletModel *model)
QTreeWidgetItem * contextMenuItem
QString labelForAddress(const QString &address) const
void listLockedCoins(std::vector< COutPoint > &vOutpts)
Serialized script, used inside transaction inputs and outputs.
Interface to Bitcoin wallet from Qt view code.
void Select(COutPoint &output)
void unlockCoin(COutPoint &output)
A reference to a CKey: the Hash160 of its serialized public key.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
void sortView(int, Qt::SortOrder)
static QList< qint64 > payAmounts
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
static const int64_t CENT
QString strPad(QString, int, QString)
void ListSelected(std::vector< COutPoint > &vOutpoints)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
void buttonBoxClicked(QAbstractButton *)
void UnSelect(COutPoint &output)
The basic transaction that is broadcasted on the network and contained in blocks. ...
QRadioButton * radioListMode
void showMenu(const QPoint &)
QDialogButtonBox * buttonBox
void listCoins(std::map< QString, std::vector< COutput > > &mapCoins) const
QLabel * labelCoinControlFee
QLabel * labelCoinControlAfterFee
QLabel * labelCoinControlBytes
static QString format(int unit, qint64 amount, bool plussign=false)
Format as string.
OptionsModel * getOptionsModel()