8 #include "ui_assetsdialog.h" 24 #include "validation.h" 33 #include <QGraphicsDropShadowEffect> 34 #include <QFontMetrics> 35 #include <QMessageBox> 38 #include <QTextDocument> 49 fNewRecipientAllowed(true),
51 platformStyle(_platformStyle)
56 ui->addButton->setIcon(QIcon());
57 ui->clearButton->setIcon(QIcon());
58 ui->sendButton->setIcon(QIcon());
69 connect(
ui->addButton, SIGNAL(clicked()),
this, SLOT(
addEntry()));
70 connect(
ui->clearButton, SIGNAL(clicked()),
this, SLOT(
clear()));
75 connect(
ui->lineEditAssetControlChange, SIGNAL(textEdited(
const QString &)),
this, SLOT(
assetControlChangeEdited(
const QString &)));
78 QAction *clipboardQuantityAction =
new QAction(tr(
"Copy quantity"),
this);
79 QAction *clipboardAmountAction =
new QAction(tr(
"Copy amount"),
this);
80 QAction *clipboardFeeAction =
new QAction(tr(
"Copy fee"),
this);
81 QAction *clipboardAfterFeeAction =
new QAction(tr(
"Copy after fee"),
this);
82 QAction *clipboardBytesAction =
new QAction(tr(
"Copy bytes"),
this);
83 QAction *clipboardLowOutputAction =
new QAction(tr(
"Copy dust"),
this);
84 QAction *clipboardChangeAction =
new QAction(tr(
"Copy change"),
this);
92 ui->labelAssetControlQuantity->addAction(clipboardQuantityAction);
93 ui->labelAssetControlAmount->addAction(clipboardAmountAction);
94 ui->labelAssetControlFee->addAction(clipboardFeeAction);
95 ui->labelAssetControlAfterFee->addAction(clipboardAfterFeeAction);
96 ui->labelAssetControlBytes->addAction(clipboardBytesAction);
97 ui->labelAssetControlLowOutput->addAction(clipboardLowOutputAction);
98 ui->labelAssetControlChange->addAction(clipboardChangeAction);
102 if (!settings.contains(
"fFeeSectionMinimized"))
103 settings.setValue(
"fFeeSectionMinimized",
true);
104 if (!settings.contains(
"nFeeRadio") && settings.contains(
"nTransactionFee") && settings.value(
"nTransactionFee").toLongLong() > 0)
105 settings.setValue(
"nFeeRadio", 1);
106 if (!settings.contains(
"nFeeRadio"))
107 settings.setValue(
"nFeeRadio", 0);
108 if (!settings.contains(
"nSmartFeeSliderPosition"))
109 settings.setValue(
"nSmartFeeSliderPosition", 0);
110 if (!settings.contains(
"nTransactionFee"))
111 settings.setValue(
"nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
112 if (!settings.contains(
"fPayOnlyMinFee"))
113 settings.setValue(
"fPayOnlyMinFee",
false);
114 ui->groupFee->setId(
ui->radioSmartFee, 0);
115 ui->groupFee->setId(
ui->radioCustomFee, 1);
116 ui->groupFee->button((
int)std::max(0, std::min(1, settings.value(
"nFeeRadio").toInt())))->setChecked(
true);
117 ui->customFee->setValue(settings.value(
"nTransactionFee").toLongLong());
118 ui->checkBoxMinimumFee->setChecked(settings.value(
"fPayOnlyMinFee").toBool());
133 connect(_clientModel, SIGNAL(numBlocksChanged(
int,QDateTime,
double,
bool)),
this, SLOT(
updateSmartFeeLabel()));
139 this->
model = _model;
143 for(
int i = 0; i <
ui->entries->count(); ++i)
154 connect(_model, SIGNAL(balanceChanged(
CAmount,
CAmount,
CAmount,
CAmount,
CAmount,
CAmount)),
this, SLOT(
setBalance(
CAmount,
CAmount,
CAmount,
CAmount,
CAmount,
CAmount)));
166 ui->frameAssetControl->setVisible(
false);
172 for (
const int &n : confTargets) {
175 connect(
ui->confTargetSelector, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
updateSmartFeeLabel()));
180 connect(
ui->checkBoxMinimumFee, SIGNAL(stateChanged(
int)),
this, SLOT(
setMinimumFee()));
192 ui->optInRBF->hide();
196 if (settings.value(
"nSmartFeeSliderPosition").toInt() != 0) {
199 int nConfirmTarget = 25 - settings.value(
"nSmartFeeSliderPosition").toInt();
200 settings.setValue(
"nConfTarget", nConfirmTarget);
201 settings.remove(
"nSmartFeeSliderPosition");
203 if (settings.value(
"nConfTarget").toInt() == 0)
214 settings.setValue(
"nFeeRadio",
ui->groupFee->checkedId());
216 settings.setValue(
"nTransactionFee", (qint64)
ui->customFee->value());
217 settings.setValue(
"fPayOnlyMinFee",
ui->checkBoxMinimumFee->isChecked());
225 ui->frameAssetControl->setStyleSheet(QString(
".QFrame {background-color: %1; padding-top: 10px; padding-right: 5px; border: none;}").arg(platformStyle->
WidgetBackGroundColor().name()));
226 ui->widgetAssetControl->setStyleSheet(
".QWidget {background-color: transparent;}");
259 ui->checkBoxAssetControlChange->setStyleSheet(QString(
".QCheckBox{ %1; }").arg(
STRING_LABEL_COLOR));
278 ui->scrollArea->setStyleSheet(QString(
".QScrollArea{background-color: %1; border: none}").arg(platformStyle->
WidgetBackGroundColor().name()));
282 ui->entries->setContentsMargins(10,10,20,0);
283 ui->scrollAreaWidgetContents->setStyleSheet(QString(
".QWidget{ background-color: %1;}").arg(platformStyle->
WidgetBackGroundColor().name()));
289 ui->frameFee->setStyleSheet(QString(
".QFrame {background-color: %1; padding-top: 10px; padding-right: 5px; border: none;}").arg(platformStyle->
WidgetBackGroundColor().name()));
329 QList<SendAssetsRecipient> recipients;
332 for(
int i = 0; i <
ui->entries->count(); ++i)
339 recipients.append(entry->
getValue());
348 if(!valid || recipients.isEmpty())
362 std::vector< std::pair<CAssetTransfer, std::string> >vTransfers;
364 for (
auto recipient : recipients) {
365 vTransfers.emplace_back(std::make_pair(
CAssetTransfer(recipient.assetName.toStdString(), recipient.amount), recipient.address.toStdString()));
377 std::pair<int, std::string>
error;
382 msgBox.setText(QString::fromStdString(error.second));
388 QStringList formatted;
392 QString amount =
"<b>" + QString::fromStdString(
ValueFromAmountString(rcp.amount, 8)) +
" " + rcp.assetName;
393 amount.append(
"</b>");
395 QString address =
"<span style='font-family: monospace;'>" + rcp.address;
396 address.append(
"</span>");
398 QString recipientElement;
400 if (!rcp.paymentRequest.IsInitialized())
402 if(rcp.label.length() > 0)
405 recipientElement.append(QString(
" (%1)").arg(address));
409 recipientElement = tr(
"%1 to %2").arg(amount, address);
412 else if(!rcp.authenticatedMerchant.isEmpty())
414 recipientElement = tr(
"%1 to %2").arg(amount,
GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
418 recipientElement = tr(
"%1 to %2").arg(amount, address);
421 formatted.append(recipientElement);
424 QString questionString = tr(
"Are you sure you want to send?");
425 questionString.append(
"<br /><br />%1");
430 questionString.append(
"<hr /><span style='color:#aa0000;'>");
432 questionString.append(
"</span> ");
433 questionString.append(tr(
"added as transaction fee"));
448 confirmationDialog.
exec();
449 QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result();
451 if(retval != QMessageBox::Yes)
474 while(
ui->entries->count())
476 ui->entries->takeAt(0)->widget()->deleteLater();
496 std::vector<std::string> assets;
501 bool fIsOwner =
false;
502 bool fIsAssetControl =
false;
506 fIsAssetControl =
true;
508 for (
auto name : assets) {
510 list << QString::fromStdString(name);
516 ui->entries->addWidget(entry);
524 ui->scrollAreaWidgetContents->resize(
ui->scrollAreaWidgetContents->sizeHint());
525 qApp->processEvents();
526 QScrollBar* bar =
ui->scrollArea->verticalScrollBar();
528 bar->setSliderPosition(bar->maximum());
532 if (list.size() == 1)
551 if (
ui->entries->count() == 1)
554 entry->deleteLater();
561 for(
int i = 0; i <
ui->entries->count(); ++i)
569 QWidget::setTabOrder(prev,
ui->sendButton);
570 QWidget::setTabOrder(
ui->sendButton,
ui->clearButton);
571 QWidget::setTabOrder(
ui->clearButton,
ui->addButton);
572 return ui->addButton;
579 if(
ui->entries->count() == 1)
602 if(
ui->entries->count() == 1)
628 const CAmount& watchBalance,
const CAmount& watchUnconfirmedBalance,
const CAmount& watchImmatureBalance)
630 Q_UNUSED(unconfirmedBalance);
631 Q_UNUSED(immatureBalance);
632 Q_UNUSED(watchBalance);
633 Q_UNUSED(watchUnconfirmedBalance);
634 Q_UNUSED(watchImmatureBalance);
655 QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
662 switch(sendCoinsReturn.
status)
665 msgParams.first = tr(
"The recipient address is not valid. Please recheck.");
668 msgParams.first = tr(
"The amount to pay must be larger than 0.");
671 msgParams.first = tr(
"The amount exceeds your balance.");
674 msgParams.first = tr(
"The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
677 msgParams.first = tr(
"Duplicate address found: addresses should only be used once each.");
680 msgParams.first = tr(
"Transaction creation failed!");
684 msgParams.first = tr(
"The transaction was rejected with the following reason: %1").arg(sendCoinsReturn.
reasonCommitFailed);
691 msgParams.first = tr(
"Payment request expired.");
700 Q_EMIT
message(tr(
"Send Coins"), msgParams.first, msgParams.second);
705 ui->labelFeeMinimized->setVisible(fMinimize);
706 ui->buttonChooseFee ->setVisible(fMinimize);
707 ui->buttonMinimizeFee->setVisible(!fMinimize);
708 ui->frameFeeSelection->setVisible(!fMinimize);
709 ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0, 0);
731 ui->confTargetSelector ->setEnabled(
ui->radioSmartFee->isChecked());
732 ui->labelSmartFee ->setEnabled(
ui->radioSmartFee->isChecked());
733 ui->labelSmartFee2 ->setEnabled(
ui->radioSmartFee->isChecked());
734 ui->labelSmartFee3 ->setEnabled(
ui->radioSmartFee->isChecked());
735 ui->labelFeeEstimation ->setEnabled(
ui->radioSmartFee->isChecked());
736 ui->checkBoxMinimumFee ->setEnabled(
ui->radioCustomFee->isChecked());
737 ui->labelMinFeeWarning ->setEnabled(
ui->radioCustomFee->isChecked());
738 ui->labelCustomPerKilobyte ->setEnabled(
ui->radioCustomFee->isChecked() && !
ui->checkBoxMinimumFee->isChecked());
739 ui->customFee ->setEnabled(
ui->radioCustomFee->isChecked() && !
ui->checkBoxMinimumFee->isChecked());
747 if (
ui->radioSmartFee->isChecked())
748 ui->labelFeeMinimized->setText(
ui->labelSmartFee->text());
757 ui->checkBoxMinimumFee->setText(tr(
"Pay only the required fee of %1").arg(
764 if (
ui->radioCustomFee->isChecked()) {
788 ui->labelSmartFee2->show();
789 ui->labelFeeEstimation->setText(
"");
790 ui->fallbackFeeWarningLabel->setVisible(
true);
791 int lightness =
ui->fallbackFeeWarningLabel->palette().color(QPalette::WindowText).lightness();
792 QColor warning_colour(255 - (lightness / 5), 176 - (lightness / 3), 48 - (lightness / 14));
793 ui->fallbackFeeWarningLabel->setStyleSheet(
"QLabel { color: " + warning_colour.name() +
"; }");
794 ui->fallbackFeeWarningLabel->setIndent(QFontMetrics(
ui->fallbackFeeWarningLabel->font()).width(
"x"));
798 ui->labelSmartFee2->hide();
799 ui->labelFeeEstimation->setText(tr(
"Estimated to begin confirmation within %n block(s).",
"", feeCalc.
returnedTarget));
800 ui->fallbackFeeWarningLabel->setVisible(
false);
851 ui->frameAssetControl->setVisible(checked);
853 if (!checked &&
model)
861 ui->frameFee->setVisible(checked);
877 if (state == Qt::Unchecked)
880 ui->labelAssetControlChangeLabel->clear();
886 ui->lineEditAssetControlChange->setEnabled((state == Qt::Checked));
896 ui->labelAssetControlChangeLabel->setStyleSheet(
"QLabel{color:red;}");
902 ui->labelAssetControlChangeLabel->setText(
"");
906 ui->labelAssetControlChangeLabel->setText(tr(
"Warning: Invalid Raven address"));
911 ui->labelAssetControlChangeLabel->setText(tr(
"Warning: Unknown change address"));
914 QMessageBox::StandardButton btnRetVal = QMessageBox::question(
this, tr(
"Confirm custom change address"), tr(
"The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?"),
915 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
917 if(btnRetVal == QMessageBox::Yes)
921 ui->lineEditAssetControlChange->setText(
"");
922 ui->labelAssetControlChangeLabel->setStyleSheet(
"QLabel{color:black;}");
923 ui->labelAssetControlChangeLabel->setText(
"");
928 ui->labelAssetControlChangeLabel->setStyleSheet(
"QLabel{color:black;}");
932 if (!associatedLabel.isEmpty())
933 ui->labelAssetControlChangeLabel->setText(associatedLabel);
935 ui->labelAssetControlChangeLabel->setText(tr(
"(no label)"));
955 for(
int i = 0; i <
ui->entries->count(); ++i)
958 if(entry && !entry->isHidden())
973 ui->labelAssetControlAutomaticallySelected->hide();
974 ui->widgetAssetControl->show();
979 ui->labelAssetControlAutomaticallySelected->show();
980 ui->widgetAssetControl->hide();
981 ui->labelAssetControlInsuffFunds->hide();
988 for(
int i = 0; i <
ui->entries->count(); ++i)
1003 for(
int i = 0; i <
ui->entries->count(); ++i)
void assetControlClipboardAmount()
void assetControlClipboardLowOutput()
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg=QString())
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
Compute the virtual transaction size (weight reinterpreted as bytes).
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
void updateFeeMinimizedLabel()
ClientModel * clientModel
void assetControlClipboardQuantity()
QGraphicsDropShadowEffect * getShadowEffect()
QString reasonCommitFailed
void handleFirstSelection()
void setAddress(const QString &address)
boost::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
bool CreateTransferAssetTransaction(CWallet *pwallet, const CCoinControl &coinControl, const std::vector< std::pair< CAssetTransfer, std::string > >vTransfers, const std::string &changeAddress, std::pair< int, std::string > &error, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRequired, std::vector< std::pair< CNullAssetTxData, std::string > > *nullAssetTxData, std::vector< CNullAssetTxData > *nullGlobalRestrictionData)
Create a transfer asset transaction.
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
void customFeeFeatureChanged(bool)
UnlockContext requestUnlock()
void assetControlButtonClicked()
void setValue(const SendAssetsRecipient &value)
CCriticalSection cs_main
Global state.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CTxDestination DecodeDestination(const std::string &str)
SendAssetsEntry * addEntry()
#define SEND_CONFIRM_DELAY
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
void assetControlClipboardChange()
static bool fSubtractFeeFromAmount
QString HtmlEscape(const QString &str, bool fMultiLine)
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
void updateFeeSectionControls()
CAmount GetRequiredFee(unsigned int nTxBytes)
Return the minimum required fee taking into account the floating relay fee and user set minimum trans...
void updateTabsAndLabels()
AddressTableModel * getAddressTableModel()
void assetControlChangeEdited(const QString &)
void on_buttonMinimizeFee_clicked()
void updateAssetControlState(CCoinControl &ctrl)
bool handlePaymentRequest(const SendAssetsRecipient &recipient)
void assetControlChangeChecked(int)
boost::optional< CFeeRate > m_feerate
Override the default payTxFee if set.
A single entry in the dialog for sending ravens.
int getDisplayUnit() const
CAmount getBalance(const CCoinControl *coinControl=nullptr) const
void setupScrollView(const PlatformStyle *platformStyle)
void updateSmartFeeLabel()
int64_t CAmount
Amount in corbies (Can be negative)
void setFocusAssetListBox()
int getConfTargetForIndex(int index)
void processNewTransaction()
CAmount getImmatureBalance() const
CBlockPolicyEstimator feeEstimator
void GetAllMyAssets(CWallet *pwallet, std::vector< std::string > &names, int nMinConf, bool fIncludeAdministrator, bool fOnlyAdministrator)
void setAddress(const QString &address)
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
void on_buttonChooseFee_clicked()
void removeEntry(SendAssetsEntry *entry)
static CCoinControl * assetControl
void setClipboard(const QString &str)
#define STRING_LABEL_COLOR
void setupFeeControl(const PlatformStyle *platformStyle)
void message(const QString &title, const QString &message, unsigned int style)
RVN END.
CTxDestination destChange
int getDefaultConfirmTarget() const
CAmount getWatchUnconfirmedBalance() const
void minimizeFeeSection(bool fMinimize)
QString labelForAddress(const QString &address) const
void assetControlClipboardAfterFee()
void setModel(WalletModel *model)
void setModel(WalletModel *model)
std::string ValueFromAmountString(const CAmount &amount, const int8_t units)
AssetsDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
static QList< CAmount > payAmounts
static void updateLabels(WalletModel *, QDialog *)
int getIndexForConfTarget(int target)
bool isClear()
Return whether the entry is still empty and unedited.
void assetControlClipboardFee()
Model for Raven network client.
A transaction with a bunch of additional info that only the owner cares about.
bool getCoinControlFeatures() const
void on_sendButton_clicked()
void setModel(WalletModel *model)
A key allocated from the key pool.
const CChainParams & Params()
Return the currently selected parameters.
Interface to Raven wallet from Qt view code.
CAmount getWatchBalance() const
void setCurrentIndex(int index)
CAmount getUnconfirmedBalance() const
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
void setupAssetControlFrame(const PlatformStyle *platformStyle)
const PlatformStyle * platformStyle
Fee rate in satoshis per kilobyte: CAmount / kB.
SendAssetsRecipient getValue()
bool error(const char *fmt, const Args &... args)
void setBalance(const CAmount &balance, const CAmount &unconfirmedBalance, const CAmount &immatureBalance, const CAmount &watchOnlyBalance, const CAmount &watchUnconfBalance, const CAmount &watchImmatureBalance)
QFont getTopLabelFont(int weight, int pxsize)
Dialog for sending ravens.
void IsAssetControl(bool fIsAssetControl, bool fIsOwner)
void assetControlUpdateSendCoinsDialog()
RVN START.
CAmount getWatchImmatureBalance() const
QString formatNiceTimeOffset(qint64 secs)
SendCoinsReturn sendAssets(CWalletTx &tx, QList< SendAssetsRecipient > &recipients, CReserveKey &reservekey)
void assetControlFeatureChanged(bool)
void pasteEntry(const SendAssetsRecipient &rv)
CWallet * getWallet() const
void assetControlUpdateLabels()
void assetControlClipboardBytes()
void focusAsset(const QModelIndex &index)
bool getCustomFeeFeatures() const
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.
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void setClientModel(ClientModel *clientModel)
bool fNewRecipientAllowed
OptionsModel * getOptionsModel()
bool IsSpendable(const CTxDestination &dest) const
bool IsAssetNameAnOwner(const std::string &name)
Check if an asset is an owner.