From e3245b43d5c6fc984e8c60495f6db54f85d64368 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 19 Jul 2016 15:51:24 +0200 Subject: [Qt] add out-of-sync modal info layer --- src/qt/modaloverlay.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/qt/modaloverlay.cpp (limited to 'src/qt/modaloverlay.cpp') diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp new file mode 100644 index 0000000000..1cd5b19966 --- /dev/null +++ b/src/qt/modaloverlay.cpp @@ -0,0 +1,150 @@ +// 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 +#include + +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(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) +{ + 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) + { + // try to get the window from the last 500 seconds or at least 10 samples + 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 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 int maxSamples = 5000; + if (blockProcessTime.count() > maxSamples) + blockProcessTime.remove(maxSamples, blockProcessTime.count()-maxSamples); + } + + // 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)); +} + +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; +} -- cgit v1.2.3 From d8b062ef5eea3addff00a09bad1dab162452b4b5 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 13 Sep 2016 16:36:24 +0200 Subject: [Qt] only update "amount of blocks left" when the header chain is in-sync --- src/qt/modaloverlay.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/qt/modaloverlay.cpp') diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 1cd5b19966..c548890391 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -63,10 +63,17 @@ bool ModalOverlay::event(QEvent* ev) { return QWidget::event(ev); } -void ModalOverlay::setKnownBestHeight(int count) +void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate) { - if (count > bestBlockHeight) - bestBlockHeight = count; + + /* 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) @@ -122,6 +129,8 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri // 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) -- cgit v1.2.3 From 08827df3ecce925928dc3bedcdef63bfca290300 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 21 Sep 2016 10:29:57 +0200 Subject: [Qt] modalinfolayer: removed unused comments, renamed signal, code style overhaul --- src/qt/modaloverlay.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/qt/modaloverlay.cpp') diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index c548890391..7b121e9e88 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -86,7 +86,6 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri // show progress speed if we have more then one sample if (blockProcessTime.size() >= 2) { - // try to get the window from the last 500 seconds or at least 10 samples double progressStart = blockProcessTime[0].second; double progressDelta = 0; double progressPerHour = 0; @@ -114,9 +113,9 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri ui->expectedTimeLeft->setText(GUIUtil::formateNiceTimeOffset(remainingMSecs/1000.0)); // keep maximal 5000 samples - static int maxSamples = 5000; - if (blockProcessTime.count() > maxSamples) - blockProcessTime.remove(maxSamples, blockProcessTime.count()-maxSamples); + static const int MAX_SAMPLES = 5000; + if (blockProcessTime.count() > MAX_SAMPLES) + blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count()-MAX_SAMPLES); } // show the last block date -- cgit v1.2.3