[test] Add getblockchaininfo functional test
[bitcoinplatinum.git] / src / qt / modaloverlay.cpp
blobe32a0bdda8ebf5cb2c7452c0752b5b0acef78662
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.
5 #include "modaloverlay.h"
6 #include "ui_modaloverlay.h"
8 #include "guiutil.h"
10 #include "chainparams.h"
12 #include <QResizeEvent>
13 #include <QPropertyAnimation>
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)
23 ui->setupUi(this);
24 connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(closeClicked()));
25 if (parent) {
26 parent->installEventFilter(this);
27 raise();
30 blockProcessTime.clear();
31 setVisible(false);
34 ModalOverlay::~ModalOverlay()
36 delete ui;
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());
48 else if (ev->type() == QEvent::ChildAdded) {
49 raise();
52 return QWidget::eventFilter(obj, ev);
55 //! Tracks parent widget changes
56 bool ModalOverlay::event(QEvent* ev) {
57 if (ev->type() == QEvent::ParentAboutToChange) {
58 if (parent()) parent()->removeEventFilter(this);
60 else if (ev->type() == QEvent::ParentChange) {
61 if (parent()) {
62 parent()->installEventFilter(this);
63 raise();
66 return QWidget::event(ev);
69 void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate)
71 if (count > bestHeaderHeight) {
72 bestHeaderHeight = count;
73 bestHeaderDate = blockDate;
77 void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress)
79 QDateTime currentDate = QDateTime::currentDateTime();
81 // keep a vector of samples of verification progress at height
82 blockProcessTime.push_front(qMakePair(currentDate.toMSecsSinceEpoch(), nVerificationProgress));
84 // show progress speed if we have more then 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];
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;
103 // show progress increase per hour
104 ui->progressIncreasePerH->setText(QString::number(progressPerHour * 100, 'f', 2)+"%");
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"));
113 static const int MAX_SAMPLES = 5000;
114 if (blockProcessTime.count() > MAX_SAMPLES) {
115 blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count() - MAX_SAMPLES);
119 // show the last block date
120 ui->newestBlockDate->setText(blockDate.toString());
122 // show the percentage done according to nVerificationProgress
123 ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%");
124 ui->progressBar->setValue(nVerificationProgress*100);
126 if (!bestHeaderDate.isValid())
127 // not syncing
128 return;
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;
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..."));
144 void ModalOverlay::toggleVisibility()
146 showHide(layerIsVisible, true);
147 if (!layerIsVisible)
148 userClosed = true;
151 void ModalOverlay::showHide(bool hide, bool userRequested)
153 if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested))
154 return;
156 if (!isVisible() && !hide)
157 setVisible(true);
159 setGeometry(0, hide ? 0 : height(), width(), height());
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;
170 void ModalOverlay::closeClicked()
172 showHide(true);
173 userClosed = true;