diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index d8f6e1a899ec1..d473c0419e86a 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -420,6 +420,7 @@ RES_ICONS = \
qt/pivx/res/img/ic-switch-on.svg \
qt/pivx/res/img/img-qr-test.png \
qt/pivx/res/img/ic-check-box.svg \
+ qt/pivx/res/img/ic-check-box-light.svg \
qt/pivx/res/img/ic-check-box-dark-active.svg \
qt/pivx/res/img/ic-check-box-indeterminate.svg \
qt/pivx/res/img/ic-check-box-liliac-indeterminate.svg \
diff --git a/src/qt/pivx.qrc b/src/qt/pivx.qrc
index 5202fb878e228..7d6ccdfef7d32 100644
--- a/src/qt/pivx.qrc
+++ b/src/qt/pivx.qrc
@@ -62,6 +62,7 @@
pivx/res/img/ic-arrow-white-right.svg
pivx/res/img/ic-check-active.svg
pivx/res/img/ic-check-box.svg
+ pivx/res/img/ic-check-box-light.svg
pivx/res/img/ic-check-box-liliac-indeterminate.svg
pivx/res/img/ic-check-connect-off.svg
pivx/res/img/ic-check-connect.svg
diff --git a/src/qt/pivx/forms/sendmultirow.ui b/src/qt/pivx/forms/sendmultirow.ui
index 55807066364e6..83272fe04631d 100644
--- a/src/qt/pivx/forms/sendmultirow.ui
+++ b/src/qt/pivx/forms/sendmultirow.ui
@@ -347,6 +347,16 @@ padding:0px;
0
+ -
+
+
+ The fee will be deducted from the amount being sent. The recipient will receive less PIV than you enter in the amount field. If multiple recipients are selected, the fee is split equally.
+
+
+ Subtract fee from amount
+
+
+
-
diff --git a/src/qt/pivx/res/css/style_dark.css b/src/qt/pivx/res/css/style_dark.css
index d127a85b8193c..c4e3ebfd7f77e 100644
--- a/src/qt/pivx/res/css/style_dark.css
+++ b/src/qt/pivx/res/css/style_dark.css
@@ -2049,7 +2049,7 @@ QCheckBox {
color:#FFFFFF;
}
-QCheckBox:checked {
+QCheckBox:checked {
spacing: 5px;
font-size:18px;
color:#b088ff;
@@ -2084,6 +2084,32 @@ QCheckBox[cssClass="btn-watch-password"]::indicator:checked {
image: url("://ic-watch-password-white");
}
+QCheckBox[cssClass="combo-light"] {
+ spacing: 5px;
+ font-size:18px;
+ color: #807b8a;
+}
+
+QCheckBox[cssClass="combo-light"]:checked {
+ spacing: 5px;
+ font-size:18px;
+ color:#b088ff;
+}
+
+QCheckBox[cssClass="combo-light"]::indicator:unchecked {
+ image: url("://ic-check-box-light");
+}
+
+QCheckBox[cssClass="combo-light"]:hover {
+ spacing: 5px;
+ font-size:18px;
+ color: #bababa;
+}
+
+QCheckBox[cssClass="combo-light"]::indicator:unchecked:hover {
+ image: url("://ic-check-box");
+}
+
/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HH REQUEST DIALOG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
@@ -3068,6 +3094,11 @@ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
color: #5c4b7d;
}
+*[cssClass="btn-list-menu"]:checked{
+ font-size:16px;
+ color:#b088ff;
+}
+
/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
diff --git a/src/qt/pivx/res/css/style_light.css b/src/qt/pivx/res/css/style_light.css
index 5f8ee68baf655..6dbd2cbe59173 100644
--- a/src/qt/pivx/res/css/style_light.css
+++ b/src/qt/pivx/res/css/style_light.css
@@ -2049,7 +2049,7 @@ QCheckBox {
color:#707070;
}
-QCheckBox:checked {
+QCheckBox:checked {
spacing: 5px;
font-size:18px;
color:#5c4b7d;
@@ -2084,6 +2084,28 @@ QCheckBox[cssClass="btn-watch-password"]::indicator:checked {
image: url("://ic-watch-password");
}
+QCheckBox[cssClass="combo-light"] {
+ spacing: 5px;
+ font-size:18px;
+ color:#bababa;
+}
+
+QCheckBox[cssClass="combo-light"]:checked {
+ spacing: 5px;
+ font-size:18px;
+ color:#707070;
+}
+
+QCheckBox[cssClass="combo-light"]:hover {
+ spacing: 5px;
+ font-size:18px;
+ color: #707070;
+}
+
+QCheckBox[cssClass="combo-light"]::indicator:unchecked:hover {
+ image: url("://ic-check-box-light");
+}
+
/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HH REQUEST DIALOG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
@@ -3066,6 +3088,11 @@ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
color: #5c4b7d;
}
+*[cssClass="btn-list-menu"]:checked{
+ font-size:16px;
+ color: #b088ff;
+}
+
/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HH EMPTY LIST
diff --git a/src/qt/pivx/res/img/ic-check-box-light.svg b/src/qt/pivx/res/img/ic-check-box-light.svg
new file mode 100755
index 0000000000000..804ce4a64ffa1
--- /dev/null
+++ b/src/qt/pivx/res/img/ic-check-box-light.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/qt/pivx/send.cpp b/src/qt/pivx/send.cpp
index af8407289cd02..9155d1c0ae821 100644
--- a/src/qt/pivx/send.cpp
+++ b/src/qt/pivx/send.cpp
@@ -863,14 +863,19 @@ void SendWidget::onMenuClicked(SendMultiRow* entry)
this->menu = new TooltipMenu(window, this);
this->menu->setCopyBtnText(tr("Add Memo"));
this->menu->setEditBtnText(tr("Save contact"));
- this->menu->setMinimumSize(this->menu->width() + 30,this->menu->height());
+ this->menu->setLastBtnVisible(true);
+ this->menu->setLastBtnText(tr("Subtract fee"));
+ this->menu->setMinimumHeight(157);
+ this->menu->setMinimumSize(this->menu->width() + 30, this->menu->height());
connect(this->menu, &TooltipMenu::message, this, &AddressesWidget::message);
connect(this->menu, &TooltipMenu::onEditClicked, this, &SendWidget::onContactMultiClicked);
connect(this->menu, &TooltipMenu::onDeleteClicked, this, &SendWidget::onDeleteClicked);
connect(this->menu, &TooltipMenu::onCopyClicked, this, &SendWidget::onEntryMemoClicked);
+ connect(this->menu, &TooltipMenu::onLastClicked, this, &SendWidget::onSubtractFeeFromAmountChecked);
} else {
this->menu->hide();
}
+ this->menu->setLastBtnCheckable(true, entry->getSubtractFeeFromAmount());
menu->move(pos);
menu->show();
}
@@ -932,6 +937,13 @@ void SendWidget::onEntryMemoClicked()
}
}
+void SendWidget::onSubtractFeeFromAmountChecked()
+{
+ if (focusedEntry) {
+ focusedEntry->toggleSubtractFeeFromAmount();
+ }
+}
+
void SendWidget::onDeleteClicked()
{
if (focusedEntry) {
diff --git a/src/qt/pivx/send.h b/src/qt/pivx/send.h
index fcc4f90384082..6cf8d6129e919 100644
--- a/src/qt/pivx/send.h
+++ b/src/qt/pivx/send.h
@@ -81,6 +81,7 @@ private Q_SLOTS:
void onContactMultiClicked();
void onDeleteClicked();
void onEntryMemoClicked();
+ void onSubtractFeeFromAmountChecked();
void onResetCustomOptions(bool fRefreshAmounts);
void onResetSettings();
diff --git a/src/qt/pivx/sendconfirmdialog.cpp b/src/qt/pivx/sendconfirmdialog.cpp
index 984a9b6e6fb5d..0b22800fedc01 100644
--- a/src/qt/pivx/sendconfirmdialog.cpp
+++ b/src/qt/pivx/sendconfirmdialog.cpp
@@ -183,16 +183,20 @@ void TxDetailDialog::setData(WalletModel *_model, WalletModelTransaction* _tx)
this->model = _model;
this->tx = _tx;
CAmount txFee = tx->getTransactionFee();
- CAmount totalAmount = tx->getTotalTransactionAmount() + txFee;
// inputs label
CTransactionRef walletTx = tx->getTransaction();
setInputsType(walletTx);
+ CAmount totalAmount = tx->getTotalTransactionAmount();
+ if (tx->subtractFeeFromRecipents() == 0) totalAmount += txFee;
+
ui->textAmount->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, totalAmount, false, BitcoinUnits::separatorAlways) + " (Fee included)");
- int nRecipients = tx->getRecipients().size();
+
+ const QList& recipients = tx->getRecipients();
+ int nRecipients = recipients.size();
if (nRecipients == 1) {
- const SendCoinsRecipient& recipient = tx->getRecipients().at(0);
+ const SendCoinsRecipient& recipient = recipients.at(0);
if (recipient.isP2CS) {
ui->labelSend->setText(tr("Delegating to"));
}
@@ -325,11 +329,14 @@ void TxDetailDialog::onOutputsClicked()
// If the there is a model tx, then this is a confirmation dialog
if (tx) {
const QList& recipients = tx->getRecipients();
+ unsigned int sffa = tx->subtractFeeFromRecipents();
+ CAmount rcp_fee = (sffa > 0) ? (tx->getTransactionFee() / sffa) : 0;
for (int i = 0; i < recipients.size(); ++i) {
const auto& recipient = recipients[i];
+ CAmount rcp_amt = recipient.amount - (recipient.fSubtractFee ? rcp_fee : 0);
int charsSize = recipient.isShieldedAddr ? 18 : 16;
QString labelRes = recipient.address.left(charsSize) + "..." + recipient.address.right(charsSize);
- appendOutput(layoutGrid, i, labelRes, recipient.amount, nDisplayUnit);
+ appendOutput(layoutGrid, i, labelRes, rcp_amt, nDisplayUnit);
}
} else {
// Tx detail dialog
diff --git a/src/qt/pivx/sendmultirow.cpp b/src/qt/pivx/sendmultirow.cpp
index a95cd6ce3b9bb..3a80e657f947a 100644
--- a/src/qt/pivx/sendmultirow.cpp
+++ b/src/qt/pivx/sendmultirow.cpp
@@ -34,6 +34,8 @@ SendMultiRow::SendMultiRow(PIVXGUI* _window, PWidget *parent) :
// future: when we get a designer, this should have another icon. A "memo" icon instead of a "+"
setCssProperty(ui->btnAddMemo, "btn-secundary-add");
+ setCssProperty(ui->checkboxSubtractFeeFromAmount, "combo-light");
+
// Button menu
setCssProperty(ui->btnMenu, "btn-menu");
ui->btnMenu->setVisible(false);
@@ -225,6 +227,7 @@ SendCoinsRecipient SendMultiRow::getValue()
recipient.amount = getAmountValue();
auto dest = Standard::DecodeDestination(recipient.address.toStdString());
recipient.isShieldedAddr = boost::get(&dest);
+ recipient.fSubtractFee = getSubtractFeeFromAmount();
return recipient;
}
@@ -263,6 +266,11 @@ int SendMultiRow::getNumber()
return number;
}
+bool SendMultiRow::getSubtractFeeFromAmount() const
+{
+ return ui->checkboxSubtractFeeFromAmount->isChecked();
+}
+
void SendMultiRow::setAddress(const QString& address)
{
ui->lineEditAddress->setText(address);
@@ -274,6 +282,12 @@ void SendMultiRow::setAmount(const QString& amount)
ui->lineEditAmount->setText(amount);
}
+void SendMultiRow::toggleSubtractFeeFromAmount()
+{
+ bool old = ui->checkboxSubtractFeeFromAmount->isChecked();
+ ui->checkboxSubtractFeeFromAmount->setChecked(!old);
+}
+
void SendMultiRow::setAddressAndLabelOrDescription(const QString& address, const QString& message)
{
QString label = walletModel->getAddressTableModel()->labelForAddress(address);
diff --git a/src/qt/pivx/sendmultirow.h b/src/qt/pivx/sendmultirow.h
index 5a6f5ad0f55b3..9bb34c5d3fbf5 100644
--- a/src/qt/pivx/sendmultirow.h
+++ b/src/qt/pivx/sendmultirow.h
@@ -50,11 +50,13 @@ class SendMultiRow : public PWidget
void setAmount(const QString& amount);
void setAddressAndLabelOrDescription(const QString& address, const QString& message);
void setFocus();
+ void toggleSubtractFeeFromAmount();
QRect getEditLineRect();
int getEditHeight();
int getEditWidth();
int getMenuBtnWidth();
+ bool getSubtractFeeFromAmount() const;
// Return true if memo was set and false if it was cleared.
bool launchMemoDialog();
diff --git a/src/qt/pivx/tooltipmenu.cpp b/src/qt/pivx/tooltipmenu.cpp
index f0b1722042b37..2ca673048b3fc 100644
--- a/src/qt/pivx/tooltipmenu.cpp
+++ b/src/qt/pivx/tooltipmenu.cpp
@@ -40,6 +40,12 @@ void TooltipMenu::setLastBtnText(QString btnText, int minHeight){
ui->btnLast->setMinimumHeight(minHeight);
}
+void TooltipMenu::setLastBtnCheckable(bool checkable, bool isChecked)
+{
+ ui->btnLast->setCheckable(checkable);
+ ui->btnLast->setChecked(isChecked);
+}
+
void TooltipMenu::setCopyBtnVisible(bool visible){
ui->btnCopy->setVisible(visible);
}
diff --git a/src/qt/pivx/tooltipmenu.h b/src/qt/pivx/tooltipmenu.h
index 00f0c460ffb5f..8b5d339ee65e8 100644
--- a/src/qt/pivx/tooltipmenu.h
+++ b/src/qt/pivx/tooltipmenu.h
@@ -39,6 +39,7 @@ class TooltipMenu : public PWidget
void setDeleteBtnVisible(bool visible);
void setEditBtnVisible(bool visible);
void setLastBtnVisible(bool visible);
+ void setLastBtnCheckable(bool checkable, bool isChecked);
Q_SIGNALS:
void onDeleteClicked();
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 567ccf24b6801..d5edb32f6f6d1 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -488,7 +488,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
// Regular P2PK or P2PKH
scriptPubKey = GetScriptForDestination(out);
}
- vecSend.emplace_back(scriptPubKey, rcp.amount, false);
+ vecSend.emplace_back(scriptPubKey, rcp.amount, rcp.fSubtractFee);
total += rcp.amount;
}
@@ -598,9 +598,9 @@ OperationResult WalletModel::PrepareShieldedTransaction(WalletModelTransaction*
const CCoinControl* coinControl)
{
// Load shieldedAddrRecipients.
- bool fSubtractFeeFromAmount{false};
std::vector recipients;
for (const auto& recipient : modelTransaction->getRecipients()) {
+ bool fSubtractFeeFromAmount = recipient.fSubtractFee;
if (recipient.isShieldedAddr) {
auto pa = KeyIO::DecodeSaplingPaymentAddress(recipient.address.toStdString());
if (!pa) return errorOut("Error, invalid shielded address");
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 4474727deef73..1fa09393584bf 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -71,6 +71,9 @@ class SendCoinsRecipient
// Quick flag to not have to check the address type more than once.
bool isShieldedAddr{false};
+ // Whether to subtract the tx fee from this recipient
+ bool fSubtractFee{false};
+
// Amount
CAmount amount{0};
// If from a payment request, this is used for storing the memo
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
index 62cd2da3e9151..a4572cf4f64e7 100644
--- a/src/qt/walletmodeltransaction.cpp
+++ b/src/qt/walletmodeltransaction.cpp
@@ -43,6 +43,15 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee)
fee = newFee;
}
+unsigned int WalletModelTransaction::subtractFeeFromRecipents() const
+{
+ unsigned int count = 0;
+ for (const SendCoinsRecipient& rcp : recipients) {
+ if (rcp.fSubtractFee) count++;
+ }
+ return count;
+}
+
CAmount WalletModelTransaction::getTotalTransactionAmount()
{
CAmount totalTransactionAmount = 0;
diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h
index 93fa24b5e5b6d..3b668b28cd140 100644
--- a/src/qt/walletmodeltransaction.h
+++ b/src/qt/walletmodeltransaction.h
@@ -39,6 +39,9 @@ class WalletModelTransaction
CTransactionRef& getTransaction();
+ // return the number of recipients with subtract-fee-from-amount
+ unsigned int subtractFeeFromRecipents() const;
+
// Whether should create a +v2 tx or go simple and create a v1.
bool useV2{false};
bool fIsStakeDelegationVoided{false};