1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "modaloverlay.h"
#include "ui_modaloverlay.h"
#include "guiutil.h"
#include <QResizeEvent>
#include <QPropertyAnimation>
ModalOverlay::ModalOverlay(QWidget *parent) :
QWidget(parent),
ui(new Ui::ModalOverlay),
bestBlockHeight(0),
layerIsVisible(false),
userClosed(false)
{
ui->setupUi(this);
connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(closeClicked()));
if (parent) {
parent->installEventFilter(this);
raise();
}
blockProcessTime.clear();
setVisible(false);
}
ModalOverlay::~ModalOverlay()
{
delete ui;
}
bool ModalOverlay::eventFilter(QObject * obj, QEvent * ev) {
if (obj == parent()) {
if (ev->type() == QEvent::Resize) {
QResizeEvent * rev = static_cast<QResizeEvent*>(ev);
resize(rev->size());
if (!layerIsVisible)
setGeometry(0, height(), width(), height());
}
else if (ev->type() == QEvent::ChildAdded) {
raise();
}
}
return QWidget::eventFilter(obj, ev);
}
//! Tracks parent widget changes
bool ModalOverlay::event(QEvent* ev) {
if (ev->type() == QEvent::ParentAboutToChange) {
if (parent()) parent()->removeEventFilter(this);
}
else if (ev->type() == QEvent::ParentChange) {
if (parent()) {
parent()->installEventFilter(this);
raise();
}
}
return QWidget::event(ev);
}
void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate)
{
/* only update the blockheight if the headerschain-tip is not older then 30 days */
int64_t now = QDateTime::currentDateTime().toTime_t();
int64_t btime = blockDate.toTime_t();
if (btime+3600*24*30 > now)
{
if (count > bestBlockHeight)
bestBlockHeight = count;
}
}
void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress)
{
QDateTime currentDate = QDateTime::currentDateTime();
// keep a vector of samples of verification progress at height
blockProcessTime.push_front(qMakePair(currentDate.currentMSecsSinceEpoch(), nVerificationProgress));
// show progress speed if we have more then one sample
if (blockProcessTime.size() >= 2)
{
double progressStart = blockProcessTime[0].second;
double progressDelta = 0;
double progressPerHour = 0;
qint64 timeDelta = 0;
qint64 remainingMSecs = 0;
double remainingProgress = 1.0 - nVerificationProgress;
for (int i = 1; i < blockProcessTime.size(); i++)
{
QPair<qint64, double> sample = blockProcessTime[i];
// take first sample after 500 seconds or last available one
if (sample.first < (currentDate.currentMSecsSinceEpoch() - 500*1000) || i == blockProcessTime.size()-1)
{
progressDelta = progressStart-sample.second;
timeDelta = blockProcessTime[0].first - sample.first;
progressPerHour = progressDelta/(double)timeDelta*1000*3600;
remainingMSecs = remainingProgress / progressDelta * timeDelta;
break;
}
}
// show progress increase per hour
ui->progressIncreasePerH->setText(QString::number(progressPerHour*100, 'f', 2)+"%");
// show expected remaining time
ui->expectedTimeLeft->setText(GUIUtil::formateNiceTimeOffset(remainingMSecs/1000.0));
// keep maximal 5000 samples
static const int MAX_SAMPLES = 5000;
if (blockProcessTime.count() > MAX_SAMPLES)
blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count()-MAX_SAMPLES);
}
// show the last block date
ui->newestBlockDate->setText(blockDate.toString());
// show the percentage done according to nVerificationProgress
ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%");
ui->progressBar->setValue(nVerificationProgress*100);
// show remaining amount of blocks
if (bestBlockHeight > 0)
ui->amountOfBlocksLeft->setText(QString::number(bestBlockHeight-count));
else
ui->expectedTimeLeft->setText(tr("Unknown. Syncing Headers..."));
}
void ModalOverlay::showHide(bool hide, bool userRequested)
{
if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested))
return;
if (!isVisible() && !hide)
setVisible(true);
setGeometry(0, hide ? 0 : height(), width(), height());
QPropertyAnimation* animation = new QPropertyAnimation(this, "pos");
animation->setDuration(300);
animation->setStartValue(QPoint(0, hide ? 0 : this->height()));
animation->setEndValue(QPoint(0, hide ? this->height() : 0));
animation->setEasingCurve(QEasingCurve::OutQuad);
animation->start(QAbstractAnimation::DeleteWhenStopped);
layerIsVisible = !hide;
}
void ModalOverlay::closeClicked()
{
showHide(true);
userClosed = true;
}
|