Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

overviewpage.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2020 The Dash 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 <qt/overviewpage.h>
7 #include <qt/forms/ui_overviewpage.h>
8 
9 #include <qt/bitcoinunits.h>
10 #include <qt/clientmodel.h>
11 #include <qt/guiutil.h>
12 #include <init.h>
13 #include <qt/optionsmodel.h>
16 #include <qt/utilitydialog.h>
17 #include <qt/walletmodel.h>
18 
21 
22 #include <QAbstractItemDelegate>
23 #include <QPainter>
24 #include <QSettings>
25 #include <QTimer>
26 
27 #define ITEM_HEIGHT 54
28 #define NUM_ITEMS_DISABLED 5
29 #define NUM_ITEMS_ENABLED_NORMAL 6
30 #define NUM_ITEMS_ENABLED_ADVANCED 8
31 
32 class TxViewDelegate : public QAbstractItemDelegate
33 {
34  Q_OBJECT
35 public:
36  explicit TxViewDelegate(QObject* parent = nullptr) :
37  QAbstractItemDelegate(), unit(BitcoinUnits::DASH)
38  {
39 
40  }
41 
42  inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
43  const QModelIndex &index ) const
44  {
45  painter->save();
46 
47  QRect mainRect = option.rect;
48  int xspace = 8;
49  int ypad = 8;
50  int halfheight = (mainRect.height() - 2*ypad)/2;
51  QRect rectTopHalf(mainRect.left() + xspace, mainRect.top() + ypad, mainRect.width() - xspace, halfheight);
52  QRect rectBottomHalf(mainRect.left() + xspace, mainRect.top() + ypad + halfheight + 5, mainRect.width() - xspace, halfheight);
53  QRect rectBounding;
54  QColor colorForeground;
55  qreal initialFontSize = painter->font().pointSizeF();
56 
57  // Grab model indexes for desired data from TransactionTableModel
58  QModelIndex indexDate = index.sibling(index.row(), TransactionTableModel::Date);
59  QModelIndex indexAmount = index.sibling(index.row(), TransactionTableModel::Amount);
60  QModelIndex indexAddress = index.sibling(index.row(), TransactionTableModel::ToAddress);
61 
62  // Draw first line (with slightly bigger font than the second line will get)
63  // Content: Date/Time, Optional IS indicator, Amount
64  painter->setFont(GUIUtil::getFont(GUIUtil::FontWeight::Normal, false, GUIUtil::getScaledFontSize(initialFontSize * 1.17)));
65  // Date/Time
66  colorForeground = qvariant_cast<QColor>(indexDate.data(Qt::ForegroundRole));
67  QString strDate = indexDate.data(Qt::DisplayRole).toString();
68  painter->setPen(colorForeground);
69  painter->drawText(rectTopHalf, Qt::AlignLeft | Qt::AlignVCenter, strDate, &rectBounding);
70  // Optional IS indicator
71  QIcon iconInstantSend = qvariant_cast<QIcon>(indexAddress.data(TransactionTableModel::RawDecorationRole));
72  QRect rectInstantSend(rectBounding.right() + 5, rectTopHalf.top(), 16, halfheight);
73  iconInstantSend.paint(painter, rectInstantSend);
74  // Amount
75  colorForeground = qvariant_cast<QColor>(indexAmount.data(Qt::ForegroundRole));
76  // Note: do NOT use Qt::DisplayRole, have format properly here
77  qint64 nAmount = index.data(TransactionTableModel::AmountRole).toLongLong();
78  QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::separatorAlways);
79  painter->setPen(colorForeground);
80  painter->drawText(rectTopHalf, Qt::AlignRight | Qt::AlignVCenter, strAmount);
81 
82  // Draw second line (with the initial font)
83  // Content: Address/label, Optional Watchonly indicator
84  painter->setFont(GUIUtil::getFont(GUIUtil::FontWeight::Normal, false, GUIUtil::getScaledFontSize(initialFontSize)));
85  // Address/Label
86  colorForeground = qvariant_cast<QColor>(indexAddress.data(Qt::ForegroundRole));
87  QString address = indexAddress.data(Qt::DisplayRole).toString();
88  painter->setPen(colorForeground);
89  painter->drawText(rectBottomHalf, Qt::AlignLeft | Qt::AlignVCenter, address, &rectBounding);
90  // Optional Watchonly indicator
91  if (index.data(TransactionTableModel::WatchonlyRole).toBool())
92  {
93  QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
94  QRect rectWatchonly(rectBounding.right() + 5, rectBottomHalf.top(), 16, halfheight);
95  iconWatchonly.paint(painter, rectWatchonly);
96  }
97 
98  painter->restore();
99  }
100 
101  inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
102  {
103  return QSize(ITEM_HEIGHT, ITEM_HEIGHT);
104  }
105 
106  int unit;
107 
108 };
109 #include <qt/overviewpage.moc>
110 
111 OverviewPage::OverviewPage(QWidget* parent) :
112  QWidget(parent),
113  timer(nullptr),
114  ui(new Ui::OverviewPage),
115  clientModel(0),
116  walletModel(0),
117  currentBalance(-1),
118  currentUnconfirmedBalance(-1),
119  currentImmatureBalance(-1),
120  currentWatchOnlyBalance(-1),
121  currentWatchUnconfBalance(-1),
122  currentWatchImmatureBalance(-1),
123  cachedNumISLocks(-1),
124  txdelegate(new TxViewDelegate(this))
125 {
126  ui->setupUi(this);
127 
128  GUIUtil::setFont({ui->label_4,
129  ui->label_5,
130  ui->labelPrivateSendHeader
132 
133  GUIUtil::setFont({ui->labelTotalText,
134  ui->labelWatchTotal,
135  ui->labelTotal
137 
138  GUIUtil::setFont({ui->labelBalanceText,
139  ui->labelPendingText,
140  ui->labelImmatureText,
141  ui->labelWatchonly,
142  ui->labelSpendable
144 
146 
147  // Recent transactions
148  ui->listTransactions->setItemDelegate(txdelegate);
149  // Note: minimum height of listTransactions will be set later in updateAdvancedPSUI() to reflect actual settings
150  ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
151 
152  connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));
153 
154  // init "out of sync" warning labels
155  ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
156  ui->labelPrivateSendSyncStatus->setText("(" + tr("out of sync") + ")");
157  ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");
158 
159  // hide PS frame (helps to preserve saved size)
160  // we'll setup and make it visible in privateSendStatus() later
161  ui->framePrivateSend->setVisible(false);
162 
163  // start with displaying the "out of sync" warnings
164  showOutOfSyncWarning(true);
165 
166  // Disable privateSendClient builtin support for automatic backups while we are in GUI,
167  // we'll handle automatic backups and user warnings in privateSendStatus()
169 
170  timer = new QTimer(this);
171  connect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
172 }
173 
174 void OverviewPage::handleTransactionClicked(const QModelIndex &index)
175 {
176  if(filter)
177  Q_EMIT transactionClicked(filter->mapToSource(index));
178 }
179 
181 {
182  Q_EMIT outOfSyncWarningClicked();
183 }
184 
186 {
187  if(timer) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
188  delete ui;
189 }
190 
191 void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& anonymizedBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance)
192 {
193  currentBalance = balance;
194  currentUnconfirmedBalance = unconfirmedBalance;
195  currentImmatureBalance = immatureBalance;
196  currentAnonymizedBalance = anonymizedBalance;
197  currentWatchOnlyBalance = watchOnlyBalance;
198  currentWatchUnconfBalance = watchUnconfBalance;
199  currentWatchImmatureBalance = watchImmatureBalance;
200  ui->labelBalance->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, balance, false, BitcoinUnits::separatorAlways));
201  ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, unconfirmedBalance, false, BitcoinUnits::separatorAlways));
202  ui->labelImmature->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, immatureBalance, false, BitcoinUnits::separatorAlways));
203  ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, anonymizedBalance, false, BitcoinUnits::separatorAlways));
204  ui->labelTotal->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, balance + unconfirmedBalance + immatureBalance, false, BitcoinUnits::separatorAlways));
205  ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, watchOnlyBalance, false, BitcoinUnits::separatorAlways));
206  ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, watchUnconfBalance, false, BitcoinUnits::separatorAlways));
207  ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, watchImmatureBalance, false, BitcoinUnits::separatorAlways));
208  ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithUnit(nDisplayUnit, watchOnlyBalance + watchUnconfBalance + watchImmatureBalance, false, BitcoinUnits::separatorAlways));
209 
210  // only show immature (newly mined) balance if it's non-zero or in UI debug mode, so as not to complicate things
211  // for the non-mining users
212  bool fDebugUI = gArgs.GetBoolArg("-debug-ui", false);
213  bool showImmature = fDebugUI || immatureBalance != 0;
214  bool showWatchOnlyImmature = fDebugUI || watchImmatureBalance != 0;
215 
216  // for symmetry reasons also show immature label when the watch-only one is shown
217  ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
218  ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
219  ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance
220 
222 
223  if (walletModel) {
224  int numISLocks = walletModel->getNumISLocks();
225  if(cachedNumISLocks != numISLocks) {
226  cachedNumISLocks = numISLocks;
227  ui->listTransactions->update();
228  }
229  }
230 }
231 
232 // show/hide watch-only labels
233 void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly)
234 {
235  ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active)
236  ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label
237  ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line
238  ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance
239  ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance
240  ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance
241 
242  if (!showWatchOnly){
243  ui->labelWatchImmature->hide();
244  }
245  else{
246  ui->labelBalance->setIndent(20);
247  ui->labelUnconfirmed->setIndent(20);
248  ui->labelImmature->setIndent(20);
249  ui->labelTotal->setIndent(20);
250  }
251 }
252 
254 {
255  this->clientModel = model;
256  if(model)
257  {
258  // Show warning if this is a prerelease version
259  connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
261  }
262 }
263 
265 {
266  this->walletModel = model;
267  if(model && model->getOptionsModel())
268  {
269  // update the display unit, to not use the default ("DASH")
271  // Keep up to date with wallet
274  connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
275 
276  connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
277  updateWatchOnlyLabels(model->haveWatchOnly() || gArgs.GetBoolArg("-debug-ui", false));
278  connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool)));
279 
280  // explicitly update PS frame and transaction list to reflect actual settings
282 
283  connect(model->getOptionsModel(), SIGNAL(privateSendRoundsChanged()), this, SLOT(updatePrivateSendProgress()));
284  connect(model->getOptionsModel(), SIGNAL(privateSentAmountChanged()), this, SLOT(updatePrivateSendProgress()));
285  connect(model->getOptionsModel(), SIGNAL(advancedPSUIChanged(bool)), this, SLOT(updateAdvancedPSUI(bool)));
286  connect(model->getOptionsModel(), &OptionsModel::privateSendEnabledChanged, [=]() {
287  privateSendStatus(true);
288  });
289 
290  connect(ui->togglePrivateSend, SIGNAL(clicked()), this, SLOT(togglePrivateSend()));
291 
292  // privatesend buttons will not react to spacebar must be clicked on
293  ui->togglePrivateSend->setFocusPolicy(Qt::NoFocus);
294  }
295 }
296 
298 {
300  {
302  if(currentBalance != -1)
305 
306  // Update txdelegate->unit with the current unit
308 
309  ui->listTransactions->update();
310  }
311 }
312 
313 void OverviewPage::updateAlerts(const QString &warnings)
314 {
315  this->ui->labelAlerts->setVisible(!warnings.isEmpty());
316  this->ui->labelAlerts->setText(warnings);
317 }
318 
320 {
321  ui->labelWalletStatus->setVisible(fShow);
322  ui->labelPrivateSendSyncStatus->setVisible(fShow);
323  ui->labelTransactionsStatus->setVisible(fShow);
324 }
325 
327 {
329 
330  if(!walletModel) return;
331 
332  QString strAmountAndRounds;
334 
335  if(currentBalance == 0)
336  {
337  ui->privateSendProgress->setValue(0);
338  ui->privateSendProgress->setToolTip(tr("No inputs detected"));
339 
340  // when balance is zero just show info from settings
341  strPrivateSendAmount = strPrivateSendAmount.remove(strPrivateSendAmount.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
342  strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", privateSendClient.nPrivateSendRounds);
343 
344  ui->labelAmountRounds->setToolTip(tr("No inputs detected"));
345  ui->labelAmountRounds->setText(strAmountAndRounds);
346  return;
347  }
348 
349  CAmount nAnonymizableBalance = walletModel->getAnonymizableBalance(false, false);
350 
351  CAmount nMaxToAnonymize = nAnonymizableBalance + currentAnonymizedBalance;
352 
353  // If it's more than the anon threshold, limit to that.
354  if(nMaxToAnonymize > privateSendClient.nPrivateSendAmount*COIN) nMaxToAnonymize = privateSendClient.nPrivateSendAmount*COIN;
355 
356  if(nMaxToAnonymize == 0) return;
357 
358  if(nMaxToAnonymize >= privateSendClient.nPrivateSendAmount * COIN) {
359  ui->labelAmountRounds->setToolTip(tr("Found enough compatible inputs to mix %1")
360  .arg(strPrivateSendAmount));
361  strPrivateSendAmount = strPrivateSendAmount.remove(strPrivateSendAmount.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
362  strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", privateSendClient.nPrivateSendRounds);
363  } else {
364  QString strMaxToAnonymize = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nMaxToAnonymize, false, BitcoinUnits::separatorAlways);
365  ui->labelAmountRounds->setToolTip(tr("Not enough compatible inputs to mix <span style='%1'>%2</span>,<br>"
366  "will mix <span style='%1'>%3</span> instead")
368  .arg(strPrivateSendAmount)
369  .arg(strMaxToAnonymize));
370  strMaxToAnonymize = strMaxToAnonymize.remove(strMaxToAnonymize.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
371  strAmountAndRounds = "<span style='" + GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR) + "'>" +
372  QString(BitcoinUnits::factor(nDisplayUnit) == 1 ? "" : "~") + strMaxToAnonymize +
373  " / " + tr("%n Rounds", "", privateSendClient.nPrivateSendRounds) + "</span>";
374  }
375  ui->labelAmountRounds->setText(strAmountAndRounds);
376 
377  if (!fShowAdvancedPSUI) return;
378 
379  CAmount nDenominatedConfirmedBalance;
380  CAmount nDenominatedUnconfirmedBalance;
381  CAmount nNormalizedAnonymizedBalance;
382  float nAverageAnonymizedRounds;
383 
384  nDenominatedConfirmedBalance = walletModel->getDenominatedBalance(false);
385  nDenominatedUnconfirmedBalance = walletModel->getDenominatedBalance(true);
386  nNormalizedAnonymizedBalance = walletModel->getNormalizedAnonymizedBalance();
387  nAverageAnonymizedRounds = walletModel->getAverageAnonymizedRounds();
388 
389  // calculate parts of the progress, each of them shouldn't be higher than 1
390  // progress of denominating
391  float denomPart = 0;
392  // mixing progress of denominated balance
393  float anonNormPart = 0;
394  // completeness of full amount anonymization
395  float anonFullPart = 0;
396 
397  CAmount denominatedBalance = nDenominatedConfirmedBalance + nDenominatedUnconfirmedBalance;
398  denomPart = (float)denominatedBalance / nMaxToAnonymize;
399  denomPart = denomPart > 1 ? 1 : denomPart;
400  denomPart *= 100;
401 
402  anonNormPart = (float)nNormalizedAnonymizedBalance / nMaxToAnonymize;
403  anonNormPart = anonNormPart > 1 ? 1 : anonNormPart;
404  anonNormPart *= 100;
405 
406  anonFullPart = (float)currentAnonymizedBalance / nMaxToAnonymize;
407  anonFullPart = anonFullPart > 1 ? 1 : anonFullPart;
408  anonFullPart *= 100;
409 
410  // apply some weights to them ...
411  float denomWeight = 1;
412  float anonNormWeight = privateSendClient.nPrivateSendRounds;
413  float anonFullWeight = 2;
414  float fullWeight = denomWeight + anonNormWeight + anonFullWeight;
415  // ... and calculate the whole progress
416  float denomPartCalc = ceilf((denomPart * denomWeight / fullWeight) * 100) / 100;
417  float anonNormPartCalc = ceilf((anonNormPart * anonNormWeight / fullWeight) * 100) / 100;
418  float anonFullPartCalc = ceilf((anonFullPart * anonFullWeight / fullWeight) * 100) / 100;
419  float progress = denomPartCalc + anonNormPartCalc + anonFullPartCalc;
420  if(progress >= 100) progress = 100;
421 
422  ui->privateSendProgress->setValue(progress);
423 
424  QString strToolPip = ("<b>" + tr("Overall progress") + ": %1%</b><br/>" +
425  tr("Denominated") + ": %2%<br/>" +
426  tr("Partially mixed") + ": %3%<br/>" +
427  tr("Mixed") + ": %4%<br/>" +
428  tr("Denominated inputs have %5 of %n rounds on average", "", privateSendClient.nPrivateSendRounds))
429  .arg(progress).arg(denomPart).arg(anonNormPart).arg(anonFullPart)
430  .arg(nAverageAnonymizedRounds);
431  ui->privateSendProgress->setToolTip(strToolPip);
432 }
433 
434 void OverviewPage::updateAdvancedPSUI(bool fShowAdvancedPSUI) {
435  this->fShowAdvancedPSUI = fShowAdvancedPSUI;
436  privateSendStatus(true);
437 }
438 
440 {
441  if (!fForce && (!masternodeSync.IsBlockchainSynced() || ShutdownRequested())) return;
442 
443  if(!walletModel) return;
444 
445  // Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason
446  if (fMasternodeMode || nWalletBackups <= 0) {
448  if (nWalletBackups <= 0) {
449  ui->labelPrivateSendEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!"));
450  }
451  return;
452  }
453 
454  bool fIsEnabled = privateSendClient.fEnablePrivateSend;
455  ui->framePrivateSend->setVisible(fIsEnabled);
456  if (!fIsEnabled) {
458  if (timer != nullptr) {
459  timer->stop();
460  }
461  return;
462  }
463 
464  if (timer != nullptr && !timer->isActive()) {
465  timer->start(1000);
466  }
467 
468  // Wrap all privatesend related widgets we want to show/hide state based.
469  // Value of the map contains a flag if this widget belongs to the advanced
470  // PrivateSend UI option or not. True if it does, false if not.
471  std::map<QWidget*, bool> privateSendWidgets = {
472  {ui->labelCompletitionText, true},
473  {ui->privateSendProgress, true},
474  {ui->labelSubmittedDenomText, true},
475  {ui->labelSubmittedDenom, true},
476  {ui->labelAmountAndRoundsText, false},
477  {ui->labelAmountRounds, false}
478  };
479 
480  auto setWidgetsVisible = [&](bool fVisible) {
481  static bool fInitial{true};
482  static bool fLastVisible{false};
483  static bool fLastShowAdvanced{false};
484  // Only update the widget's visibility if something changed since the last call of setWidgetsVisible
485  if (fLastShowAdvanced == fShowAdvancedPSUI && fLastVisible == fVisible) {
486  if (fInitial) {
487  fInitial = false;
488  } else {
489  return;
490  }
491  }
492  // Set visible if: fVisible and not advanced UI element or advanced ui element and advanced ui active
493  for (const auto& it : privateSendWidgets) {
494  it.first->setVisible(fVisible && (!it.second || it.second == fShowAdvancedPSUI));
495  }
496  fLastVisible = fVisible;
497  fLastShowAdvanced = fShowAdvancedPSUI;
498  };
499 
500  static int64_t nLastDSProgressBlockTime = 0;
501  int nBestHeight = clientModel->getNumBlocks();
502 
503  // We are processing more than 1 block per second, we'll just leave
504  if(nBestHeight > privateSendClient.nCachedNumBlocks && GetTime() - nLastDSProgressBlockTime <= 1) return;
505  nLastDSProgressBlockTime = GetTime();
506 
507  QString strKeysLeftText(tr("keys left: %1").arg(walletModel->getKeysLeftSinceAutoBackup()));
509  strKeysLeftText = "<span style='" + GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR) + "'>" + strKeysLeftText + "</span>";
510  }
511  ui->labelPrivateSendEnabled->setToolTip(strKeysLeftText);
512 
514  if (nBestHeight != privateSendClient.nCachedNumBlocks) {
515  privateSendClient.nCachedNumBlocks = nBestHeight;
517  }
518 
519  setWidgetsVisible(false);
520  ui->togglePrivateSend->setText(tr("Start Mixing"));
521 
522  QString strEnabled = tr("Disabled");
523  // Show how many keys left in advanced PS UI mode only
524  if (fShowAdvancedPSUI) strEnabled += ", " + strKeysLeftText;
525  ui->labelPrivateSendEnabled->setText(strEnabled);
526 
527  // If mixing isn't active always show the lower number of txes because there are
528  // anyway the most PS widgets hidden.
530 
531  return;
532  } else {
534  }
535 
536  // Warn user that wallet is running out of keys
537  // NOTE: we do NOT warn user and do NOT create autobackups if mixing is not running
539  QSettings settings;
540  if(settings.value("fLowKeysWarning").toBool()) {
541  QString strWarn = tr("Very low number of keys left since last automatic backup!") + "<br><br>" +
542  tr("We are about to create a new automatic backup for you, however "
543  "<span style='%1'> you should always make sure you have backups "
544  "saved in some safe place</span>!").arg(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_COMMAND)) + "<br><br>" +
545  tr("Note: You can turn this message off in options.");
546  ui->labelPrivateSendEnabled->setToolTip(strWarn);
547  LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- Very low number of keys left since last automatic backup, warning user and trying to create new backup...\n");
548  QMessageBox::warning(this, "PrivateSend", strWarn, QMessageBox::Ok, QMessageBox::Ok);
549  } else {
550  LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- Very low number of keys left since last automatic backup, skipping warning and trying to create new backup...\n");
551  }
552 
553  QString strBackupWarning;
554  QString strBackupError;
555  if(!walletModel->autoBackupWallet(strBackupWarning, strBackupError)) {
556  if (!strBackupWarning.isEmpty()) {
557  // It's still more or less safe to continue but warn user anyway
558  LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- WARNING! Something went wrong on automatic backup: %s\n", strBackupWarning.toStdString());
559 
560  QMessageBox::warning(this, "PrivateSend",
561  tr("WARNING! Something went wrong on automatic backup") + ":<br><br>" + strBackupWarning,
562  QMessageBox::Ok, QMessageBox::Ok);
563  }
564  if (!strBackupError.isEmpty()) {
565  // Things are really broken, warn user and stop mixing immediately
566  LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- ERROR! Failed to create automatic backup: %s\n", strBackupError.toStdString());
567 
568  QMessageBox::warning(this, "PrivateSend",
569  tr("ERROR! Failed to create automatic backup") + ":<br><br>" + strBackupError + "<br>" +
570  tr("Mixing is disabled, please close your wallet and fix the issue!"),
571  QMessageBox::Ok, QMessageBox::Ok);
572  }
573  }
574  }
575 
576  QString strEnabled = privateSendClient.fPrivateSendRunning ? tr("Enabled") : tr("Disabled");
577  // Show how many keys left in advanced PS UI mode only
578  if(fShowAdvancedPSUI) strEnabled += ", " + strKeysLeftText;
579  ui->labelPrivateSendEnabled->setText(strEnabled);
580 
581  if(nWalletBackups == -1) {
582  // Automatic backup failed, nothing else we can do until user fixes the issue manually
584 
585  QString strError = tr("ERROR! Failed to create automatic backup") + ", " +
586  tr("see debug.log for details.") + "<br><br>" +
587  tr("Mixing is disabled, please close your wallet and fix the issue!");
588  ui->labelPrivateSendEnabled->setToolTip(strError);
589 
590  return;
591  } else if(nWalletBackups == -2) {
592  // We were able to create automatic backup but keypool was not replenished because wallet is locked.
593  QString strWarning = tr("WARNING! Failed to replenish keypool, please unlock your wallet to do so.");
594  ui->labelPrivateSendEnabled->setToolTip(strWarning);
595  }
596 
597  // check privatesend status and unlock if needed
598  if(nBestHeight != privateSendClient.nCachedNumBlocks) {
599  // Balance and number of transactions might have changed
600  privateSendClient.nCachedNumBlocks = nBestHeight;
602  }
603 
604  setWidgetsVisible(true);
605 
606  ui->labelSubmittedDenom->setText(QString(privateSendClient.GetSessionDenoms().c_str()));
607 }
608 
610  QSettings settings;
611  // Popup some information on first mixing
612  QString hasMixed = settings.value("hasMixed").toString();
613  if(hasMixed.isEmpty()){
614  QMessageBox::information(this, "PrivateSend",
615  tr("If you don't want to see internal PrivateSend fees/transactions select \"Most Common\" as Type on the \"Transactions\" tab."),
616  QMessageBox::Ok, QMessageBox::Ok);
617  settings.setValue("hasMixed", "hasMixed");
618  }
621  if(currentBalance < nMinAmount){
622  QString strMinAmount(BitcoinUnits::formatWithUnit(nDisplayUnit, nMinAmount));
623  QMessageBox::warning(this, "PrivateSend",
624  tr("PrivateSend requires at least %1 to use.").arg(strMinAmount),
625  QMessageBox::Ok, QMessageBox::Ok);
626  return;
627  }
628 
629  // if wallet is locked, ask for a passphrase
631  {
633  if(!ctx.isValid())
634  {
635  //unlock was cancelled
636  privateSendClient.nCachedNumBlocks = std::numeric_limits<int>::max();
637  QMessageBox::warning(this, "PrivateSend",
638  tr("Wallet is locked and user declined to unlock. Disabling PrivateSend."),
639  QMessageBox::Ok, QMessageBox::Ok);
640  LogPrint(BCLog::PRIVATESEND, "OverviewPage::togglePrivateSend -- Wallet is locked and user declined to unlock. Disabling PrivateSend.\n");
641  return;
642  }
643  }
644 
645  }
646 
648  privateSendClient.nCachedNumBlocks = std::numeric_limits<int>::max();
649 
651  ui->togglePrivateSend->setText(tr("Start Mixing"));
653  } else {
654  ui->togglePrivateSend->setText(tr("Stop Mixing"));
655  }
656 }
657 
659 {
660  if (walletModel == nullptr || walletModel->getTransactionTableModel() == nullptr) {
661  return;
662  }
663 
664  // Set up transaction list
665  if (filter == nullptr) {
666  filter.reset(new TransactionFilterProxy());
667  filter->setSourceModel(walletModel->getTransactionTableModel());
668  filter->setDynamicSortFilter(true);
669  filter->setSortRole(Qt::EditRole);
670  filter->setShowInactive(false);
671  filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
672  ui->listTransactions->setModel(filter.get());
673  }
674 
675  if (filter->rowCount() == nNumItems) {
676  return;
677  }
678 
679  filter->setLimit(nNumItems);
680  ui->listTransactions->setMinimumHeight(nNumItems * ITEM_HEIGHT);
681 }
682 
684  ui->togglePrivateSend->setText("(" + tr("Disabled") + ")");
685  ui->framePrivateSend->setEnabled(false);
686  if (nWalletBackups <= 0) {
687  ui->labelPrivateSendEnabled->setText("<span style='" + GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR) + "'>(" + tr("Disabled") + ")</span>");
688  }
690 }
double getScaledFontSize(int nSize)
get font size with GUIUtil::fontScale applied
Definition: guiutil.cpp:1404
static CAmount GetSmallestDenomination()
Definition: privatesend.h:437
CMasternodeSync masternodeSync
void setWalletModel(WalletModel *walletModel)
QFont getFont(FontFamily family, QFont::Weight qWeight, bool fItalic, int nPointSize)
Get a properly weighted QFont object with the selected font.
Definition: guiutil.cpp:1666
Dash unit definitions.
Definition: bitcoinunits.h:48
void updateAlerts(const QString &warnings)
void DisablePrivateSendCompletely()
#define NUM_ITEMS_ENABLED_ADVANCED
void handleTransactionClicked(const QModelIndex &index)
CAmount currentBalance
Definition: overviewpage.h:53
void setFont(const std::vector< QWidget *> &vecWidgets, FontWeight weight, int nPointSize, bool fItalic)
Workaround to set correct font styles in all themes since there is a bug in macOS which leads to issu...
Definition: guiutil.cpp:1552
bool ShutdownRequested()
Definition: init.cpp:179
std::unique_ptr< TransactionFilterProxy > filter
Definition: overviewpage.h:65
static const CAmount COIN
Definition: amount.h:14
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
TxViewDelegate(QObject *parent=nullptr)
static const int PRIVATESEND_KEYS_THRESHOLD_WARNING
#define NUM_ITEMS_ENABLED_NORMAL
CAmount currentWatchOnlyBalance
Definition: overviewpage.h:57
TxViewDelegate * txdelegate
Definition: overviewpage.h:64
WalletModel * walletModel
Definition: overviewpage.h:52
CAmount currentUnconfirmedBalance
Definition: overviewpage.h:54
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:824
bool IsBlockchainSynced()
CAmount getDenominatedBalance(bool unconfirmed) const
Definition: walletmodel.cpp:97
bool haveWatchOnly() const
void outOfSyncWarningClicked()
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
EncryptionStatus getEncryptionStatus() const
int getDisplayUnit() const
Definition: optionsmodel.h:82
CAmount getBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:76
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
int cachedNumISLocks
Definition: overviewpage.h:62
CAmount getImmatureBalance() const
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: utiltime.cpp:22
bool fMasternodeMode
Definition: util.cpp:93
void updateFonts()
Update the font of all widgets where a custom font has been set with GUIUtil::setFont.
Definition: guiutil.cpp:1563
CAmount currentWatchUnconfBalance
Definition: overviewpage.h:58
int nWalletBackups
nWalletBackups: 1..10 - number of automatic backups to keep 0 - disabled by command-line -1 - disable...
Definition: util.cpp:102
CAmount currentAnonymizedBalance
Definition: overviewpage.h:56
int64_t getKeysLeftSinceAutoBackup() const
void updateWatchOnlyLabels(bool showWatchOnly)
void togglePrivateSend()
void updateAdvancedPSUI(bool fShowAdvancedPSUI)
static secp256k1_context * ctx
Definition: tests.c:46
bool fShowAdvancedPSUI
Definition: overviewpage.h:61
CAmount getWatchUnconfirmedBalance() const
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
void privateSendEnabledChanged()
static qint64 factor(int unit)
Number of Satoshis (1e-8) per unit.
CAmount getAnonymizedBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:92
TransactionTableModel * getTransactionTableModel()
Model for Dash network client.
Definition: clientmodel.h:42
ClientModel * clientModel
Definition: overviewpage.h:51
void privateSendStatus(bool fForce=false)
void transactionClicked(const QModelIndex &index)
#define LogPrint(category,...)
Definition: util.h:214
#define NUM_ITEMS_DISABLED
void showOutOfSyncWarning(bool fShow)
static QString floorWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit) but floor value up to "digits" settings.
QTimer * timer
Definition: overviewpage.h:49
ArgsManager gArgs
Definition: util.cpp:108
CAmount getAverageAnonymizedRounds() const
UnlockContext requestUnlock(bool fForMixingOnly=false)
CPrivateSendClientManager privateSendClient
bool autoBackupWallet(QString &strBackupWarningRet, QString &strBackupErrorRet)
bool getShowAdvancedPSUI()
Definition: optionsmodel.h:86
OverviewPage(QWidget *parent=0)
Filter the transaction list according to pre-specified rules.
void updateDisplayUnit()
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:100
CAmount getWatchBalance() const
CAmount getNormalizedAnonymizedBalance() const
CAmount getUnconfirmedBalance() const
void updatePrivateSendProgress()
QString getThemedStyleQString(ThemedStyle style)
Helper to get css style strings which are injected into rich text through qt.
Definition: guiutil.cpp:210
CAmount currentWatchImmatureBalance
Definition: overviewpage.h:59
CAmount currentImmatureBalance
Definition: overviewpage.h:55
static CAmount GetMaxCollateralAmount()
Definition: privatesend.h:461
void setClientModel(ClientModel *clientModel)
void handleOutOfSyncWarningClicks()
CAmount getWatchImmatureBalance() const
static QString floorHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
int getNumBlocks() const
#define ITEM_HEIGHT
void setBalance(const CAmount &balance, const CAmount &unconfirmedBalance, const CAmount &immatureBalance, const CAmount &anonymizedBalance, const CAmount &watchOnlyBalance, const CAmount &watchUnconfBalance, const CAmount &watchImmatureBalance)
CAmount getAnonymizableBalance(bool fSkipDenominated, bool fSkipUnconfirmed) const
Definition: walletmodel.cpp:87
int getNumISLocks() const
Overview ("home") page widget.
Definition: overviewpage.h:27
Ui::OverviewPage * ui
Definition: overviewpage.h:50
void SetupTransactionList(int nNumItems)
OptionsModel * getOptionsModel()
static int decimals(int unit)
Number of decimals left.
Released under the MIT license