PIVX Core  5.6.99
P2P Digital Currency
sendmultirow.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2021 The PIVX Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "sendmultirow.h"
6 #include "ui_sendmultirow.h"
7 
8 #include "addresstablemodel.h"
9 #include "bitcoinunits.h"
10 #include "guiutil.h"
11 #include "optionsmodel.h"
12 #include "qtutils.h"
13 #include "sendmemodialog.h"
14 
16  PWidget(_window, parent),
17  ui(new Ui::SendMultiRow),
18  iconNumber(new QPushButton())
19 {
20  ui->setupUi(this);
21  this->setStyleSheet(parent->styleSheet());
22 
23  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book");
24  ui->lineEditAddress->setAttribute(Qt::WA_MacShowFocusRect, 0);
25  setShadow(ui->stackedAddress);
26 
27  initCssEditLine(ui->lineEditAmount);
28  GUIUtil::setupAmountWidget(ui->lineEditAmount, this);
29 
30  /* Description */
31  setCssProperty(ui->labelSubtitleDescription, "text-title");
32  initCssEditLine(ui->lineEditDescription);
33 
34  // future: when we get a designer, this should have another icon. A "memo" icon instead of a "+"
35  setCssProperty(ui->btnAddMemo, "btn-secundary-add");
36 
37  setCssProperty(ui->checkboxSubtractFeeFromAmount, "combo-light");
38 
39  // Button menu
40  setCssProperty(ui->btnMenu, "btn-menu");
41  ui->btnMenu->setVisible(false);
42 
43  // Button Contact
44  btnContact = ui->lineEditAddress->addAction(QIcon("://ic-contact-arrow-down"), QLineEdit::TrailingPosition);
45  // Icon Number
46  ui->stackedAddress->addWidget(iconNumber);
47  iconNumber->show();
48  iconNumber->raise();
49 
50  setCssProperty(iconNumber, "ic-multi-number");
51  iconNumber->setText("1");
52  iconNumber->setVisible(false);
53  QSize size = QSize(24, 24);
54  iconNumber->setMinimumSize(size);
55  iconNumber->setMaximumSize(size);
56 
57  int posIconX = 0;
58  int posIconY = 14;
59  iconNumber->move(posIconX, posIconY);
60 
61  connect(ui->lineEditAmount, &QLineEdit::textChanged, this, &SendMultiRow::amountChanged);
62  connect(ui->lineEditAddress, &QLineEdit::textChanged, [this](){addressChanged(ui->lineEditAddress->text());});
63  connect(btnContact, &QAction::triggered, [this](){Q_EMIT onContactsClicked(this);});
64  connect(ui->btnMenu, &QPushButton::clicked, [this](){Q_EMIT onMenuClicked(this);});
65  connect(ui->btnAddMemo, &QPushButton::clicked, this, &SendMultiRow::onMemoClicked);
66 }
67 
68 void SendMultiRow::amountChanged(const QString& amountStr)
69 {
70  if (!amountStr.isEmpty()) {
71  auto value = GUIUtil::parseValue(amountStr, displayUnit);
72  if (value > 0) {
73  GUIUtil::updateWidgetTextAndCursorPosition(ui->lineEditAmount, amountStr);
74  setCssEditLine(ui->lineEditAmount, true, true);
75  }
76  }
77  Q_EMIT onValueChanged();
78 }
79 
81 {
83 }
84 
86 {
87  window->showHide(true);
89  dialog->setMemo(recipient.message);
90  bool ret = false;
91  if (openDialogWithOpaqueBackgroundY(dialog, window, 3, 5)) {
92  recipient.message = dialog->getMemo();
93  ui->btnAddMemo->setText(tr("Update memo"));
94  setCssProperty(ui->btnAddMemo, "btn-secondary-update", true);
95  } else if (dialog->getOperationResult()) {
96  bool isMemoEmpty = recipient.message.isEmpty();
97  // reset..
98  recipient.message.clear();
99  ui->btnAddMemo->setText(tr("Add encrypted memo"));
100  setCssProperty(ui->btnAddMemo, "btn-secundary-add", true);
101  if (!isMemoEmpty) inform(tr("Memo field reset"));
102  ret = false;
103  }
104  dialog->deleteLater();
105  return ret;
106 }
107 
108 bool SendMultiRow::addressChanged(const QString& str, bool fOnlyValidate)
109 {
110  if (!str.isEmpty()) {
111  QString trimmedStr = str.trimmed();
112  bool isShielded = false;
113  const bool valid = walletModel->validateAddress(trimmedStr, this->onlyStakingAddressAccepted, isShielded);
114  if (!valid) {
115  // check URI
116  SendCoinsRecipient rcp;
117  if (GUIUtil::parseBitcoinURI(trimmedStr, &rcp)) {
118  ui->lineEditAddress->setText(rcp.address);
119  ui->lineEditAmount->setText(BitcoinUnits::format(displayUnit, rcp.amount, false));
120 
121  QString label = walletModel->getAddressTableModel()->labelForAddress(rcp.address);
122  if (!label.isNull() && !label.isEmpty()){
123  ui->lineEditDescription->setText(label);
124  } else if (!rcp.message.isEmpty())
125  ui->lineEditDescription->setText(rcp.message);
126 
127  Q_EMIT onUriParsed(rcp);
128  } else {
129  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book-error");
130  }
131  } else {
132  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book");
133  if (!fOnlyValidate) {
134  QString label = walletModel->getAddressTableModel()->labelForAddress(trimmedStr);
135  if (!label.isEmpty()) {
136  ui->lineEditDescription->setText(label);
137  }
138  }
139  }
140  updateStyle(ui->lineEditAddress);
141  return valid;
142  }
143 
144  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book");
145  updateStyle(ui->lineEditAddress);
146 
147  return false;
148 }
149 
150 
152 {
156  }
157  clear();
158 }
159 
161 {
162  // Update edit text..
164 }
165 
167 {
168  Q_EMIT removeEntry(this);
169 }
170 
172 {
173  ui->lineEditAddress->clear();
174  ui->lineEditAmount->clear();
175  ui->lineEditDescription->clear();
176  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book", true);
177 }
178 
180 {
181  if (!walletModel)
182  return false;
183 
184  // Check input validity
185  bool retval = true;
186 
187  // Check address validity, returns false if it's invalid
188  QString address = ui->lineEditAddress->text();
189  if (address.isEmpty()){
190  retval = false;
191  setCssProperty(ui->lineEditAddress, "edit-primary-multi-book-error", true);
192  } else
193  retval = addressChanged(address, true);
194 
195  CAmount value = getAmountValue();
196 
197  // Sending a zero amount is invalid
198  if (value <= 0) {
199  setCssEditLine(ui->lineEditAmount, false, true);
200  retval = false;
201  }
202 
203  // Reject dust outputs:
204  if (retval && GUIUtil::isDust(address, value)) {
205  setCssEditLine(ui->lineEditAmount, false, true);
206  retval = false;
207  }
208 
209  return retval;
210 }
211 
213 {
215  recipient.label = ui->lineEditDescription->text();
217  auto dest = Standard::DecodeDestination(recipient.address.toStdString());
218  recipient.isShieldedAddr = boost::get<libzcash::SaplingPaymentAddress>(&dest);
220  return recipient;
221 }
222 
224 {
225  return ui->lineEditAddress->text().trimmed();
226 }
227 
229 {
230  return GUIUtil::parseValue(ui->lineEditAmount->text(), displayUnit);
231 }
232 
234 {
235  return recipient.message;
236 }
237 
239 {
240  return ui->lineEditAddress->rect();
241 }
242 
244 {
245  return ui->stackedAddress->height();
246 }
247 
249 {
250  return ui->lineEditAddress->width();
251 }
252 
254 {
255  return number;
256 }
257 
259 {
260  return ui->checkboxSubtractFeeFromAmount->isChecked();
261 }
262 
263 void SendMultiRow::setAddress(const QString& address)
264 {
265  ui->lineEditAddress->setText(address);
266  ui->lineEditAmount->setFocus();
267 }
268 
269 void SendMultiRow::setAmount(const QString& amount)
270 {
271  ui->lineEditAmount->setText(amount);
272 }
273 
275 {
276  bool old = ui->checkboxSubtractFeeFromAmount->isChecked();
277  ui->checkboxSubtractFeeFromAmount->setChecked(!old);
278 }
279 
280 void SendMultiRow::setAddressAndLabelOrDescription(const QString& address, const QString& message)
281 {
282  QString label = walletModel->getAddressTableModel()->labelForAddress(address);
283  if (!label.isNull() && !label.isEmpty()){
284  ui->lineEditDescription->setText(label);
285  } else if(!message.isEmpty())
286  ui->lineEditDescription->setText(message);
287  setAddress(address);
288 }
289 
290 void SendMultiRow::setLabel(const QString& label)
291 {
292  ui->lineEditDescription->setText(label);
293 }
294 
296 {
297  return ui->lineEditAddress->text().isEmpty();
298 }
299 
301 {
302  ui->lineEditAddress->setFocus();
303 }
304 
305 void SendMultiRow::setOnlyStakingAddressAccepted(bool onlyStakingAddress)
306 {
307  this->onlyStakingAddressAccepted = onlyStakingAddress;
308  ui->containerMemo->setVisible(!onlyStakingAddress);
309 }
310 
311 
312 void SendMultiRow::setNumber(int _number)
313 {
314  number = _number;
315  iconNumber->setText(QString::number(_number));
316 }
317 
319 {
320  ui->layoutLabel->setVisible(false);
321  iconNumber->setVisible(true);
322 }
323 
325 {
326  ui->layoutLabel->setVisible(true);
327  iconNumber->setVisible(false);
328 }
329 
330 void SendMultiRow::resizeEvent(QResizeEvent *event)
331 {
332  QWidget::resizeEvent(event);
333 }
334 
336 {
337  if (!this->isExpanded && iconNumber->isVisible()) {
338  isExpanded = true;
339  ui->btnMenu->setVisible(isExpanded);
340  }
341 }
342 
344 {
345  if (isExpanded) {
346  isExpanded = false;
347  ui->btnMenu->setVisible(isExpanded);
348  }
349 }
350 
352 {
353  return ui->btnMenu->width();
354 }
355 
357 {
358  delete ui;
359 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
QString labelForAddress(const QString &address) const
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard, bool cleanRemainderZeros=true)
Format as string.
int getDisplayUnit()
Definition: optionsmodel.h:74
void displayUnitChanged(int unit)
PIVX GUI main class.
Definition: pivxgui.h:46
void showHide(bool show)
Definition: pivxgui.cpp:579
PIVXGUI * window
Definition: pwidget.h:59
void inform(const QString &message)
Definition: pwidget.cpp:45
WalletModel * walletModel
Definition: pwidget.h:61
void message(const QString &title, const QString &body, unsigned int style, bool *ret=nullptr)
void setMemo(QString memo)
bool getOperationResult()
QAction * btnContact
Definition: sendmultirow.h:90
SendCoinsRecipient recipient
Definition: sendmultirow.h:97
bool onlyStakingAddressAccepted
Definition: sendmultirow.h:95
bool launchMemoDialog()
void updateDisplayUnit()
void deleteClicked()
void amountChanged(const QString &)
SendCoinsRecipient getValue()
QPushButton * iconNumber
Definition: sendmultirow.h:89
void loadWalletModel() override
void setLabel(const QString &label)
void resizeEvent(QResizeEvent *event) override
void removeEntry(SendMultiRow *entry)
bool addressChanged(const QString &, bool fOnlyValidate=false)
void toggleSubtractFeeFromAmount()
virtual void enterEvent(QEvent *) override
void setNumber(int number)
void onUriParsed(const SendCoinsRecipient &rcp)
bool getSubtractFeeFromAmount() const
QRect getEditLineRect()
Ui::SendMultiRow * ui
Definition: sendmultirow.h:88
QString getAddress()
void setAmount(const QString &amount)
void setAddressAndLabelOrDescription(const QString &address, const QString &message)
QString getMemo()
void onValueChanged()
void onContactsClicked(SendMultiRow *entry)
virtual void leaveEvent(QEvent *) override
void setOnlyStakingAddressAccepted(bool onlyStakingAddress)
CAmount getAmountValue()
int getMenuBtnWidth()
bool isClear()
Return whether the entry is still empty and unedited.
SendMultiRow(PIVXGUI *_window, PWidget *parent=nullptr)
void setAddress(const QString &address)
void onMemoClicked()
bool validateAddress(const QString &address)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
void setupAmountWidget(QLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:141
void updateWidgetTextAndCursorPosition(QLineEdit *widget, const QString &str)
Definition: guiutil.cpp:148
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
Definition: guiutil.cpp:156
bool isDust(const QString &address, const CAmount &amount)
Definition: guiutil.cpp:243
CWDestination DecodeDestination(const std::string &strAddress)
bool openDialogWithOpaqueBackgroundY(QDialog *widget, PIVXGUI *gui, double posX, int posY, bool hideOpaqueBackground)
Definition: qtutils.cpp:59
void initCssEditLine(QLineEdit *edit, bool isDialog)
Definition: qtutils.cpp:272
void setShadow(QWidget *edit)
Definition: qtutils.cpp:292
void setCssProperty(std::initializer_list< QWidget * > args, const QString &value)
Definition: qtutils.cpp:334
void setCssEditLine(QLineEdit *edit, bool isValid, bool forceUpdate)
Definition: qtutils.cpp:282
void updateStyle(QWidget *widget)
Definition: qtutils.cpp:225