bitcoin/src/qt/splashscreen.cpp
MarcoFalke 0a267f4eb8
Merge bitcoin-core/gui#46: refactor: Fix deprecation warnings when building against Qt 5.15
705c1f0648 qt, refactor: Fix 'buttonClicked is deprecated' warnings (Hennadii Stepanov)
c2f4e5ea1d qt, refactor: Fix 'split is deprecated' warnings (Hennadii Stepanov)
8e12d69961 qt, refactor: Fix 'QFlags is deprecated' warnings (Hennadii Stepanov)
fa5749c805 qt, refactor: Fix 'pixmap is deprecated' warnings (Hennadii Stepanov)
b02264cb5d qt, refactor: Fix 'QDateTime is deprecated' warnings (Hennadii Stepanov)

Pull request description:

  [What's New in Qt 5.15](https://doc.qt.io/qt-5/whatsnew515.html#deprecated-modules):
  > To help preparing for the transition to Qt 6, numerous classes and member functions that will be removed from Qt 6.0 have been marked as deprecated in the Qt 5.15 release.

  Fixes #36

ACKs for top commit:
  jonasschnelli:
    utACK 705c1f0648
  promag:
    Tested ACK 705c1f0648 on macos with Apple clang version 11.0.3 (clang-1103.0.32.62) and brew qt 5.15.1.

Tree-SHA512: 29e00535b4583ceec0dfb29612e86ee29bdea13651b548c6d22167917a4a10464af49160a12b05151030699f690f437ebb9c4ae9f130f66a722415222165b44f
2020-11-19 19:04:22 +01:00

241 lines
8 KiB
C++

// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <qt/splashscreen.h>
#include <clientversion.h>
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <qt/guiutil.h>
#include <qt/networkstyle.h>
#include <qt/walletmodel.h>
#include <util/system.h>
#include <util/translation.h>
#include <QApplication>
#include <QCloseEvent>
#include <QPainter>
#include <QRadialGradient>
#include <QScreen>
SplashScreen::SplashScreen(const NetworkStyle* networkStyle)
: QWidget(), curAlignment(0)
{
// set reference point, paddings
int paddingRight = 50;
int paddingTop = 50;
int titleVersionVSpace = 17;
int titleCopyrightVSpace = 40;
float fontFactor = 1.0;
float devicePixelRatio = 1.0;
devicePixelRatio = static_cast<QGuiApplication*>(QCoreApplication::instance())->devicePixelRatio();
// define text to place
QString titleText = PACKAGE_NAME;
QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
QString copyrightText = QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR)).c_str());
QString titleAddText = networkStyle->getTitleAddText();
QString font = QApplication::font().toString();
// 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);
QPainter pixPaint(&pixmap);
pixPaint.setPen(QColor(100,100,100));
// draw a slightly radial gradient
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);
QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize));
pixPaint.drawPixmap(rectIcon, icon);
// check font size and drawing with
pixPaint.setFont(QFont(font, 33*fontFactor));
QFontMetrics fm = pixPaint.fontMetrics();
int titleTextWidth = GUIUtil::TextWidth(fm, titleText);
if (titleTextWidth > 176) {
fontFactor = fontFactor * 176 / titleTextWidth;
}
pixPaint.setFont(QFont(font, 33*fontFactor));
fm = pixPaint.fontMetrics();
titleTextWidth = GUIUtil::TextWidth(fm, titleText);
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
pixPaint.setFont(QFont(font, 15*fontFactor));
// if the version string is too long, reduce size
fm = pixPaint.fontMetrics();
int versionTextWidth = GUIUtil::TextWidth(fm, versionText);
if(versionTextWidth > titleTextWidth+paddingRight-10) {
pixPaint.setFont(QFont(font, 10*fontFactor));
titleVersionVSpace -= 5;
}
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
// draw copyright stuff
{
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);
}
// draw additional text if special network
if(!titleAddText.isEmpty()) {
QFont boldFont = QFont(font, 10*fontFactor);
boldFont.setWeight(QFont::Bold);
pixPaint.setFont(boldFont);
fm = pixPaint.fontMetrics();
int titleAddTextWidth = GUIUtil::TextWidth(fm, titleAddText);
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
}
pixPaint.end();
// Set window title
setWindowTitle(titleText + " " + titleAddText);
// Resize window and move to center of desktop, disallow resizing
QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
resize(r.size());
setFixedSize(r.size());
move(QGuiApplication::primaryScreen()->geometry().center() - r.center());
installEventFilter(this);
GUIUtil::handleCloseWindowShortcut(this);
}
SplashScreen::~SplashScreen()
{
if (m_node) unsubscribeFromCoreSignals();
}
void SplashScreen::setNode(interfaces::Node& node)
{
assert(!m_node);
m_node = &node;
subscribeToCoreSignals();
if (m_shutdown) m_node->startShutdown();
}
void SplashScreen::shutdown()
{
m_shutdown = true;
if (m_node) m_node->startShutdown();
}
bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
if (ev->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
if (keyEvent->key() == Qt::Key_Q) {
shutdown();
}
}
return QObject::eventFilter(obj, ev);
}
void SplashScreen::finish()
{
/* If the window is minimized, hide() will be ignored. */
/* Make sure we de-minimize the splashscreen window before hiding */
if (isMinimized())
showNormal();
hide();
deleteLater(); // No more need for this
}
static void InitMessage(SplashScreen *splash, const std::string &message)
{
bool invoked = QMetaObject::invokeMethod(splash, "showMessage",
Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(message)),
Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
Q_ARG(QColor, QColor(55,55,55)));
assert(invoked);
}
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible)
{
InitMessage(splash, title + std::string("\n") +
(resume_possible ? _("(press q to shutdown and continue later)").translated
: _("press q to shutdown").translated) +
strprintf("\n%d", nProgress) + "%");
}
void SplashScreen::subscribeToCoreSignals()
{
// Connect signals to client
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));
}
void SplashScreen::handleLoadWallet()
{
#ifdef ENABLE_WALLET
if (!WalletModel::isWalletEnabled()) return;
m_handler_load_wallet = m_node->walletClient().handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
m_connected_wallet_handlers.emplace_back(wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, false)));
m_connected_wallets.emplace_back(std::move(wallet));
});
#endif
}
void SplashScreen::unsubscribeFromCoreSignals()
{
// Disconnect signals from client
m_handler_init_message->disconnect();
m_handler_show_progress->disconnect();
for (const auto& handler : m_connected_wallet_handlers) {
handler->disconnect();
}
m_connected_wallet_handlers.clear();
m_connected_wallets.clear();
}
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);
}
void SplashScreen::closeEvent(QCloseEvent *event)
{
shutdown(); // allows an "emergency" shutdown during startup
event->ignore();
}