Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
qt
modaloverlay.cpp
Go to the documentation of this file.
1
// Copyright (c) 2016-present 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 <bitcoin-build-config.h>
// IWYU pragma: keep
6
7
#include <
qt/modaloverlay.h
>
8
#include <qt/forms/ui_modaloverlay.h>
9
10
#include <chainparams.h>
11
#include <
qt/guiutil.h
>
12
13
#include <QEasingCurve>
14
#include <QPropertyAnimation>
15
#include <QResizeEvent>
16
17
ModalOverlay::ModalOverlay
(
bool
enable_wallet, QWidget* parent)
18
: QWidget(parent),
19
ui
(new
Ui
::
ModalOverlay
),
20
bestHeaderDate
(QDateTime())
21
{
22
ui
->setupUi(
this
);
23
connect(
ui
->closeButton, &QPushButton::clicked,
this
, &
ModalOverlay::closeClicked
);
24
if
(parent) {
25
parent->installEventFilter(
this
);
26
raise();
27
}
28
ui
->closeButton->installEventFilter(
this
);
29
30
blockProcessTime
.clear();
31
setVisible(
false
);
32
if
(!enable_wallet) {
33
ui
->infoText->setVisible(
false
);
34
ui
->infoTextStrong->setText(tr(
"%1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain."
).arg(CLIENT_NAME));
35
}
36
37
m_animation
.setTargetObject(
this
);
38
m_animation
.setPropertyName(
"pos"
);
39
m_animation
.setDuration(300
/* ms */
);
40
m_animation
.setEasingCurve(QEasingCurve::OutQuad);
41
}
42
43
ModalOverlay::~ModalOverlay
()
44
{
45
delete
ui
;
46
}
47
48
bool
ModalOverlay::eventFilter
(QObject * obj, QEvent * ev) {
49
if
(obj == parent()) {
50
if
(ev->type() == QEvent::Resize) {
51
QResizeEvent * rev =
static_cast<
QResizeEvent*
>
(ev);
52
resize(rev->size());
53
if
(!
layerIsVisible
)
54
setGeometry(0, height(), width(), height());
55
56
if
(
m_animation
.endValue().toPoint().y() > 0) {
57
m_animation
.setEndValue(QPoint(0, height()));
58
}
59
}
60
else
if
(ev->type() == QEvent::ChildAdded) {
61
raise();
62
}
63
}
64
65
if
(obj ==
ui
->closeButton && ev->type() == QEvent::FocusOut &&
layerIsVisible
) {
66
ui
->closeButton->setFocus(Qt::OtherFocusReason);
67
}
68
69
return
QWidget::eventFilter(obj, ev);
70
}
71
73
bool
ModalOverlay::event
(QEvent* ev) {
74
if
(ev->type() == QEvent::ParentAboutToChange) {
75
if
(parent()) parent()->removeEventFilter(
this
);
76
}
77
else
if
(ev->type() == QEvent::ParentChange) {
78
if
(parent()) {
79
parent()->installEventFilter(
this
);
80
raise();
81
}
82
}
83
return
QWidget::event(ev);
84
}
85
86
void
ModalOverlay::setKnownBestHeight
(
int
count
,
const
QDateTime& blockDate,
bool
presync)
87
{
88
if
(!presync &&
count
>
bestHeaderHeight
) {
89
bestHeaderHeight
=
count
;
90
bestHeaderDate
= blockDate;
91
UpdateHeaderSyncLabel
();
92
}
93
if
(presync) {
94
UpdateHeaderPresyncLabel
(
count
, blockDate);
95
}
96
}
97
98
void
ModalOverlay::tipUpdate
(
int
count
,
const
QDateTime& blockDate,
double
nVerificationProgress)
99
{
100
QDateTime currentDate = QDateTime::currentDateTime();
101
102
// keep a vector of samples of verification progress at height
103
blockProcessTime
.push_front(qMakePair(currentDate.toMSecsSinceEpoch(), nVerificationProgress));
104
105
// show progress speed if we have more than one sample
106
if
(
blockProcessTime
.size() >= 2) {
107
double
progressDelta = 0;
108
double
progressPerHour = 0;
109
qint64 timeDelta = 0;
110
qint64 remainingMSecs = 0;
111
double
remainingProgress = 1.0 - nVerificationProgress;
112
for
(
int
i = 1; i <
blockProcessTime
.size(); i++) {
113
QPair<qint64, double> sample =
blockProcessTime
[i];
114
115
// take first sample after 500 seconds or last available one
116
if
(sample.first < (currentDate.toMSecsSinceEpoch() - 500 * 1000) || i ==
blockProcessTime
.size() - 1) {
117
progressDelta =
blockProcessTime
[0].second - sample.second;
118
timeDelta =
blockProcessTime
[0].first - sample.first;
119
progressPerHour = (progressDelta > 0) ? progressDelta / (
double
)timeDelta * 1000 * 3600 : 0;
120
remainingMSecs = (progressDelta > 0) ? remainingProgress / progressDelta * timeDelta : -1;
121
break
;
122
}
123
}
124
// show progress increase per hour
125
ui
->progressIncreasePerH->setText(QString::number(progressPerHour * 100,
'f'
, 2)+
"%"
);
126
127
// show expected remaining time
128
if
(remainingMSecs >= 0) {
129
ui
->expectedTimeLeft->setText(
GUIUtil::formatNiceTimeOffset
(remainingMSecs / 1000.0));
130
}
else
{
131
ui
->expectedTimeLeft->setText(QObject::tr(
"unknown"
));
132
}
133
134
static
const
int
MAX_SAMPLES = 5000;
135
if
(
blockProcessTime
.count() > MAX_SAMPLES) {
136
blockProcessTime
.remove(MAX_SAMPLES,
blockProcessTime
.count() - MAX_SAMPLES);
137
}
138
}
139
140
// show the last block date
141
ui
->newestBlockDate->setText(blockDate.toString());
142
143
// show the percentage done according to nVerificationProgress
144
ui
->percentageProgress->setText(QString::number(nVerificationProgress*100,
'f'
, 2)+
"%"
);
145
146
if
(!
bestHeaderDate
.isValid())
147
// not syncing
148
return
;
149
150
// estimate the number of headers left based on nPowTargetSpacing
151
// and check if the gui is not aware of the best header (happens rarely)
152
int
estimateNumHeadersLeft =
bestHeaderDate
.secsTo(currentDate) /
Params
().
GetConsensus
().
nPowTargetSpacing
;
153
bool
hasBestHeader =
bestHeaderHeight
>=
count
;
154
155
// show remaining number of blocks
156
if
(estimateNumHeadersLeft <
HEADER_HEIGHT_DELTA_SYNC
&& hasBestHeader) {
157
ui
->numberOfBlocksLeft->setText(QString::number(
bestHeaderHeight
-
count
));
158
}
else
{
159
UpdateHeaderSyncLabel
();
160
ui
->expectedTimeLeft->setText(tr(
"Unknown…"
));
161
}
162
}
163
164
void
ModalOverlay::UpdateHeaderSyncLabel
() {
165
int
est_headers_left =
bestHeaderDate
.secsTo(QDateTime::currentDateTime()) /
Params
().
GetConsensus
().
nPowTargetSpacing
;
166
ui
->numberOfBlocksLeft->setText(tr(
"Unknown. Syncing Headers (%1, %2%)…"
).arg(
bestHeaderHeight
).arg(QString::number(100.0 / (
bestHeaderHeight
+ est_headers_left) *
bestHeaderHeight
,
'f'
, 1)));
167
}
168
169
void
ModalOverlay::UpdateHeaderPresyncLabel
(
int
height,
const
QDateTime& blockDate) {
170
int
est_headers_left = blockDate.secsTo(QDateTime::currentDateTime()) /
Params
().
GetConsensus
().
nPowTargetSpacing
;
171
ui
->numberOfBlocksLeft->setText(tr(
"Unknown. Pre-syncing Headers (%1, %2%)…"
).arg(height).arg(QString::number(100.0 / (height + est_headers_left) * height,
'f'
, 1)));
172
}
173
174
void
ModalOverlay::toggleVisibility
()
175
{
176
showHide
(
layerIsVisible
,
true
);
177
if
(!
layerIsVisible
)
178
userClosed
=
true
;
179
}
180
181
void
ModalOverlay::showHide
(
bool
hide,
bool
userRequested)
182
{
183
if
( (
layerIsVisible
&& !hide) || (!
layerIsVisible
&& hide) || (!hide &&
userClosed
&& !userRequested))
184
return
;
185
186
Q_EMIT
triggered
(hide);
187
188
if
(!isVisible() && !hide)
189
setVisible(
true
);
190
191
m_animation
.setStartValue(QPoint(0, hide ? 0 : height()));
192
// The eventFilter() updates the endValue if it is required for QEvent::Resize.
193
m_animation
.setEndValue(QPoint(0, hide ? height() : 0));
194
m_animation
.start(QAbstractAnimation::KeepWhenStopped);
195
layerIsVisible
= !hide;
196
197
if
(
layerIsVisible
) {
198
ui
->closeButton->setFocus(Qt::OtherFocusReason);
199
}
200
}
201
202
void
ModalOverlay::closeClicked
()
203
{
204
showHide
(
true
);
205
userClosed
=
true
;
206
}
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition
chainparams.cpp:112
CChainParams::GetConsensus
const Consensus::Params & GetConsensus() const
Definition
chainparams.h:89
ModalOverlay::showHide
void showHide(bool hide=false, bool userRequested=false)
Definition
modaloverlay.cpp:181
ModalOverlay::event
bool event(QEvent *ev) override
Tracks parent widget changes.
Definition
modaloverlay.cpp:73
ModalOverlay::userClosed
bool userClosed
Definition
modaloverlay.h:52
ModalOverlay::tipUpdate
void tipUpdate(int count, const QDateTime &blockDate, double nVerificationProgress)
Definition
modaloverlay.cpp:98
ModalOverlay::UpdateHeaderSyncLabel
void UpdateHeaderSyncLabel()
Definition
modaloverlay.cpp:164
ModalOverlay::ModalOverlay
ModalOverlay(bool enable_wallet, QWidget *parent)
Definition
modaloverlay.cpp:17
ModalOverlay::toggleVisibility
void toggleVisibility()
Definition
modaloverlay.cpp:174
ModalOverlay::bestHeaderDate
QDateTime bestHeaderDate
Definition
modaloverlay.h:49
ModalOverlay::~ModalOverlay
~ModalOverlay()
Definition
modaloverlay.cpp:43
ModalOverlay::layerIsVisible
bool layerIsVisible
Definition
modaloverlay.h:51
ModalOverlay::triggered
void triggered(bool hidden)
ModalOverlay::ui
Ui::ModalOverlay * ui
Definition
modaloverlay.h:47
ModalOverlay::closeClicked
void closeClicked()
Definition
modaloverlay.cpp:202
ModalOverlay::setKnownBestHeight
void setKnownBestHeight(int count, const QDateTime &blockDate, bool presync)
Definition
modaloverlay.cpp:86
ModalOverlay::blockProcessTime
QVector< QPair< qint64, double > > blockProcessTime
Definition
modaloverlay.h:50
ModalOverlay::bestHeaderHeight
int bestHeaderHeight
Definition
modaloverlay.h:48
ModalOverlay::eventFilter
bool eventFilter(QObject *obj, QEvent *ev) override
Definition
modaloverlay.cpp:48
ModalOverlay::UpdateHeaderPresyncLabel
void UpdateHeaderPresyncLabel(int height, const QDateTime &blockDate)
Definition
modaloverlay.cpp:169
ModalOverlay::m_animation
QPropertyAnimation m_animation
Definition
modaloverlay.h:53
guiutil.h
modaloverlay.h
HEADER_HEIGHT_DELTA_SYNC
static constexpr int HEADER_HEIGHT_DELTA_SYNC
The required delta of headers to the estimated number of available headers until we show the IBD prog...
Definition
modaloverlay.h:13
GUIUtil::formatNiceTimeOffset
QString formatNiceTimeOffset(qint64 secs)
Definition
guiutil.cpp:782
Ui
Definition
addressbookpage.h:14
Consensus::Params::nPowTargetSpacing
int64_t nPowTargetSpacing
Definition
params.h:120
count
static int count
Definition
tests_exhaustive.c:34
Generated on
for Bitcoin Core by
1.17.0