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