7 #include "ui_assetcontroldialog.h" 21 #include "validation.h" 25 #include <QApplication> 28 #include <QDialogButtonBox> 33 #include <QTreeWidget> 34 #include <QTreeWidgetItem> 35 #include <QStringListModel> 36 #include <QSortFilterProxyModel> 45 int column = treeWidget()->sortColumn();
47 return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong();
55 platformStyle(_platformStyle)
60 QAction *copyAddressAction =
new QAction(tr(
"Copy address"),
this);
61 QAction *copyLabelAction =
new QAction(tr(
"Copy label"),
this);
62 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
64 lockAction =
new QAction(tr(
"Lock unspent"),
this);
78 connect(
ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showMenu(QPoint)));
79 connect(copyAddressAction, SIGNAL(triggered()),
this, SLOT(
copyAddress()));
80 connect(copyLabelAction, SIGNAL(triggered()),
this, SLOT(
copyLabel()));
81 connect(copyAmountAction, SIGNAL(triggered()),
this, SLOT(
copyAmount()));
87 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
88 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
89 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
90 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
91 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
92 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy dust"),
this);
93 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
95 connect(clipboardQuantityAction, SIGNAL(triggered()),
this, SLOT(
clipboardQuantity()));
96 connect(clipboardAmountAction, SIGNAL(triggered()),
this, SLOT(
clipboardAmount()));
97 connect(clipboardFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardFee()));
98 connect(clipboardAfterFeeAction, SIGNAL(triggered()),
this, SLOT(
clipboardAfterFee()));
99 connect(clipboardBytesAction, SIGNAL(triggered()),
this, SLOT(
clipboardBytes()));
100 connect(clipboardLowOutputAction, SIGNAL(triggered()),
this, SLOT(
clipboardLowOutput()));
101 connect(clipboardChangeAction, SIGNAL(triggered()),
this, SLOT(
clipboardChange()));
103 ui->labelAssetControlQuantity->addAction(clipboardQuantityAction);
104 ui->labelAssetControlAmount->addAction(clipboardAmountAction);
105 ui->labelAssetControlFee->addAction(clipboardFeeAction);
106 ui->labelAssetControlAfterFee->addAction(clipboardAfterFeeAction);
107 ui->labelAssetControlBytes->addAction(clipboardBytesAction);
108 ui->labelAssetControlLowOutput->addAction(clipboardLowOutputAction);
109 ui->labelAssetControlChange->addAction(clipboardChangeAction);
112 connect(
ui->radioTreeMode, SIGNAL(toggled(
bool)),
this, SLOT(
radioTreeMode(
bool)));
113 connect(
ui->radioListMode, SIGNAL(toggled(
bool)),
this, SLOT(
radioListMode(
bool)));
116 connect(
ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,
int)),
this, SLOT(
viewItemChanged(QTreeWidgetItem*,
int)));
119 #if QT_VERSION < 0x050000 120 ui->treeWidget->header()->setClickable(
true);
122 ui->treeWidget->header()->setSectionsClickable(
true);
127 connect(
ui->buttonBox, SIGNAL(clicked( QAbstractButton*)),
this, SLOT(
buttonBoxClicked(QAbstractButton*)));
150 if (settings.contains(
"nCoinControlMode") && !settings.value(
"nCoinControlMode").toBool())
151 ui->radioTreeMode->click();
152 if (settings.contains(
"nCoinControlSortColumn") && settings.contains(
"nCoinControlSortOrder"))
153 sortView(settings.value(
"nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value(
"nCoinControlSortOrder").toInt()));
157 connect(
ui->assetList, SIGNAL(currentIndexChanged(QString)),
this, SLOT(
onAssetSelected(QString)));
162 proxy =
new QSortFilterProxyModel;
164 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
166 ui->assetList->setModel(
proxy);
167 ui->assetList->setEditable(
true);
168 ui->assetList->lineEdit()->setPlaceholderText(
"Select an asset");
171 completer->setCompletionMode(QCompleter::PopupCompletion);
172 completer->setCaseSensitivity(Qt::CaseInsensitive);
179 settings.setValue(
"nCoinControlMode",
ui->radioListMode->isChecked());
180 settings.setValue(
"nCoinControlSortColumn",
sortColumn);
181 settings.setValue(
"nCoinControlSortOrder", (
int)
sortOrder);
188 this->
model = _model;
202 if (
ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
203 if (AssetControlDialog::assetControl->HasAssetSelected())
204 AssetControlDialog::assetControl->strAssetSelected =
ui->assetList->currentText().toStdString();
205 done(QDialog::Accepted);
212 Qt::CheckState state = Qt::Checked;
213 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
215 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) != Qt::Unchecked)
217 state = Qt::Unchecked;
221 ui->treeWidget->setEnabled(
false);
222 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
225 ui->treeWidget->setEnabled(
true);
226 if (state == Qt::Unchecked)
234 QTreeWidgetItem *item =
ui->treeWidget->itemAt(point);
366 ui->treeWidget->sortItems(column, order);
380 sortOrder = ((
sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
394 if (checked &&
model)
401 if (checked &&
model)
414 else if (item->isDisabled())
420 if (
ui->treeWidget->isEnabled())
426 #if QT_VERSION >= 0x050000 438 std::vector<COutPoint> vOutpts;
440 if (vOutpts.size() > 0)
442 ui->labelLocked->setText(tr(
"(%1 locked)").arg(vOutpts.size()));
443 ui->labelLocked->setVisible(
true);
445 else ui->labelLocked->setVisible(
false);
459 nPayAmount += amount;
463 CTxOut txout(amount, (
CScript)std::vector<unsigned char>(24, 0));
464 txDummy.
vout.push_back(txout);
469 std::string strAssetName =
"";
475 unsigned int nBytes = 0;
476 unsigned int nBytesInputs = 0;
477 unsigned int nQuantity = 0;
478 bool fWitness =
false;
480 std::vector<COutPoint> vCoinControl;
481 std::vector<COutput> vOutputs;
485 for (
const COutput& out : vOutputs) {
488 uint256 txhash = out.tx->GetHash();
502 nAssetAmount += nCoinAmount;
506 int witnessversion = 0;
507 std::vector<unsigned char> witnessprogram;
508 if (out.tx->tx->vout[out.i].scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram))
510 nBytesInputs += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
516 CKeyID *keyid = boost::get<CKeyID>(&address);
517 if (keyid && model->
getPubKey(*keyid, pubkey))
524 else nBytesInputs += 148;
531 nBytes = nBytesInputs + ((AssetControlDialog::payAmounts.size() > 0 ? AssetControlDialog::payAmounts.size() + 1 : 2) * 34) + 10;
543 if (nAmount - nPayAmount == 0)
551 nChange = nAssetAmount - nPayAmount;
558 nAfterFee = std::max<CAmount>(nPayFee, 0);
566 QLabel *l1 = dialog->findChild<QLabel *>(
"labelAssetControlQuantity");
567 QLabel *l2 = dialog->findChild<QLabel *>(
"labelAssetControlAmount");
568 QLabel *l3 = dialog->findChild<QLabel *>(
"labelAssetControlFee");
569 QLabel *l4 = dialog->findChild<QLabel *>(
"labelAssetControlAfterFee");
570 QLabel *l5 = dialog->findChild<QLabel *>(
"labelAssetControlBytes");
571 QLabel *l7 = dialog->findChild<QLabel *>(
"labelAssetControlLowOutput");
572 QLabel *l8 = dialog->findChild<QLabel *>(
"labelAssetControlChange");
575 dialog->findChild<QLabel *>(
"labelAssetControlLowOutputText")->setEnabled(nPayAmount > 0);
576 dialog->findChild<QLabel *>(
"labelAssetControlLowOutput") ->setEnabled(nPayAmount > 0);
577 dialog->findChild<QLabel *>(
"labelAssetControlChangeText") ->setEnabled(nPayAmount > 0);
578 dialog->findChild<QLabel *>(
"labelAssetControlChange") ->setEnabled(nPayAmount > 0);
581 l1->setText(QString::number(nQuantity));
585 l5->setText(((nBytes > 0) ?
ASYMP_UTF8 :
"") + QString::number(nBytes));
586 l7->setText(fDust ? tr(
"yes") : tr(
"no"));
595 l7->setStyleSheet((fDust) ?
"color:red;" :
"");
598 QString toolTipDust = tr(
"This label turns red if any recipient receives an amount smaller than the current dust threshold.");
601 double dFeeVary = (nBytes != 0) ? (
double)nPayFee / nBytes : 0;
603 QString toolTip4 = tr(
"Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
605 l3->setToolTip(toolTip4);
606 l4->setToolTip(toolTip4);
607 l7->setToolTip(toolTipDust);
608 l8->setToolTip(toolTip4);
609 dialog->findChild<QLabel *>(
"labelAssetControlFeeText") ->setToolTip(l3->toolTip());
610 dialog->findChild<QLabel *>(
"labelAssetControlAfterFeeText") ->setToolTip(l4->toolTip());
611 dialog->findChild<QLabel *>(
"labelAssetControlBytesText") ->setToolTip(l5->toolTip());
612 dialog->findChild<QLabel *>(
"labelAssetControlLowOutputText")->setToolTip(l7->toolTip());
613 dialog->findChild<QLabel *>(
"labelAssetControlChangeText") ->setToolTip(l8->toolTip());
616 QLabel *label = dialog->findChild<QLabel *>(
"labelAssetControlInsuffFunds");
618 label->setVisible(nChange < 0);
626 bool treeMode =
ui->radioTreeMode->isChecked();
628 ui->treeWidget->clear();
629 ui->treeWidget->setEnabled(
false);
630 ui->treeWidget->setAlternatingRowColors(!treeMode);
631 QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
632 QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
636 std::map<QString, std::map<QString, std::vector<COutput> > > mapCoins;
639 QString assetToDisplay =
ui->assetList->currentText();
642 if (!mapCoins.count(assetToDisplay))
647 auto mapAssetCoins = mapCoins.at(assetToDisplay);
649 for (
const std::pair<QString, std::vector<COutput>> &coins : mapAssetCoins) {
652 QString sWalletAddress = coins.first;
654 if (sWalletLabel.isEmpty())
655 sWalletLabel = tr(
"(no label)");
659 ui->treeWidget->addTopLevelItem(itemWalletAddress);
661 itemWalletAddress->setFlags(flgTristate);
676 for (
const COutput &out : coins.second) {
677 std::string strAssetName;
682 if (strAssetName != assetToDisplay.toStdString())
691 itemOutput->setFlags(flgCheckbox);
696 QString sAddress =
"";
701 if (!treeMode || (!(sAddress == sWalletAddress))) {
709 if (!(sAddress == sWalletAddress))
713 tr(
"change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
715 }
else if (!treeMode) {
717 if (sLabel.isEmpty())
718 sLabel = tr(
"(no label)");
725 QVariant((qlonglong) nAmount));
746 itemOutput->setDisabled(
true);
757 itemWalletAddress->setText(
COLUMN_CHECKBOX,
"(" + QString::number(nChildren) +
")");
759 itemWalletAddress->setData(
COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong) nSum));
766 for (
int i = 0; i <
ui->treeWidget->topLevelItemCount(); i++)
767 if (
ui->treeWidget->topLevelItem(i)->checkState(
COLUMN_CHECKBOX) == Qt::PartiallyChecked)
768 ui->treeWidget->topLevelItem(i)->setExpanded(
true);
773 ui->treeWidget->setEnabled(
true);
788 bool showAdministrator =
ui->viewAdministrator->isChecked();
791 ui->viewAdministrator->setChecked(showAdministrator);
794 std::vector<std::string> assets;
795 if (showAdministrator)
802 for (
auto name : assets) {
803 list << QString::fromStdString(name);
811 ui->assetList->setCurrentIndex(index);
AssetControlDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
bool isLockedCoin(uint256 hash, unsigned int n) const
RVN END.
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.
void onAssetSelected(QString name)
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
void lockCoin(COutPoint &output)
void buttonBoxClicked(QAbstractButton *)
void sortView(int, Qt::SortOrder)
std::string strAssetSelected
RVN START.
const uint256 & GetHash() const
QTreeWidgetItem * contextMenuItem
void updateAssetList(bool fSetOnStart=false)
QString dateTimeStr(const QDateTime &date)
static bool fSubtractFeeFromAmount
AddressTableModel * getAddressTableModel()
void headerSectionClicked(int)
int getDisplayUnit() const
int64_t CAmount
Amount in corbies (Can be negative)
bool IsAssetSelected(const COutPoint &output) const
void viewAdministratorClicked()
CBlockPolicyEstimator feeEstimator
void GetAllMyAssets(CWallet *pwallet, std::vector< std::string > &names, int nMinConf, bool fIncludeAdministrator, bool fOnlyAdministrator)
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
void showMenu(const QPoint &)
static CCoinControl * assetControl
void setClipboard(const QString &str)
void buttonSelectAllClicked()
uint256 uint256S(const char *str)
An encapsulated public key.
static QString removeSpaces(QString text)
QString labelForAddress(const QString &address) const
void clipboardLowOutput()
void setModel(WalletModel *model)
bool GetAssetInfoFromScript(const CScript &scriptPubKey, std::string &strName, CAmount &nAmount)
bool isSpent(const COutPoint &outpoint) const
static QList< CAmount > payAmounts
An output of a transaction.
An outpoint - a combination of a transaction hash and an index n into its vout.
void viewItemChanged(QTreeWidgetItem *, int)
static void updateLabels(WalletModel *, QDialog *)
std::vector< CTxOut > vout
friend class CAssetControlWidgetItem
void GetAllAdministrativeAssets(CWallet *pwallet, std::vector< std::string > &names, int nMinConf)
bool operator<(const CNetAddr &a, const CNetAddr &b)
void ListSelectedAssets(std::vector< COutPoint > &vOutpoints) const
std::string EncodeDestination(const CTxDestination &dest)
const PlatformStyle * platformStyle
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.
Ui::AssetControlDialog * ui
void unlockCoin(COutPoint &output)
A reference to a CKey: the Hash160 of its serialized public key.
std::string GetHex() const
QSortFilterProxyModel * proxy
QStringListModel * stringModel
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
A mutable version of CTransaction.
QAction * copyTransactionHashAction
void listAssets(std::map< QString, std::map< QString, std::vector< COutput > > > &mapCoins) const
RVN START.
void copyTransactionHash()
CWallet * getWallet() const
static QString formatWithCustomName(QString customName, const CAmount &amount, int unit=MAX_ASSET_UNITS, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with custom name)
void UnSelectAsset(const COutPoint &output)
void SelectAsset(const COutPoint &output)
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 IsAssetNameAnOwner(const std::string &name)
Check if an asset is an owner.
bool IsCompressed() const
Check whether this is a compressed public key.