BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
modaloverlay.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <qt/modaloverlay.h>
6 #include <qt/forms/ui_modaloverlay.h>
7 
8 #include <qt/guiutil.h>
9 
10 #include <chainparams.h>
11 
12 #include <QResizeEvent>
13 #include <QPropertyAnimation>
14 
15 ModalOverlay::ModalOverlay(QWidget *parent) :
16 QWidget(parent),
17 ui(new Ui::ModalOverlay),
18 bestHeaderHeight(0),
19 bestHeaderDate(QDateTime()),
20 layerIsVisible(false),
21 userClosed(false)
22 {
23  ui->setupUi(this);
24  connect(ui->closeButton, &QPushButton::clicked, this, &ModalOverlay::closeClicked);
25  if (parent) {
26  parent->installEventFilter(this);
27  raise();
28  }
29 
30  blockProcessTime.clear();
31  setVisible(false);
32 }
33 
35 {
36  delete ui;
37 }
38 
39 bool ModalOverlay::eventFilter(QObject * obj, QEvent * ev) {
40  if (obj == parent()) {
41  if (ev->type() == QEvent::Resize) {
42  QResizeEvent * rev = static_cast<QResizeEvent*>(ev);
43  resize(rev->size());
44  if (!layerIsVisible)
45  setGeometry(0, height(), width(), height());
46 
47  }
48  else if (ev->type() == QEvent::ChildAdded) {
49  raise();
50  }
51  }
52  return QWidget::eventFilter(obj, ev);
53 }
54 
56 bool ModalOverlay::event(QEvent* ev) {
57  if (ev->type() == QEvent::ParentAboutToChange) {
58  if (parent()) parent()->removeEventFilter(this);
59  }
60  else if (ev->type() == QEvent::ParentChange) {
61  if (parent()) {
62  parent()->installEventFilter(this);
63  raise();
64  }
65  }
66  return QWidget::event(ev);
67 }
68 
69 void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate)
70 {
71  if (count > bestHeaderHeight) {
72  bestHeaderHeight = count;
73  bestHeaderDate = blockDate;
74  }
75 }
76 
77 void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress)
78 {
79  QDateTime currentDate = QDateTime::currentDateTime();
80 
81  // keep a vector of samples of verification progress at height
82  blockProcessTime.push_front(qMakePair(currentDate.toMSecsSinceEpoch(), nVerificationProgress));
83 
84  // show progress speed if we have more than one sample
85  if (blockProcessTime.size() >= 2) {
86  double progressDelta = 0;
87  double progressPerHour = 0;
88  qint64 timeDelta = 0;
89  qint64 remainingMSecs = 0;
90  double remainingProgress = 1.0 - nVerificationProgress;
91  for (int i = 1; i < blockProcessTime.size(); i++) {
92  QPair<qint64, double> sample = blockProcessTime[i];
93 
94  // take first sample after 500 seconds or last available one
95  if (sample.first < (currentDate.toMSecsSinceEpoch() - 500 * 1000) || i == blockProcessTime.size() - 1) {
96  progressDelta = blockProcessTime[0].second - sample.second;
97  timeDelta = blockProcessTime[0].first - sample.first;
98  progressPerHour = progressDelta / (double) timeDelta * 1000 * 3600;
99  remainingMSecs = (progressDelta > 0) ? remainingProgress / progressDelta * timeDelta : -1;
100  break;
101  }
102  }
103  // show progress increase per hour
104  ui->progressIncreasePerH->setText(QString::number(progressPerHour * 100, 'f', 2)+"%");
105 
106  // show expected remaining time
107  if(remainingMSecs >= 0) {
108  ui->expectedTimeLeft->setText(GUIUtil::formatNiceTimeOffset(remainingMSecs / 1000.0));
109  } else {
110  ui->expectedTimeLeft->setText(QObject::tr("unknown"));
111  }
112 
113  static const int MAX_SAMPLES = 5000;
114  if (blockProcessTime.count() > MAX_SAMPLES) {
115  blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count() - MAX_SAMPLES);
116  }
117  }
118 
119  // show the last block date
120  ui->newestBlockDate->setText(blockDate.toString());
121 
122  // show the percentage done according to nVerificationProgress
123  ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%");
124  ui->progressBar->setValue(nVerificationProgress*100);
125 
126  if (!bestHeaderDate.isValid())
127  // not syncing
128  return;
129 
130  // estimate the number of headers left based on nPowTargetSpacing
131  // and check if the gui is not aware of the best header (happens rarely)
132  int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus().nPowTargetSpacing;
133  bool hasBestHeader = bestHeaderHeight >= count;
134 
135  // show remaining number of blocks
136  if (estimateNumHeadersLeft < HEADER_HEIGHT_DELTA_SYNC && hasBestHeader) {
137  ui->numberOfBlocksLeft->setText(QString::number(bestHeaderHeight - count));
138  } else {
139  ui->numberOfBlocksLeft->setText(tr("Unknown. Syncing Headers (%1)...").arg(bestHeaderHeight));
140  ui->expectedTimeLeft->setText(tr("Unknown..."));
141  }
142 }
143 
145 {
146  showHide(layerIsVisible, true);
147  if (!layerIsVisible)
148  userClosed = true;
149 }
150 
151 void ModalOverlay::showHide(bool hide, bool userRequested)
152 {
153  if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested))
154  return;
155 
156  if (!isVisible() && !hide)
157  setVisible(true);
158 
159  setGeometry(0, hide ? 0 : height(), width(), height());
160 
161  QPropertyAnimation* animation = new QPropertyAnimation(this, "pos");
162  animation->setDuration(300);
163  animation->setStartValue(QPoint(0, hide ? 0 : this->height()));
164  animation->setEndValue(QPoint(0, hide ? this->height() : 0));
165  animation->setEasingCurve(QEasingCurve::OutQuad);
166  animation->start(QAbstractAnimation::DeleteWhenStopped);
167  layerIsVisible = !hide;
168 }
169 
171 {
172  showHide(true);
173  userClosed = true;
174 }
ModalOverlay(QWidget *parent)
bool event(QEvent *ev)
Tracks parent widget changes.
bool eventFilter(QObject *obj, QEvent *ev)
void tipUpdate(int count, const QDateTime &blockDate, double nVerificationProgress)
Modal overlay to display information about the chain-sync state.
Definition: modaloverlay.h:19
Ui::ModalOverlay * ui
Definition: modaloverlay.h:42
void setKnownBestHeight(int count, const QDateTime &blockDate)
int64_t nPowTargetSpacing
Definition: params.h:60
void toggleVisibility()
QDateTime bestHeaderDate
Definition: modaloverlay.h:44
bool layerIsVisible
Definition: modaloverlay.h:46
int bestHeaderHeight
Definition: modaloverlay.h:43
void showHide(bool hide=false, bool userRequested=false)
const CChainParams & Params()
Return the currently selected parameters.
QVector< QPair< qint64, double > > blockProcessTime
Definition: modaloverlay.h:45
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:841
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:60
void closeClicked()