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