Skip to content

Commit 5b45bf4

Browse files
committed
Merge pull request #3488
2102ab9 ui: Fix GUI initialization order (Wladimir J. van der Laan)
2 parents 5c72e3d + 2102ab9 commit 5b45bf4

File tree

4 files changed

+64
-41
lines changed

4 files changed

+64
-41
lines changed

src/qt/bitcoin.cpp

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,23 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
161161
#ifndef BITCOIN_QT_TEST
162162
int main(int argc, char *argv[])
163163
{
164-
bool fMissingDatadir = false;
165164
bool fSelParFromCLFailed = false;
166-
165+
/// 1. Parse command-line options. These take precedence over anything else.
167166
// Command-line options take precedence:
168167
ParseParameters(argc, argv);
169-
// ... then bitcoin.conf:
170-
if (!boost::filesystem::is_directory(GetDataDir(false))) {
171-
fMissingDatadir = true;
172-
} else {
173-
ReadConfigFile(mapArgs, mapMultiArgs);
174-
}
175168
// Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause)
176169
if (!SelectParamsFromCommandLine()) {
177170
fSelParFromCLFailed = true;
178171
}
172+
// Parse URIs on command line -- this can affect TestNet() / RegTest() mode
173+
if (!PaymentServer::ipcParseCommandLine(argc, argv))
174+
exit(0);
175+
176+
bool isaTestNet = TestNet() || RegTest();
177+
178+
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
179179

180+
/// 2. Basic Qt initialization (not dependent on parameters or configuration)
180181
#if QT_VERSION < 0x050000
181182
// Internal string conversion is all UTF-8
182183
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
@@ -196,44 +197,62 @@ int main(int argc, char *argv[])
196197
// Register meta types used for QMetaObject::invokeMethod
197198
qRegisterMetaType< bool* >();
198199

199-
// Application identification (must be set before OptionsModel is initialized,
200-
// as it is used to locate QSettings)
201-
bool isaTestNet = TestNet() || RegTest();
200+
/// 3. Application identification
201+
// must be set before OptionsModel is initialized or translations are loaded,
202+
// as it is used to locate QSettings
202203
QApplication::setOrganizationName("Bitcoin");
203204
QApplication::setOrganizationDomain("bitcoin.org");
204205
if (isaTestNet) // Separate UI settings for testnets
205206
QApplication::setApplicationName("Bitcoin-Qt-testnet");
206207
else
207208
QApplication::setApplicationName("Bitcoin-Qt");
208209

210+
/// 4. Initialization of translations, so that intro dialog is in user's language
209211
// Now that QSettings are accessible, initialize translations
210212
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
211213
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
212214

213-
// Do this early as we don't want to bother initializing if we are just calling IPC
214-
// ... but do it after creating app and setting up translations, so errors are
215-
// translated properly.
216-
if (PaymentServer::ipcSendCommandLine(argc, argv))
217-
exit(0);
218-
219-
// Now that translations are initialized check for errors and allow a translatable error message
220-
if (fMissingDatadir) {
221-
QMessageBox::critical(0, QObject::tr("Bitcoin"),
222-
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
215+
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
216+
// but before showing splash screen.
217+
if (mapArgs.count("-?") || mapArgs.count("--help"))
218+
{
219+
GUIUtil::HelpMessageBox help;
220+
help.showOrPrint();
223221
return 1;
224222
}
225-
else if (fSelParFromCLFailed) {
223+
// Now that translations are initialized, check for earlier errors and show a translatable error message
224+
if (fSelParFromCLFailed) {
226225
QMessageBox::critical(0, QObject::tr("Bitcoin"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
227226
return 1;
228227
}
229228

229+
/// 5. Now that settings and translations are available, ask user for data directory
230+
// User language is set up: pick a data directory
231+
Intro::pickDataDirectory(isaTestNet);
232+
233+
/// 6. Determine availability of data directory and parse bitcoin.conf
234+
if (!boost::filesystem::is_directory(GetDataDir(false)))
235+
{
236+
QMessageBox::critical(0, QObject::tr("Bitcoin"),
237+
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
238+
return 1;
239+
}
240+
ReadConfigFile(mapArgs, mapMultiArgs);
241+
242+
/// 7. URI IPC sending
243+
// - Do this early as we don't want to bother initializing if we are just calling IPC
244+
// - Do this *after* setting up the data directory, as the data directory hash is used in the name
245+
// of the server.
246+
// - Do this after creating app and setting up translations, so errors are
247+
// translated properly.
248+
if (PaymentServer::ipcSendCommandLine())
249+
exit(0);
250+
230251
// Start up the payment server early, too, so impatient users that click on
231252
// bitcoin: links repeatedly have their payment requests routed to this process:
232253
PaymentServer* paymentServer = new PaymentServer(&app);
233254

234-
// User language is set up: pick a data directory
235-
Intro::pickDataDirectory(isaTestNet);
236-
255+
/// 8. Main GUI initialization
237256
// Install global event filter that makes sure that long tooltips can be word-wrapped
238257
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
239258
// Install qDebug() message handler to route to debug.log
@@ -242,24 +261,15 @@ int main(int argc, char *argv[])
242261
#else
243262
qInstallMessageHandler(DebugMessageHandler);
244263
#endif
245-
246-
// ... now GUI settings:
264+
// Load GUI settings from QSettings
247265
OptionsModel optionsModel;
248266

249267
// Subscribe to global signals from core
250268
uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
251269
uiInterface.InitMessage.connect(InitMessage);
252270
uiInterface.Translate.connect(Translate);
253271

254-
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
255-
// but before showing splash screen.
256-
if (mapArgs.count("-?") || mapArgs.count("--help"))
257-
{
258-
GUIUtil::HelpMessageBox help;
259-
help.showOrPrint();
260-
return 1;
261-
}
262-
272+
// Show splash screen if appropriate
263273
SplashScreen splash(QPixmap(), 0, isaTestNet);
264274
if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
265275
{

src/qt/intro.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ QString Intro::getDefaultDataDirectory()
148148

149149
void Intro::pickDataDirectory(bool fIsTestnet)
150150
{
151-
namespace fs = boost::filesystem;;
151+
namespace fs = boost::filesystem;
152152
QSettings settings;
153153
/* If data directory provided on command line, no need to look at settings
154154
or show a picking dialog */

src/qt/paymentserver.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,8 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
180180
// and the items in savedPaymentRequest will be handled
181181
// when uiReady() is called.
182182
//
183-
bool PaymentServer::ipcSendCommandLine(int argc, char* argv[])
183+
bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
184184
{
185-
bool fResult = false;
186-
187185
for (int i = 1; i < argc; i++)
188186
{
189187
QString arg(argv[i]);
@@ -226,7 +224,18 @@ bool PaymentServer::ipcSendCommandLine(int argc, char* argv[])
226224
qDebug() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
227225
}
228226
}
227+
return true;
228+
}
229229

230+
//
231+
// Sending to the server is done synchronously, at startup.
232+
// If the server isn't already running, startup continues,
233+
// and the items in savedPaymentRequest will be handled
234+
// when uiReady() is called.
235+
//
236+
bool PaymentServer::ipcSendCommandLine()
237+
{
238+
bool fResult = false;
230239
foreach (const QString& r, savedPaymentRequests)
231240
{
232241
QLocalSocket* socket = new QLocalSocket();

src/qt/paymentserver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,16 @@ class PaymentServer : public QObject
5656
Q_OBJECT
5757

5858
public:
59+
// Parse URIs on command line
60+
// Returns false on error
61+
static bool ipcParseCommandLine(int argc, char *argv[]);
62+
5963
// Returns true if there were URIs on the command line
6064
// which were successfully sent to an already-running
6165
// process.
6266
// Note: if a payment request is given, SelectParams(MAIN/TESTNET)
6367
// will be called so we startup in the right mode.
64-
static bool ipcSendCommandLine(int argc, char *argv[]);
68+
static bool ipcSendCommandLine();
6569

6670
// parent should be QApplication object
6771
PaymentServer(QObject* parent, bool startLocalServer = true);

0 commit comments

Comments
 (0)