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