5#if defined(HAVE_CONFIG_H)
35#include <validation.h>
43#include <boost/signals2/connection.hpp>
46#include <QApplication>
48#include <QLatin1String>
49#include <QLibraryInfo>
58#if defined(QT_STATICPLUGIN)
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);
72Q_DECLARE_METATYPE(
bool*)
80 qRegisterMetaType<bool*>();
81 qRegisterMetaType<SynchronizationState>();
83 qRegisterMetaType<WalletModel*>();
87 qRegisterMetaType<CAmount>(
"CAmount");
88 qRegisterMetaType<size_t>(
"size_t");
90 qRegisterMetaType<std::function<void()>>(
"std::function<void()>");
91 qRegisterMetaType<QMessageBox::Icon>(
"QMessageBox::Icon");
92 qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>(
"interfaces::BlockAndHeaderTipInfo");
100 QString lang_territory = QLocale::system().name();
102 QString lang_territory_qsettings = settings.value(
"language",
"").toString();
103 if(!lang_territory_qsettings.isEmpty())
104 lang_territory = lang_territory_qsettings;
106 lang_territory = QString::fromStdString(
gArgs.
GetArg(
"-lang", lang_territory.toStdString()));
107 return lang_territory;
111static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
114 QApplication::removeTranslator(&qtTranslatorBase);
115 QApplication::removeTranslator(&qtTranslator);
116 QApplication::removeTranslator(&translatorBase);
117 QApplication::removeTranslator(&translator);
124 QString lang = lang_territory;
125 lang.truncate(lang_territory.lastIndexOf(
'_'));
132 if (qtTranslatorBase.load(
"qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
133 QApplication::installTranslator(&qtTranslatorBase);
136 if (qtTranslator.load(
"qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
137 QApplication::installTranslator(&qtTranslator);
140 if (translatorBase.load(lang,
":/translations/"))
141 QApplication::installTranslator(&translatorBase);
144 if (translator.load(lang_territory,
":/translations/"))
145 QApplication::installTranslator(&translator);
154 std::vector<std::string> 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();
160 QMessageBox messagebox(QMessageBox::Critical,
PACKAGE_NAME, QString::fromStdString(
strprintf(
"%s.", error_translated)), QMessageBox::Reset | QMessageBox::Abort);
163 messagebox.setInformativeText(QObject::tr(
"Do you want to reset settings to default values, or to abort without making changes?"));
165 messagebox.setTextFormat(Qt::PlainText);
166 messagebox.setDefaultButton(QMessageBox::Reset);
167 switch (messagebox.exec()) {
168 case QMessageBox::Reset:
170 case QMessageBox::Abort:
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();
183 QMessageBox messagebox(QMessageBox::Critical,
PACKAGE_NAME, QString::fromStdString(
strprintf(
"%s.", error_translated)), QMessageBox::Ok);
187 messagebox.setInformativeText(QObject::tr(
"A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
189 messagebox.setTextFormat(Qt::PlainText);
190 messagebox.setDefaultButton(QMessageBox::Ok);
201 if (type == QtDebugMsg) {
204 LogPrintf(
"GUI: %s\n", msg.toStdString());
213 optionsModel(nullptr),
214 clientModel(nullptr),
216 pollShutdownTimer(nullptr),
218 platformStyle(nullptr)
222 setQuitOnLastWindowClosed(
false);
230 std::string platformName;
249void BitcoinApplication::createPaymentServer()
324 qDebug() << __func__ <<
": Requesting initialize";
331 for (
const auto w : QGuiApplication::topLevelWindows()) {
340 qDebug() << __func__ <<
": Requesting shutdown";
360 delete m_wallet_controller;
361 m_wallet_controller =
nullptr;
373 qDebug() << __func__ <<
": Initialization result: " << success;
375 returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
385 window->setWalletController(m_wallet_controller);
409 connect(paymentServer, &
PaymentServer::message, [
this](
const QString& title,
const QString& message,
unsigned int style) {
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) +
428 ::exit(EXIT_FAILURE);
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) +
462 util::WinCmdLineArgs winArgs;
463 std::tie(argc, argv) = winArgs.get();
479 Q_INIT_RESOURCE(bitcoin);
480 Q_INIT_RESOURCE(bitcoin_locale);
483 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
484 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
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);
505 QString::fromStdString(
"Error parsing command line arguments: %1.").arg(QString::fromStdString(
error)));
521 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
522 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
537 bool did_show_intro =
false;
538 int64_t prune_MiB = 0;
547 QObject::tr(
"Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(
gArgs.
GetArg(
"-datadir",
""))));
553 QObject::tr(
"Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(
error)));
566 }
catch(std::exception &e) {
568 QMessageBox::critical(
nullptr,
PACKAGE_NAME, QObject::tr(
"Error: %1").arg(e.what()));
581 assert(!networkStyle.isNull());
583 QApplication::setApplicationName(networkStyle->getAppName());
585 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
600 app.createPaymentServer();
609 qApp->installNativeEventFilter(
new WinShutdownMonitor());
619 if (did_show_intro) {
629 int rv = EXIT_SUCCESS;
639 WinShutdownMonitor::registerShutdownBlockReason(QObject::tr(
"%1 didn't yet exit safely…").arg(
PACKAGE_NAME), (HWND)app.
getMainWinId());
647 }
catch (
const std::exception& e) {
int64_t CAmount
Amount in satoshis (Can be negative)
#define PACKAGE_BUGREPORT
static void RegisterMetaTypes()
static QString GetLangTerritory()
int GuiMain(int argc, char *argv[])
static void SetupUIArgs(ArgsManager &argsman)
static bool InitSettings()
static const char * qt_argv
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
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
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
bool ParseParameters(int argc, const char *const argv[], std::string &error)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
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.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Main Bitcoin application object.
std::optional< InitExecutor > m_executor
void requestedInitialize()
ClientModel * clientModel
void InitPruneSetting(int64_t prune_MiB)
Initialize prune setting.
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
void requestShutdown()
Request core shutdown.
void windowShown(BitcoinGUI *window)
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
interfaces::Node & node() const
void createNode(interfaces::Init &init)
Create or spawn node.
QTimer * pollShutdownTimer
const PlatformStyle * platformStyle
bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread. Return true on success.
int getReturnValue() const
Get process return value.
void createWindow(const NetworkStyle *networkStyle)
Create main window.
void parameterSetup()
parameter interaction/setup based on rules
void handleRunawayException(const QString &message)
Handle runaway exceptions. Shows a message box with the problem and quits the program.
OptionsModel * optionsModel
void createOptionsModel(bool resetSettings)
Create options model.
void setupPlatformStyle()
Setup platform style.
std::unique_ptr< interfaces::Node > m_node
std::unique_ptr< QWidget > shutdownWindow
void requestInitialize()
Request core initialization.
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
void handleNonFatalException(const QString &message)
A helper function that shows a message box with details about a non-fatal exception.
static const std::string DEFAULT_UIPLATFORM
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
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.
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.
Model for Bitcoin network client.
OptionsModel * getOptionsModel()
Qt event filter that intercepts QEvent::FocusOut events for QLabel objects, and resets their ‘textInt...
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
"Help message" dialog box
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.
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.
void SetPruneTargetGB(int prune_target_gb, bool force=false)
bool getMinimizeToTray() const
void setNode(interfaces::Node &node)
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)
static QWidget * showShutdownWindow(QMainWindow *window)
Class for the splashscreen with information of the running client.
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...
virtual bool baseInitialize()=0
Initialize app dependencies.
virtual bilingual_str getWarnings()=0
Get warnings.
virtual void startShutdown()=0
Start shutdown.
static const int TOOLTIP_WRAP_THRESHOLD
static const bool DEFAULT_SPLASHSCREEN
#define QAPP_APP_NAME_DEFAULT
void InitLogging(const ArgsManager &args)
Initialize global loggers.
void SetupServerArgs(ArgsManager &argsman)
Register all arguments with the ArgsManager.
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
static const bool DEFAULT_CHOOSE_DATADIR
#define LogPrint(category,...)
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
void LoadFont(const QString &file_name)
Loads the font from the file specified by file_name, aborts if it fails.
std::unique_ptr< Init > MakeGuiInit(int argc, char *argv[])
Return implementation of Init interface for the gui process.
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
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.
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
bool noui_ThreadSafeMessageBox(const bilingual_str &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints messages.
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
Block and header tip information.
bool error(const char *fmt, const Args &... args)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
CClientUIInterface uiInterface
bool InitError(const bilingual_str &str)
Show error message.
bool HelpRequested(const ArgsManager &args)
bool CheckDataDirOption()
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
SynchronizationState
Current sync state passed to tip changed callbacks.