Bitcoin Core  22.99.0
P2P Digital Currency
bitcoin.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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/bitcoin.h>
10 
11 #include <chainparams.h>
12 #include <init.h>
13 #include <interfaces/handler.h>
14 #include <interfaces/init.h>
15 #include <interfaces/node.h>
16 #include <node/ui_interface.h>
17 #include <noui.h>
18 #include <qt/bitcoingui.h>
19 #include <qt/clientmodel.h>
20 #include <qt/guiconstants.h>
21 #include <qt/guiutil.h>
22 #include <qt/initexecutor.h>
23 #include <qt/intro.h>
24 #include <qt/networkstyle.h>
25 #include <qt/optionsmodel.h>
26 #include <qt/platformstyle.h>
27 #include <qt/splashscreen.h>
28 #include <qt/utilitydialog.h>
29 #include <qt/winshutdownmonitor.h>
30 #include <uint256.h>
31 #include <util/string.h>
32 #include <util/system.h>
33 #include <util/threadnames.h>
34 #include <util/translation.h>
35 #include <validation.h>
36 
37 #ifdef ENABLE_WALLET
38 #include <qt/paymentserver.h>
39 #include <qt/walletcontroller.h>
40 #include <qt/walletmodel.h>
41 #endif // ENABLE_WALLET
42 
43 #include <boost/signals2/connection.hpp>
44 #include <chrono>
45 #include <memory>
46 
47 #include <QApplication>
48 #include <QDebug>
49 #include <QLatin1String>
50 #include <QLibraryInfo>
51 #include <QLocale>
52 #include <QMessageBox>
53 #include <QSettings>
54 #include <QThread>
55 #include <QTimer>
56 #include <QTranslator>
57 #include <QWindow>
58 
59 #if defined(QT_STATICPLUGIN)
60 #include <QtPlugin>
61 #if defined(QT_QPA_PLATFORM_XCB)
62 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
63 #elif defined(QT_QPA_PLATFORM_WINDOWS)
64 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
65 Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin);
66 #elif defined(QT_QPA_PLATFORM_COCOA)
67 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
68 Q_IMPORT_PLUGIN(QMacStylePlugin);
69 #elif defined(QT_QPA_PLATFORM_ANDROID)
70 Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
71 #endif
72 #endif
73 
74 // Declare meta types used for QMetaObject::invokeMethod
75 Q_DECLARE_METATYPE(bool*)
76 Q_DECLARE_METATYPE(CAmount)
77 Q_DECLARE_METATYPE(SynchronizationState)
78 Q_DECLARE_METATYPE(uint256)
79 
80 using node::NodeContext;
81 
82 static void RegisterMetaTypes()
83 {
84  // Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection
85  qRegisterMetaType<bool*>();
86  qRegisterMetaType<SynchronizationState>();
87  #ifdef ENABLE_WALLET
88  qRegisterMetaType<WalletModel*>();
89  #endif
90  // Register typedefs (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType)
91  // IMPORTANT: if CAmount is no longer a typedef use the normal variant above (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1)
92  qRegisterMetaType<CAmount>("CAmount");
93  qRegisterMetaType<size_t>("size_t");
94 
95  qRegisterMetaType<std::function<void()>>("std::function<void()>");
96  qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
97  qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo");
98 }
99 
100 static QString GetLangTerritory()
101 {
102  QSettings settings;
103  // Get desired locale (e.g. "de_DE")
104  // 1) System default language
105  QString lang_territory = QLocale::system().name();
106  // 2) Language from QSettings
107  QString lang_territory_qsettings = settings.value("language", "").toString();
108  if(!lang_territory_qsettings.isEmpty())
109  lang_territory = lang_territory_qsettings;
110  // 3) -lang command line argument
111  lang_territory = QString::fromStdString(gArgs.GetArg("-lang", lang_territory.toStdString()));
112  return lang_territory;
113 }
114 
116 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
117 {
118  // Remove old translators
119  QApplication::removeTranslator(&qtTranslatorBase);
120  QApplication::removeTranslator(&qtTranslator);
121  QApplication::removeTranslator(&translatorBase);
122  QApplication::removeTranslator(&translator);
123 
124  // Get desired locale (e.g. "de_DE")
125  // 1) System default language
126  QString lang_territory = GetLangTerritory();
127 
128  // Convert to "de" only by truncating "_DE"
129  QString lang = lang_territory;
130  lang.truncate(lang_territory.lastIndexOf('_'));
131 
132  // Load language files for configured locale:
133  // - First load the translator for the base language, without territory
134  // - Then load the more specific locale translator
135 
136  // Load e.g. qt_de.qm
137  if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
138  QApplication::installTranslator(&qtTranslatorBase);
139 
140  // Load e.g. qt_de_DE.qm
141  if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
142  QApplication::installTranslator(&qtTranslator);
143 
144  // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
145  if (translatorBase.load(lang, ":/translations/"))
146  QApplication::installTranslator(&translatorBase);
147 
148  // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
149  if (translator.load(lang_territory, ":/translations/"))
150  QApplication::installTranslator(&translator);
151 }
152 
153 static bool InitSettings()
154 {
155  if (!gArgs.GetSettingsPath()) {
156  return true; // Do nothing if settings file disabled.
157  }
158 
159  std::vector<std::string> errors;
160  if (!gArgs.ReadSettingsFile(&errors)) {
161  std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be read");
162  std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
163  InitError(Untranslated(strprintf("%s:\n%s\n", error, MakeUnorderedList(errors))));
164 
165  QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Reset | QMessageBox::Abort);
166  /*: Explanatory text shown on startup when the settings file cannot be read.
167  Prompts user to make a choice between resetting or aborting. */
168  messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
169  messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
170  messagebox.setTextFormat(Qt::PlainText);
171  messagebox.setDefaultButton(QMessageBox::Reset);
172  switch (messagebox.exec()) {
173  case QMessageBox::Reset:
174  break;
175  case QMessageBox::Abort:
176  return false;
177  default:
178  assert(false);
179  }
180  }
181 
182  errors.clear();
183  if (!gArgs.WriteSettingsFile(&errors)) {
184  std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be written");
185  std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
186  InitError(Untranslated(strprintf("%s:\n%s\n", error, MakeUnorderedList(errors))));
187 
188  QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Ok);
189  /*: Explanatory text shown on startup when the settings file could not be written.
190  Prompts user to check that we have the ability to write to the file.
191  Explains that the user has the option of running without a settings file.*/
192  messagebox.setInformativeText(QObject::tr("A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
193  messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
194  messagebox.setTextFormat(Qt::PlainText);
195  messagebox.setDefaultButton(QMessageBox::Ok);
196  messagebox.exec();
197  return false;
198  }
199  return true;
200 }
201 
202 /* qDebug() message handler --> debug.log */
203 void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
204 {
205  Q_UNUSED(context);
206  if (type == QtDebugMsg) {
207  LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
208  } else {
209  LogPrintf("GUI: %s\n", msg.toStdString());
210  }
211 }
212 
213 static int qt_argc = 1;
214 static const char* qt_argv = "bitcoin-qt";
215 
217  QApplication(qt_argc, const_cast<char **>(&qt_argv)),
218  optionsModel(nullptr),
219  clientModel(nullptr),
220  window(nullptr),
221  pollShutdownTimer(nullptr),
222  returnValue(0),
223  platformStyle(nullptr)
224 {
225  // Qt runs setlocale(LC_ALL, "") on initialization.
227  setQuitOnLastWindowClosed(false);
228 }
229 
231 {
232  // UI per-platform customization
233  // This must be done inside the BitcoinApplication constructor, or after it, because
234  // PlatformStyle::instantiate requires a QApplication
235  std::string platformName;
236  platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM);
237  platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
238  if (!platformStyle) // Fall back to "other" if specified name not found
241 }
242 
244 {
245  m_executor.reset();
246 
247  delete window;
248  window = nullptr;
249  delete platformStyle;
250  platformStyle = nullptr;
251 }
252 
253 #ifdef ENABLE_WALLET
254 void BitcoinApplication::createPaymentServer()
255 {
256  paymentServer = new PaymentServer(this);
257 }
258 #endif
259 
261 {
262  optionsModel = new OptionsModel(this, resetSettings);
263 }
264 
266 {
267  window = new BitcoinGUI(node(), platformStyle, networkStyle, nullptr);
269 
270  pollShutdownTimer = new QTimer(window);
271  connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown);
272 }
273 
275 {
276  assert(!m_splash);
277  m_splash = new SplashScreen(networkStyle);
278  // We don't hold a direct pointer to the splash screen after creation, but the splash
279  // screen will take care of deleting itself when finish() happens.
280  m_splash->show();
282  connect(this, &BitcoinApplication::requestedShutdown, m_splash, &QWidget::close);
283 }
284 
286 {
287  assert(!m_node);
288  m_node = init.makeNode();
291 }
292 
294 {
295  return node().baseInitialize();
296 }
297 
299 {
300  assert(!m_executor);
301  m_executor.emplace(node());
302 
303  /* communication to and from thread */
305  connect(&m_executor.value(), &InitExecutor::shutdownResult, this, &QCoreApplication::quit);
309 }
310 
312 {
313  // Default printtoconsole to false for the GUI. GUI programs should not
314  // print to the console unnecessarily.
315  gArgs.SoftSetBoolArg("-printtoconsole", false);
316 
319 }
320 
322 {
323  optionsModel->SetPruneTargetGB(PruneMiBtoGB(prune_MiB), true);
324 }
325 
327 {
328  qDebug() << __func__ << ": Requesting initialize";
329  startThread();
330  Q_EMIT requestedInitialize();
331 }
332 
334 {
335  for (const auto w : QGuiApplication::topLevelWindows()) {
336  w->hide();
337  }
338 
339  // Show a simple window indicating shutdown status
340  // Do this first as some of the steps may take some time below,
341  // for example the RPC console may still be executing a command.
343 
344  qDebug() << __func__ << ": Requesting shutdown";
345 
346  // Must disconnect node signals otherwise current thread can deadlock since
347  // no event loop is running.
349  // Request node shutdown, which can interrupt long operations, like
350  // rescanning a wallet.
351  node().startShutdown();
352  // Unsetting the client model can cause the current thread to wait for node
353  // to complete an operation, like wait for a RPC execution to complete.
354  window->setClientModel(nullptr);
355  pollShutdownTimer->stop();
356 
357 #ifdef ENABLE_WALLET
358  // Delete wallet controller here manually, instead of relying on Qt object
359  // tracking (https://doc.qt.io/qt-5/objecttrees.html). This makes sure
360  // walletmodel m_handle_* notification handlers are deleted before wallets
361  // are unloaded, which can simplify wallet implementations. It also avoids
362  // these notifications having to be handled while GUI objects are being
363  // destroyed, making GUI code less fragile as well.
364  delete m_wallet_controller;
365  m_wallet_controller = nullptr;
366 #endif // ENABLE_WALLET
367 
368  delete clientModel;
369  clientModel = nullptr;
370 
371  // Request shutdown from core thread
372  Q_EMIT requestedShutdown();
373 }
374 
376 {
377  qDebug() << __func__ << ": Initialization result: " << success;
378  // Set exit result.
379  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
380  if(success)
381  {
382  // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
383  qInfo() << "Platform customization:" << platformStyle->getName();
385  window->setClientModel(clientModel, &tip_info);
386 #ifdef ENABLE_WALLET
388  m_wallet_controller = new WalletController(*clientModel, platformStyle, this);
389  window->setWalletController(m_wallet_controller);
390  if (paymentServer) {
391  paymentServer->setOptionsModel(optionsModel);
392  }
393  }
394 #endif // ENABLE_WALLET
395 
396  // If -min option passed, start window minimized (iconified) or minimized to tray
397  if (!gArgs.GetBoolArg("-min", false)) {
398  window->show();
400  // do nothing as the window is managed by the tray icon
401  } else {
402  window->showMinimized();
403  }
404  Q_EMIT splashFinished();
405  Q_EMIT windowShown(window);
406 
407 #ifdef ENABLE_WALLET
408  // Now that initialization/startup is done, process any command-line
409  // bitcoin: URIs or payment requests:
410  if (paymentServer) {
411  connect(paymentServer, &PaymentServer::receivedPaymentRequest, window, &BitcoinGUI::handlePaymentRequest);
413  connect(paymentServer, &PaymentServer::message, [this](const QString& title, const QString& message, unsigned int style) {
414  window->message(title, message, style);
415  });
416  QTimer::singleShot(100ms, paymentServer, &PaymentServer::uiReady);
417  }
418 #endif
420  } else {
421  Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown
422  requestShutdown();
423  }
424 }
425 
426 void BitcoinApplication::handleRunawayException(const QString &message)
427 {
428  QMessageBox::critical(
429  nullptr, tr("Runaway exception"),
430  tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) +
431  QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
432  ::exit(EXIT_FAILURE);
433 }
434 
436 {
437  assert(QThread::currentThread() == thread());
438  QMessageBox::warning(
439  nullptr, tr("Internal error"),
440  tr("An internal error occurred. %1 will attempt to continue safely. This is "
441  "an unexpected bug which can be reported as described below.").arg(PACKAGE_NAME) +
442  QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
443 }
444 
446 {
447  if (!window)
448  return 0;
449 
450  return window->winId();
451 }
452 
453 static void SetupUIArgs(ArgsManager& argsman)
454 {
455  argsman.AddArg("-choosedatadir", strprintf("Choose data directory on startup (default: %u)", DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
456  argsman.AddArg("-lang=<lang>", "Set language, for example \"de_DE\" (default: system locale)", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
457  argsman.AddArg("-min", "Start minimized", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
458  argsman.AddArg("-resetguisettings", "Reset all settings changed in the GUI", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
459  argsman.AddArg("-splash", strprintf("Show splash screen on startup (default: %u)", DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
460  argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI);
461 }
462 
463 int GuiMain(int argc, char* argv[])
464 {
465 #ifdef WIN32
466  util::WinCmdLineArgs winArgs;
467  std::tie(argc, argv) = winArgs.get();
468 #endif
469 
470  std::unique_ptr<interfaces::Init> init = interfaces::MakeGuiInit(argc, argv);
471 
474 
475  // Subscribe to global signals from core
476  boost::signals2::scoped_connection handler_message_box = ::uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
477  boost::signals2::scoped_connection handler_question = ::uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
478  boost::signals2::scoped_connection handler_init_message = ::uiInterface.InitMessage_connect(noui_InitMessage);
479 
480  // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
481 
483  Q_INIT_RESOURCE(bitcoin);
484  Q_INIT_RESOURCE(bitcoin_locale);
485 
486  // Generate high-dpi pixmaps
487  QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
488  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
489 
490 #if defined(QT_QPA_PLATFORM_ANDROID)
491  QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
492  QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
493  QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
494 #endif
495 
496  BitcoinApplication app;
497  GUIUtil::LoadFont(QStringLiteral(":/fonts/monospace"));
498 
500  // Command-line options take precedence:
503  std::string error;
504  if (!gArgs.ParseParameters(argc, argv, error)) {
505  InitError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error));
506  // Create a message box, because the gui has neither been created nor has subscribed to core signals
507  QMessageBox::critical(nullptr, PACKAGE_NAME,
508  // message can not be translated because translations have not been initialized
509  QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
510  return EXIT_FAILURE;
511  }
512 
513  // Now that the QApplication is setup and we have parsed our parameters, we can set the platform style
514  app.setupPlatformStyle();
515 
517  // must be set before OptionsModel is initialized or translations are loaded,
518  // as it is used to locate QSettings
519  QApplication::setOrganizationName(QAPP_ORG_NAME);
520  QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
521  QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
522 
524  // Now that QSettings are accessible, initialize translations
525  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
526  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
527 
528  // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
529  // but before showing splash screen.
530  if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
531  HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version"));
532  help.showOrPrint();
533  return EXIT_SUCCESS;
534  }
535 
536  // Install global event filter that makes sure that long tooltips can be word-wrapped
537  app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
538 
540  // User language is set up: pick a data directory
541  bool did_show_intro = false;
542  int64_t prune_MiB = 0; // Intro dialog prune configuration
543  // Gracefully exit if the user cancels
544  if (!Intro::showIfNeeded(did_show_intro, prune_MiB)) return EXIT_SUCCESS;
545 
548  if (!CheckDataDirOption()) {
549  InitError(strprintf(Untranslated("Specified data directory \"%s\" does not exist.\n"), gArgs.GetArg("-datadir", "")));
550  QMessageBox::critical(nullptr, PACKAGE_NAME,
551  QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
552  return EXIT_FAILURE;
553  }
554  if (!gArgs.ReadConfigFiles(error, true)) {
555  InitError(strprintf(Untranslated("Error reading configuration file: %s\n"), error));
556  QMessageBox::critical(nullptr, PACKAGE_NAME,
557  QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
558  return EXIT_FAILURE;
559  }
560 
562  // - Do not call Params() before this step
563  // - Do this after parsing the configuration file, as the network can be switched there
564  // - QSettings() will use the new application name after this, resulting in network-specific settings
565  // - Needs to be done before createOptionsModel
566 
567  // Check for chain settings (Params() calls are only valid after this clause)
568  try {
570  } catch(std::exception &e) {
571  InitError(Untranslated(strprintf("%s\n", e.what())));
572  QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(e.what()));
573  return EXIT_FAILURE;
574  }
575 #ifdef ENABLE_WALLET
576  // Parse URIs on command line -- this can affect Params()
578 #endif
579 
580  if (!InitSettings()) {
581  return EXIT_FAILURE;
582  }
583 
584  QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(Params().NetworkIDString()));
585  assert(!networkStyle.isNull());
586  // Allow for separate UI settings for testnets
587  QApplication::setApplicationName(networkStyle->getAppName());
588  // Re-initialize translations after changing application name (language in network-specific settings can be different)
589  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
590 
591 #ifdef ENABLE_WALLET
592  // - Do this early as we don't want to bother initializing if we are just calling IPC
594  // - Do this *after* setting up the data directory, as the data directory hash is used in the name
595  // of the server.
596  // - Do this after creating app and setting up translations, so errors are
597  // translated properly.
599  exit(EXIT_SUCCESS);
600 
601  // Start up the payment server early, too, so impatient users that click on
602  // bitcoin: links repeatedly have their payment requests routed to this process:
604  app.createPaymentServer();
605  }
606 #endif // ENABLE_WALLET
607 
609  // Install global event filter that makes sure that out-of-focus labels do not contain text cursor.
610  app.installEventFilter(new GUIUtil::LabelOutOfFocusEventFilter(&app));
611 #if defined(Q_OS_WIN)
612  // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
613  qApp->installNativeEventFilter(new WinShutdownMonitor());
614 #endif
615  // Install qDebug() message handler to route to debug.log
616  qInstallMessageHandler(DebugMessageHandler);
617  // Allow parameter interaction before we create the options model
618  app.parameterSetup();
620  // Load GUI settings from QSettings
621  app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
622 
623  if (did_show_intro) {
624  // Store intro dialog settings other than datadir (network specific)
625  app.InitPruneSetting(prune_MiB);
626  }
627 
628  if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
629  app.createSplashScreen(networkStyle.data());
630 
631  app.createNode(*init);
632 
633  int rv = EXIT_SUCCESS;
634  try
635  {
636  app.createWindow(networkStyle.data());
637  // Perform base initialization before spinning up initialization/shutdown thread
638  // This is acceptable because this function only contains steps that are quick to execute,
639  // so the GUI thread won't be held up.
640  if (app.baseInitialize()) {
641  app.requestInitialize();
642 #if defined(Q_OS_WIN)
643  WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely…").arg(PACKAGE_NAME), (HWND)app.getMainWinId());
644 #endif
645  app.exec();
646  rv = app.getReturnValue();
647  } else {
648  // A dialog with detailed error will have been shown by InitError()
649  rv = EXIT_FAILURE;
650  }
651  } catch (const std::exception& e) {
652  PrintExceptionContinue(&e, "Runaway exception");
653  app.handleRunawayException(QString::fromStdString(app.node().getWarnings().translated));
654  } catch (...) {
655  PrintExceptionContinue(nullptr, "Runaway exception");
656  app.handleRunawayException(QString::fromStdString(app.node().getWarnings().translated));
657  }
658  return rv;
659 }
PruneMiBtoGB
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
Definition: optionsmodel.h:25
winshutdownmonitor.h
BitcoinGUI::setClientModel
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
Definition: bitcoingui.cpp:580
SetupUIArgs
static void SetupUIArgs(ArgsManager &argsman)
Definition: bitcoin.cpp:453
GUIUtil::ToolTipToRichTextFilter
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:179
BitcoinApplication::setupPlatformStyle
void setupPlatformStyle()
Setup platform style.
Definition: bitcoin.cpp:230
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:602
BitcoinApplication::createSplashScreen
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Definition: bitcoin.cpp:274
DEFAULT_SPLASHSCREEN
static const bool DEFAULT_SPLASHSCREEN
Definition: guiconstants.h:25
SplashScreen::setNode
void setNode(interfaces::Node &node)
Definition: splashscreen.cpp:140
assert
assert(!tx.IsCoinBase())
BitcoinApplication::splashFinished
void splashFinished()
QAPP_ORG_NAME
#define QAPP_ORG_NAME
Definition: guiconstants.h:51
BitcoinApplication::platformStyle
const PlatformStyle * platformStyle
Definition: bitcoin.h:106
BitcoinApplication::node
interfaces::Node & node() const
Definition: bitcoin.h:74
BitcoinApplication::~BitcoinApplication
~BitcoinApplication()
Definition: bitcoin.cpp:243
InitExecutor::shutdown
void shutdown()
Definition: initexecutor.cpp:57
HelpMessageDialog
"Help message" dialog box
Definition: utilitydialog.h:20
BitcoinGUI::receivedURI
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
PACKAGE_BUGREPORT
#define PACKAGE_BUGREPORT
Definition: bitcoin-config.h:360
InitParameterInteraction
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:656
BitcoinApplication::handleRunawayException
void handleRunawayException(const QString &message)
Handle runaway exceptions. Shows a message box with the problem and quits the program.
Definition: bitcoin.cpp:426
BitcoinApplication::pollShutdownTimer
QTimer * pollShutdownTimer
Definition: bitcoin.h:100
ArgsManager::SoftSetBoolArg
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:616
uiInterface
CClientUIInterface uiInterface
Definition: ui_interface.cpp:12
InitLogging
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:734
help
static RPCHelpMan help()
Definition: server.cpp:133
BitcoinApplication::m_executor
std::optional< InitExecutor > m_executor
Definition: bitcoin.h:96
walletcontroller.h
intro.h
initTranslations
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
Definition: bitcoin.cpp:116
walletmodel.h
PaymentServer::message
void message(const QString &title, const QString &message, unsigned int style)
SplashScreen::finish
void finish()
Hide the splash screen window and schedule the splash screen object for deletion.
Definition: splashscreen.cpp:164
string.h
utilitydialog.h
WalletModel::isWalletEnabled
static bool isWalletEnabled()
Definition: walletmodel.cpp:572
uint256.h
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
disable validation
Definition: system.h:166
ArgsManager::GetChainName
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:989
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:496
node::NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:40
interfaces::Init
Initial interface created when a process is first started, and used to give and get access to other i...
Definition: init.h:28
handler.h
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1296
Intro::showIfNeeded
static bool showIfNeeded(bool &did_show_intro, int64_t &prune_MiB)
Determine data directory.
Definition: intro.cpp:205
BitcoinApplication::optionsModel
OptionsModel * optionsModel
Definition: bitcoin.h:97
InitExecutor::runawayException
void runawayException(const QString &message)
NetworkStyle
Definition: networkstyle.h:13
BitcoinApplication::requestedInitialize
void requestedInitialize()
interfaces::BlockAndHeaderTipInfo
Block and header tip information.
Definition: node.h:48
PlatformStyle::getName
const QString & getName() const
Definition: platformstyle.h:19
PaymentServer::ipcParseCommandLine
static void ipcParseCommandLine(int argc, char *argv[])
Definition: paymentserver.cpp:76
BitcoinApplication::getReturnValue
int getReturnValue() const
Get process return value.
Definition: bitcoin.h:66
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:739
bitcoin.h
bitcoin-config.h
chainparams.h
BitcoinGUI::message
void message(const QString &title, QString message, unsigned int style, bool *ret=nullptr, const QString &detailed_message=QString())
Notify the user of an event from the core network or transaction handling code.
Definition: bitcoingui.cpp:1116
interfaces::MakeGuiInit
std::unique_ptr< Init > MakeGuiInit(int argc, char *argv[])
Return implementation of Init interface for the gui process.
Definition: bitcoin-gui.cpp:43
ArgsManager::DEBUG_ONLY
@ DEBUG_ONLY
Definition: system.h:173
qt_argv
static const char * qt_argv
Definition: bitcoin.cpp:214
BitcoinGUI::hasTrayIcon
bool hasTrayIcon() const
Get the tray icon status.
Definition: bitcoingui.h:101
PaymentServer::uiReady
void uiReady()
Definition: paymentserver.cpp:204
BitcoinApplication::requestedShutdown
void requestedShutdown()
InitExecutor::shutdownResult
void shutdownResult()
MakeUnorderedList
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
Definition: string.h:70
TOOLTIP_WRAP_THRESHOLD
static const int TOOLTIP_WRAP_THRESHOLD
Definition: guiconstants.h:46
GUIUtil::LabelOutOfFocusEventFilter
Qt event filter that intercepts QEvent::FocusOut events for QLabel objects, and resets their ‘textInt...
Definition: guiutil.h:199
PaymentServer::ipcSendCommandLine
static bool ipcSendCommandLine()
Definition: paymentserver.cpp:117
OptionsModel
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:38
ClientModel::getOptionsModel
OptionsModel * getOptionsModel()
Definition: clientmodel.cpp:183
DebugMessageHandler
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
Definition: bitcoin.cpp:203
PaymentServer
Definition: paymentserver.h:57
GetLangTerritory
static QString GetLangTerritory()
Definition: bitcoin.cpp:100
ArgsManager::GetSettingsPath
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: system.cpp:519
BitcoinApplication::createWindow
void createWindow(const NetworkStyle *networkStyle)
Create main window.
Definition: bitcoin.cpp:265
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:46
BitcoinGUI::unsubscribeFromCoreSignals
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
Definition: bitcoingui.cpp:1471
QAPP_APP_NAME_DEFAULT
#define QAPP_APP_NAME_DEFAULT
Definition: guiconstants.h:53
GuiMain
int GuiMain(int argc, char *argv[])
Definition: bitcoin.cpp:463
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:363
OptionsModel::SetPruneTargetGB
void SetPruneTargetGB(int prune_target_gb, bool force=false)
Definition: optionsmodel.cpp:295
InitSettings
static bool InitSettings()
Definition: bitcoin.cpp:153
PaymentServer::receivedPaymentRequest
void receivedPaymentRequest(SendCoinsRecipient)
node.h
InitError
bool InitError(const bilingual_str &str)
Show error message.
Definition: ui_interface.cpp:59
noui_InitMessage
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
Definition: noui.cpp:54
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:642
ArgsManager::WriteSettingsFile
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:565
interfaces::Node::startShutdown
virtual void startShutdown()=0
Start shutdown.
BitcoinApplication::requestInitialize
void requestInitialize()
Request core initialization.
Definition: bitcoin.cpp:326
WalletController
Controller between interfaces::Node, WalletModel instances and the GUI.
Definition: walletcontroller.h:45
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:590
LogPrintf
#define LogPrintf(...)
Definition: logging.h:187
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
init.h
context
WalletContext context
Definition: notifications.cpp:37
BitcoinApplication::returnValue
int returnValue
Definition: bitcoin.h:105
BitcoinApplication::createNode
void createNode(interfaces::Init &init)
Create or spawn node.
Definition: bitcoin.cpp:285
guiutil.h
BCLog::QT
@ QT
Definition: logging.h:57
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
Definition: chainparams.cpp:580
BitcoinApplication::createOptionsModel
void createOptionsModel(bool resetSettings)
Create options model.
Definition: bitcoin.cpp:260
bilingual_str::translated
std::string translated
Definition: translation.h:18
ArgsManager::ParseParameters
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:308
uint256
256-bit opaque blob.
Definition: uint256.h:124
LogPrint
#define LogPrint(category,...)
Definition: logging.h:191
ArgsManager::ReadConfigFiles
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:897
SHUTDOWN_POLLING_DELAY
static constexpr auto SHUTDOWN_POLLING_DELAY
Definition: guiconstants.h:17
BitcoinGUI::detectShutdown
void detectShutdown()
called by a timer to check if ShutdownRequested() has been set
Definition: bitcoingui.cpp:1404
BitcoinApplication::shutdownWindow
std::unique_ptr< QWidget > shutdownWindow
Definition: bitcoin.h:107
gArgs
ArgsManager gArgs
Definition: system.cpp:85
InitExecutor::initialize
void initialize()
Definition: initexecutor.cpp:40
PlatformStyle::instantiate
static const PlatformStyle * instantiate(const QString &platformId)
Get style associated with provided platform name, or 0 if not known.
Definition: platformstyle.cpp:124
GUIUtil::MakeHtmlLink
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
Definition: guiutil.cpp:964
BitcoinApplication::window
BitcoinGUI * window
Definition: bitcoin.h:99
OptionsModel::setNode
void setNode(interfaces::Node &node)
Definition: optionsmodel.h:106
ui_interface.h
platformstyle.h
ArgsManager::ReadSettingsFile
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:542
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:813
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
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:47
SplashScreen
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:26
qt_argc
static int qt_argc
Definition: bitcoin.cpp:213
BitcoinApplication::BitcoinApplication
BitcoinApplication()
Definition: bitcoin.cpp:216
guiconstants.h
NetworkStyle::instantiate
static const NetworkStyle * instantiate(const std::string &networkId)
Get style associated with provided network id, or 0 if not known.
Definition: networkstyle.cpp:80
ArgsManager
Definition: system.h:158
BitcoinApplication::startThread
void startThread()
Definition: bitcoin.cpp:298
translation.h
splashscreen.h
networkstyle.h
BitcoinApplication::requestShutdown
void requestShutdown()
Request core shutdown.
Definition: bitcoin.cpp:333
ShutdownWindow::showShutdownWindow
static QWidget * showShutdownWindow(QMainWindow *window)
Definition: utilitydialog.cpp:152
init
Definition: bitcoin-gui.cpp:16
BitcoinApplication::m_splash
SplashScreen * m_splash
Definition: bitcoin.h:108
GUIUtil::LogQtInfo
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
Definition: guiutil.cpp:893
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:561
initexecutor.h
interfaces::Node::getWarnings
virtual bilingual_str getWarnings()=0
Get warnings.
BitcoinGUI::quitRequested
void quitRequested()
BitcoinApplication::baseInitialize
bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread. Return true on success.
Definition: bitcoin.cpp:293
noui.h
BitcoinApplication::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
Definition: bitcoin.cpp:375
bitcoingui.h
BitcoinApplication::getMainWinId
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
Definition: bitcoin.cpp:445
SynchronizationState
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:105
BitcoinApplication::handleNonFatalException
void handleNonFatalException(const QString &message)
A helper function that shows a message box with details about a non-fatal exception.
Definition: bitcoin.cpp:435
DEFAULT_CHOOSE_DATADIR
static const bool DEFAULT_CHOOSE_DATADIR
Definition: intro.h:12
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:781
PaymentServer::handleURIOrFile
void handleURIOrFile(const QString &s)
Definition: paymentserver.cpp:214
InitExecutor::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
optionsmodel.h
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
RegisterMetaTypes
static void RegisterMetaTypes()
Definition: bitcoin.cpp:82
BitcoinApplication::windowShown
void windowShown(BitcoinGUI *window)
BitcoinApplication::InitPruneSetting
void InitPruneSetting(int64_t prune_MiB)
Initialize prune setting.
Definition: bitcoin.cpp:321
GUIUtil::LoadFont
void LoadFont(const QString &file_name)
Loads the font from the file specified by file_name, aborts if it fails.
Definition: guiutil.cpp:276
OptionsCategory::GUI
@ GUI
OptionsModel::getMinimizeToTray
bool getMinimizeToTray() const
Definition: optionsmodel.h:87
BitcoinGUI
Bitcoin GUI main class.
Definition: bitcoingui.h:68
threadnames.h
BitcoinApplication::m_node
std::unique_ptr< interfaces::Node > m_node
Definition: bitcoin.h:109
BitcoinApplication::parameterSetup
void parameterSetup()
parameter interaction/setup based on rules
Definition: bitcoin.cpp:311
BitcoinApplication
Main Bitcoin application object.
Definition: bitcoin.h:36
SetupServerArgs
void SetupServerArgs(ArgsManager &argsman)
Register all arguments with the ArgsManager.
Definition: init.cpp:371
util::ThreadSetInternalName
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
Definition: threadnames.cpp:63
BitcoinGUI::DEFAULT_UIPLATFORM
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:73
interfaces::Node::baseInitialize
virtual bool baseInitialize()=0
Initialize app dependencies.
clientmodel.h
QAPP_ORG_DOMAIN
#define QAPP_ORG_DOMAIN
Definition: guiconstants.h:52
noui_ThreadSafeQuestion
bool noui_ThreadSafeQuestion(const bilingual_str &, const std::string &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints questions.
Definition: noui.cpp:49
BitcoinApplication::clientModel
ClientModel * clientModel
Definition: bitcoin.h:98
noui_ThreadSafeMessageBox
bool noui_ThreadSafeMessageBox(const bilingual_str &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints messages.
Definition: noui.cpp:22
paymentserver.h