Bitcoin Core  21.99.0
P2P Digital Currency
splashscreen.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-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 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <qt/splashscreen.h>
10 
11 #include <clientversion.h>
12 #include <interfaces/handler.h>
13 #include <interfaces/node.h>
14 #include <interfaces/wallet.h>
15 #include <qt/guiutil.h>
16 #include <qt/networkstyle.h>
17 #include <qt/walletmodel.h>
18 #include <util/system.h>
19 #include <util/translation.h>
20 
21 #include <functional>
22 
23 #include <QApplication>
24 #include <QCloseEvent>
25 #include <QPainter>
26 #include <QRadialGradient>
27 #include <QScreen>
28 
29 
31  : QWidget(), curAlignment(0)
32 {
33  // set reference point, paddings
34  int paddingRight = 50;
35  int paddingTop = 50;
36  int titleVersionVSpace = 17;
37  int titleCopyrightVSpace = 40;
38 
39  float fontFactor = 1.0;
40  float devicePixelRatio = 1.0;
41  devicePixelRatio = static_cast<QGuiApplication*>(QCoreApplication::instance())->devicePixelRatio();
42 
43  // define text to place
44  QString titleText = PACKAGE_NAME;
45  QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
46  QString copyrightText = QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR)).c_str());
47  QString titleAddText = networkStyle->getTitleAddText();
48 
49  QString font = QApplication::font().toString();
50 
51  // create a bitmap according to device pixelratio
52  QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
53  pixmap = QPixmap(splashSize);
54 
55  // change to HiDPI if it makes sense
56  pixmap.setDevicePixelRatio(devicePixelRatio);
57 
58  QPainter pixPaint(&pixmap);
59  pixPaint.setPen(QColor(100,100,100));
60 
61  // draw a slightly radial gradient
62  QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
63  gradient.setColorAt(0, Qt::white);
64  gradient.setColorAt(1, QColor(247,247,247));
65  QRect rGradient(QPoint(0,0), splashSize);
66  pixPaint.fillRect(rGradient, gradient);
67 
68  // draw the bitcoin icon, expected size of PNG: 1024x1024
69  QRect rectIcon(QPoint(-150,-122), QSize(430,430));
70 
71  const QSize requiredSize(1024,1024);
72  QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize));
73 
74  pixPaint.drawPixmap(rectIcon, icon);
75 
76  // check font size and drawing with
77  pixPaint.setFont(QFont(font, 33*fontFactor));
78  QFontMetrics fm = pixPaint.fontMetrics();
79  int titleTextWidth = GUIUtil::TextWidth(fm, titleText);
80  if (titleTextWidth > 176) {
81  fontFactor = fontFactor * 176 / titleTextWidth;
82  }
83 
84  pixPaint.setFont(QFont(font, 33*fontFactor));
85  fm = pixPaint.fontMetrics();
86  titleTextWidth = GUIUtil::TextWidth(fm, titleText);
87  pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
88 
89  pixPaint.setFont(QFont(font, 15*fontFactor));
90 
91  // if the version string is too long, reduce size
92  fm = pixPaint.fontMetrics();
93  int versionTextWidth = GUIUtil::TextWidth(fm, versionText);
94  if(versionTextWidth > titleTextWidth+paddingRight-10) {
95  pixPaint.setFont(QFont(font, 10*fontFactor));
96  titleVersionVSpace -= 5;
97  }
98  pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
99 
100  // draw copyright stuff
101  {
102  pixPaint.setFont(QFont(font, 10*fontFactor));
103  const int x = pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight;
104  const int y = paddingTop+titleCopyrightVSpace;
105  QRect copyrightRect(x, y, pixmap.width() - x - paddingRight, pixmap.height() - y);
106  pixPaint.drawText(copyrightRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, copyrightText);
107  }
108 
109  // draw additional text if special network
110  if(!titleAddText.isEmpty()) {
111  QFont boldFont = QFont(font, 10*fontFactor);
112  boldFont.setWeight(QFont::Bold);
113  pixPaint.setFont(boldFont);
114  fm = pixPaint.fontMetrics();
115  int titleAddTextWidth = GUIUtil::TextWidth(fm, titleAddText);
116  pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
117  }
118 
119  pixPaint.end();
120 
121  // Set window title
122  setWindowTitle(titleText + " " + titleAddText);
123 
124  // Resize window and move to center of desktop, disallow resizing
125  QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
126  resize(r.size());
127  setFixedSize(r.size());
128  move(QGuiApplication::primaryScreen()->geometry().center() - r.center());
129 
130  installEventFilter(this);
131 
133 }
134 
136 {
138 }
139 
141 {
142  assert(!m_node);
143  m_node = &node;
146 }
147 
149 {
150  m_shutdown = true;
151  if (m_node) m_node->startShutdown();
152 }
153 
154 bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) {
155  if (ev->type() == QEvent::KeyPress) {
156  QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
157  if (keyEvent->key() == Qt::Key_Q) {
158  shutdown();
159  }
160  }
161  return QObject::eventFilter(obj, ev);
162 }
163 
165 {
166  /* If the window is minimized, hide() will be ignored. */
167  /* Make sure we de-minimize the splashscreen window before hiding */
168  if (isMinimized())
169  showNormal();
170  hide();
171  deleteLater(); // No more need for this
172 }
173 
174 static void InitMessage(SplashScreen *splash, const std::string &message)
175 {
176  bool invoked = QMetaObject::invokeMethod(splash, "showMessage",
177  Qt::QueuedConnection,
178  Q_ARG(QString, QString::fromStdString(message)),
179  Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
180  Q_ARG(QColor, QColor(55,55,55)));
181  assert(invoked);
182 }
183 
184 static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible)
185 {
186  InitMessage(splash, title + std::string("\n") +
187  (resume_possible ? _("(press q to shutdown and continue later)").translated
188  : _("press q to shutdown").translated) +
189  strprintf("\n%d", nProgress) + "%");
190 }
191 
193 {
194  // Connect signals to client
195  m_handler_init_message = m_node->handleInitMessage(std::bind(InitMessage, this, std::placeholders::_1));
196  m_handler_show_progress = m_node->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
197 }
198 
200 {
201 #ifdef ENABLE_WALLET
202  if (!WalletModel::isWalletEnabled()) return;
203  m_handler_load_wallet = m_node->walletClient().handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
204  m_connected_wallet_handlers.emplace_back(wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, false)));
205  m_connected_wallets.emplace_back(std::move(wallet));
206  });
207 #endif
208 }
209 
211 {
212  // Disconnect signals from client
213  m_handler_init_message->disconnect();
214  m_handler_show_progress->disconnect();
215  for (const auto& handler : m_connected_wallet_handlers) {
216  handler->disconnect();
217  }
219  m_connected_wallets.clear();
220 }
221 
222 void SplashScreen::showMessage(const QString &message, int alignment, const QColor &color)
223 {
224  curMessage = message;
225  curAlignment = alignment;
226  curColor = color;
227  update();
228 }
229 
230 void SplashScreen::paintEvent(QPaintEvent *event)
231 {
232  QPainter painter(this);
233  painter.drawPixmap(0, 0, pixmap);
234  QRect r = rect().adjusted(5, 5, -5, -5);
235  painter.setPen(curColor);
236  painter.drawText(r, curAlignment, curMessage);
237 }
238 
239 void SplashScreen::closeEvent(QCloseEvent *event)
240 {
241  shutdown(); // allows an "emergency" shutdown during startup
242  event->ignore();
243 }
CopyrightHolders
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1341
SplashScreen::curAlignment
int curAlignment
Definition: splashscreen.h:63
interfaces::Node::handleShowProgress
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
SplashScreen::m_connected_wallet_handlers
std::list< std::unique_ptr< interfaces::Handler > > m_connected_wallet_handlers
Definition: splashscreen.h:71
SplashScreen::setNode
void setNode(interfaces::Node &node)
Definition: splashscreen.cpp:140
interfaces::Node::handleInitMessage
virtual std::unique_ptr< Handler > handleInitMessage(InitMessageFn fn)=0
SplashScreen::m_shutdown
bool m_shutdown
Definition: splashscreen.h:66
InitMessage
static void InitMessage(SplashScreen *splash, const std::string &message)
Definition: splashscreen.cpp:174
handler
bool(* handler)(const std::any &context, HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:683
walletmodel.h
SplashScreen::finish
void finish()
Hide the splash screen window and schedule the splash screen object for deletion.
Definition: splashscreen.cpp:164
WalletModel::isWalletEnabled
static bool isWalletEnabled()
Definition: walletmodel.cpp:574
handler.h
SplashScreen::paintEvent
void paintEvent(QPaintEvent *event) override
Definition: splashscreen.cpp:230
ShowProgress
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible)
Definition: splashscreen.cpp:184
NetworkStyle
Definition: networkstyle.h:13
clientversion.h
wallet
Definition: interfaces.cpp:47
SplashScreen::handleLoadWallet
void handleLoadWallet()
Handle wallet load notifications.
Definition: splashscreen.cpp:199
bitcoin-config.h
SplashScreen::eventFilter
bool eventFilter(QObject *obj, QEvent *ev) override
Definition: splashscreen.cpp:154
interfaces::WalletClient::handleLoadWallet
virtual std::unique_ptr< Handler > handleLoadWallet(LoadWalletFn fn)=0
SplashScreen::unsubscribeFromCoreSignals
void unsubscribeFromCoreSignals()
Disconnect core signals to splash screen.
Definition: splashscreen.cpp:210
SplashScreen::m_handler_init_message
std::unique_ptr< interfaces::Handler > m_handler_init_message
Definition: splashscreen.h:67
SplashScreen::~SplashScreen
~SplashScreen()
Definition: splashscreen.cpp:135
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:365
node.h
interfaces::Node::startShutdown
virtual void startShutdown()=0
Start shutdown.
SplashScreen::SplashScreen
SplashScreen(const NetworkStyle *networkStyle)
Definition: splashscreen.cpp:30
interfaces::Node::walletClient
virtual WalletClient & walletClient()=0
Get wallet client.
SplashScreen::subscribeToCoreSignals
void subscribeToCoreSignals()
Connect core signals to splash screen.
Definition: splashscreen.cpp:192
SplashScreen::m_connected_wallets
std::list< std::unique_ptr< interfaces::Wallet > > m_connected_wallets
Definition: splashscreen.h:70
guiutil.h
SplashScreen::m_handler_show_progress
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: splashscreen.h:68
SplashScreen::curMessage
QString curMessage
Definition: splashscreen.h:61
SplashScreen::showMessage
void showMessage(const QString &message, int alignment, const QColor &color)
Show message and progress.
Definition: splashscreen.cpp:222
interfaces::Node
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:53
SplashScreen::m_node
interfaces::Node * m_node
Definition: splashscreen.h:65
SplashScreen::pixmap
QPixmap pixmap
Definition: splashscreen.h:60
NetworkStyle::getTitleAddText
const QString & getTitleAddText() const
Definition: networkstyle.h:22
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
SplashScreen
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:26
translation.h
splashscreen.h
networkstyle.h
node
Definition: interfaces.cpp:66
SplashScreen::curColor
QColor curColor
Definition: splashscreen.h:62
wallet.h
GUIUtil::TextWidth
int TextWidth(const QFontMetrics &fm, const QString &text)
Returns the distance in pixels appropriate for drawing a subsequent character after text.
Definition: guiutil.cpp:821
SplashScreen::closeEvent
void closeEvent(QCloseEvent *event) override
Definition: splashscreen.cpp:239
GUIUtil::handleCloseWindowShortcut
void handleCloseWindowShortcut(QWidget *w)
Definition: guiutil.cpp:395
SplashScreen::shutdown
void shutdown()
Initiate shutdown.
Definition: splashscreen.cpp:148
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:50
NetworkStyle::getAppIcon
const QIcon & getAppIcon() const
Definition: networkstyle.h:20
COPYRIGHT_YEAR
#define COPYRIGHT_YEAR
Definition: bitcoin-config.h:36
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
SplashScreen::m_handler_load_wallet
std::unique_ptr< interfaces::Handler > m_handler_load_wallet
Definition: splashscreen.h:69