Skip to content

Commit

Permalink
Merge #2347: [GUI] Add GUI controls for subtract-fee-from-amount
Browse files Browse the repository at this point in the history
3e860c5 [GUI] Display actual recipient amount with sffa in confirmation dlg (random-zebra)
3f45e09 GUI: Add styling for subtract fee from amount checkbox for light and dark themes. (furszy)
26ac915 [GUI] Add checkable btn in the contextual menu, for sffa with multirows (random-zebra)
c8e74e0 [GUI] Add checkboxSubtractFeeFromAmount checkbox in sendmultirow (random-zebra)
04e43f9 [CSS] Prepare styling for btn-list-menu::checked (font-size/color) (random-zebra)

Pull request description:

  Follow up to #2341.
  As per title, add controls for this feature in the graphical interface.

  For the moment, it's a simple checkbox, which is visible in case of single recipient.
  The confirmation dialog shows the difference in the "total amount" (paid) when the fee is subtracted, or not, from the recipient amount (in the example, sending `1.00 PIV`).

  <div>
  <img src="https://user-images.githubusercontent.com/18186894/116305097-99fdff80-a7a3-11eb-83a7-35d3d25b8881.png" width="700px"/>

  <img src="https://user-images.githubusercontent.com/18186894/116305490-23adcd00-a7a4-11eb-92dc-4b5a68089653.png" width="700px"/>
  </div>

  ---

  When there are multiple recipients, the checkbox is hidden, and controlled by a checkable button inside the contextual menu.

  <div>
  <img src="https://user-images.githubusercontent.com/18186894/116305579-44762280-a7a4-11eb-84dc-30ac3a7f29ce.png" width="600px" margin="center"/>
  </div>

  Maybe this is not very intuitive, or pretty, but it does the job.
  Later on, possibly with the help of @Neoperol, we can design a better placement for these controls.

  Closes #894
  Closes #2196

  Obviously based on top of
  - [x] #2341

  which must be reviewed before this one.

ACKs for top commit:
  furszy:
    Tested ACK 3e860c5.
  Fuzzbawls:
    ACK 3e860c5

Tree-SHA512: 651045d9fd655b7108682bd5478f2ae2cd5f6c61a725e952d6705a9df0809fab0c1b99152340d829262e7133c3228db0e1fb9abdcc1671dc5d7898f9ff485038
  • Loading branch information
random-zebra committed Jul 18, 2021
2 parents 152d244 + 3e860c5 commit c4496f4
Show file tree
Hide file tree
Showing 17 changed files with 148 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions src/qt/pivx.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<file alias="ic-arrow-white-right">pivx/res/img/ic-arrow-white-right.svg</file>
<file alias="ic-check-active">pivx/res/img/ic-check-active.svg</file>
<file alias="ic-check-box">pivx/res/img/ic-check-box.svg</file>
<file alias="ic-check-box-light">pivx/res/img/ic-check-box-light.svg</file>
<file alias="ic-check-box-liliac-indeterminate">pivx/res/img/ic-check-box-liliac-indeterminate.svg</file>
<file alias="ic-check-connect-off">pivx/res/img/ic-check-connect-off.svg</file>
<file alias="ic-check-connect">pivx/res/img/ic-check-connect.svg</file>
Expand Down
10 changes: 10 additions & 0 deletions src/qt/pivx/forms/sendmultirow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,16 @@ padding:0px;</string>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
<property name="toolTip">
<string>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.</string>
</property>
<property name="text">
<string>Subtract fee from amount</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
Expand Down
33 changes: 32 additions & 1 deletion src/qt/pivx/res/css/style_dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ QCheckBox {
color:#FFFFFF;
}

QCheckBox:checked {
QCheckBox:checked {
spacing: 5px;
font-size:18px;
color:#b088ff;
Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -3068,6 +3094,11 @@ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
color: #5c4b7d;
}

*[cssClass="btn-list-menu"]:checked{
font-size:16px;
color:#b088ff;
}



/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Expand Down
29 changes: 28 additions & 1 deletion src/qt/pivx/res/css/style_light.css
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ QCheckBox {
color:#707070;
}

QCheckBox:checked {
QCheckBox:checked {
spacing: 5px;
font-size:18px;
color:#5c4b7d;
Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -3066,6 +3088,11 @@ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/
color: #5c4b7d;
}

*[cssClass="btn-list-menu"]:checked{
font-size:16px;
color: #b088ff;
}


/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HH EMPTY LIST
Expand Down
11 changes: 11 additions & 0 deletions src/qt/pivx/res/img/ic-check-box-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion src/qt/pivx/send.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -932,6 +937,13 @@ void SendWidget::onEntryMemoClicked()
}
}

void SendWidget::onSubtractFeeFromAmountChecked()
{
if (focusedEntry) {
focusedEntry->toggleSubtractFeeFromAmount();
}
}

void SendWidget::onDeleteClicked()
{
if (focusedEntry) {
Expand Down
1 change: 1 addition & 0 deletions src/qt/pivx/send.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ private Q_SLOTS:
void onContactMultiClicked();
void onDeleteClicked();
void onEntryMemoClicked();
void onSubtractFeeFromAmountChecked();
void onResetCustomOptions(bool fRefreshAmounts);
void onResetSettings();

Expand Down
15 changes: 11 additions & 4 deletions src/qt/pivx/sendconfirmdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SendCoinsRecipient>& 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"));
}
Expand Down Expand Up @@ -325,11 +329,14 @@ void TxDetailDialog::onOutputsClicked()
// If the there is a model tx, then this is a confirmation dialog
if (tx) {
const QList<SendCoinsRecipient>& 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
Expand Down
14 changes: 14 additions & 0 deletions src/qt/pivx/sendmultirow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -225,6 +227,7 @@ SendCoinsRecipient SendMultiRow::getValue()
recipient.amount = getAmountValue();
auto dest = Standard::DecodeDestination(recipient.address.toStdString());
recipient.isShieldedAddr = boost::get<libzcash::SaplingPaymentAddress>(&dest);
recipient.fSubtractFee = getSubtractFeeFromAmount();
return recipient;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/qt/pivx/sendmultirow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions src/qt/pivx/tooltipmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions src/qt/pivx/tooltipmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -598,9 +598,9 @@ OperationResult WalletModel::PrepareShieldedTransaction(WalletModelTransaction*
const CCoinControl* coinControl)
{
// Load shieldedAddrRecipients.
bool fSubtractFeeFromAmount{false};
std::vector<SendManyRecipient> 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");
Expand Down
3 changes: 3 additions & 0 deletions src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/qt/walletmodeltransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/qt/walletmodeltransaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down

0 comments on commit c4496f4

Please sign in to comment.