14
14
#include " researcher/researchermodel.h"
15
15
#include " optionsmodel.h"
16
16
#include " guiutil.h"
17
+ #include " qt/intro.h"
17
18
#include " guiconstants.h"
18
19
#include " init.h"
19
20
#include " ui_interface.h"
@@ -67,7 +68,7 @@ extern bool bGridcoinCoreInitComplete;
67
68
static BitcoinGUI *guiref;
68
69
static QSplashScreen *splashref;
69
70
70
- int StartGridcoinQt (int argc, char *argv[]);
71
+ int StartGridcoinQt (int argc, char *argv[], QApplication& app, OptionsModel& optionsModel );
71
72
72
73
static void ThreadSafeMessageBox (const std::string& message, const std::string& caption, int style)
73
74
{
@@ -230,9 +231,116 @@ int main(int argc, char *argv[])
230
231
// Before this would of been done in main then config file loaded.
231
232
// We will load config file here as well.
232
233
ParseParameters (argc, argv);
233
-
234
234
SelectParams (CBaseChainParams::MAIN);
235
- ReadConfigFile (mapArgs, mapMultiArgs);
235
+
236
+ // Generate high-dpi pixmaps
237
+ QApplication::setAttribute (Qt::AA_UseHighDpiPixmaps);
238
+ #if QT_VERSION >= 0x050600 && !defined(WIN32)
239
+ QCoreApplication::setAttribute (Qt::AA_EnableHighDpiScaling);
240
+ #endif
241
+
242
+ // Initiate the app here to support choosing the data directory.
243
+ Q_INIT_RESOURCE (bitcoin);
244
+ Q_INIT_RESOURCE (bitcoin_locale);
245
+
246
+ QApplication app (argc, argv);
247
+
248
+ #if defined(WIN32) && defined(QT_GUI)
249
+ SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
250
+ #endif
251
+
252
+ // Application identification (must be set before OptionsModel is initialized,
253
+ // as it is used to locate QSettings)
254
+ app.setOrganizationName (" Gridcoin" );
255
+ // XXX app.setOrganizationDomain("");
256
+ if (GetBoolArg (" -testnet" )) // Separate UI settings for testnet
257
+ app.setApplicationName (" Gridcoin-Qt-testnet" );
258
+ else
259
+ app.setApplicationName (" Gridcoin-Qt" );
260
+
261
+ // Install global event filter that makes sure that long tooltips can be word-wrapped
262
+ app.installEventFilter (new GUIUtil::ToolTipToRichTextFilter (TOOLTIP_WRAP_THRESHOLD, &app));
263
+
264
+ // Install global event filter that suppresses help context question mark
265
+ app.installEventFilter (new GUIUtil::WindowContextHelpButtonHintFilter (&app));
266
+
267
+ #if defined(WIN32) && QT_VERSION >= 0x050000
268
+ // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
269
+ app.installNativeEventFilter (new WinShutdownMonitor ());
270
+ #endif
271
+
272
+ // Load the optionsModel. This has to be loaded before the translations, because the language selection is
273
+ // a setting that can be stored in options.
274
+ OptionsModel optionsModel;
275
+
276
+ // Get desired locale (e.g. "de_DE") from command line or use system locale
277
+ QString lang_territory = QString::fromStdString (GetArg (" -lang" , QLocale::system ().name ().toStdString ()));
278
+ QString lang = lang_territory;
279
+ // Convert to "de" only by truncating "_DE"
280
+ lang.truncate (lang_territory.lastIndexOf (' _' ));
281
+
282
+ QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
283
+ // Load language files for configured locale:
284
+ // - First load the translator for the base language, without territory
285
+ // - Then load the more specific locale translator
286
+
287
+ // Load e.g. qt_de.qm
288
+ if (qtTranslatorBase.load (" qt_" + lang, QLibraryInfo::location (QLibraryInfo::TranslationsPath)))
289
+ app.installTranslator (&qtTranslatorBase);
290
+
291
+ // Load e.g. qt_de_DE.qm
292
+ if (qtTranslator.load (" qt_" + lang_territory, QLibraryInfo::location (QLibraryInfo::TranslationsPath)))
293
+ app.installTranslator (&qtTranslator);
294
+
295
+ // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
296
+ if (translatorBase.load (lang, " :/translations/" ))
297
+ app.installTranslator (&translatorBase);
298
+
299
+ // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
300
+ if (translator.load (lang_territory, " :/translations/" ))
301
+ app.installTranslator (&translator);
302
+
303
+ // Now that settings and translations are available, ask user for data directory
304
+ bool did_show_intro = false ;
305
+ // Gracefully exit if the user cancels
306
+ if (!Intro::showIfNeeded (did_show_intro)) return EXIT_SUCCESS;
307
+
308
+ // Determine availability of data directory and parse gridcoinresearch.conf
309
+ // Do not call GetDataDir(true) before this step finishes
310
+ if (!CheckDataDirOption ()) {
311
+ ThreadSafeMessageBox (strprintf (" Specified data directory \" %s\" does not exist.\n " , GetArg (" -datadir" , " " )),
312
+ " " , CClientUIInterface::ICON_ERROR | CClientUIInterface::OK | CClientUIInterface::MODAL);
313
+ QMessageBox::critical (nullptr , PACKAGE_NAME,
314
+ QObject::tr (" Error: Specified data directory \" %1\" does not exist." )
315
+ .arg (QString::fromStdString (GetArg (" -datadir" , " " ))));
316
+ return EXIT_FAILURE;
317
+ }
318
+
319
+ // This check must be done before logging is initialized or the config file is read. We do not want another
320
+ // instance writing into an already running Gridcoin instance's logs. This is checked in init too,
321
+ // but that is too late.
322
+ fs::path dataDir = GetDataDir ();
323
+
324
+ if (!LockDirectory (dataDir, " .lock" , false )) {
325
+ std::string str = strprintf (_ (" Cannot obtain a lock on data directory %s. %s is probably already running "
326
+ " and using that directory." ),
327
+ dataDir, PACKAGE_NAME);
328
+ ThreadSafeMessageBox (str, _ (" Gridcoin" ), CClientUIInterface::OK | CClientUIInterface::MODAL);
329
+ QMessageBox::critical (nullptr , PACKAGE_NAME,
330
+ QObject::tr (" Error: Cannot obtain a lock on the specified data directory. "
331
+ " An instance is probably already using that directory." ));
332
+
333
+ return EXIT_FAILURE;
334
+ }
335
+
336
+ if (!ReadConfigFile (mapArgs, mapMultiArgs)) {
337
+ ThreadSafeMessageBox (strprintf (" Error reading configuration file.\n " ),
338
+ " " , CClientUIInterface::ICON_ERROR | CClientUIInterface::OK | CClientUIInterface::MODAL);
339
+ QMessageBox::critical (nullptr , PACKAGE_NAME,
340
+ QObject::tr (" Error: Cannot parse configuration file." ));
341
+ return EXIT_FAILURE;
342
+ }
343
+
236
344
SelectParams (mapArgs.count (" -testnet" ) ? CBaseChainParams::TESTNET : CBaseChainParams::MAIN);
237
345
238
346
// Initialize logging as early as possible.
@@ -241,42 +349,31 @@ int main(int argc, char *argv[])
241
349
// Do this early as we don't want to bother initializing if we are just calling IPC
242
350
ipcScanRelay (argc, argv);
243
351
244
- // Here we do it if it was started with the snapshot argument and we not TestNet
352
+ // Run snapshot main if Gridcoin was started with the snapshot argument and we are not TestNet
245
353
if (mapArgs.count (" -snapshotdownload" ) && !mapArgs.count (" -testnet" ))
246
354
{
247
355
GRC::Upgrade snapshot;
248
356
249
- // Let's check make sure gridcoin is not already running in the data directory.
250
- if (!LockDirectory (GetDataDir (), " .lock" , false ))
357
+ try
251
358
{
252
- fprintf (stderr, " Cannot obtain a lock on data directory %s. Gridcoin is probably already running." , GetDataDir ().string ().c_str ());
253
-
254
- exit (1 );
359
+ snapshot.SnapshotMain ();
255
360
}
256
- else
257
- {
258
- try
259
- {
260
- snapshot.SnapshotMain ();
261
- }
262
361
263
- catch (std::runtime_error& e)
264
- {
265
- LogPrintf (" Snapshot Downloader: Runtime exception occurred in SnapshotMain() (%s)" , e.what ());
266
-
267
- snapshot.DeleteSnapshot ();
362
+ catch (std::runtime_error& e)
363
+ {
364
+ LogPrintf (" Snapshot Downloader: Runtime exception occurred in SnapshotMain() (%s)" , e.what ());
268
365
269
- exit (1 );
270
- }
366
+ snapshot.DeleteSnapshot ();
271
367
368
+ return EXIT_FAILURE;
272
369
}
273
370
274
371
// Delete snapshot regardless of result.
275
372
snapshot.DeleteSnapshot ();
276
373
}
277
374
278
375
/* * Start Qt as normal before it was moved into this function **/
279
- StartGridcoinQt (argc, argv);
376
+ StartGridcoinQt (argc, argv, app, optionsModel );
280
377
281
378
// We got a request to apply snapshot from GUI Menu selection
282
379
// We got this request and everything should be shutdown now.
@@ -319,31 +416,16 @@ int main(int argc, char *argv[])
319
416
Snapshot.DeleteSnapshot ();
320
417
}
321
418
322
- return 0 ;
419
+ return EXIT_SUCCESS ;
323
420
}
324
421
325
- int StartGridcoinQt (int argc, char *argv[])
422
+ int StartGridcoinQt (int argc, char *argv[], QApplication& app, OptionsModel& optionsModel )
326
423
{
327
424
// Set global boolean to indicate intended presence of GUI to core.
328
425
fQtActive = true ;
329
426
330
427
std::shared_ptr<ThreadHandler> threads = std::make_shared<ThreadHandler>();
331
428
332
- Q_INIT_RESOURCE (bitcoin);
333
- Q_INIT_RESOURCE (bitcoin_locale);
334
- QApplication app (argc, argv);
335
- // uint SEM_FAILCRITICALERRORS= 0x0001;
336
- // uint SEM_NOGPFAULTERRORBOX = 0x0002;
337
- #if defined(WIN32) && defined(QT_GUI)
338
- SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
339
- #endif
340
-
341
- // Install global event filter that makes sure that long tooltips can be word-wrapped
342
- app.installEventFilter (new GUIUtil::ToolTipToRichTextFilter (TOOLTIP_WRAP_THRESHOLD, &app));
343
-
344
- // Install global event filter that suppresses help context question mark
345
- app.installEventFilter (new GUIUtil::WindowContextHelpButtonHintFilter (&app));
346
-
347
429
#if QT_VERSION < 0x050000
348
430
// Install qDebug() message handler to route to debug.log
349
431
qInstallMsgHandler (DebugMessageHandler);
@@ -352,57 +434,6 @@ int StartGridcoinQt(int argc, char *argv[])
352
434
qInstallMessageHandler (DebugMessageHandler);
353
435
#endif
354
436
355
- #if defined(WIN32) && QT_VERSION >= 0x050000
356
- // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
357
- app.installNativeEventFilter (new WinShutdownMonitor ());
358
- #endif
359
-
360
- if (!fs::is_directory (GetDataDir (false )))
361
- {
362
- QMessageBox::critical (0 , " Gridcoin" ,
363
- QString (" Error: Specified data directory \" %1\" does not exist." ).arg (QString::fromStdString (mapArgs[" -datadir" ])));
364
- return 1 ;
365
- }
366
-
367
- // Application identification (must be set before OptionsModel is initialized,
368
- // as it is used to locate QSettings)
369
- app.setOrganizationName (" Gridcoin" );
370
- // XXX app.setOrganizationDomain("");
371
- if (GetBoolArg (" -testnet" )) // Separate UI settings for testnet
372
- app.setApplicationName (" Gridcoin-Qt-testnet" );
373
- else
374
- app.setApplicationName (" Gridcoin-Qt" );
375
-
376
- // ... then GUI settings:
377
- OptionsModel optionsModel;
378
-
379
- // Get desired locale (e.g. "de_DE") from command line or use system locale
380
- QString lang_territory = QString::fromStdString (GetArg (" -lang" , QLocale::system ().name ().toStdString ()));
381
- QString lang = lang_territory;
382
- // Convert to "de" only by truncating "_DE"
383
- lang.truncate (lang_territory.lastIndexOf (' _' ));
384
-
385
- QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
386
- // Load language files for configured locale:
387
- // - First load the translator for the base language, without territory
388
- // - Then load the more specific locale translator
389
-
390
- // Load e.g. qt_de.qm
391
- if (qtTranslatorBase.load (" qt_" + lang, QLibraryInfo::location (QLibraryInfo::TranslationsPath)))
392
- app.installTranslator (&qtTranslatorBase);
393
-
394
- // Load e.g. qt_de_DE.qm
395
- if (qtTranslator.load (" qt_" + lang_territory, QLibraryInfo::location (QLibraryInfo::TranslationsPath)))
396
- app.installTranslator (&qtTranslator);
397
-
398
- // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
399
- if (translatorBase.load (lang, " :/translations/" ))
400
- app.installTranslator (&translatorBase);
401
-
402
- // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
403
- if (translator.load (lang_territory, " :/translations/" ))
404
- app.installTranslator (&translator);
405
-
406
437
// Subscribe to global signals from core
407
438
uiInterface.ThreadSafeMessageBox .connect (ThreadSafeMessageBox);
408
439
uiInterface.ThreadSafeAskFee .connect (ThreadSafeAskFee);
@@ -421,7 +452,7 @@ int StartGridcoinQt(int argc, char *argv[])
421
452
{
422
453
GUIUtil::HelpMessageBox help;
423
454
help.showOrPrint ();
424
- return 1 ;
455
+ return EXIT_FAILURE ;
425
456
}
426
457
427
458
QSplashScreen splash (QPixmap (" :/images/splash" ), 0 );
@@ -446,7 +477,7 @@ int StartGridcoinQt(int argc, char *argv[])
446
477
if (!threads->createThread (ThreadAppInit2,threads," AppInit2 Thread" ))
447
478
{
448
479
LogPrintf (" Error; NewThread(ThreadAppInit2) failed" );
449
- return 1 ;
480
+ return EXIT_FAILURE ;
450
481
}
451
482
else
452
483
{
@@ -526,7 +557,7 @@ int StartGridcoinQt(int argc, char *argv[])
526
557
threads->removeAll ();
527
558
threads.reset ();
528
559
529
- return 0 ;
560
+ return EXIT_SUCCESS ;
530
561
}
531
562
532
563
#endif // BITCOIN_QT_TEST
0 commit comments