Jonas Schnelli
8 years ago
6 changed files with 602 additions and 1 deletions
@ -0,0 +1,370 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<ui version="4.0"> |
||||||
|
<class>ModalOverlay</class> |
||||||
|
<widget class="ModalOverlay" name="ModalOverlay"> |
||||||
|
<property name="geometry"> |
||||||
|
<rect> |
||||||
|
<x>0</x> |
||||||
|
<y>0</y> |
||||||
|
<width>640</width> |
||||||
|
<height>385</height> |
||||||
|
</rect> |
||||||
|
</property> |
||||||
|
<property name="windowTitle"> |
||||||
|
<string>Form</string> |
||||||
|
</property> |
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0"> |
||||||
|
<property name="sizeConstraint"> |
||||||
|
<enum>QLayout::SetDefaultConstraint</enum> |
||||||
|
</property> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<property name="rightMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<property name="bottomMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<widget class="QWidget" name="bgWidget" native="true"> |
||||||
|
<property name="styleSheet"> |
||||||
|
<string notr="true">#bgWidget { background: rgba(0,0,0,220); }</string> |
||||||
|
</property> |
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutMain" stretch="1"> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>60</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>60</number> |
||||||
|
</property> |
||||||
|
<property name="rightMargin"> |
||||||
|
<number>60</number> |
||||||
|
</property> |
||||||
|
<property name="bottomMargin"> |
||||||
|
<number>60</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<widget class="QWidget" name="contentWidget" native="true"> |
||||||
|
<property name="styleSheet"> |
||||||
|
<string notr="true">#contentWidget { background: rgba(255,255,255,240); border-radius: 6px; } |
||||||
|
|
||||||
|
QLabel { color: rgb(40,40,40); }</string> |
||||||
|
</property> |
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutSub" stretch="1,0,0,0"> |
||||||
|
<property name="spacing"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<property name="rightMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<property name="bottomMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<layout class="QHBoxLayout" name="horizontalLayoutIconText" stretch="0,1"> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>20</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutIcon"> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<widget class="QPushButton" name="warningIcon"> |
||||||
|
<property name="text"> |
||||||
|
<string/> |
||||||
|
</property> |
||||||
|
<property name="icon"> |
||||||
|
<iconset> |
||||||
|
<normaloff>:/icons/warning</normaloff> |
||||||
|
<disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset> |
||||||
|
</property> |
||||||
|
<property name="iconSize"> |
||||||
|
<size> |
||||||
|
<width>48</width> |
||||||
|
<height>48</height> |
||||||
|
</size> |
||||||
|
</property> |
||||||
|
<property name="flat"> |
||||||
|
<bool>true</bool> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<spacer name="verticalSpacerWarningIcon"> |
||||||
|
<property name="orientation"> |
||||||
|
<enum>Qt::Vertical</enum> |
||||||
|
</property> |
||||||
|
<property name="sizeHint" stdset="0"> |
||||||
|
<size> |
||||||
|
<width>20</width> |
||||||
|
<height>40</height> |
||||||
|
</size> |
||||||
|
</property> |
||||||
|
</spacer> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutInfoText"> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>0</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<widget class="QLabel" name="infoText"> |
||||||
|
<property name="text"> |
||||||
|
<string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string> |
||||||
|
</property> |
||||||
|
<property name="textFormat"> |
||||||
|
<enum>Qt::RichText</enum> |
||||||
|
</property> |
||||||
|
<property name="wordWrap"> |
||||||
|
<bool>true</bool> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<widget class="QLabel" name="infoTextStrong"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>This means that recent transactions will not be visible, and the balance will not be up-to-date until this process has completed. Spending bitcoins is not possible during that phase!</string> |
||||||
|
</property> |
||||||
|
<property name="textFormat"> |
||||||
|
<enum>Qt::RichText</enum> |
||||||
|
</property> |
||||||
|
<property name="wordWrap"> |
||||||
|
<bool>true</bool> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<spacer name="verticalSpacerInTextSpace"> |
||||||
|
<property name="orientation"> |
||||||
|
<enum>Qt::Vertical</enum> |
||||||
|
</property> |
||||||
|
<property name="sizeHint" stdset="0"> |
||||||
|
<size> |
||||||
|
<width>20</width> |
||||||
|
<height>40</height> |
||||||
|
</size> |
||||||
|
</property> |
||||||
|
</spacer> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<spacer name="verticalSpacerAfterText"> |
||||||
|
<property name="orientation"> |
||||||
|
<enum>Qt::Vertical</enum> |
||||||
|
</property> |
||||||
|
<property name="sizeHint" stdset="0"> |
||||||
|
<size> |
||||||
|
<width>20</width> |
||||||
|
<height>40</height> |
||||||
|
</size> |
||||||
|
</property> |
||||||
|
</spacer> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<layout class="QFormLayout" name="formLayout"> |
||||||
|
<property name="fieldGrowthPolicy"> |
||||||
|
<enum>QFormLayout::FieldsStayAtSizeHint</enum> |
||||||
|
</property> |
||||||
|
<property name="horizontalSpacing"> |
||||||
|
<number>6</number> |
||||||
|
</property> |
||||||
|
<property name="verticalSpacing"> |
||||||
|
<number>6</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<item row="0" column="0"> |
||||||
|
<widget class="QLabel" name="labelAmoutOfBlocksLeft"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>Amount of blocks left</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="0" column="1"> |
||||||
|
<widget class="QLabel" name="amountOfBlocksLeft"> |
||||||
|
<property name="text"> |
||||||
|
<string>unknown...</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="1" column="0"> |
||||||
|
<widget class="QLabel" name="labelLastBlockTime"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>Last block time</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="1" column="1"> |
||||||
|
<widget class="QLabel" name="newestBlockDate"> |
||||||
|
<property name="sizePolicy"> |
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
||||||
|
<horstretch>0</horstretch> |
||||||
|
<verstretch>0</verstretch> |
||||||
|
</sizepolicy> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>unknown...</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="2" column="0"> |
||||||
|
<widget class="QLabel" name="labelSyncDone"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>Progress</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="2" column="1"> |
||||||
|
<layout class="QHBoxLayout" name="horizontalLayoutSync" stretch="0,1"> |
||||||
|
<item> |
||||||
|
<widget class="QLabel" name="percentageProgress"> |
||||||
|
<property name="text"> |
||||||
|
<string>~</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<widget class="QProgressBar" name="progressBar"> |
||||||
|
<property name="value"> |
||||||
|
<number>24</number> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
<item row="4" column="0"> |
||||||
|
<widget class="QLabel" name="labelProgressIncrease"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>Progress increase per Hour</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="4" column="1"> |
||||||
|
<widget class="QLabel" name="progressIncreasePerH"> |
||||||
|
<property name="text"> |
||||||
|
<string>calculating...</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="5" column="0"> |
||||||
|
<widget class="QLabel" name="labelEstimatedTimeLeft"> |
||||||
|
<property name="font"> |
||||||
|
<font> |
||||||
|
<weight>75</weight> |
||||||
|
<bold>true</bold> |
||||||
|
</font> |
||||||
|
</property> |
||||||
|
<property name="text"> |
||||||
|
<string>Estimated time left until synced</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
<item row="5" column="1"> |
||||||
|
<widget class="QLabel" name="expectedTimeLeft"> |
||||||
|
<property name="text"> |
||||||
|
<string>calculating...</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<layout class="QHBoxLayout" name="horizontalLayoutButtons"> |
||||||
|
<property name="leftMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<property name="topMargin"> |
||||||
|
<number>10</number> |
||||||
|
</property> |
||||||
|
<item> |
||||||
|
<spacer name="horizontalSpacer"> |
||||||
|
<property name="orientation"> |
||||||
|
<enum>Qt::Horizontal</enum> |
||||||
|
</property> |
||||||
|
<property name="sizeHint" stdset="0"> |
||||||
|
<size> |
||||||
|
<width>40</width> |
||||||
|
<height>20</height> |
||||||
|
</size> |
||||||
|
</property> |
||||||
|
</spacer> |
||||||
|
</item> |
||||||
|
<item> |
||||||
|
<widget class="QPushButton" name="closeButton"> |
||||||
|
<property name="text"> |
||||||
|
<string>Hide</string> |
||||||
|
</property> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</widget> |
||||||
|
</item> |
||||||
|
</layout> |
||||||
|
</widget> |
||||||
|
<customwidgets> |
||||||
|
<customwidget> |
||||||
|
<class>ModalOverlay</class> |
||||||
|
<extends>QWidget</extends> |
||||||
|
<header>modaloverlay.h</header> |
||||||
|
<container>1</container> |
||||||
|
</customwidget> |
||||||
|
</customwidgets> |
||||||
|
<resources/> |
||||||
|
<connections/> |
||||||
|
</ui> |
@ -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 <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) |
||||||
|
{ |
||||||
|
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<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 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; |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_QT_MODALOVERLAY_H |
||||||
|
#define BITCOIN_QT_MODALOVERLAY_H |
||||||
|
|
||||||
|
#include <QDateTime> |
||||||
|
#include <QWidget> |
||||||
|
|
||||||
|
namespace Ui { |
||||||
|
class ModalOverlay; |
||||||
|
} |
||||||
|
|
||||||
|
/** Modal overlay to display information about the chain-sync state */ |
||||||
|
class ModalOverlay : public QWidget |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
public: |
||||||
|
explicit ModalOverlay(QWidget *parent); |
||||||
|
~ModalOverlay(); |
||||||
|
|
||||||
|
public Q_SLOTS: |
||||||
|
void tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress); |
||||||
|
void setKnownBestHeight(int count); |
||||||
|
|
||||||
|
// will show or hide the modal layer
|
||||||
|
void showHide(bool hide = false, bool userRequested = false); |
||||||
|
void closeClicked(); |
||||||
|
|
||||||
|
protected: |
||||||
|
bool eventFilter(QObject * obj, QEvent * ev); |
||||||
|
bool event(QEvent* ev); |
||||||
|
|
||||||
|
private: |
||||||
|
Ui::ModalOverlay *ui; |
||||||
|
int bestBlockHeight; //best known height (based on the headers)
|
||||||
|
QVector<QPair<qint64, double> > blockProcessTime; |
||||||
|
bool layerIsVisible; |
||||||
|
bool userClosed; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // BITCOIN_QT_MODALOVERLAY_H
|
Loading…
Reference in new issue