Raven Core  3.0.0
P2P Digital Currency
assetsdialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "assetsdialog.h"
7 #include "sendcoinsdialog.h"
8 #include "ui_assetsdialog.h"
9 
10 #include "addresstablemodel.h"
11 #include "ravenunits.h"
12 #include "clientmodel.h"
13 #include "assetcontroldialog.h"
14 #include "guiutil.h"
15 #include "optionsmodel.h"
16 #include "platformstyle.h"
17 #include "sendassetsentry.h"
18 #include "walletmodel.h"
19 #include "assettablemodel.h"
20 
21 #include "base58.h"
22 #include "chainparams.h"
23 #include "wallet/coincontrol.h"
24 #include "validation.h" // mempool and minRelayTxFee
25 #include "ui_interface.h"
26 #include "txmempool.h"
27 #include "policy/fees.h"
28 #include "wallet/fees.h"
29 #include "createassetdialog.h"
30 #include "reissueassetdialog.h"
31 #include "guiconstants.h"
32 
33 #include <QGraphicsDropShadowEffect>
34 #include <QFontMetrics>
35 #include <QMessageBox>
36 #include <QScrollBar>
37 #include <QSettings>
38 #include <QTextDocument>
39 #include <QTimer>
40 #include <policy/policy.h>
41 #include <core_io.h>
42 #include <rpc/mining.h>
43 
44 AssetsDialog::AssetsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
45  QDialog(parent),
46  ui(new Ui::AssetsDialog),
47  clientModel(0),
48  model(0),
49  fNewRecipientAllowed(true),
50  fFeeMinimized(true),
51  platformStyle(_platformStyle)
52 {
53  ui->setupUi(this);
54 
55  if (!_platformStyle->getImagesOnButtons()) {
56  ui->addButton->setIcon(QIcon());
57  ui->clearButton->setIcon(QIcon());
58  ui->sendButton->setIcon(QIcon());
59  } else {
60  ui->addButton->setIcon(_platformStyle->SingleColorIcon(":/icons/add"));
61  ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
62  ui->sendButton->setIcon(_platformStyle->SingleColorIcon(":/icons/send"));
63  }
64 
65  GUIUtil::setupAddressWidget(ui->lineEditAssetControlChange, this);
66 
67  addEntry();
68 
69  connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
70  connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
71 
72  // Coin Control
73  connect(ui->pushButtonAssetControl, SIGNAL(clicked()), this, SLOT(assetControlButtonClicked()));
74  connect(ui->checkBoxAssetControlChange, SIGNAL(stateChanged(int)), this, SLOT(assetControlChangeChecked(int)));
75  connect(ui->lineEditAssetControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(assetControlChangeEdited(const QString &)));
76 
77  // Coin Control: clipboard actions
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);
85  connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardQuantity()));
86  connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardAmount()));
87  connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardFee()));
88  connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardAfterFee()));
89  connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardBytes()));
90  connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardLowOutput()));
91  connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(assetControlClipboardChange()));
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);
99 
100  // init transaction fee section
101  QSettings settings;
102  if (!settings.contains("fFeeSectionMinimized"))
103  settings.setValue("fFeeSectionMinimized", true);
104  if (!settings.contains("nFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility
105  settings.setValue("nFeeRadio", 1); // custom
106  if (!settings.contains("nFeeRadio"))
107  settings.setValue("nFeeRadio", 0); // recommended
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());
119  minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
120 
126 }
127 
129 {
130  this->clientModel = _clientModel;
131 
132  if (_clientModel) {
133  connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel()));
134  }
135 }
136 
138 {
139  this->model = _model;
140 
141  if(_model && _model->getOptionsModel())
142  {
143  for(int i = 0; i < ui->entries->count(); ++i)
144  {
145  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
146  if(entry)
147  {
148  entry->setModel(_model);
149  }
150  }
151 
152  setBalance(_model->getBalance(), _model->getUnconfirmedBalance(), _model->getImmatureBalance(),
153  _model->getWatchBalance(), _model->getWatchUnconfirmedBalance(), _model->getWatchImmatureBalance());
154  connect(_model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
155  connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
157 
158  // Coin Control
159  connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(assetControlUpdateLabels()));
160  connect(_model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(assetControlFeatureChanged(bool)));
161 
162  // Custom Fee Control
163  connect(_model->getOptionsModel(), SIGNAL(customFeeFeaturesChanged(bool)), this, SLOT(customFeeFeatureChanged(bool)));
164 
165 
166  ui->frameAssetControl->setVisible(false);
167  ui->frameAssetControl->setVisible(_model->getOptionsModel()->getCoinControlFeatures());
168  ui->frameFee->setVisible(_model->getOptionsModel()->getCustomFeeFeatures());
170 
171  // fee section
172  for (const int &n : confTargets) {
173  ui->confTargetSelector->addItem(tr("%1 (%2 blocks)").arg(GUIUtil::formatNiceTimeOffset(n*Params().GetConsensus().nPowTargetSpacing)).arg(n));
174  }
175  connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSmartFeeLabel()));
176  connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(assetControlUpdateLabels()));
177  connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls()));
178  connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(assetControlUpdateLabels()));
179  connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(assetControlUpdateLabels()));
180  connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee()));
181  connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls()));
182  connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(assetControlUpdateLabels()));
183 // connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
184 // connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(assetControlUpdateLabels()));
185  ui->customFee->setSingleStep(GetRequiredFee(1000));
189 
190  // set default rbf checkbox state
191 // ui->optInRBF->setCheckState(model->getDefaultWalletRbf() ? Qt::Checked : Qt::Unchecked);
192  ui->optInRBF->hide();
193 
194  // set the smartfee-sliders default value (wallets default conf.target or last stored value)
195  QSettings settings;
196  if (settings.value("nSmartFeeSliderPosition").toInt() != 0) {
197  // migrate nSmartFeeSliderPosition to nConfTarget
198  // nConfTarget is available since 0.15 (replaced nSmartFeeSliderPosition)
199  int nConfirmTarget = 25 - settings.value("nSmartFeeSliderPosition").toInt(); // 25 == old slider range
200  settings.setValue("nConfTarget", nConfirmTarget);
201  settings.remove("nSmartFeeSliderPosition");
202  }
203  if (settings.value("nConfTarget").toInt() == 0)
204  ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(model->getDefaultConfirmTarget()));
205  else
206  ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(settings.value("nConfTarget").toInt()));
207  }
208 }
209 
211 {
212  QSettings settings;
213  settings.setValue("fFeeSectionMinimized", fFeeMinimized);
214  settings.setValue("nFeeRadio", ui->groupFee->checkedId());
215  settings.setValue("nConfTarget", getConfTargetForIndex(ui->confTargetSelector->currentIndex()));
216  settings.setValue("nTransactionFee", (qint64)ui->customFee->value());
217  settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked());
218 
219  delete ui;
220 }
221 
223 {
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;}");
229  ui->frameAssetControl->setGraphicsEffect(GUIUtil::getShadowEffect());
230 
231  ui->labelAssetControlFeatures->setStyleSheet(STRING_LABEL_COLOR);
232  ui->labelAssetControlFeatures->setFont(GUIUtil::getTopLabelFont());
233 
234  ui->labelAssetControlQuantityText->setStyleSheet(STRING_LABEL_COLOR);
235  ui->labelAssetControlQuantityText->setFont(GUIUtil::getSubLabelFont());
236 
237  ui->labelAssetControlAmountText->setStyleSheet(STRING_LABEL_COLOR);
238  ui->labelAssetControlAmountText->setFont(GUIUtil::getSubLabelFont());
239 
240  ui->labelAssetControlFeeText->setStyleSheet(STRING_LABEL_COLOR);
241  ui->labelAssetControlFeeText->setFont(GUIUtil::getSubLabelFont());
242 
243  ui->labelAssetControlAfterFeeText->setStyleSheet(STRING_LABEL_COLOR);
244  ui->labelAssetControlAfterFeeText->setFont(GUIUtil::getSubLabelFont());
245 
246  ui->labelAssetControlBytesText->setStyleSheet(STRING_LABEL_COLOR);
247  ui->labelAssetControlBytesText->setFont(GUIUtil::getSubLabelFont());
248 
249  ui->labelAssetControlLowOutputText->setStyleSheet(STRING_LABEL_COLOR);
250  ui->labelAssetControlLowOutputText->setFont(GUIUtil::getSubLabelFont());
251 
252  ui->labelAssetControlChangeText->setStyleSheet(STRING_LABEL_COLOR);
253  ui->labelAssetControlChangeText->setFont(GUIUtil::getSubLabelFont());
254 
255  // Align the other labels next to the input buttons to the text in the same height
256  ui->labelAssetControlAutomaticallySelected->setStyleSheet(STRING_LABEL_COLOR);
257 
258  // Align the Custom change address checkbox
259  ui->checkBoxAssetControlChange->setStyleSheet(QString(".QCheckBox{ %1; }").arg(STRING_LABEL_COLOR));
260 
261  ui->labelAssetControlQuantity->setFont(GUIUtil::getSubLabelFont());
262  ui->labelAssetControlAmount->setFont(GUIUtil::getSubLabelFont());
263  ui->labelAssetControlFee->setFont(GUIUtil::getSubLabelFont());
264  ui->labelAssetControlAfterFee->setFont(GUIUtil::getSubLabelFont());
265  ui->labelAssetControlBytes->setFont(GUIUtil::getSubLabelFont());
266  ui->labelAssetControlLowOutput->setFont(GUIUtil::getSubLabelFont());
267  ui->labelAssetControlChange->setFont(GUIUtil::getSubLabelFont());
268  ui->checkBoxAssetControlChange->setFont(GUIUtil::getSubLabelFont());
269  ui->lineEditAssetControlChange->setFont(GUIUtil::getSubLabelFont());
270  ui->labelAssetControlInsuffFunds->setFont(GUIUtil::getSubLabelFont());
271  ui->labelAssetControlAutomaticallySelected->setFont(GUIUtil::getSubLabelFont());
272 
273 }
274 
276 {
278  ui->scrollArea->setStyleSheet(QString(".QScrollArea{background-color: %1; border: none}").arg(platformStyle->WidgetBackGroundColor().name()));
279  ui->scrollArea->setGraphicsEffect(GUIUtil::getShadowEffect());
280 
281  // Add some spacing so we can see the whole card
282  ui->entries->setContentsMargins(10,10,20,0);
283  ui->scrollAreaWidgetContents->setStyleSheet(QString(".QWidget{ background-color: %1;}").arg(platformStyle->WidgetBackGroundColor().name()));
284 }
285 
287 {
289  ui->frameFee->setStyleSheet(QString(".QFrame {background-color: %1; padding-top: 10px; padding-right: 5px; border: none;}").arg(platformStyle->WidgetBackGroundColor().name()));
292  ui->frameFee->setGraphicsEffect(GUIUtil::getShadowEffect());
293 
294  ui->labelFeeHeadline->setStyleSheet(STRING_LABEL_COLOR);
295  ui->labelFeeHeadline->setFont(GUIUtil::getSubLabelFont());
296 
297  ui->labelSmartFee3->setStyleSheet(STRING_LABEL_COLOR);
298  ui->labelCustomPerKilobyte->setStyleSheet(QString(".QLabel{ %1; }").arg(STRING_LABEL_COLOR));
299  ui->radioSmartFee->setStyleSheet(STRING_LABEL_COLOR);
300  ui->radioCustomFee->setStyleSheet(STRING_LABEL_COLOR);
301  ui->checkBoxMinimumFee->setStyleSheet(QString(".QCheckBox{ %1; }").arg(STRING_LABEL_COLOR));
302 
303  ui->buttonChooseFee->setFont(GUIUtil::getSubLabelFont());
304  ui->fallbackFeeWarningLabel->setFont(GUIUtil::getSubLabelFont());
305  ui->buttonMinimizeFee->setFont(GUIUtil::getSubLabelFont());
306  ui->radioSmartFee->setFont(GUIUtil::getSubLabelFont());
307  ui->labelSmartFee2->setFont(GUIUtil::getSubLabelFont());
308  ui->labelSmartFee3->setFont(GUIUtil::getSubLabelFont());
309  ui->confTargetSelector->setFont(GUIUtil::getSubLabelFont());
310  ui->radioCustomFee->setFont(GUIUtil::getSubLabelFont());
311  ui->labelCustomPerKilobyte->setFont(GUIUtil::getSubLabelFont());
312  ui->customFee->setFont(GUIUtil::getSubLabelFont());
313  ui->labelMinFeeWarning->setFont(GUIUtil::getSubLabelFont());
314  ui->optInRBF->setFont(GUIUtil::getSubLabelFont());
315  ui->sendButton->setFont(GUIUtil::getSubLabelFont());
316  ui->clearButton->setFont(GUIUtil::getSubLabelFont());
317  ui->addButton->setFont(GUIUtil::getSubLabelFont());
318  ui->labelSmartFee->setFont(GUIUtil::getSubLabelFont());
319  ui->labelFeeEstimation->setFont(GUIUtil::getSubLabelFont());
320  ui->labelFeeMinimized->setFont(GUIUtil::getSubLabelFont());
321 
322 }
323 
325 {
326  if(!model || !model->getOptionsModel())
327  return;
328 
329  QList<SendAssetsRecipient> recipients;
330  bool valid = true;
331 
332  for(int i = 0; i < ui->entries->count(); ++i)
333  {
334  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
335  if(entry)
336  {
337  if(entry->validate())
338  {
339  recipients.append(entry->getValue());
340  }
341  else
342  {
343  valid = false;
344  }
345  }
346  }
347 
348  if(!valid || recipients.isEmpty())
349  {
350  return;
351  }
352 
353  fNewRecipientAllowed = false;
355  if(!ctx.isValid())
356  {
357  // Unlock wallet was cancelled
358  fNewRecipientAllowed = true;
359  return;
360  }
361 
362  std::vector< std::pair<CAssetTransfer, std::string> >vTransfers;
363 
364  for (auto recipient : recipients) {
365  vTransfers.emplace_back(std::make_pair(CAssetTransfer(recipient.assetName.toStdString(), recipient.amount), recipient.address.toStdString()));
366  }
367 
368  // Always use a CCoinControl instance, use the AssetControlDialog instance if CoinControl has been enabled
369  CCoinControl ctrl;
372 
374 
375  CWalletTx tx;
376  CReserveKey reservekey(model->getWallet());
377  std::pair<int, std::string> error;
378  CAmount nFeeRequired;
379 
380  if (!CreateTransferAssetTransaction(model->getWallet(), ctrl, vTransfers, "", error, tx, reservekey, nFeeRequired)) {
381  QMessageBox msgBox;
382  msgBox.setText(QString::fromStdString(error.second));
383  msgBox.exec();
384  return;
385  }
386 
387  // Format confirmation message
388  QStringList formatted;
389  for (SendAssetsRecipient &rcp : recipients)
390  {
391  // generate bold amount string
392  QString amount = "<b>" + QString::fromStdString(ValueFromAmountString(rcp.amount, 8)) + " " + rcp.assetName;
393  amount.append("</b>");
394  // generate monospace address string
395  QString address = "<span style='font-family: monospace;'>" + rcp.address;
396  address.append("</span>");
397 
398  QString recipientElement;
399 
400  if (!rcp.paymentRequest.IsInitialized()) // normal payment
401  {
402  if(rcp.label.length() > 0) // label with address
403  {
404  recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label));
405  recipientElement.append(QString(" (%1)").arg(address));
406  }
407  else // just address
408  {
409  recipientElement = tr("%1 to %2").arg(amount, address);
410  }
411  }
412  else if(!rcp.authenticatedMerchant.isEmpty()) // authenticated payment request
413  {
414  recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
415  }
416  else // unauthenticated payment request
417  {
418  recipientElement = tr("%1 to %2").arg(amount, address);
419  }
420 
421  formatted.append(recipientElement);
422  }
423 
424  QString questionString = tr("Are you sure you want to send?");
425  questionString.append("<br /><br />%1");
426 
427  if(nFeeRequired > 0)
428  {
429  // append fee string if a fee is required
430  questionString.append("<hr /><span style='color:#aa0000;'>");
431  questionString.append(RavenUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), nFeeRequired));
432  questionString.append("</span> ");
433  questionString.append(tr("added as transaction fee"));
434 
435  // append transaction size
436  questionString.append(" (" + QString::number((double)GetVirtualTransactionSize(tx) / 1000) + " kB)");
437  }
438 
439 // if (ui->optInRBF->isChecked())
440 // {
441 // questionString.append("<hr /><span>");
442 // questionString.append(tr("This transaction signals replaceability (optin-RBF)."));
443 // questionString.append("</span>");
444 // }
445 
446  SendConfirmationDialog confirmationDialog(tr("Confirm send assets"),
447  questionString.arg(formatted.join("<br />")), SEND_CONFIRM_DELAY, this);
448  confirmationDialog.exec();
449  QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result();
450 
451  if(retval != QMessageBox::Yes)
452  {
453  fNewRecipientAllowed = true;
454  return;
455  }
456 
457  // now send the prepared transaction
458  WalletModel::SendCoinsReturn sendStatus = model->sendAssets(tx, recipients, reservekey);
459  // process sendStatus and on error generate message shown to user
460  processSendCoinsReturn(sendStatus);
461 
462  if (sendStatus.status == WalletModel::OK)
463  {
466  accept();
467  }
468  fNewRecipientAllowed = true;
469 }
470 
472 {
473  // Remove entries until only one left
474  while(ui->entries->count())
475  {
476  ui->entries->takeAt(0)->widget()->deleteLater();
477  }
478  addEntry();
479 
481 }
482 
484 {
485  clear();
486 }
487 
489 {
490  clear();
491 }
492 
494 {
495  LOCK(cs_main);
496  std::vector<std::string> assets;
497  if (model)
498  GetAllMyAssets(model->getWallet(), assets, 0);
499 
500  QStringList list;
501  bool fIsOwner = false;
502  bool fIsAssetControl = false;
503  if (AssetControlDialog::assetControl->HasAssetSelected()) {
504  list << QString::fromStdString(AssetControlDialog::assetControl->strAssetSelected);
505  fIsOwner = IsAssetNameAnOwner(AssetControlDialog::assetControl->strAssetSelected);
506  fIsAssetControl = true;
507  } else {
508  for (auto name : assets) {
509  if (!IsAssetNameAnOwner(name))
510  list << QString::fromStdString(name);
511  }
512  }
513 
514  SendAssetsEntry *entry = new SendAssetsEntry(platformStyle, list, this);
515  entry->setModel(model);
516  ui->entries->addWidget(entry);
517  connect(entry, SIGNAL(removeEntry(SendAssetsEntry*)), this, SLOT(removeEntry(SendAssetsEntry*)));
518  connect(entry, SIGNAL(payAmountChanged()), this, SLOT(assetControlUpdateLabels()));
519  connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(assetControlUpdateLabels()));
520 
521  // Focus the field, so that entry can start immediately
522  entry->clear();
523  entry->setFocusAssetListBox();
524  ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
525  qApp->processEvents();
526  QScrollBar* bar = ui->scrollArea->verticalScrollBar();
527  if(bar)
528  bar->setSliderPosition(bar->maximum());
529 
530  entry->IsAssetControl(fIsAssetControl, fIsOwner);
531 
532  if (list.size() == 1)
533  entry->setCurrentIndex(1);
534 
536 
537  return entry;
538 }
539 
541 {
542  setupTabChain(0);
544 }
545 
547 {
548  entry->hide();
549 
550  // If the last entry is about to be removed add an empty one
551  if (ui->entries->count() == 1)
552  addEntry();
553 
554  entry->deleteLater();
555 
557 }
558 
559 QWidget *AssetsDialog::setupTabChain(QWidget *prev)
560 {
561  for(int i = 0; i < ui->entries->count(); ++i)
562  {
563  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
564  if(entry)
565  {
566  prev = entry->setupTabChain(prev);
567  }
568  }
569  QWidget::setTabOrder(prev, ui->sendButton);
570  QWidget::setTabOrder(ui->sendButton, ui->clearButton);
571  QWidget::setTabOrder(ui->clearButton, ui->addButton);
572  return ui->addButton;
573 }
574 
575 void AssetsDialog::setAddress(const QString &address)
576 {
577  SendAssetsEntry *entry = 0;
578  // Replace the first entry if it is still unused
579  if(ui->entries->count() == 1)
580  {
581  SendAssetsEntry *first = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(0)->widget());
582  if(first->isClear())
583  {
584  entry = first;
585  }
586  }
587  if(!entry)
588  {
589  entry = addEntry();
590  }
591 
592  entry->setAddress(address);
593 }
594 
596 {
598  return;
599 
600  SendAssetsEntry *entry = 0;
601  // Replace the first entry if it is still unused
602  if(ui->entries->count() == 1)
603  {
604  SendAssetsEntry *first = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(0)->widget());
605  if(first->isClear())
606  {
607  entry = first;
608  }
609  }
610  if(!entry)
611  {
612  entry = addEntry();
613  }
614 
615  entry->setValue(rv);
617 }
618 
620 {
621  // Just paste the entry, all pre-checks
622  // are done in paymentserver.cpp.
623  pasteEntry(rv);
624  return true;
625 }
626 
627 void AssetsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
628  const CAmount& watchBalance, const CAmount& watchUnconfirmedBalance, const CAmount& watchImmatureBalance)
629 {
630  Q_UNUSED(unconfirmedBalance);
631  Q_UNUSED(immatureBalance);
632  Q_UNUSED(watchBalance);
633  Q_UNUSED(watchUnconfirmedBalance);
634  Q_UNUSED(watchImmatureBalance);
635 
636  ui->labelBalance->setFont(GUIUtil::getSubLabelFont());
637  ui->label->setFont(GUIUtil::getSubLabelFont());
638 
639  if(model && model->getOptionsModel())
640  {
641  ui->labelBalance->setText(RavenUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balance));
642  }
643 }
644 
646 {
647  setBalance(model->getBalance(), 0, 0, 0, 0, 0);
648  ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
651 }
652 
653 void AssetsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
654 {
655  QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
656  // Default to a warning message, override if error message is needed
657  msgParams.second = CClientUIInterface::MSG_WARNING;
658 
659  // This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
660  // WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
661  // all others are used only in WalletModel::prepareTransaction()
662  switch(sendCoinsReturn.status)
663  {
665  msgParams.first = tr("The recipient address is not valid. Please recheck.");
666  break;
668  msgParams.first = tr("The amount to pay must be larger than 0.");
669  break;
671  msgParams.first = tr("The amount exceeds your balance.");
672  break;
674  msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
675  break;
677  msgParams.first = tr("Duplicate address found: addresses should only be used once each.");
678  break;
680  msgParams.first = tr("Transaction creation failed!");
681  msgParams.second = CClientUIInterface::MSG_ERROR;
682  break;
684  msgParams.first = tr("The transaction was rejected with the following reason: %1").arg(sendCoinsReturn.reasonCommitFailed);
685  msgParams.second = CClientUIInterface::MSG_ERROR;
686  break;
688  msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(RavenUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), maxTxFee));
689  break;
691  msgParams.first = tr("Payment request expired.");
692  msgParams.second = CClientUIInterface::MSG_ERROR;
693  break;
694  // included to prevent a compiler warning.
695  case WalletModel::OK:
696  default:
697  return;
698  }
699 
700  Q_EMIT message(tr("Send Coins"), msgParams.first, msgParams.second);
701 }
702 
704 {
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);
710  fFeeMinimized = fMinimize;
711 }
712 
714 {
715  minimizeFeeSection(false);
716 }
717 
719 {
721  minimizeFeeSection(true);
722 }
723 
725 {
726  ui->customFee->setValue(GetRequiredFee(1000));
727 }
728 
730 {
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());
740 }
741 
743 {
744  if(!model || !model->getOptionsModel())
745  return;
746 
747  if (ui->radioSmartFee->isChecked())
748  ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
749  else {
750  ui->labelFeeMinimized->setText(RavenUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) + "/kB");
751  }
752 }
753 
755 {
756  if (model && model->getOptionsModel())
757  ui->checkBoxMinimumFee->setText(tr("Pay only the required fee of %1").arg(
759  );
760 }
761 
763 {
764  if (ui->radioCustomFee->isChecked()) {
765  ctrl.m_feerate = CFeeRate(ui->customFee->value());
766  } else {
767  ctrl.m_feerate.reset();
768  }
769  // Avoid using global defaults when sending money from the GUI
770  // Either custom fee will be used or if not selected, the confirmation target from dropdown box
771  ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
772 // ctrl.signalRbf = ui->optInRBF->isChecked();
773 }
774 
776 {
777  if(!model || !model->getOptionsModel())
778  return;
779  CCoinControl coin_control;
780  updateAssetControlState(coin_control);
781  coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
782  FeeCalculation feeCalc;
783  CFeeRate feeRate = CFeeRate(GetMinimumFee(1000, coin_control, ::mempool, ::feeEstimator, &feeCalc));
784 
785  ui->labelSmartFee->setText(RavenUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
786 
787  if (feeCalc.reason == FeeReason::FALLBACK) {
788  ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...)
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"));
795  }
796  else
797  {
798  ui->labelSmartFee2->hide();
799  ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", feeCalc.returnedTarget));
800  ui->fallbackFeeWarningLabel->setVisible(false);
801  }
802 
804 }
805 
806 // Coin Control: copy label "Quantity" to clipboard
808 {
809  GUIUtil::setClipboard(ui->labelAssetControlQuantity->text());
810 }
811 
812 // Coin Control: copy label "Amount" to clipboard
814 {
815  GUIUtil::setClipboard(ui->labelAssetControlAmount->text().left(ui->labelAssetControlAmount->text().indexOf(" ")));
816 }
817 
818 // Coin Control: copy label "Fee" to clipboard
820 {
821  GUIUtil::setClipboard(ui->labelAssetControlFee->text().left(ui->labelAssetControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
822 }
823 
824 // Coin Control: copy label "After fee" to clipboard
826 {
827  GUIUtil::setClipboard(ui->labelAssetControlAfterFee->text().left(ui->labelAssetControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
828 }
829 
830 // Coin Control: copy label "Bytes" to clipboard
832 {
833  GUIUtil::setClipboard(ui->labelAssetControlBytes->text().replace(ASYMP_UTF8, ""));
834 }
835 
836 // Coin Control: copy label "Dust" to clipboard
838 {
839  GUIUtil::setClipboard(ui->labelAssetControlLowOutput->text());
840 }
841 
842 // Coin Control: copy label "Change" to clipboard
844 {
845  GUIUtil::setClipboard(ui->labelAssetControlChange->text().left(ui->labelAssetControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
846 }
847 
848 // Coin Control: settings menu - coin control enabled/disabled by user
850 {
851  ui->frameAssetControl->setVisible(checked);
852 
853  if (!checked && model) // coin control features disabled
855 
857 }
858 
860 {
861  ui->frameFee->setVisible(checked);
862 }
863 
864 // Coin Control: button inputs -> show actual coin control dialog
866 {
868  dlg.setModel(model);
869  dlg.exec();
872 }
873 
874 // Coin Control: checkbox custom change address
876 {
877  if (state == Qt::Unchecked)
878  {
880  ui->labelAssetControlChangeLabel->clear();
881  }
882  else
883  // use this to re-validate an already entered address
884  assetControlChangeEdited(ui->lineEditAssetControlChange->text());
885 
886  ui->lineEditAssetControlChange->setEnabled((state == Qt::Checked));
887 }
888 
889 // Coin Control: custom change address changed
890 void AssetsDialog::assetControlChangeEdited(const QString& text)
891 {
892  if (model && model->getAddressTableModel())
893  {
894  // Default to no change address until verified
896  ui->labelAssetControlChangeLabel->setStyleSheet("QLabel{color:red;}");
897 
898  const CTxDestination dest = DecodeDestination(text.toStdString());
899 
900  if (text.isEmpty()) // Nothing entered
901  {
902  ui->labelAssetControlChangeLabel->setText("");
903  }
904  else if (!IsValidDestination(dest)) // Invalid address
905  {
906  ui->labelAssetControlChangeLabel->setText(tr("Warning: Invalid Raven address"));
907  }
908  else // Valid address
909  {
910  if (!model->IsSpendable(dest)) {
911  ui->labelAssetControlChangeLabel->setText(tr("Warning: Unknown change address"));
912 
913  // confirmation dialog
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);
916 
917  if(btnRetVal == QMessageBox::Yes)
919  else
920  {
921  ui->lineEditAssetControlChange->setText("");
922  ui->labelAssetControlChangeLabel->setStyleSheet("QLabel{color:black;}");
923  ui->labelAssetControlChangeLabel->setText("");
924  }
925  }
926  else // Known change address
927  {
928  ui->labelAssetControlChangeLabel->setStyleSheet("QLabel{color:black;}");
929 
930  // Query label
931  QString associatedLabel = model->getAddressTableModel()->labelForAddress(text);
932  if (!associatedLabel.isEmpty())
933  ui->labelAssetControlChangeLabel->setText(associatedLabel);
934  else
935  ui->labelAssetControlChangeLabel->setText(tr("(no label)"));
936 
938  }
939  }
940  }
941 }
942 
943 // Coin Control: update labels
945 {
946  if (!model || !model->getOptionsModel())
947  return;
948 
950 
951  // set pay amounts
954 
955  for(int i = 0; i < ui->entries->count(); ++i)
956  {
957  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
958  if(entry && !entry->isHidden())
959  {
960  SendAssetsRecipient rcp = entry->getValue();
962 // if (rcp.fSubtractFeeFromAmount)
963 // AssetControlDialog::fSubtractFeeFromAmount = true;
964  }
965  }
966 
967  if (AssetControlDialog::assetControl->HasAssetSelected())
968  {
969  // actual coin control calculation
971 
972  // show coin control stats
973  ui->labelAssetControlAutomaticallySelected->hide();
974  ui->widgetAssetControl->show();
975  }
976  else
977  {
978  // hide coin control stats
979  ui->labelAssetControlAutomaticallySelected->show();
980  ui->widgetAssetControl->hide();
981  ui->labelAssetControlInsuffFunds->hide();
982  }
983 }
984 
987 {
988  for(int i = 0; i < ui->entries->count(); ++i)
989  {
990  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
991  if(entry)
992  {
993  removeEntry(entry);
994  }
995  }
996 
997  addEntry();
998 
999 }
1000 
1002 {
1003  for(int i = 0; i < ui->entries->count(); ++i)
1004  {
1005  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(i)->widget());
1006  if(entry)
1007  {
1008  entry->refreshAssetList();
1009  }
1010  }
1011 }
1012 
1013 void AssetsDialog::focusAsset(const QModelIndex &idx)
1014 {
1015 
1016  clear();
1017 
1018  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(0)->widget());
1019  if(entry)
1020  {
1021  SendAssetsRecipient recipient;
1022  recipient.assetName = idx.data(AssetTableModel::AssetNameRole).toString();
1023 
1024  entry->setValue(recipient);
1025  entry->setFocus();
1026  }
1027 }
1028 
1030 {
1031 
1032  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(0)->widget());
1033  if (entry)
1034  {
1035  entry->setFocusAssetListBox();
1036 
1037  if (entry->getValue().assetName != "")
1038  entry->setFocus();
1039 
1040  }
1041 }
1042 
1044 {
1045  SendAssetsEntry *entry = qobject_cast<SendAssetsEntry*>(ui->entries->itemAt(0)->widget());
1046  if (entry) {
1047  entry->refreshAssetList();
1048  }
1049 }
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).
Definition: policy.cpp:266
CTxMemPool mempool
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
void updateFeeMinimizedLabel()
ClientModel * clientModel
Definition: assetsdialog.h:69
int returnedTarget
Definition: fees.h:131
void assetControlClipboardQuantity()
QGraphicsDropShadowEffect * getShadowEffect()
Definition: guiutil.cpp:146
void handleFirstSelection()
void setAddress(const QString &address)
boost::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
Definition: coincontrol.h:30
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.
Definition: assets.cpp:4094
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
Definition: validation.cpp:105
void customFeeFeatureChanged(bool)
UnlockContext requestUnlock()
void assetControlButtonClicked()
void setValue(const SendAssetsRecipient &value)
FeeReason reason
Definition: fees.h:129
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:402
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:333
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()
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
static bool fSubtractFeeFromAmount
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:336
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...
Definition: fees.cpp:17
void updateTabsAndLabels()
AddressTableModel * getAddressTableModel()
void assetControlChangeEdited(const QString &)
void on_buttonMinimizeFee_clicked()
void updateAssetControlState(CCoinControl &ctrl)
Coin Control Features.
Definition: coincontrol.h:17
bool handlePaymentRequest(const SendAssetsRecipient &recipient)
void assetControlChangeChecked(int)
boost::optional< CFeeRate > m_feerate
Override the default payTxFee if set.
Definition: coincontrol.h:28
A single entry in the dialog for sending ravens.
int getDisplayUnit() const
Definition: optionsmodel.h:68
CAmount getBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:72
void setupScrollView(const PlatformStyle *platformStyle)
void updateSmartFeeLabel()
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
void setFocusAssetListBox()
int getConfTargetForIndex(int index)
Definition: fees.cpp:1056
void processNewTransaction()
void setMinimumFee()
CAmount getImmatureBalance() const
Definition: walletmodel.cpp:87
CBlockPolicyEstimator feeEstimator
Definition: validation.cpp:109
void GetAllMyAssets(CWallet *pwallet, std::vector< std::string > &names, int nMinConf, bool fIncludeAdministrator, bool fOnlyAdministrator)
Definition: assets.cpp:3507
QFont getSubLabelFont()
Definition: guiutil.cpp:86
void setAddress(const QString &address)
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
Definition: ravenunits.cpp:146
bool fFeeMinimized
Definition: assetsdialog.h:72
void updateMinFeeLabel()
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:201
void on_buttonChooseFee_clicked()
void removeEntry(SendAssetsEntry *entry)
static CCoinControl * assetControl
void setClipboard(const QString &str)
Definition: guiutil.cpp:945
#define STRING_LABEL_COLOR
Definition: guiconstants.h:90
#define LOCK(cs)
Definition: sync.h:176
void setupFeeControl(const PlatformStyle *platformStyle)
void message(const QString &title, const QString &message, unsigned int style)
RVN END.
void SetNull()
Definition: coincontrol.h:46
CTxDestination destChange
Definition: coincontrol.h:20
int getDefaultConfirmTarget() const
Ui::AssetsDialog * ui
Definition: assetsdialog.h:68
CAmount getWatchUnconfirmedBalance() const
void minimizeFeeSection(bool fMinimize)
QString labelForAddress(const QString &address) const
bool validate()
void assetControlClipboardAfterFee()
void updateDisplayUnit()
void setModel(WalletModel *model)
void setModel(WalletModel *model)
std::string ValueFromAmountString(const CAmount &amount, const int8_t units)
Definition: core_write.cpp:22
AssetsDialog(const PlatformStyle *platformStyle, QWidget *parent=0)
static QList< CAmount > payAmounts
static void updateLabels(WalletModel *, QDialog *)
int getIndexForConfTarget(int target)
Definition: fees.cpp:1066
bool isClear()
Return whether the entry is still empty and unedited.
void assetControlClipboardFee()
Model for Raven network client.
Definition: clientmodel.h:39
void UnSelectAll()
Definition: coincontrol.h:106
WalletModel * model
Definition: assetsdialog.h:70
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:285
bool getCoinControlFeatures() const
Definition: optionsmodel.h:71
RVN or name of an asset.
void on_sendButton_clicked()
QColor WidgetBackGroundColor() const
#define ASYMP_UTF8
void setModel(WalletModel *model)
void setFocus()
void refreshAssetList()
A key allocated from the key pool.
Definition: wallet.h:1193
const CChainParams & Params()
Return the currently selected parameters.
Interface to Raven wallet from Qt view code.
Definition: walletmodel.h:165
CAmount getWatchBalance() const
Definition: walletmodel.cpp:97
void setCurrentIndex(int index)
void clear()
CAmount getUnconfirmedBalance() const
Definition: walletmodel.cpp:82
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
Definition: ravenunits.cpp:156
void setupAssetControlFrame(const PlatformStyle *platformStyle)
const PlatformStyle * platformStyle
Definition: assetsdialog.h:73
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:20
SendAssetsRecipient getValue()
bool error(const char *fmt, const Args &... args)
Definition: util.h:168
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)
Definition: guiutil.cpp:122
Dialog for sending ravens.
Definition: assetsdialog.h:30
void IsAssetControl(bool fIsAssetControl, bool fIsOwner)
void assetControlUpdateSendCoinsDialog()
RVN START.
CAmount getWatchImmatureBalance() const
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:1029
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
Definition: optionsmodel.h:72
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.
Definition: fees.cpp:23
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:42
bool getImagesOnButtons() const
Definition: platformstyle.h:24
void setClientModel(ClientModel *clientModel)
void focusAssetListBox()
bool fNewRecipientAllowed
Definition: assetsdialog.h:71
OptionsModel * getOptionsModel()
bool IsSpendable(const CTxDestination &dest) const
bool IsAssetNameAnOwner(const std::string &name)
Check if an asset is an owner.
Definition: assets.cpp:296