PIVX Core  5.6.99
P2P Digital Currency
topbar.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 https://www.opensource.org/licenses/mit-license.php.
4 
5 #include "topbar.h"
6 #include "ui_topbar.h"
7 
8 #include "askpassphrasedialog.h"
9 #include "loadingdialog.h"
10 #include "lockunlock.h"
11 
12 #include "qtutils.h"
13 #include "receivedialog.h"
14 
15 #include "addresstablemodel.h"
16 #include "balancebubble.h"
17 #include "bitcoinunits.h"
18 #include "clientmodel.h"
19 #include "optionsmodel.h"
20 #include "qt/guiutil.h"
21 #include "walletmodel.h"
22 
23 #include "masternode-sync.h" // for MASTERNODE_SYNC_THRESHOLD
25 
26 #include <QPixmap>
27 
28 #define REQUEST_UPGRADE_WALLET 1
29 
30 class ButtonHoverWatcher : public QObject
31 {
32 public:
33  explicit ButtonHoverWatcher(QObject* parent = nullptr) :
34  QObject(parent) {}
35  bool eventFilter(QObject* watched, QEvent* event) override
36  {
37  QPushButton* button = qobject_cast<QPushButton*>(watched);
38  if (!button) return false;
39 
40  if (event->type() == QEvent::Enter) {
41  button->setIcon(QIcon("://ic-information-hover"));
42  return true;
43  }
44 
45  if (event->type() == QEvent::Leave){
46  button->setIcon(QIcon("://ic-information"));
47  return true;
48  }
49  return false;
50  }
51 };
52 
53 TopBar::TopBar(PIVXGUI* _mainWindow, QWidget *parent) :
54  PWidget(_mainWindow, parent),
55  ui(new Ui::TopBar)
56 {
57  ui->setupUi(this);
58 
59  // Set parent stylesheet
60  this->setStyleSheet(_mainWindow->styleSheet());
61  /* Containers */
62  ui->containerTop->setContentsMargins(10, 4, 10, 10);
63 #ifdef Q_OS_MAC
64  ui->containerTop->load("://bg-dashboard-banner");
65  setCssProperty(ui->containerTop,"container-topbar-no-image");
66 #else
67  ui->containerTop->setProperty("cssClass", "container-top");
68 #endif
69 
70  std::initializer_list<QWidget*> lblTitles = {ui->labelTitle1, ui->labelTitle3, ui->labelTitle4, ui->labelTrans, ui->labelShield};
71  setCssProperty(lblTitles, "text-title-topbar");
72  QFont font;
73  font.setWeight(QFont::Light);
74  for (QWidget* w : lblTitles) { w->setFont(font); }
75 
76  // Amount information top
77  ui->widgetTopAmount->setVisible(false);
78  setCssProperty({ui->labelAmountTopPiv, ui->labelAmountTopShieldedPiv}, "amount-small-topbar");
79  setCssProperty({ui->labelAmountPiv}, "amount-topbar");
80  setCssProperty({ui->labelPendingPiv, ui->labelImmaturePiv}, "amount-small-topbar");
81 
82  // Progress Sync
83  progressBar = new QProgressBar(ui->layoutSync);
84  progressBar->setRange(1, 10);
85  progressBar->setValue(4);
86  progressBar->setTextVisible(false);
87  progressBar->setMaximumHeight(2);
88  progressBar->setMaximumWidth(36);
89  setCssProperty(progressBar, "progress-sync");
90  progressBar->show();
91  progressBar->raise();
92  progressBar->move(0, 34);
93 
94  ui->pushButtonFAQ->setButtonClassStyle("cssClass", "btn-check-faq");
95  ui->pushButtonFAQ->setButtonText(tr("FAQ"));
96 
97  ui->pushButtonHDUpgrade->setButtonClassStyle("cssClass", "btn-check-hd-upgrade");
98  ui->pushButtonHDUpgrade->setButtonText(tr("Upgrade to HD Wallet"));
99  ui->pushButtonHDUpgrade->setNoIconText("HD");
100 
101  ui->pushButtonConnection->setButtonClassStyle("cssClass", "btn-check-connect-inactive");
102  ui->pushButtonConnection->setButtonText(tr("No Connection"));
103 
104  ui->pushButtonTor->setButtonClassStyle("cssClass", "btn-check-tor-inactive");
105  ui->pushButtonTor->setButtonText(tr("Tor Disabled"));
106  ui->pushButtonTor->setChecked(false);
107 
108  ui->pushButtonStack->setButtonClassStyle("cssClass", "btn-check-stack-inactive");
109  ui->pushButtonStack->setButtonText(tr("Staking Disabled"));
110 
111  ui->pushButtonColdStaking->setButtonClassStyle("cssClass", "btn-check-cold-staking-inactive");
112  ui->pushButtonColdStaking->setButtonText(tr("Cold Staking Disabled"));
113 
114  ui->pushButtonSync->setButtonClassStyle("cssClass", "btn-check-sync");
115  ui->pushButtonSync->setButtonText(tr(" %54 Synchronizing.."));
116 
117  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-lock");
118 
119  if (isLightTheme()) {
120  ui->pushButtonTheme->setButtonClassStyle("cssClass", "btn-check-theme-light");
121  ui->pushButtonTheme->setButtonText(tr("Light Theme"));
122  } else {
123  ui->pushButtonTheme->setButtonClassStyle("cssClass", "btn-check-theme-dark");
124  ui->pushButtonTheme->setButtonText(tr("Dark Theme"));
125  }
126 
127  setCssProperty(ui->qrContainer, "container-qr");
128  setCssProperty(ui->pushButtonQR, "btn-qr");
129  setCssProperty(ui->pushButtonBalanceInfo, "btn-info");
130  ButtonHoverWatcher * watcher = new ButtonHoverWatcher(this);
131  ui->pushButtonBalanceInfo->installEventFilter(watcher);
132 
133  // QR image
134  QPixmap pixmap("://img-qr-test");
135  ui->btnQr->setIcon(
136  QIcon(pixmap.scaled(
137  70,
138  70,
139  Qt::KeepAspectRatio))
140  );
141 
142  ui->pushButtonLock->setButtonText(tr("Wallet Locked "));
143  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-lock");
144 
145 
146  connect(ui->pushButtonQR, &QPushButton::clicked, this, &TopBar::onBtnReceiveClicked);
147  connect(ui->btnQr, &QPushButton::clicked, this, &TopBar::onBtnReceiveClicked);
148  connect(ui->pushButtonBalanceInfo, &QPushButton::clicked, this, &TopBar::onBtnBalanceInfoClicked);
149  connect(ui->pushButtonLock, &ExpandableButton::Mouse_Pressed, this, &TopBar::onBtnLockClicked);
150  connect(ui->pushButtonTheme, &ExpandableButton::Mouse_Pressed, this, &TopBar::onThemeClicked);
151  connect(ui->pushButtonFAQ, &ExpandableButton::Mouse_Pressed, [this](){window->openFAQ();});
152  connect(ui->pushButtonColdStaking, &ExpandableButton::Mouse_Pressed, this, &TopBar::onColdStakingClicked);
153  connect(ui->pushButtonSync, &ExpandableButton::Mouse_HoverLeave, this, &TopBar::refreshProgressBarSize);
154  connect(ui->pushButtonSync, &ExpandableButton::Mouse_Hover, this, &TopBar::refreshProgressBarSize);
155  connect(ui->pushButtonSync, &ExpandableButton::Mouse_Pressed, [this](){window->goToSettingsInfo();});
156  connect(ui->pushButtonConnection, &ExpandableButton::Mouse_Pressed, [this](){window->openNetworkMonitor();});
157 }
158 
160 {
161  // Store theme
162  bool lightTheme = !isLightTheme();
163 
164  setTheme(lightTheme);
165 
166  if (lightTheme) {
167  ui->pushButtonTheme->setButtonClassStyle("cssClass", "btn-check-theme-light", true);
168  ui->pushButtonTheme->setButtonText(tr("Light Theme"));
169  } else {
170  ui->pushButtonTheme->setButtonClassStyle("cssClass", "btn-check-theme-dark", true);
171  ui->pushButtonTheme->setButtonText(tr("Dark Theme"));
172  }
173  updateStyle(ui->pushButtonTheme);
174 
175  Q_EMIT themeChanged(lightTheme);
176 }
177 
179 {
180  if (walletModel) {
182  encryptWallet();
183  } else {
184  if (!lockUnlockWidget) {
186  lockUnlockWidget->setStyleSheet("margin:0px; padding:0px;");
188  connect(ui->pushButtonLock, &ExpandableButton::Mouse_HoverLeave, [this]() {
189  QMetaObject::invokeMethod(this, "lockDropdownMouseLeave", Qt::QueuedConnection);
190  });
192  }
193 
195  if (ui->pushButtonLock->width() <= 40) {
196  ui->pushButtonLock->setExpanded();
197  }
198  // Keep it open
199  ui->pushButtonLock->setKeepExpanded(true);
200  QMetaObject::invokeMethod(this, "openLockUnlock", Qt::QueuedConnection);
201  }
202  }
203 }
204 
206 {
207  lockUnlockWidget->setFixedWidth(ui->pushButtonLock->width());
208  lockUnlockWidget->adjustSize();
209 
210  lockUnlockWidget->move(
211  ui->pushButtonLock->pos().rx() + window->getNavWidth() + 10,
212  ui->pushButtonLock->y() + 36
213  );
214 
215  lockUnlockWidget->raise();
216  lockUnlockWidget->activateWindow();
217  lockUnlockWidget->show();
218 }
219 
221 {
222  if (!walletModel)
223  return;
224 
225  showHideOp(true);
227  dlg->adjustSize();
229 
230  refreshStatus();
231  dlg->deleteLater();
232 }
233 
235 {
237 }
238 
240 {
241  if (!walletModel)
242  return;
243  // Unlock wallet when requested by wallet model (if unlocked or unlocked for staking only)
244  if (walletModel->isWalletLocked(false))
246 }
247 
248 static bool isExecuting = false;
249 
251 {
252  lockUnlockWidget->close();
253  if (walletModel && !isExecuting) {
254  isExecuting = true;
255 
256  switch (lockUnlockWidget->lock) {
257  case 0: {
259  break;
261  ui->pushButtonLock->setButtonText(tr("Wallet Locked"));
262  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-lock", true);
263  // Directly update the staking status icon when the wallet is manually locked here
264  // so the feedback is instant (no need to wait for the polling timeout)
265  setStakingStatusActive(false);
266  break;
267  }
268  case 1: {
270  break;
271  showHideOp(true);
274  dlg->adjustSize();
277  ui->pushButtonLock->setButtonText(tr("Wallet Unlocked"));
278  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-unlock", true);
279  }
280  dlg->deleteLater();
281  break;
282  }
283  case 2: {
285  if (status == WalletModel::UnlockedForStaking)
286  break;
287 
288  if (status == WalletModel::Unlocked) {
290  } else {
291  showHideOp(true);
295  dlg->adjustSize();
297  dlg->deleteLater();
298  }
300  ui->pushButtonLock->setButtonText(tr("Wallet Unlocked for staking"));
301  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-staking", true);
302  }
303  break;
304  }
305  }
306 
307  ui->pushButtonLock->setKeepExpanded(false);
308  ui->pushButtonLock->setSmall();
309  ui->pushButtonLock->update();
310 
311  isExecuting = false;
312  }
313 }
314 
316 {
317  if (lockUnlockWidget->isVisible() && !lockUnlockWidget->isHovered()) {
318  lockUnlockWidget->hide();
319  ui->pushButtonLock->setKeepExpanded(false);
320  ui->pushButtonLock->setSmall();
321  ui->pushButtonLock->update();
322  }
323 }
324 
326 {
327  if (walletModel) {
328  QString addressStr = walletModel->getAddressTableModel()->getAddressToShow();
329  if (addressStr.isNull()) {
330  inform(tr("Error generating address"));
331  return;
332  }
333  showHideOp(true);
334  ReceiveDialog *receiveDialog = new ReceiveDialog(window);
335  receiveDialog->updateQr(addressStr);
336  if (openDialogWithOpaqueBackground(receiveDialog, window)) {
337  inform(tr("Address Copied"));
338  }
339  receiveDialog->deleteLater();
340  }
341 }
342 
344 {
345  if (!walletModel) return;
346  if (balanceBubble) {
347  if (balanceBubble->isVisible()) {
348  balanceBubble->hide();
349  return;
350  }
351  } else balanceBubble = new BalanceBubble(this);
352 
353  const auto& balances = walletModel->GetWalletBalances();
354  balanceBubble->updateValues(balances.balance - balances.shielded_balance, balances.shielded_balance, nDisplayUnit);
355  QPoint pos = this->pos();
356  pos.setX(pos.x() + (ui->labelTitle1->width()) + 60);
357  pos.setY(pos.y() + 20);
358  balanceBubble->move(pos);
359  balanceBubble->show();
360 }
361 
363 {
364  if (ui->bottom_container->isVisible()) {
365  if (balanceBubble && balanceBubble->isVisible()) balanceBubble->hide();
366  ui->bottom_container->setVisible(false);
367  ui->widgetTopAmount->setVisible(true);
368  this->setFixedHeight(75);
369  }
370 }
371 
373 {
374  ui->widgetTopAmount->setVisible(false);
375  ui->bottom_container->setVisible(true);
376  this->setFixedHeight(200);
377  this->adjustSize();
378 }
379 
381 {
382  bool isColdStakingEnabled = walletModel->isColdStaking();
383  ui->pushButtonColdStaking->setChecked(isColdStakingEnabled);
384 
387  QString className;
388  QString text;
389 
390  if (isColdStakingEnabled) {
391  text = "Cold Staking Active";
392  className = (show) ? "btn-check-cold-staking-checked" : "btn-check-cold-staking-unchecked";
393  } else if (show) {
394  className = "btn-check-cold-staking";
395  text = "Cold Staking Enabled";
396  } else {
397  className = "btn-check-cold-staking-inactive";
398  text = "Cold Staking Disabled";
399  }
400 
401  ui->pushButtonColdStaking->setButtonClassStyle("cssClass", className, true);
402  ui->pushButtonColdStaking->setButtonText(text);
403  updateStyle(ui->pushButtonColdStaking);
404 
405  Q_EMIT onShowHideColdStakingChanged(show);
406 }
407 
409 {
410  if (timerStakingIcon) {
411  timerStakingIcon->stop();
412  }
413  delete ui;
414 }
415 
417 {
418  if (clientModel) {
419  // Keep up to date with client
422 
426 
427  timerStakingIcon = new QTimer(ui->pushButtonStack);
428  connect(timerStakingIcon, &QTimer::timeout, this, &TopBar::updateStakingStatus);
429  timerStakingIcon->start(50000);
431  }
432 }
433 
435 {
436  if (ui->pushButtonStack->isChecked() != fActive) {
437  ui->pushButtonStack->setButtonText(fActive ? tr("Staking active") : tr("Staking not active"));
438  ui->pushButtonStack->setChecked(fActive);
439  ui->pushButtonStack->setButtonClassStyle("cssClass", (fActive ?
440  "btn-check-stack" :
441  "btn-check-stack-inactive"), true);
442  }
443 }
445 {
449 
450  // Taking advantage of this timer to update Tor status if needed.
451  updateTorIcon();
452  }
453 }
454 
456 {
457  if (count > 0) {
458  if (!ui->pushButtonConnection->isChecked()) {
459  ui->pushButtonConnection->setChecked(true);
460  ui->pushButtonConnection->setButtonClassStyle("cssClass", "btn-check-connect", true);
461  }
462  } else {
463  if (ui->pushButtonConnection->isChecked()) {
464  ui->pushButtonConnection->setChecked(false);
465  ui->pushButtonConnection->setButtonClassStyle("cssClass", "btn-check-connect-inactive", true);
466  }
467  }
468 
469  ui->pushButtonConnection->setButtonText(tr("%n active connection(s)", "", count));
470 }
471 
472 void TopBar::setNetworkActive(bool active)
473 {
474  if (!active) {
475  ui->pushButtonSync->setButtonText(tr("Network activity disabled"));
476  ui->pushButtonSync->setButtonClassStyle("cssClass", "btn-check-sync-inactive", true);
477  } else {
478  if (!clientModel) return;
480  ui->pushButtonSync->setButtonClassStyle("cssClass", "btn-check-sync", true);
481  }
482 }
483 
484 void TopBar::setNumBlocks(int count)
485 {
486  if (!clientModel)
487  return;
488 
489  std::string text;
490  bool needState = true;
492  // chain synced
493  Q_EMIT walletSynced(true);
495  // Node synced
496  ui->pushButtonSync->setButtonText(tr("Synchronized - Block: %1").arg(QString::number(count)));
497  progressBar->setRange(0, 100);
498  progressBar->setValue(100);
499  Q_EMIT tierTwoSynced(true);
500  return;
501  } else {
502 
503  // TODO: Show out of sync warning
504  int RequestedMasternodeAssets = g_tiertwo_sync_state.GetSyncPhase();
508  int progress = nAttempt + (RequestedMasternodeAssets - 1) * MASTERNODE_SYNC_THRESHOLD;
509  if (progress >= 0) {
510  // todo: MN progress..
511  text = strprintf("%s - Block: %d", masternodeSync.GetSyncStatus(), count);
512  //progressBar->setMaximum(4 * MASTERNODE_SYNC_THRESHOLD);
513  //progressBar->setValue(progress);
514  needState = false;
515  }
516  }
517  } else {
518  Q_EMIT walletSynced(false);
519  }
520 
521  if (needState && clientModel->isTipCached()) {
522  // Represent time from last generated block in human readable text
523  QDateTime lastBlockDate = clientModel->getLastBlockDate();
524  QDateTime currentDate = QDateTime::currentDateTime();
525  int secs = lastBlockDate.secsTo(currentDate);
526 
527  QString timeBehindText;
528  const int HOUR_IN_SECONDS = 60 * 60;
529  const int DAY_IN_SECONDS = 24 * 60 * 60;
530  const int WEEK_IN_SECONDS = 7 * 24 * 60 * 60;
531  const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
532  if (secs < 2 * DAY_IN_SECONDS) {
533  timeBehindText = tr("%n hour(s)", "", secs / HOUR_IN_SECONDS);
534  } else if (secs < 2 * WEEK_IN_SECONDS) {
535  timeBehindText = tr("%n day(s)", "", secs / DAY_IN_SECONDS);
536  } else if (secs < YEAR_IN_SECONDS) {
537  timeBehindText = tr("%n week(s)", "", secs / WEEK_IN_SECONDS);
538  } else {
539  int years = secs / YEAR_IN_SECONDS;
540  int remainder = secs % YEAR_IN_SECONDS;
541  timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(
542  tr("%n week(s)", "", remainder / WEEK_IN_SECONDS));
543  }
544  QString timeBehind(" behind. Scanning block ");
545  QString str = timeBehindText + timeBehind + QString::number(count);
546  text = str.toStdString();
547 
548  progressBar->setMaximum(1000000000);
549  progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5);
550  }
551 
552  if (text.empty()) {
553  text = "No block source available..";
554  }
555 
556  ui->pushButtonSync->setButtonText(tr(text.data()));
557 }
558 
559 void TopBar::showUpgradeDialog(const QString& message)
560 {
561  QString title = tr("Wallet Upgrade");
562  if (ask(title, message)) {
563  std::unique_ptr<WalletModel::UnlockContext> pctx = std::make_unique<WalletModel::UnlockContext>(walletModel->requestUnlock());
564  if (!pctx->isValid()) {
565  warn(tr("Upgrade Wallet"), tr("Wallet unlock cancelled"));
566  return;
567  }
568  // Action performed on a separate thread, it's locking cs_main and cs_wallet.
569  LoadingDialog *dialog = new LoadingDialog(window);
570  dialog->execute(this, REQUEST_UPGRADE_WALLET, std::move(pctx));
572  }
573 }
574 
576 {
577  // Upgrade wallet.
578  if (walletModel->isHDEnabled()) {
580  // hide upgrade
581  ui->pushButtonHDUpgrade->setVisible(false);
582  } else {
583  // show upgrade to Sapling
584  ui->pushButtonHDUpgrade->setButtonText(tr("Upgrade to Sapling Wallet"));
585  ui->pushButtonHDUpgrade->setNoIconText("SHIELD UPGRADE");
586  connectUpgradeBtnAndDialogTimer(tr("Upgrading to Sapling wallet will enable\nall of the privacy features!\n\n\n"
587  "NOTE: after the upgrade, a new\nbackup will be created.\n"));
588  }
589  } else {
590  connectUpgradeBtnAndDialogTimer(tr("Upgrading to HD wallet will improve\nthe wallet's reliability and security.\n\n\n"
591  "NOTE: after the upgrade, a new\nbackup will be created.\n"));
592  }
593 
597  // Ask for passphrase if needed
599  // update the display unit, to not use the default ("PIVX")
601 
602  refreshStatus();
604 
605  isInitializing = false;
606 }
607 
608 void TopBar::connectUpgradeBtnAndDialogTimer(const QString& message)
609 {
610  const auto& func = [this, message]() { showUpgradeDialog(message); };
611  connect(ui->pushButtonHDUpgrade, &ExpandableButton::Mouse_Pressed, func);
612 
613  // Upgrade wallet timer, only once. launched 4 seconds after the wallet started.
614  QTimer::singleShot(4000, func);
615 }
616 
618 {
619  std::string ip_port;
620  bool torEnabled = clientModel->getTorInfo(ip_port);
621 
622  if (torEnabled) {
623  if (!ui->pushButtonTor->isChecked()) {
624  ui->pushButtonTor->setChecked(true);
625  ui->pushButtonTor->setButtonClassStyle("cssClass", "btn-check-tor", true);
626  }
627  ui->pushButtonTor->setButtonText(tr("Tor Active"));
628  ui->pushButtonTor->setToolTip("Address: " + QString::fromStdString(ip_port));
629  } else {
630  if (ui->pushButtonTor->isChecked()) {
631  ui->pushButtonTor->setChecked(false);
632  ui->pushButtonTor->setButtonClassStyle("cssClass", "btn-check-tor-inactive", true);
633  ui->pushButtonTor->setButtonText(tr("Tor Disabled"));
634  }
635  }
636 }
637 
639 {
640  // Check lock status
641  if (!walletModel || !walletModel->hasWallet())
642  return;
643 
645 
646  switch (encStatus) {
647  case WalletModel::EncryptionStatus::Unencrypted:
648  ui->pushButtonLock->setButtonText(tr("Wallet Unencrypted"));
649  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-unlock", true);
650  break;
651  case WalletModel::EncryptionStatus::Locked:
652  ui->pushButtonLock->setButtonText(tr("Wallet Locked"));
653  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-lock", true);
654  break;
655  case WalletModel::EncryptionStatus::UnlockedForStaking:
656  ui->pushButtonLock->setButtonText(tr("Wallet Unlocked for staking"));
657  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-staking", true);
658  break;
659  case WalletModel::EncryptionStatus::Unlocked:
660  ui->pushButtonLock->setButtonText(tr("Wallet Unlocked"));
661  ui->pushButtonLock->setButtonClassStyle("cssClass", "btn-check-status-unlock", true);
662  break;
663  }
664  updateStyle(ui->pushButtonLock);
665 }
666 
668 {
670  int displayUnitPrev = nDisplayUnit;
672  if (displayUnitPrev != nDisplayUnit)
674  }
675 }
676 
678 {
679  // Locked balance. //TODO move this to the signal properly in the future..
680  CAmount nLockedBalance = 0;
681  if (walletModel) {
682  nLockedBalance = walletModel->getLockedBalance(true) + walletModel->getLockedBalance(false);
683  }
684  ui->labelTitle1->setText(nLockedBalance > 0 ? tr("Available (Locked included)") : tr("Available"));
685 
686  // PIV Total
687  QString totalPiv = GUIUtil::formatBalance(newBalance.balance, nDisplayUnit);
688  QString totalTransparent = GUIUtil::formatBalance(newBalance.balance - newBalance.shielded_balance);
689  QString totalShielded = GUIUtil::formatBalance(newBalance.shielded_balance);
690 
691  // PIV
692  // Top
693  ui->labelAmountTopPiv->setText(totalTransparent);
694  ui->labelAmountTopShieldedPiv->setText(totalShielded);
695  // Expanded
696  ui->labelAmountPiv->setText(totalPiv);
697  ui->labelPendingPiv->setText(GUIUtil::formatBalance(newBalance.unconfirmed_balance + newBalance.unconfirmed_shielded_balance, nDisplayUnit));
698  ui->labelImmaturePiv->setText(GUIUtil::formatBalance(newBalance.immature_balance, nDisplayUnit));
699 }
700 
701 void TopBar::resizeEvent(QResizeEvent *event)
702 {
704  QWidget::resizeEvent(event);
705 }
706 
708 {
709  QMetaObject::invokeMethod(this, "expandSync", Qt::QueuedConnection);
710 }
711 
713 {
714  if (progressBar) {
715  progressBar->setMaximumWidth(ui->pushButtonSync->maximumWidth());
716  progressBar->setFixedWidth(ui->pushButtonSync->width());
717  progressBar->setMinimumWidth(ui->pushButtonSync->width() - 2);
718  }
719 }
720 
721 void TopBar::updateHDState(const bool upgraded, const QString& upgradeError)
722 {
723  if (upgraded) {
724  ui->pushButtonHDUpgrade->setVisible(false);
725  if (ask("HD Upgrade Complete", tr("The wallet has been successfully upgraded to HD.") + "\n" +
726  tr("It is advised to make a backup.") + "\n\n" + tr("Do you wish to backup now?") + "\n\n")) {
727  // backup wallet
728  QString filename = GUIUtil::getSaveFileName(this,
729  tr("Backup Wallet"), QString(),
730  tr("Wallet Data (*.dat)"), nullptr);
731  if (!filename.isEmpty()) {
732  inform(walletModel->backupWallet(filename) ? tr("Backup created") : tr("Backup creation failed"));
733  } else {
734  warn(tr("Backup creation failed"), tr("no file selected"));
735  }
736  } else {
737  inform(tr("Wallet upgraded successfully, but no backup created.") + "\n" +
738  tr("WARNING: remember to make a copy of your wallet file!"));
739  }
740  } else {
741  warn(tr("Upgrade Wallet Error"), upgradeError);
742  }
743 }
744 
745 void TopBar::run(int type)
746 {
747  if (type == REQUEST_UPGRADE_WALLET) {
748  std::string upgradeError;
749  bool ret = this->walletModel->upgradeWallet(upgradeError);
750  QMetaObject::invokeMethod(this,
751  "updateHDState",
752  Qt::QueuedConnection,
753  Q_ARG(bool, ret),
754  Q_ARG(QString, QString::fromStdString(upgradeError))
755  );
756  }
757 }
758 
759 void TopBar::onError(QString error, int type)
760 {
761  if (type == REQUEST_UPGRADE_WALLET) {
762  warn(tr("Upgrade Wallet Error"), error);
763  }
764 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
QString getAddressToShow(bool shielded=false) const
Return last unused address.
Multifunctional dialog to ask for passphrases.
@ Encrypt
Wallet needs to be fully unlocked.
@ Unlock_Full
Unlock wallet from menu
@ ToggleLock
Encrypt unencrypted wallet.
@ Encrypt
Ask passphrase twice and encrypt.
@ UnlockAnonymize
Ask passphrase and unlock only for anonymization.
@ Unlock
Ask passphrase and unlock.
void updateValues(int64_t nTransparentBalance, int64_t nShieldedBalance, int unit)
bool eventFilter(QObject *watched, QEvent *event) override
Definition: topbar.cpp:35
ButtonHoverWatcher(QObject *parent=nullptr)
Definition: topbar.cpp:33
int RequestedMasternodeAttempt
std::string GetSyncStatus()
bool getTorInfo(std::string &ip_port) const
void numBlocksChanged(int count)
double getVerificationProgress() const
QDateTime getLastBlockDate() const
void numConnectionsChanged(int count)
int getNumBlocks()
bool isTipCached() const
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:63
int getLastBlockProcessedHeight() const
void networkActiveChanged(bool networkActive)
void Mouse_HoverLeave()
void execute(Runnable *runnable, int type, std::unique_ptr< WalletModel::UnlockContext > pctx=nullptr)
void lockClicked(const StateClicked &state)
void Mouse_Leave()
void updateStatus(WalletModel::EncryptionStatus status)
Definition: lockunlock.cpp:37
bool isHovered()
Definition: lockunlock.cpp:90
bool invertColdStakingScreenStatus()
Definition: optionsmodel.h:86
int getDisplayUnit()
Definition: optionsmodel.h:74
void displayUnitChanged(int unit)
bool isColdStakingScreenEnabled()
Definition: optionsmodel.h:85
PIVX GUI main class.
Definition: pivxgui.h:46
int getNavWidth()
Definition: pivxgui.cpp:607
PIVXGUI * window
Definition: pwidget.h:59
void inform(const QString &message)
Definition: pwidget.cpp:45
WalletModel * walletModel
Definition: pwidget.h:61
void warn(const QString &title, const QString &message)
Definition: pwidget.cpp:50
ClientModel * clientModel
Definition: pwidget.h:60
void showHideOp(bool show)
Definition: pwidget.cpp:40
void message(const QString &title, const QString &body, unsigned int style, bool *ret=nullptr)
bool ask(const QString &title, const QString &message)
Definition: pwidget.cpp:55
void updateQr(const QString &address)
bool IsBlockchainSynced() const
bool IsSynced() const
int GetSyncPhase() const
Definition: topbar.h:27
void showTop()
Definition: topbar.cpp:362
void onBtnLockClicked()
Definition: topbar.cpp:178
TopBar(PIVXGUI *_mainWindow, QWidget *parent=nullptr)
Definition: topbar.cpp:53
void openLockUnlock()
Definition: topbar.cpp:205
void resizeEvent(QResizeEvent *event) override
Definition: topbar.cpp:701
void walletSynced(bool isSync)
void loadClientModel() override
Definition: topbar.cpp:416
Ui::TopBar * ui
Definition: topbar.h:80
void updateHDState(const bool upgraded, const QString &upgradeError)
Definition: topbar.cpp:721
~TopBar()
Definition: topbar.cpp:408
QProgressBar * progressBar
Definition: topbar.h:82
int nDisplayUnit
Definition: topbar.h:84
void expandSync()
Definition: topbar.cpp:712
void setNumBlocks(int count)
Definition: topbar.cpp:484
void updateTorIcon()
Definition: topbar.cpp:617
void unlockWallet()
Definition: topbar.cpp:239
bool isInitializing
Definition: topbar.h:86
void updateDisplayUnit()
Definition: topbar.cpp:667
void onError(QString error, int type) override
Definition: topbar.cpp:759
void onColdStakingClicked()
Definition: topbar.cpp:380
void run(int type) override
Definition: topbar.cpp:745
void showBottom()
Definition: topbar.cpp:372
QTimer * timerStakingIcon
Definition: topbar.h:85
void onShowHideColdStakingChanged(bool show)
void updateBalances(const interfaces::WalletBalances &newBalance)
Definition: topbar.cpp:677
void loadWalletModel() override
Definition: topbar.cpp:575
void onBtnBalanceInfoClicked()
Definition: topbar.cpp:343
void refreshProgressBarSize()
Definition: topbar.cpp:707
void openPassPhraseDialog(AskPassphraseDialog::Mode mode, AskPassphraseDialog::Context ctx)
Definition: topbar.cpp:220
void refreshStatus()
Definition: topbar.cpp:638
BalanceBubble * balanceBubble
Definition: topbar.h:89
void onBtnReceiveClicked()
Definition: topbar.cpp:325
void connectUpgradeBtnAndDialogTimer(const QString &message)
Definition: topbar.cpp:608
void setNetworkActive(bool active)
Definition: topbar.cpp:472
void updateStakingStatus()
Definition: topbar.cpp:444
void tierTwoSynced(bool isSync)
void encryptWallet()
Definition: topbar.cpp:234
void setNumConnections(int count)
Definition: topbar.cpp:455
void setStakingStatusActive(bool fActive)
Definition: topbar.cpp:434
void lockDropdownMouseLeave()
Definition: topbar.cpp:315
void lockDropdownClicked(const StateClicked &)
Definition: topbar.cpp:250
void themeChanged(bool isLight)
void showUpgradeDialog(const QString &message)
Definition: topbar.cpp:559
void onThemeClicked()
Definition: topbar.cpp:159
LockUnlock * lockUnlockWidget
Definition: topbar.h:81
bool hasWallet()
Definition: walletmodel.h:156
bool isStakingStatusActive() const
void balanceChanged(const interfaces::WalletBalances &walletBalances)
bool isWalletLocked(bool fFullUnlocked=true) const
CAmount getLockedBalance(bool isTransparent) const
bool isShutdownRequested()
Definition: walletmodel.cpp:86
void encryptionStatusChanged(int status)
bool isHDEnabled() const
@ UnlockedForStaking
Definition: walletmodel.h:137
bool upgradeWallet(std::string &upgradeError)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
bool isColdStaking() const
bool backupWallet(const QString &filename)
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString(), bool stakingOnly=false)
EncryptionStatus getEncryptionStatus() const
void requireUnlock()
interfaces::WalletBalances GetWalletBalances()
Definition: walletmodel.h:165
UnlockContext requestUnlock()
bool lockForStakingOnly(const SecureString &passPhrase=SecureString())
bool isSaplingWalletEnabled() const
StateClicked
Definition: lockunlock.h:15
CMasternodeSync masternodeSync
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition: guiutil.cpp:291
QString formatBalance(CAmount amount, int nDisplayUnit, bool isZpiv)
Definition: guiutil.cpp:119
bool isLightTheme()
Definition: qtutils.cpp:210
bool openDialogWithOpaqueBackgroundFullScreen(QDialog *widget, PIVXGUI *gui)
Definition: qtutils.cpp:81
bool openDialogWithOpaqueBackgroundY(QDialog *widget, PIVXGUI *gui, double posX, int posY, bool hideOpaqueBackground)
Definition: qtutils.cpp:59
bool openDialogWithOpaqueBackground(QDialog *widget, PIVXGUI *gui, double posX)
Definition: qtutils.cpp:76
void setCssProperty(std::initializer_list< QWidget * > args, const QString &value)
Definition: qtutils.cpp:334
void updateStyle(QWidget *widget)
Definition: qtutils.cpp:225
void setTheme(bool isLight)
Definition: qtutils.cpp:215
Collection of wallet balances.
Definition: wallet.h:16
CAmount unconfirmed_balance
Definition: wallet.h:18
CAmount unconfirmed_shielded_balance
Definition: wallet.h:28
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
TierTwoSyncState g_tiertwo_sync_state
#define MASTERNODE_SYNC_THRESHOLD
#define strprintf
Definition: tinyformat.h:1056
#define REQUEST_UPGRADE_WALLET
Definition: topbar.cpp:28