LCOV - code coverage report
Current view: top level - src/qt - modaloverlay.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 118 0.0 %
Date: 2020-09-26 01:30:44 Functions: 0 13 0.0 %

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

Generated by: LCOV version 1.15