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