2018-07-27 00:36:45 +02:00
|
|
|
// Copyright (c) 2011-2018 The Bitcoin Core developers
|
2014-12-13 05:09:33 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-11-04 16:20:43 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2015-12-09 11:53:12 +01:00
|
|
|
#if defined(HAVE_CONFIG_H)
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <config/bitcoin-config.h>
|
2015-12-09 11:53:12 +01:00
|
|
|
#endif
|
|
|
|
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <qt/splashscreen.h>
|
2013-04-13 07:13:08 +02:00
|
|
|
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <qt/networkstyle.h>
|
2015-01-30 10:08:46 +01:00
|
|
|
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <clientversion.h>
|
2018-04-07 09:42:02 +02:00
|
|
|
#include <interfaces/handler.h>
|
|
|
|
#include <interfaces/node.h>
|
|
|
|
#include <interfaces/wallet.h>
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <ui_interface.h>
|
2018-10-23 00:51:11 +02:00
|
|
|
#include <util/system.h>
|
2019-06-17 09:56:52 +02:00
|
|
|
#include <util/translation.h>
|
2017-11-10 01:57:53 +01:00
|
|
|
#include <version.h>
|
2014-09-05 13:18:35 +02:00
|
|
|
|
2013-04-14 11:35:37 +02:00
|
|
|
#include <QApplication>
|
2014-09-22 10:08:47 +02:00
|
|
|
#include <QCloseEvent>
|
2014-09-18 13:14:38 +02:00
|
|
|
#include <QDesktopWidget>
|
2014-09-22 10:08:47 +02:00
|
|
|
#include <QPainter>
|
2014-11-06 16:28:29 +01:00
|
|
|
#include <QRadialGradient>
|
2013-04-14 11:35:37 +02:00
|
|
|
|
2018-08-13 22:13:29 +02:00
|
|
|
|
2018-04-07 09:42:02 +02:00
|
|
|
SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) :
|
2018-07-31 20:02:34 +02:00
|
|
|
QWidget(nullptr, f), curAlignment(0), m_node(node)
|
2013-04-14 11:35:37 +02:00
|
|
|
{
|
|
|
|
// set reference point, paddings
|
|
|
|
int paddingRight = 50;
|
|
|
|
int paddingTop = 50;
|
|
|
|
int titleVersionVSpace = 17;
|
|
|
|
int titleCopyrightVSpace = 40;
|
|
|
|
|
|
|
|
float fontFactor = 1.0;
|
2014-11-06 16:28:29 +01:00
|
|
|
float devicePixelRatio = 1.0;
|
2017-06-01 16:13:35 +02:00
|
|
|
devicePixelRatio = static_cast<QGuiApplication*>(QCoreApplication::instance())->devicePixelRatio();
|
2013-04-14 11:35:37 +02:00
|
|
|
|
|
|
|
// define text to place
|
2019-06-26 16:28:13 +02:00
|
|
|
QString titleText = PACKAGE_NAME;
|
2013-04-14 11:35:37 +02:00
|
|
|
QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
|
2016-02-03 06:38:27 +01:00
|
|
|
QString copyrightText = QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR)).c_str());
|
2014-10-09 11:04:49 +02:00
|
|
|
QString titleAddText = networkStyle->getTitleAddText();
|
2013-04-14 11:35:37 +02:00
|
|
|
|
2015-01-16 22:27:12 +01:00
|
|
|
QString font = QApplication::font().toString();
|
2013-04-14 11:35:37 +02:00
|
|
|
|
2014-11-06 16:28:29 +01:00
|
|
|
// create a bitmap according to device pixelratio
|
|
|
|
QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
|
|
|
|
pixmap = QPixmap(splashSize);
|
|
|
|
|
|
|
|
// change to HiDPI if it makes sense
|
|
|
|
pixmap.setDevicePixelRatio(devicePixelRatio);
|
2013-04-14 11:35:37 +02:00
|
|
|
|
2014-09-18 13:14:38 +02:00
|
|
|
QPainter pixPaint(&pixmap);
|
2013-04-14 11:35:37 +02:00
|
|
|
pixPaint.setPen(QColor(100,100,100));
|
|
|
|
|
2015-08-09 01:17:27 +02:00
|
|
|
// draw a slightly radial gradient
|
2014-11-06 16:28:29 +01:00
|
|
|
QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
|
|
|
|
gradient.setColorAt(0, Qt::white);
|
|
|
|
gradient.setColorAt(1, QColor(247,247,247));
|
|
|
|
QRect rGradient(QPoint(0,0), splashSize);
|
|
|
|
pixPaint.fillRect(rGradient, gradient);
|
|
|
|
|
|
|
|
// draw the bitcoin icon, expected size of PNG: 1024x1024
|
|
|
|
QRect rectIcon(QPoint(-150,-122), QSize(430,430));
|
|
|
|
|
|
|
|
const QSize requiredSize(1024,1024);
|
2014-11-14 12:58:30 +01:00
|
|
|
QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize));
|
2014-11-06 16:28:29 +01:00
|
|
|
|
|
|
|
pixPaint.drawPixmap(rectIcon, icon);
|
|
|
|
|
2013-04-14 11:35:37 +02:00
|
|
|
// check font size and drawing with
|
|
|
|
pixPaint.setFont(QFont(font, 33*fontFactor));
|
|
|
|
QFontMetrics fm = pixPaint.fontMetrics();
|
2016-01-27 21:28:04 +01:00
|
|
|
int titleTextWidth = fm.width(titleText);
|
|
|
|
if (titleTextWidth > 176) {
|
|
|
|
fontFactor = fontFactor * 176 / titleTextWidth;
|
2013-04-14 11:35:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pixPaint.setFont(QFont(font, 33*fontFactor));
|
|
|
|
fm = pixPaint.fontMetrics();
|
|
|
|
titleTextWidth = fm.width(titleText);
|
2014-11-06 16:28:29 +01:00
|
|
|
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
|
2013-04-14 11:35:37 +02:00
|
|
|
|
|
|
|
pixPaint.setFont(QFont(font, 15*fontFactor));
|
|
|
|
|
2018-03-18 15:26:45 +01:00
|
|
|
// if the version string is too long, reduce size
|
2013-04-14 11:35:37 +02:00
|
|
|
fm = pixPaint.fontMetrics();
|
|
|
|
int versionTextWidth = fm.width(versionText);
|
|
|
|
if(versionTextWidth > titleTextWidth+paddingRight-10) {
|
|
|
|
pixPaint.setFont(QFont(font, 10*fontFactor));
|
|
|
|
titleVersionVSpace -= 5;
|
|
|
|
}
|
2014-11-06 16:28:29 +01:00
|
|
|
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
|
2013-04-14 11:35:37 +02:00
|
|
|
|
|
|
|
// draw copyright stuff
|
2016-02-03 06:38:27 +01:00
|
|
|
{
|
|
|
|
pixPaint.setFont(QFont(font, 10*fontFactor));
|
|
|
|
const int x = pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight;
|
|
|
|
const int y = paddingTop+titleCopyrightVSpace;
|
|
|
|
QRect copyrightRect(x, y, pixmap.width() - x - paddingRight, pixmap.height() - y);
|
|
|
|
pixPaint.drawText(copyrightRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, copyrightText);
|
|
|
|
}
|
2013-04-14 11:35:37 +02:00
|
|
|
|
2014-10-09 11:04:49 +02:00
|
|
|
// draw additional text if special network
|
|
|
|
if(!titleAddText.isEmpty()) {
|
2013-04-14 11:35:37 +02:00
|
|
|
QFont boldFont = QFont(font, 10*fontFactor);
|
|
|
|
boldFont.setWeight(QFont::Bold);
|
|
|
|
pixPaint.setFont(boldFont);
|
|
|
|
fm = pixPaint.fontMetrics();
|
2014-10-09 11:04:49 +02:00
|
|
|
int titleAddTextWidth = fm.width(titleAddText);
|
2014-11-06 16:28:29 +01:00
|
|
|
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
|
2013-04-14 11:35:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pixPaint.end();
|
|
|
|
|
2014-09-18 13:14:38 +02:00
|
|
|
// Set window title
|
2014-10-09 11:04:49 +02:00
|
|
|
setWindowTitle(titleText + " " + titleAddText);
|
2014-09-18 13:14:38 +02:00
|
|
|
|
|
|
|
// Resize window and move to center of desktop, disallow resizing
|
2014-11-06 16:28:29 +01:00
|
|
|
QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
|
2014-09-18 13:14:38 +02:00
|
|
|
resize(r.size());
|
|
|
|
setFixedSize(r.size());
|
|
|
|
move(QApplication::desktop()->screenGeometry().center() - r.center());
|
2014-01-08 08:59:24 +01:00
|
|
|
|
|
|
|
subscribeToCoreSignals();
|
2017-06-23 09:32:38 +02:00
|
|
|
installEventFilter(this);
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
SplashScreen::~SplashScreen()
|
|
|
|
{
|
|
|
|
unsubscribeFromCoreSignals();
|
|
|
|
}
|
|
|
|
|
2017-06-23 09:32:38 +02:00
|
|
|
bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
|
|
|
|
if (ev->type() == QEvent::KeyPress) {
|
|
|
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
|
2017-07-07 23:09:55 +02:00
|
|
|
if(keyEvent->text()[0] == 'q') {
|
2017-04-17 21:10:47 +02:00
|
|
|
m_node.startShutdown();
|
2017-06-23 09:32:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return QObject::eventFilter(obj, ev);
|
|
|
|
}
|
|
|
|
|
2018-12-02 00:26:28 +01:00
|
|
|
void SplashScreen::finish()
|
2014-01-08 08:59:24 +01:00
|
|
|
{
|
2016-06-21 10:54:57 +02:00
|
|
|
/* If the window is minimized, hide() will be ignored. */
|
|
|
|
/* Make sure we de-minimize the splashscreen window before hiding */
|
|
|
|
if (isMinimized())
|
|
|
|
showNormal();
|
2014-09-18 13:14:38 +02:00
|
|
|
hide();
|
2016-11-19 11:08:19 +01:00
|
|
|
deleteLater(); // No more need for this
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void InitMessage(SplashScreen *splash, const std::string &message)
|
|
|
|
{
|
2019-07-06 18:16:01 +02:00
|
|
|
bool invoked = QMetaObject::invokeMethod(splash, "showMessage",
|
2014-01-08 08:59:24 +01:00
|
|
|
Qt::QueuedConnection,
|
|
|
|
Q_ARG(QString, QString::fromStdString(message)),
|
|
|
|
Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
|
|
|
|
Q_ARG(QColor, QColor(55,55,55)));
|
2019-07-06 18:16:01 +02:00
|
|
|
assert(invoked);
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
|
|
|
|
2017-07-07 23:09:55 +02:00
|
|
|
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible)
|
2014-03-19 00:26:14 +01:00
|
|
|
{
|
2017-07-07 23:09:55 +02:00
|
|
|
InitMessage(splash, title + std::string("\n") +
|
|
|
|
(resume_possible ? _("(press q to shutdown and continue later)")
|
|
|
|
: _("press q to shutdown")) +
|
|
|
|
strprintf("\n%d", nProgress) + "%");
|
2017-06-23 09:32:38 +02:00
|
|
|
}
|
2014-03-19 00:26:14 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2018-04-07 09:42:02 +02:00
|
|
|
void SplashScreen::ConnectWallet(std::unique_ptr<interfaces::Wallet> wallet)
|
2014-03-19 00:26:14 +01:00
|
|
|
{
|
2018-10-17 17:51:17 +02:00
|
|
|
m_connected_wallet_handlers.emplace_back(wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, false)));
|
2017-04-17 21:10:47 +02:00
|
|
|
m_connected_wallets.emplace_back(std::move(wallet));
|
2014-03-19 00:26:14 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-01-08 08:59:24 +01:00
|
|
|
void SplashScreen::subscribeToCoreSignals()
|
|
|
|
{
|
|
|
|
// Connect signals to client
|
2018-10-17 17:51:17 +02:00
|
|
|
m_handler_init_message = m_node.handleInitMessage(std::bind(InitMessage, this, std::placeholders::_1));
|
|
|
|
m_handler_show_progress = m_node.handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
2014-03-19 00:26:14 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2018-04-07 09:42:02 +02:00
|
|
|
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) { ConnectWallet(std::move(wallet)); });
|
2014-03-19 00:26:14 +01:00
|
|
|
#endif
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SplashScreen::unsubscribeFromCoreSignals()
|
|
|
|
{
|
|
|
|
// Disconnect signals from client
|
2017-04-17 21:10:47 +02:00
|
|
|
m_handler_init_message->disconnect();
|
|
|
|
m_handler_show_progress->disconnect();
|
2018-06-18 07:58:28 +02:00
|
|
|
for (const auto& handler : m_connected_wallet_handlers) {
|
2017-04-17 21:10:47 +02:00
|
|
|
handler->disconnect();
|
2016-09-08 21:58:30 +02:00
|
|
|
}
|
2017-04-17 21:10:47 +02:00
|
|
|
m_connected_wallet_handlers.clear();
|
|
|
|
m_connected_wallets.clear();
|
2013-04-14 11:35:37 +02:00
|
|
|
}
|
2014-09-18 13:14:38 +02:00
|
|
|
|
|
|
|
void SplashScreen::showMessage(const QString &message, int alignment, const QColor &color)
|
|
|
|
{
|
|
|
|
curMessage = message;
|
|
|
|
curAlignment = alignment;
|
|
|
|
curColor = color;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplashScreen::paintEvent(QPaintEvent *event)
|
|
|
|
{
|
|
|
|
QPainter painter(this);
|
|
|
|
painter.drawPixmap(0, 0, pixmap);
|
|
|
|
QRect r = rect().adjusted(5, 5, -5, -5);
|
|
|
|
painter.setPen(curColor);
|
|
|
|
painter.drawText(r, curAlignment, curMessage);
|
|
|
|
}
|
|
|
|
|
2014-09-22 10:08:47 +02:00
|
|
|
void SplashScreen::closeEvent(QCloseEvent *event)
|
|
|
|
{
|
2017-04-17 21:10:47 +02:00
|
|
|
m_node.startShutdown(); // allows an "emergency" shutdown during startup
|
2014-09-22 10:08:47 +02:00
|
|
|
event->ignore();
|
|
|
|
}
|