5 #include <bitcoin-build-config.h> 9 #include <chainparams.h> 38 #include <validation.h> 45 #endif // ENABLE_WALLET 47 #include <boost/signals2/connection.hpp> 51 #include <QApplication> 53 #include <QLatin1String> 54 #include <QLibraryInfo> 56 #include <QMessageBox> 60 #include <QTranslator> 64 Q_DECLARE_METATYPE(
bool*)
71 #endif // ENABLE_WALLET 78 qRegisterMetaType<bool*>();
79 qRegisterMetaType<SynchronizationState>();
80 qRegisterMetaType<SyncType>();
82 qRegisterMetaType<WalletModel*>();
83 qRegisterMetaType<wallet::AddressPurpose>();
84 #endif // ENABLE_WALLET 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");
94 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 95 qRegisterMetaTypeStreamOperators<BitcoinUnit>(
"BitcoinUnit");
97 qRegisterMetaType<BitcoinUnit>(
"BitcoinUnit");
106 QString lang_territory = QLocale::system().name();
108 QString lang_territory_qsettings = settings.value(
"language",
"").toString();
109 if(!lang_territory_qsettings.isEmpty())
110 lang_territory = lang_territory_qsettings;
112 lang_territory = QString::fromStdString(
gArgs.
GetArg(
"-lang", lang_territory.toStdString()));
113 return lang_territory;
117 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
120 QApplication::removeTranslator(&qtTranslatorBase);
121 QApplication::removeTranslator(&qtTranslator);
122 QApplication::removeTranslator(&translatorBase);
123 QApplication::removeTranslator(&translator);
130 QString lang = lang_territory;
131 lang.truncate(lang_territory.lastIndexOf(
'_'));
137 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 138 const QString translation_path{QLibraryInfo::location(QLibraryInfo::TranslationsPath)};
140 const QString translation_path{QLibraryInfo::path(QLibraryInfo::TranslationsPath)};
143 if (qtTranslatorBase.load(
"qt_" + lang, translation_path)) {
144 QApplication::installTranslator(&qtTranslatorBase);
148 if (qtTranslator.load(
"qt_" + lang_territory, translation_path)) {
149 QApplication::installTranslator(&qtTranslator);
153 if (translatorBase.load(lang,
":/translations/")) {
154 QApplication::installTranslator(&translatorBase);
158 if (translator.load(lang_territory,
":/translations/")) {
159 QApplication::installTranslator(&translator);
165 QMessageBox messagebox(QMessageBox::Critical, CLIENT_NAME, QString::fromStdString(
strprintf(
"%s.", error.
translated)), QMessageBox::Reset | QMessageBox::Abort);
168 messagebox.setInformativeText(QObject::tr(
"Do you want to reset settings to default values, or to abort without making changes?"));
170 messagebox.setTextFormat(Qt::PlainText);
171 messagebox.setDefaultButton(QMessageBox::Reset);
172 switch (messagebox.exec()) {
173 case QMessageBox::Reset:
175 case QMessageBox::Abort:
184 QMessageBox messagebox(QMessageBox::Critical, CLIENT_NAME, QString::fromStdString(
strprintf(
"%s.", error.
translated)), QMessageBox::Ok);
188 messagebox.setInformativeText(QObject::tr(
"A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
190 messagebox.setTextFormat(Qt::PlainText);
191 messagebox.setDefaultButton(QMessageBox::Ok);
199 if (type == QtDebugMsg) {
214 setQuitOnLastWindowClosed(
false);
222 std::string platformName;
241 void BitcoinApplication::createPaymentServer()
259 error.
original +=
strprintf(
"Settings file %s might be corrupt or invalid.", quoted_path);
260 error.
translated += tr(
"Settings file %1 might be corrupt or invalid.").arg(QString::fromStdString(quoted_path)).toStdString();
263 QMessageBox::critical(
nullptr, CLIENT_NAME, QString::fromStdString(error.
translated));
276 if (!QApplication::activeModalWidget()) {
309 QCoreApplication::exit(0);
333 qDebug() << __func__ <<
": Requesting initialize";
340 for (
const auto w : QGuiApplication::topLevelWindows()) {
352 qDebug() << __func__ <<
": Requesting shutdown";
377 delete m_wallet_controller;
378 m_wallet_controller =
nullptr;
379 #endif // ENABLE_WALLET 390 qDebug() << __func__ <<
": Initialization result: " << success;
406 window->setWalletController(m_wallet_controller, start_minimized);
411 #endif // ENABLE_WALLET 414 if (!start_minimized) {
429 connect(paymentServer, &
PaymentServer::message, [
this](
const QString& title,
const QString& message,
unsigned int style) {
443 QMessageBox::critical(
444 nullptr, tr(
"Runaway exception"),
445 tr(
"A fatal error occurred. %1 can no longer continue safely and will quit.").arg(CLIENT_NAME) +
447 ::exit(EXIT_FAILURE);
452 assert(QThread::currentThread() == thread());
453 QMessageBox::warning(
454 nullptr, tr(
"Internal error"),
455 tr(
"An internal error occurred. %1 will attempt to continue safely. This is " 456 "an unexpected bug which can be reported as described below.").arg(CLIENT_NAME) +
470 if (e->type() == QEvent::Quit) {
475 return QApplication::event(e);
491 common::WinCmdLineArgs winArgs;
492 std::tie(argc, argv) = winArgs.get();
508 Q_INIT_RESOURCE(bitcoin);
509 Q_INIT_RESOURCE(bitcoin_locale);
511 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 513 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
514 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
517 #if defined(QT_QPA_PLATFORM_ANDROID) 518 QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
519 QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
520 QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
534 QMessageBox::critical(
nullptr, CLIENT_NAME,
536 QString::fromStdString(
"Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
542 bool payment_server_token_seen =
false;
543 for (
int i = 1; i < argc; i++) {
544 QString arg(argv[i]);
545 bool invalid_token = !arg.startsWith(
"-");
548 invalid_token &=
false;
549 payment_server_token_seen =
true;
552 if (payment_server_token_seen && arg.startsWith(
"-")) {
554 QMessageBox::critical(
nullptr, CLIENT_NAME,
556 QString::fromStdString(
"Options ('%1') cannot follow a BIP-21 payment URI").arg(QString::fromStdString(argv[i])));
561 QMessageBox::critical(
nullptr, CLIENT_NAME,
563 QString::fromStdString(
"Command line contains unexpected token '%1', see bitcoin-qt -h for a list of options.").arg(QString::fromStdString(argv[i])));
580 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
581 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
596 bool did_show_intro =
false;
597 int64_t prune_MiB = 0;
608 InitError(error->message, error->details);
616 QMessageBox::critical(
nullptr, CLIENT_NAME, QObject::tr(
"Error: %1").arg(QString::fromStdString(error->message.translated)));
626 assert(!networkStyle.isNull());
628 QApplication::setApplicationName(networkStyle->getAppName());
630 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
645 app.createPaymentServer();
647 #endif // ENABLE_WALLET 652 #if defined(Q_OS_WIN) 657 qApp->installNativeEventFilter(
new WinShutdownMonitor([&app] { app.
node().
startShutdown(); }));
675 if (did_show_intro) {
688 #if defined(Q_OS_WIN) 689 WinShutdownMonitor::registerShutdownBlockReason(QObject::tr(
"%1 didn't yet exit safely…").arg(CLIENT_NAME), (HWND)app.
getMainWinId());
696 }
catch (
const std::exception& e) {
OptionsModel * optionsModel
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
static const bool DEFAULT_CHOOSE_DATADIR
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 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)
CClientUIInterface uiInterface
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.
void setNode(interfaces::Node &node)
virtual bool baseInitialize()=0
Initialize app dependencies.
void parameterSetup()
parameter interaction/setup based on rules
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. Shows a message box with the problem and quits the program.
void SetPruneTargetGB(int prune_target_gb)
void requestInitialize()
Request core initialization.
Failed to write settings.json.
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
Controller between interfaces::Node, WalletModel instances and the GUI.
OptionsModel * getOptionsModel()
void receivedPaymentRequest(SendCoinsRecipient)
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.
static void SetupUIArgs(ArgsManager &argsman)
std::unique_ptr< interfaces::Node > m_node
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
void handleNonFatalException(const QString &message)
A helper function that shows a message box with details about a non-fatal exception.
void requestedInitialize()
interfaces::Node & node() const
void PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
Qt event filter that intercepts QEvent::FocusOut events for QLabel objects, and resets their ‘textI...
static const bool DEFAULT_SPLASHSCREEN
static void ipcParseCommandLine(int argc, char *argv[])
static constexpr auto SHUTDOWN_POLLING_DELAY
void InitPruneSetting(int64_t prune_MiB)
Initialize prune setting.
void handleURIOrFile(const QString &s)
void SetupServerArgs(ArgsManager &argsman, bool can_listen_ipc)
Register all arguments with the ArgsManager.
static const NetworkStyle * instantiate(const ChainType networkId)
Get style associated with provided network id, or 0 if not known.
bool Init(bilingual_str &error)
static bool showIfNeeded(bool &did_show_intro, int64_t &prune_MiB)
Determine data directory.
static bool ipcSendCommandLine()
int64_t CAmount
Amount in satoshis (Can be negative)
static QWidget * showShutdownWindow(QMainWindow *window)
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
AddressPurpose
Address purpose field that has been been stored with wallet sending and receiving addresses since BIP...
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false, bool backup=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings...
static std::string PathToString(const path &path)
Convert path object to a byte string.
void createNode(interfaces::Init &init)
Create or spawn node.
static void RegisterMetaTypes()
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
virtual int getExitStatus()=0
Get exit status.
Main Bitcoin application object.
bool InitError(const bilingual_str &str)
Show error message.
QT_END_NAMESPACE const QString BITCOIN_IPC_PREFIX
virtual bilingual_str getWarnings()=0
Get warnings.
int GuiMain(int argc, char *argv[])
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
void detectShutdown()
called by a timer to check if shutdown has been requested
Block and header tip information.
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
std::unique_ptr< QWidget > shutdownWindow
void windowShown(BitcoinGUI *window)
Model for Bitcoin network client.
is a home for public enum and struct type definitions that are used by internally by wallet code...
bool hasTrayIcon() const
Get the tray icon status.
static const char * qt_argv
bool createOptionsModel(bool resetSettings)
Create options model.
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 requestShutdown()
Request core shutdown.
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
#define QAPP_APP_NAME_DEFAULT
void createWindow(const NetworkStyle *networkStyle)
Create main window.
static const int TOOLTIP_WRAP_THRESHOLD
#define LogDebug(category,...)
Interface from Qt to configuration data structure for Bitcoin client.
const CChainParams & Params()
Return the currently selected parameters.
bool getMinimizeToTray() const
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool HelpRequested(const ArgsManager &args)
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
void LoadFont(const QString &file_name)
Loads the font from the file specified by file_name, aborts if it fails.
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
"Help message" dialog box
static bool ErrorSettingsRead(const bilingual_str &error, const std::vector< std::string > &details)
static auto quoted(const std::string &s)
void ThreadSetInternalName(const std::string &)
Set the internal (in-memory) name of the current thread only.
Initial interface created when a process is first started, and used to give and get access to other i...
static QString GetLangTerritory()
std::unique_ptr< Init > MakeGuiInit(int argc, char *argv[])
Return implementation of Init interface for the gui process.
static const std::string DEFAULT_UIPLATFORM
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
void runawayException(const QString &message)
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
std::optional< ConfigError > InitConfig(ArgsManager &args, SettingsAbortFn settings_abort_fn)
bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread. Return true on success...
bool event(QEvent *e) override
static void ErrorSettingsWrite(const bilingual_str &error, const std::vector< std::string > &details)
ClientModel * clientModel
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
std::optional< InitExecutor > m_executor
QTimer * pollShutdownTimer
const PlatformStyle * platformStyle