7#include <chainparams.h>
35#include <validation.h>
44#include <QLibraryInfo>
53#include <boost/signals2/connection.hpp>
57#if defined(QT_STATICPLUGIN)
59#if defined(QT_QPA_PLATFORM_XCB)
60Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
61#elif defined(QT_QPA_PLATFORM_WINDOWS)
62Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
63#elif defined(QT_QPA_PLATFORM_COCOA)
64Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
65Q_IMPORT_PLUGIN(QMacStylePlugin);
70Q_DECLARE_METATYPE(
bool *)
79Q_DECLARE_METATYPE(
Config *)
86 qRegisterMetaType<bool *>();
87 qRegisterMetaType<SynchronizationState>();
88 qRegisterMetaType<SyncType>();
90 qRegisterMetaType<WalletModel *>();
92 qRegisterMetaType<Amount>();
95 qRegisterMetaType<size_t>(
"size_t");
97 qRegisterMetaType<std::function<void()>>(
"std::function<void()>");
98 qRegisterMetaType<QMessageBox::Icon>(
"QMessageBox::Icon");
99 qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>(
100 "interfaces::BlockAndHeaderTipInfo");
108 qRegisterMetaType<Config *>();
109 qRegisterMetaType<RPCServer *>();
110 qRegisterMetaType<HTTPRPCRequestProcessor *>();
119 QString lang_territory = QLocale::system().name();
121 QString lang_territory_qsettings =
122 settings.value(
"language",
"").toString();
123 if (!lang_territory_qsettings.isEmpty()) {
124 lang_territory = lang_territory_qsettings;
127 lang_territory = QString::fromStdString(
128 gArgs.
GetArg(
"-lang", lang_territory.toStdString()));
129 return lang_territory;
134 QTranslator &qtTranslator,
135 QTranslator &translatorBase,
136 QTranslator &translator) {
138 QApplication::removeTranslator(&qtTranslatorBase);
139 QApplication::removeTranslator(&qtTranslator);
140 QApplication::removeTranslator(&translatorBase);
141 QApplication::removeTranslator(&translator);
148 QString lang = lang_territory;
149 lang.truncate(lang_territory.lastIndexOf(
'_'));
155#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
156 const QString translation_path{
157 QLibraryInfo::location(QLibraryInfo::TranslationsPath)};
159 const QString translation_path{
160 QLibraryInfo::path(QLibraryInfo::TranslationsPath)};
163 if (qtTranslatorBase.load(
"qt_" + lang, translation_path)) {
164 QApplication::installTranslator(&qtTranslatorBase);
168 if (qtTranslator.load(
"qt_" + lang_territory, translation_path)) {
169 QApplication::installTranslator(&qtTranslator);
174 if (translatorBase.load(lang,
":/translations/")) {
175 QApplication::installTranslator(&translatorBase);
180 if (translator.load(lang_territory,
":/translations/")) {
181 QApplication::installTranslator(&translator);
186 const std::vector<std::string> &details) {
187 QMessageBox messagebox(
188 QMessageBox::Critical, PACKAGE_NAME,
190 QMessageBox::Reset | QMessageBox::Abort);
193 messagebox.setInformativeText(
194 QObject::tr(
"Do you want to reset settings to default values, or to "
195 "abort without making changes?"));
196 messagebox.setDetailedText(
198 messagebox.setTextFormat(Qt::PlainText);
199 messagebox.setDefaultButton(QMessageBox::Reset);
200 switch (messagebox.exec()) {
201 case QMessageBox::Reset:
203 case QMessageBox::Abort:
211 const std::vector<std::string> &details) {
212 QMessageBox messagebox(
213 QMessageBox::Critical, PACKAGE_NAME,
220 messagebox.setInformativeText(
221 QObject::tr(
"A fatal error occurred. Check that settings file is "
222 "writable, or try running with -nosettings."));
223 messagebox.setDetailedText(
225 messagebox.setTextFormat(Qt::PlainText);
226 messagebox.setDefaultButton(QMessageBox::Ok);
232 const QString &msg) {
234 if (type == QtDebugMsg) {
237 LogPrintf(
"GUI: %s\n", msg.toStdString());
253 qDebug() << __func__ <<
": Running initialization in thread";
256 *httpRPCRequestProcessor, &tip_info);
258 }
catch (
const std::exception &e) {
267 qDebug() << __func__ <<
": Running Shutdown in thread";
269 qDebug() << __func__ <<
": Shutdown finished";
271 }
catch (
const std::exception &e) {
282 : QApplication(
qt_argc, const_cast<char **>(&
qt_argv)), coreThread(nullptr),
283 optionsModel(nullptr), clientModel(nullptr), window(nullptr),
284 pollShutdownTimer(nullptr), platformStyle(nullptr) {
287 setQuitOnLastWindowClosed(
false);
294 std::string platformName;
307 qDebug() << __func__ <<
": Stopping thread";
310 qDebug() << __func__ <<
": Stopped thread";
320void BitcoinApplication::createPaymentServer() {
338 if (!QApplication::activeModalWidget()) {
386 [] { QCoreApplication::exit(0); });
409 connect(
coreThread, &QThread::finished, executor, &QObject::deleteLater);
432 qDebug() << __func__ <<
": Requesting initialize";
441 for (
const auto w : QGuiApplication::topLevelWindows()) {
450 qDebug() << __func__ <<
": Requesting shutdown";
476 delete m_wallet_controller;
477 m_wallet_controller =
nullptr;
489 qDebug() << __func__ <<
": Initialization result: " << success;
503 m_wallet_controller =
505 window->setWalletController(m_wallet_controller);
509 PaymentServer::LoadRootCAs();
511 paymentServer, &PaymentServer::fetchPaymentACK);
535 &BitcoinGUI::handlePaymentRequest);
539 [
this](
const QString &title,
const QString &message,
540 unsigned int style) {
551 QMessageBox::critical(
552 nullptr,
"Runaway exception",
553 BitcoinGUI::tr(
"A fatal error occurred. %1 can no longer continue "
554 "safely and will quit.")
556 QString(
"<br><br>") + message);
557 ::exit(EXIT_FAILURE);
569 if (e->type() == QEvent::Quit) {
574 return QApplication::event(e);
578#if defined(ENABLE_WALLET) && defined(ENABLE_BIP70)
580 "-allowselfsignedrootcertificates",
581 strprintf(
"Allow self signed root certificates (default: %d)",
585 argsman.
AddArg(
"-choosedatadir",
586 strprintf(
"Choose data directory on startup (default: %d)",
591 "Set language, for example \"de_DE\" (default: system locale)",
596 "-rootcertificates=<file>",
597 "Set SSL root certificates for payment request (default: -system-)",
600 strprintf(
"Show splash screen on startup (default: %d)",
603 argsman.
AddArg(
"-resetguisettings",
"Reset all settings changed in the GUI",
605 argsman.
AddArg(
"-uiplatform",
606 strprintf(
"Select platform to customize UI for (one of "
607 "windows, macosx, other; default: %s)",
615 common::WinCmdLineArgs winArgs;
616 std::tie(argc, argv) = winArgs.get();
622 std::unique_ptr<interfaces::Node>
node =
626 boost::signals2::scoped_connection handler_message_box =
628 boost::signals2::scoped_connection handler_question =
630 boost::signals2::scoped_connection handler_init_message =
638 Q_INIT_RESOURCE(bitcoin);
639 Q_INIT_RESOURCE(bitcoin_locale);
641#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
643 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
644 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
657 Untranslated(
"Error parsing command line arguments: %s"), error));
660 QMessageBox::critical(
661 nullptr, PACKAGE_NAME,
664 QString::fromStdString(
"Error parsing command line arguments: %1.")
665 .arg(QString::fromStdString(error)));
682 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
696 app.installEventFilter(
701 bool did_show_intro =
false;
725 QMessageBox::critical(
726 nullptr, PACKAGE_NAME,
727 QObject::tr(
"Error: %1")
728 .arg(QString::fromStdString(err->message.translated)));
737 QScopedPointer<const NetworkStyle> networkStyle(
739 assert(!networkStyle.isNull());
741 QApplication::setApplicationName(networkStyle->getAppName());
764 app.createPaymentServer();
775 qApp->installNativeEventFilter(
new WinShutdownMonitor());
785 if (did_show_intro) {
801 std::any context{&node_context};
816 WinShutdownMonitor::registerShutdownBlockReason(
817 QObject::tr(
"%1 didn't yet exit safely...").arg(PACKAGE_NAME),
821 }
catch (
const std::exception &e) {
bool HelpRequested(const ArgsManager &args)
const CChainParams & Params()
Return the currently selected parameters.
@ ALLOW_ANY
disable validation
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.
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 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.
Class encapsulating Bitcoin ABC startup and shutdown.
interfaces::Node & m_node
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
void handleRunawayException(const std::exception *e)
Pass fatal exception message to UI thread.
void runawayException(const QString &message)
BitcoinABC(interfaces::Node &node)
void initialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
Main Bitcoin application object.
void createWindow(const Config &, const NetworkStyle *networkStyle)
Create main window.
ClientModel * clientModel
bool baseInitialize(Config &config)
Basic initialization, before starting initialization/shutdown thread.
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)
void setNode(interfaces::Node &node)
interfaces::Node & node() const
QTimer * pollShutdownTimer
void InitializePruneSetting(bool prune)
Initialize prune setting.
interfaces::Node * m_node
const PlatformStyle * platformStyle
void parameterSetup()
parameter interaction/setup based on rules
void handleRunawayException(const QString &message)
Handle runaway exceptions.
OptionsModel * optionsModel
bool event(QEvent *e) override
void createOptionsModel(bool resetSettings)
Create options model.
void requestInitialize(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor)
Request core initialization.
void setupPlatformStyle()
Setup platform style.
void requestedInitialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
std::unique_ptr< QWidget > shutdownWindow
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
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
static bool showIfNeeded(bool &did_show_intro, bool &prune)
Determine data directory.
static const NetworkStyle * instantiate(const ChainType networkId)
Get style associated with provided BIP70 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)
Class for registering and managing all RPC calls.
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.
void coinsSent(interfaces::Wallet &wallet, SendCoinsRecipient recipient, QByteArray transaction)
static bool isWalletEnabled()
Top-level interface for a bitcoin node (bitcoind process).
virtual bilingual_str getWarnings()=0
Get warnings.
virtual void appShutdown()=0
Stop node.
virtual bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)=0
Start node.
virtual void startShutdown()=0
Start shutdown.
virtual int getExitStatus()=0
Get exit status.
virtual bool baseInitialize(Config &config)=0
Initialize app dependencies.
const Config & GetConfig()
void PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
static constexpr int DEFAULT_PRUNE_TARGET_GB
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(NodeContext &node)
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,...)
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
std::optional< ConfigError > InitConfig(ArgsManager &args, SettingsAbortFn settings_abort_fn)
Read config files, and create datadir and settings.json if they don't exist.
@ ABORTED
Aborted by user.
@ FAILED_WRITE
Failed to write settings.json.
std::unique_ptr< Node > MakeNode(node::NodeContext *context)
Return implementation of Node interface.
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
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 const bool DEFAULT_SELFSIGNED_ROOTCERTS
static bool ErrorSettingsRead(const bilingual_str &error, const std::vector< std::string > &details)
static void RegisterMetaTypes()
static QString GetLangTerritory()
int GuiMain(int argc, char *argv[])
static void ErrorSettingsWrite(const bilingual_str &error, const std::vector< std::string > &details)
static void SetupUIArgs(ArgsManager &argsman)
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)
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
Block and header tip information.
NodeContext struct containing references to chain state and connection state.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
CClientUIInterface uiInterface
bool InitError(const bilingual_str &str)
Show error message.
SynchronizationState
Current sync state passed to tip changed callbacks.