32 #include <validation.h> 38 #endif // ENABLE_WALLET 41 #include <QLibraryInfo> 43 #include <QMessageBox> 45 #include <QStringList> 48 #include <QTranslator> 50 #include <boost/signals2/connection.hpp> 52 #if defined(QT_STATICPLUGIN) 54 #if defined(QT_QPA_PLATFORM_XCB) 55 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
56 #elif defined(QT_QPA_PLATFORM_WINDOWS) 57 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
58 #elif defined(QT_QPA_PLATFORM_COCOA) 59 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
64 Q_DECLARE_METATYPE(
bool *)
70 Q_DECLARE_METATYPE(
Config *)
76 QString lang_territory = QLocale::system().name();
78 QString lang_territory_qsettings =
79 settings.value(
"language",
"").toString();
80 if (!lang_territory_qsettings.isEmpty()) {
81 lang_territory = lang_territory_qsettings;
84 lang_territory = QString::fromStdString(
85 gArgs.
GetArg(
"-lang", lang_territory.toStdString()));
86 return lang_territory;
91 QTranslator &qtTranslator,
92 QTranslator &translatorBase,
93 QTranslator &translator) {
95 QApplication::removeTranslator(&qtTranslatorBase);
96 QApplication::removeTranslator(&qtTranslator);
97 QApplication::removeTranslator(&translatorBase);
98 QApplication::removeTranslator(&translator);
105 QString lang = lang_territory;
106 lang.truncate(lang_territory.lastIndexOf(
'_'));
113 if (qtTranslatorBase.load(
115 QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
116 QApplication::installTranslator(&qtTranslatorBase);
120 if (qtTranslator.load(
121 "qt_" + lang_territory,
122 QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
123 QApplication::installTranslator(&qtTranslator);
128 if (translatorBase.load(lang,
":/translations/")) {
129 QApplication::installTranslator(&translatorBase);
134 if (translator.load(lang_territory,
":/translations/")) {
135 QApplication::installTranslator(&translator);
141 const QString &msg) {
143 if (type == QtDebugMsg) {
146 LogPrintf(
"GUI: %s\n", msg.toStdString());
160 qDebug() << __func__ <<
": Running initialization in thread";
165 }
catch (
const std::exception &e) {
174 qDebug() << __func__ <<
": Running Shutdown in thread";
176 qDebug() << __func__ <<
": Shutdown finished";
178 }
catch (
const std::exception &e) {
189 : QApplication(
qt_argc, const_cast<char **>(&
qt_argv)), coreThread(nullptr),
190 optionsModel(nullptr), clientModel(nullptr), window(nullptr),
191 pollShutdownTimer(nullptr), returnValue(0), platformStyle(nullptr) {
192 setQuitOnLastWindowClosed(
false);
199 std::string platformName;
212 qDebug() << __func__ <<
": Stopping thread";
215 qDebug() << __func__ <<
": Stopped thread";
227 void BitcoinApplication::createPaymentServer() {
309 connect(
coreThread, &QThread::finished, executor, &QObject::deleteLater);
332 qDebug() << __func__ <<
": Requesting initialize";
346 qDebug() << __func__ <<
": Requesting shutdown";
368 qDebug() << __func__ <<
": Initialization result: " << success;
369 returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
384 m_wallet_controller =
386 window->setWalletController(m_wallet_controller);
390 PaymentServer::LoadRootCAs();
392 paymentServer, &PaymentServer::fetchPaymentACK);
396 #endif // ENABLE_WALLET 416 &BitcoinGUI::handlePaymentRequest);
420 [
this](
const QString &title,
const QString &message,
421 unsigned int style) {
437 QMessageBox::critical(
438 nullptr,
"Runaway exception",
439 BitcoinGUI::tr(
"A fatal error occurred. %1 can no longer continue " 440 "safely and will quit.")
442 QString(
"\n\n") + message);
443 ::exit(EXIT_FAILURE);
455 #if defined(ENABLE_WALLET) && defined(ENABLE_BIP70) 457 "-allowselfsignedrootcertificates",
458 strprintf(
"Allow self signed root certificates (default: %d)",
462 argsman.
AddArg(
"-choosedatadir",
463 strprintf(
"Choose data directory on startup (default: %d)",
468 "Set language, for example \"de_DE\" (default: system locale)",
473 "-rootcertificates=<file>",
474 "Set SSL root certificates for payment request (default: -system-)",
477 strprintf(
"Show splash screen on startup (default: %d)",
480 argsman.
AddArg(
"-resetguisettings",
"Reset all settings changed in the GUI",
482 argsman.
AddArg(
"-uiplatform",
483 strprintf(
"Select platform to customize UI for (one of " 484 "windows, macosx, other; default: %s)",
491 assert(!QApplication::applicationName().isEmpty());
493 static const QString legacyAppName(
"Bitcoin-Qt"),
498 legacyOrg(
"bitcoin.org");
500 legacyOrg(
"Bitcoin");
504 legacy(legacyOrg, legacyAppName),
512 legacy.setFallbacksEnabled(
false);
513 abc.setFallbacksEnabled(
false);
515 const QStringList legacyKeys(legacy.allKeys());
519 if (!legacyKeys.isEmpty() && abc.allKeys().isEmpty()) {
520 for (
const QString &key : legacyKeys) {
522 abc.setValue(key, legacy.value(key));
529 util::WinCmdLineArgs winArgs;
530 std::tie(argc, argv) = winArgs.get();
536 std::unique_ptr<interfaces::Node>
node =
540 boost::signals2::scoped_connection handler_message_box =
542 boost::signals2::scoped_connection handler_question =
544 boost::signals2::scoped_connection handler_init_message =
552 Q_INIT_RESOURCE(bitcoin);
553 Q_INIT_RESOURCE(bitcoin_locale);
556 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
557 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
563 qRegisterMetaType<bool *>();
564 qRegisterMetaType<SynchronizationState>();
566 qRegisterMetaType<WalletModel *>();
572 qRegisterMetaType<Amount>(
"Amount");
573 qRegisterMetaType<size_t>(
"size_t");
575 qRegisterMetaType<std::function<void()>>(
"std::function<void()>");
576 qRegisterMetaType<QMessageBox::Icon>(
"QMessageBox::Icon");
584 qRegisterMetaType<Config *>();
594 Untranslated(
"Error parsing command line arguments: %s\n"), error));
597 QMessageBox::critical(
598 nullptr, PACKAGE_NAME,
601 QString::fromStdString(
"Error parsing command line arguments: %1.")
602 .arg(QString::fromStdString(error)));
627 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
641 bool did_show_intro =
false;
654 Untranslated(
"Specified data directory \"%s\" does not exist.\n"),
656 QMessageBox::critical(
657 nullptr, PACKAGE_NAME,
659 "Error: Specified data directory \"%1\" does not exist.")
660 .arg(QString::fromStdString(
gArgs.
GetArg(
"-datadir",
""))));
665 Untranslated(
"Error reading configuration file: %s\n"), error));
666 QMessageBox::critical(
667 nullptr, PACKAGE_NAME,
668 QObject::tr(
"Error: Cannot parse configuration file: %1.")
669 .arg(QString::fromStdString(error)));
685 }
catch (std::exception &e) {
687 QMessageBox::critical(
nullptr, PACKAGE_NAME,
688 QObject::tr(
"Error: %1").arg(e.what()));
697 QMessageBox::critical(
nullptr, PACKAGE_NAME,
698 QObject::tr(
"Error initializing settings: %1")
699 .arg(QString::fromStdString(error)));
703 QScopedPointer<const NetworkStyle> networkStyle(
705 assert(!networkStyle.isNull());
707 QApplication::setApplicationName(networkStyle->getAppName());
730 app.createPaymentServer();
732 #endif // ENABLE_WALLET 737 app.installEventFilter(
739 #if defined(Q_OS_WIN) 742 qApp->installNativeEventFilter(
new WinShutdownMonitor());
752 if (did_show_intro) {
782 #if defined(Q_OS_WIN) 783 WinShutdownMonitor::registerShutdownBlockReason(
784 QObject::tr(
"%1 didn't yet exit safely...").arg(PACKAGE_NAME),
791 }
catch (
const std::exception &e) {
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
OptionsModel * optionsModel
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
static const bool DEFAULT_CHOOSE_DATADIR
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
static UniValue help(Config &config, const JSONRPCRequest &jsonRequest)
BitcoinABC(interfaces::Node &node)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
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.
static constexpr int DEFAULT_PRUNE_TARGET_GB
void setupPlatformStyle()
Setup platform style.
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
void InitLogging(const ArgsManager &args)
Initialize global loggers.
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
SynchronizationState
Current sync state passed to tip changed callbacks.
void message(const QString &title, const QString &message, unsigned int style)
#define LogPrint(category,...)
static bool isWalletEnabled()
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Class for the splashscreen with information of the running client.
static const NetworkStyle * instantiate(const std::string &networkId)
Get style associated with provided BIP70 network id, or 0 if not known.
void setNode(interfaces::Node &node)
static QString GetLangTerritory()
void parameterSetup()
parameter interaction/setup based on rules
void coinsSent(interfaces::Wallet &wallet, SendCoinsRecipient recipient, QByteArray transaction)
virtual void startShutdown()=0
Start shutdown.
bool noui_ThreadSafeMessageBox(const bilingual_str &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints messages.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
void handleRunawayException(const QString &message)
Handle runaway exceptions.
void SetPruneTargetGB(int prune_target_gb, bool force=false)
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name...
static void LogPrintf(const char *fmt, const Args &... args)
Controller between interfaces::Node, WalletModel instances and the GUI.
OptionsModel * getOptionsModel()
void receivedPaymentRequest(SendCoinsRecipient)
static const bool DEFAULT_SELFSIGNED_ROOTCERTS
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void createOptionsModel(bool resetSettings)
Create options model.
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
interfaces::Node & node() const
void SetupServerArgs(NodeContext &node)
Register all arguments with the ArgsManager.
void requestedInitialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
static const bool DEFAULT_SPLASHSCREEN
static void ipcParseCommandLine(int argc, char *argv[])
void setNode(interfaces::Node &node)
void handleURIOrFile(const QString &s)
void requestInitialize(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor)
Request core initialization.
static bool ipcSendCommandLine()
bool CheckDataDirOption()
void createWindow(const Config *, const NetworkStyle *networkStyle)
Create main window.
void setClientModel(ClientModel *clientModel)
Set the client model.
static QWidget * showShutdownWindow(QMainWindow *window)
void finish()
Hide the splash screen window and schedule the splash screen object for deletion. ...
NodeContext struct containing references to chain state and connection state.
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Main Bitcoin application object.
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
interfaces::Node & m_node
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
bool HelpRequested(const ArgsManager &args)
int GuiMain(int argc, char *argv[])
void detectShutdown()
called by a timer to check if ShutdownRequested() has been set
const Config & GetConfig()
Class for registering and managing all RPC calls.
bool InitError(const bilingual_str &str)
Show error message.
std::unique_ptr< QWidget > shutdownWindow
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
void setNode(interfaces::Node &node)
bool baseInitialize(Config &config)
Basic initialization, before starting initialization/shutdown thread.
void windowShown(BitcoinGUI *window)
Model for Bitcoin network client.
Type-safe dynamic reference.
bool hasTrayIcon() const
Get the tray icon status.
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
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.
static void SetupUIArgs(ArgsManager &argsman)
static void MigrateSettings()
#define QAPP_APP_NAME_DEFAULT
virtual void appShutdown()=0
Stop node.
static const int TOOLTIP_WRAP_THRESHOLD
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Interface from Qt to configuration data structure for Bitcoin client.
void initializeResult(bool success)
const CChainParams & Params()
Return the currently selected parameters.
bool getMinimizeToTray() const
Class encapsulating Bitcoin ABC startup and shutdown.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
static bool showIfNeeded(bool &did_show_intro, bool &prune)
Determine data directory.
virtual bool baseInitialize(Config &config)=0
Initialize app dependencies.
virtual bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor)=0
Start node.
void handleRunawayException(const std::exception *e)
Pass fatal exception message to UI thread.
static const char * qt_argv
interfaces::Node * m_node
"Help message" dialog box
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
CClientUIInterface uiInterface
virtual std::string getWarnings()=0
Get warnings.
void runawayException(const QString &message)
void initialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
void InitializePruneSetting(bool prune)
Initialize prune setting.
static const std::string DEFAULT_UIPLATFORM
std::unique_ptr< Node > MakeNode(NodeContext *context)
Return implementation of Node interface.
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
Top-level interface for a bitcoin node (bitcoind process).
bool error(const char *fmt, const Args &... args)
void initializeResult(bool success)
ClientModel * clientModel
void requestShutdown(Config &config)
Request core shutdown.
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
int getReturnValue() const
Get process return value.
QTimer * pollShutdownTimer
const PlatformStyle * platformStyle