Dogecoin Core  1.14.2
P2P Digital Currency
modaloverlay.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016 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 "modaloverlay.h"
6 #include "ui_modaloverlay.h"
7 
8 #include "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, SIGNAL(clicked()), this, SLOT(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 then one sample
85  if (blockProcessTime.size() >= 2)
86  {
87  double progressStart = blockProcessTime[0].second;
88  double progressDelta = 0;
89  double progressPerHour = 0;
90  qint64 timeDelta = 0;
91  qint64 remainingMSecs = 0;
92  double remainingProgress = 1.0 - nVerificationProgress;
93  for (int i = 1; i < blockProcessTime.size(); i++)
94  {
95  QPair<qint64, double> sample = blockProcessTime[i];
96 
97  // take first sample after 500 seconds or last available one
98  if (sample.first < (currentDate.toMSecsSinceEpoch() - 500 * 1000) || i == blockProcessTime.size() - 1) {
99  progressDelta = progressStart-sample.second;
100  timeDelta = blockProcessTime[0].first - sample.first;
101  progressPerHour = progressDelta/(double)timeDelta*1000*3600;
102  remainingMSecs = remainingProgress / progressDelta * timeDelta;
103  break;
104  }
105  }
106  // show progress increase per hour
107  ui->progressIncreasePerH->setText(QString::number(progressPerHour*100, 'f', 2)+"%");
108 
109  // show expected remaining time
110  ui->expectedTimeLeft->setText(GUIUtil::formatNiceTimeOffset(remainingMSecs/1000.0));
111 
112  static const int MAX_SAMPLES = 5000;
113  if (blockProcessTime.count() > MAX_SAMPLES)
114  blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count()-MAX_SAMPLES);
115  }
116 
117  // show the last block date
118  ui->newestBlockDate->setText(blockDate.toString());
119 
120  // show the percentage done according to nVerificationProgress
121  ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%");
122  ui->progressBar->setValue(nVerificationProgress*100);
123 
124  if (!bestHeaderDate.isValid())
125  // not syncing
126  return;
127 
128  // estimate the number of headers left based on nPowTargetSpacing
129  // and check if the gui is not aware of the the best header (happens rarely)
130  int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus(bestHeaderHeight).nPowTargetSpacing;
131  bool hasBestHeader = bestHeaderHeight >= count;
132 
133  // show remaining number of blocks
134  if (estimateNumHeadersLeft < HEADER_HEIGHT_DELTA_SYNC && hasBestHeader) {
135  ui->numberOfBlocksLeft->setText(QString::number(bestHeaderHeight - count));
136  } else {
137  ui->numberOfBlocksLeft->setText(tr("Unknown. Syncing Headers (%1)...").arg(bestHeaderHeight));
138  ui->expectedTimeLeft->setText(tr("Unknown..."));
139  }
140 }
141 
143 {
144  showHide(layerIsVisible, true);
145  if (!layerIsVisible)
146  userClosed = true;
147 }
148 
149 void ModalOverlay::showHide(bool hide, bool userRequested)
150 {
151  if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested))
152  return;
153 
154  if (!isVisible() && !hide)
155  setVisible(true);
156 
157  setGeometry(0, hide ? 0 : height(), width(), height());
158 
159  QPropertyAnimation* animation = new QPropertyAnimation(this, "pos");
160  animation->setDuration(300);
161  animation->setStartValue(QPoint(0, hide ? 0 : this->height()));
162  animation->setEndValue(QPoint(0, hide ? this->height() : 0));
163  animation->setEasingCurve(QEasingCurve::OutQuad);
164  animation->start(QAbstractAnimation::DeleteWhenStopped);
165  layerIsVisible = !hide;
166 }
167 
169 {
170  showHide(true);
171  userClosed = true;
172 }
const CChainParams & Params()
Return the currently selected parameters.
const Consensus::Params & GetConsensus(uint32_t nTargetHeight) const
Definition: chainparams.h:59
Modal overlay to display information about the chain-sync state.
Definition: modaloverlay.h:20
void showHide(bool hide=false, bool userRequested=false)
void setKnownBestHeight(int count, const QDateTime &blockDate)
bool event(QEvent *ev)
Tracks parent widget changes.
void tipUpdate(int count, const QDateTime &blockDate, double nVerificationProgress)
void toggleVisibility()
bool eventFilter(QObject *obj, QEvent *ev)
QDateTime bestHeaderDate
Definition: modaloverlay.h:44
bool layerIsVisible
Definition: modaloverlay.h:46
ModalOverlay(QWidget *parent)
Ui::ModalOverlay * ui
Definition: modaloverlay.h:42
void closeClicked()
QVector< QPair< qint64, double > > blockProcessTime
Definition: modaloverlay.h:45
int bestHeaderHeight
Definition: modaloverlay.h:43
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:949
int64_t nPowTargetSpacing
Definition: params.h:66