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");
93 qRegisterMetaType<BitcoinUnit>(
"BitcoinUnit");
101 QString lang_territory = QLocale::system().name();
103 QString lang_territory_qsettings = settings.value(
"language",
"").toString();
104 if(!lang_territory_qsettings.isEmpty())
105 lang_territory = lang_territory_qsettings;
107 lang_territory = QString::fromStdString(
gArgs.
GetArg(
"-lang", lang_territory.toStdString()));
108 return lang_territory;
112 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
115 QApplication::removeTranslator(&qtTranslatorBase);
116 QApplication::removeTranslator(&qtTranslator);
117 QApplication::removeTranslator(&translatorBase);
118 QApplication::removeTranslator(&translator);
125 QString lang = lang_territory;
126 lang.truncate(lang_territory.lastIndexOf(
'_'));
132 const QString translation_path{QLibraryInfo::path(QLibraryInfo::TranslationsPath)};
134 if (qtTranslatorBase.load(
"qt_" + lang, translation_path)) {
135 QApplication::installTranslator(&qtTranslatorBase);
139 if (qtTranslator.load(
"qt_" + lang_territory, translation_path)) {
140 QApplication::installTranslator(&qtTranslator);
144 if (translatorBase.load(lang,
":/translations/")) {
145 QApplication::installTranslator(&translatorBase);
149 if (translator.load(lang_territory,
":/translations/")) {
150 QApplication::installTranslator(&translator);
156 QMessageBox messagebox(QMessageBox::Critical, CLIENT_NAME, QString::fromStdString(
strprintf(
"%s.", error.
translated)), QMessageBox::Reset | QMessageBox::Abort);
159 messagebox.setInformativeText(QObject::tr(
"Do you want to reset settings to default values, or to abort without making changes?"));
161 messagebox.setTextFormat(Qt::PlainText);
162 messagebox.setDefaultButton(QMessageBox::Reset);
163 switch (messagebox.exec()) {
164 case QMessageBox::Reset:
166 case QMessageBox::Abort:
175 QMessageBox messagebox(QMessageBox::Critical, CLIENT_NAME, QString::fromStdString(
strprintf(
"%s.", error.
translated)), QMessageBox::Ok);
179 messagebox.setInformativeText(QObject::tr(
"A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
181 messagebox.setTextFormat(Qt::PlainText);
182 messagebox.setDefaultButton(QMessageBox::Ok);
190 if (type == QtDebugMsg) {
205 setQuitOnLastWindowClosed(
false);
213 std::string platformName;
232 void BitcoinApplication::createPaymentServer()
250 error.
original +=
strprintf(
"Settings file %s might be corrupt or invalid.", quoted_path);
251 error.
translated += tr(
"Settings file %1 might be corrupt or invalid.").arg(QString::fromStdString(quoted_path)).toStdString();
254 QMessageBox::critical(
nullptr, CLIENT_NAME, QString::fromStdString(error.
translated));
267 if (!QApplication::activeModalWidget()) {
300 QCoreApplication::exit(0);
324 qDebug() << __func__ <<
": Requesting initialize";
331 for (
const auto w : QGuiApplication::topLevelWindows()) {
343 qDebug() << __func__ <<
": Requesting shutdown";
368 delete m_wallet_controller;
369 m_wallet_controller =
nullptr;
370 #endif // ENABLE_WALLET 381 qDebug() << __func__ <<
": Initialization result: " << success;
383 if (!success ||
m_node->shutdownRequested()) {
401 window->setWalletController(m_wallet_controller, start_minimized);
406 #endif // ENABLE_WALLET 409 if (!start_minimized) {
424 connect(paymentServer, &
PaymentServer::message, [
this](
const QString& title,
const QString& message,
unsigned int style) {
435 QMessageBox::critical(
436 nullptr, tr(
"Runaway exception"),
437 tr(
"A fatal error occurred. %1 can no longer continue safely and will quit.").arg(CLIENT_NAME) +
439 ::exit(EXIT_FAILURE);
444 assert(QThread::currentThread() == thread());
445 QMessageBox::warning(
446 nullptr, tr(
"Internal error"),
447 tr(
"An internal error occurred. %1 will attempt to continue safely. This is " 448 "an unexpected bug which can be reported as described below.").arg(CLIENT_NAME) +
462 if (e->type() == QEvent::Quit) {
467 return QApplication::event(e);
495 Q_INIT_RESOURCE(bitcoin);
496 Q_INIT_RESOURCE(bitcoin_locale);
498 #if defined(QT_QPA_PLATFORM_ANDROID) 499 QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
500 QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
501 QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
515 QMessageBox::critical(
nullptr, CLIENT_NAME,
517 QString::fromStdString(
"Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
523 bool payment_server_token_seen =
false;
524 for (
int i = 1; i < argc; i++) {
525 QString arg(argv[i]);
526 bool invalid_token = !arg.startsWith(
"-");
529 invalid_token &=
false;
530 payment_server_token_seen =
true;
533 if (payment_server_token_seen && arg.startsWith(
"-")) {
535 QMessageBox::critical(
nullptr, CLIENT_NAME,
537 QString::fromStdString(
"Options ('%1') cannot follow a BIP-21 payment URI").arg(QString::fromStdString(argv[i])));
542 QMessageBox::critical(
nullptr, CLIENT_NAME,
544 QString::fromStdString(
"Command line contains unexpected token '%1', see bitcoin-qt -h for a list of options.").arg(QString::fromStdString(argv[i])));
561 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
562 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
577 bool did_show_intro =
false;
578 int64_t prune_MiB = 0;
589 InitError(error->message, error->details);
597 QMessageBox::critical(
nullptr, CLIENT_NAME, QObject::tr(
"Error: %1").arg(QString::fromStdString(error->message.translated)));
607 assert(!networkStyle.isNull());
609 QApplication::setApplicationName(networkStyle->getAppName());
611 initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
626 app.createPaymentServer();
628 #endif // ENABLE_WALLET 633 #if defined(Q_OS_WIN) 638 qApp->installNativeEventFilter(
new WinShutdownMonitor([&app] { app.
node().
startShutdown(); }));
656 if (did_show_intro) {
669 #if defined(Q_OS_WIN) 670 WinShutdownMonitor::registerShutdownBlockReason(QObject::tr(
"%1 didn't yet exit safely…").arg(CLIENT_NAME), (HWND)app.
getMainWinId());
677 }
catch (
const std::exception& e) {
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 void ErrorSettingsWrite(const bilingual_str &error, const std::vector< std::string > &details)
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
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)
bool noui_ThreadSafeMessageBox(const bilingual_str &message, unsigned int style)
Non-GUI handler, which logs and prints messages.
static QString GetLangTerritory()
virtual bool baseInitialize()=0
Initialize app dependencies.
void parameterSetup()
parameter interaction/setup based on rules
virtual void startShutdown()=0
Start shutdown.
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)
bool noui_ThreadSafeQuestion(const bilingual_str &, const std::string &message, unsigned int style)
Non-GUI handler, which logs and prints questions.
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.
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 ‘textIn...
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.
static bool ErrorSettingsRead(const bilingual_str &error, const std::vector< std::string > &details)
void handleURIOrFile(const QString &s)
void SetupServerArgs(ArgsManager &argsman, bool can_listen_ipc)
Register all arguments with the ArgsManager.
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 void RegisterMetaTypes()
void createNode(interfaces::Init &init)
Create or spawn node.
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.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
int GuiMain(int argc, char *argv[])
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.
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.
#define LogDebug(category,...)
static void SetupUIArgs(ArgsManager &argsman)
#define QAPP_APP_NAME_DEFAULT
void createWindow(const NetworkStyle *networkStyle)
Create main window.
static const int TOOLTIP_WRAP_THRESHOLD
Interface from Qt to configuration data structure for Bitcoin client.
const CChainParams & Params()
Return the currently selected parameters.
bool getMinimizeToTray() const
static auto quoted(const std::string &s)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool HelpRequested(const ArgsManager &args)
static std::string PathToString(const path &path)
Convert path object to a byte string.
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.
static const char * qt_argv
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
"Help message" dialog box
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 const NetworkStyle * instantiate(ChainType networkId)
Get style associated with provided network id, or 0 if not known.
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
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