Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

dash.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2019 The Dash Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
7 #include <config/dash-config.h>
8 #endif
9 
10 #include <qt/bitcoingui.h>
11 
12 #include <chainparams.h>
13 #include <qt/clientmodel.h>
14 #include <fs.h>
15 #include <qt/guiconstants.h>
16 #include <qt/guiutil.h>
17 #include <qt/intro.h>
18 #include <net.h>
19 #include <qt/networkstyle.h>
20 #include <qt/optionsmodel.h>
21 #include <qt/splashscreen.h>
22 #include <qt/utilitydialog.h>
23 #include <qt/winshutdownmonitor.h>
24 
25 #ifdef ENABLE_WALLET
26 #include <qt/paymentserver.h>
27 #include <qt/walletmodel.h>
28 #endif
29 
30 #include <init.h>
31 #include <rpc/server.h>
32 #include <stacktraces.h>
33 #include <ui_interface.h>
34 #include <util.h>
35 #include <warnings.h>
36 
37 #ifdef ENABLE_WALLET
38 #include <wallet/wallet.h>
39 #endif
40 #include <walletinitinterface.h>
41 
42 #include <memory>
43 #include <stdint.h>
44 
45 #include <boost/thread.hpp>
46 
47 #include <QApplication>
48 #include <QDebug>
49 #include <QLibraryInfo>
50 #include <QLocale>
51 #include <QMessageBox>
52 #include <QProcess>
53 #include <QSettings>
54 #include <QThread>
55 #include <QTimer>
56 #include <QTranslator>
57 
58 #if defined(QT_STATICPLUGIN)
59 #include <QtPlugin>
60 #if QT_VERSION < 0x050000
61 Q_IMPORT_PLUGIN(qcncodecs)
62 Q_IMPORT_PLUGIN(qjpcodecs)
63 Q_IMPORT_PLUGIN(qtwcodecs)
64 Q_IMPORT_PLUGIN(qkrcodecs)
65 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
66 #else
67 #if QT_VERSION < 0x050400
68 Q_IMPORT_PLUGIN(AccessibleFactory)
69 #endif
70 #if defined(QT_QPA_PLATFORM_XCB)
71 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
72 #elif defined(QT_QPA_PLATFORM_WINDOWS)
73 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
74 #elif defined(QT_QPA_PLATFORM_COCOA)
75 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
76 #endif
77 #endif
78 #endif
79 
80 #if QT_VERSION < 0x050000
81 #include <QTextCodec>
82 #endif
83 
84 // Declare meta types used for QMetaObject::invokeMethod
85 Q_DECLARE_METATYPE(bool*)
86 Q_DECLARE_METATYPE(CAmount)
87 
88 static void InitMessage(const std::string &message)
89 {
90  LogPrintf("init message: %s\n", message);
91 }
92 
93 /*
94  Translate string to current locale using Qt.
95  */
96 static std::string Translate(const char* psz)
97 {
98  return QCoreApplication::translate("dash-core", psz).toStdString();
99 }
100 
101 static QString GetLangTerritory()
102 {
103  QSettings settings;
104  // Get desired locale (e.g. "de_DE")
105  // 1) System default language
106  QString lang_territory = QLocale::system().name();
107  // 2) Language from QSettings
108  QString lang_territory_qsettings = settings.value("language", "").toString();
109  if(!lang_territory_qsettings.isEmpty())
110  lang_territory = lang_territory_qsettings;
111  // 3) -lang command line argument
112  lang_territory = QString::fromStdString(gArgs.GetArg("-lang", lang_territory.toStdString()));
113  return lang_territory;
114 }
115 
117 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
118 {
119  // Remove old translators
120  QApplication::removeTranslator(&qtTranslatorBase);
121  QApplication::removeTranslator(&qtTranslator);
122  QApplication::removeTranslator(&translatorBase);
123  QApplication::removeTranslator(&translator);
124 
125  // Get desired locale (e.g. "de_DE")
126  // 1) System default language
127  QString lang_territory = GetLangTerritory();
128 
129  // Convert to "de" only by truncating "_DE"
130  QString lang = lang_territory;
131  lang.truncate(lang_territory.lastIndexOf('_'));
132 
133  // Load language files for configured locale:
134  // - First load the translator for the base language, without territory
135  // - Then load the more specific locale translator
136 
137  // Load e.g. qt_de.qm
138  if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
139  QApplication::installTranslator(&qtTranslatorBase);
140 
141  // Load e.g. qt_de_DE.qm
142  if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
143  QApplication::installTranslator(&qtTranslator);
144 
145  // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in dash.qrc)
146  if (translatorBase.load(lang, ":/translations/"))
147  QApplication::installTranslator(&translatorBase);
148 
149  // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in dash.qrc)
150  if (translator.load(lang_territory, ":/translations/"))
151  QApplication::installTranslator(&translator);
152 }
153 
154 /* qDebug() message handler --> debug.log */
155 #if QT_VERSION < 0x050000
156 void DebugMessageHandler(QtMsgType type, const char *msg)
157 {
158  if (type == QtDebugMsg) {
159  LogPrint(BCLog::QT, "GUI: %s\n", msg);
160  } else {
161  LogPrintf("GUI: %s\n", msg);
162  }
163 }
164 #else
165 void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
166 {
167  Q_UNUSED(context);
168  if (type == QtDebugMsg) {
169  LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
170  } else {
171  LogPrintf("GUI: %s\n", msg.toStdString());
172  }
173 }
174 #endif
175 
179 class BitcoinCore: public QObject
180 {
181  Q_OBJECT
182 public:
183  explicit BitcoinCore();
187  static bool baseInitialize();
188 
189 public Q_SLOTS:
190  void initialize();
191  void shutdown();
192  void restart(QStringList args);
193 
194 Q_SIGNALS:
195  void initializeResult(bool success);
196  void shutdownResult();
197  void runawayException(const QString &message);
198 
199 private:
200 
202  void handleRunawayException(const std::exception_ptr e);
203 };
204 
206 class BitcoinApplication: public QApplication
207 {
208  Q_OBJECT
209 public:
210  explicit BitcoinApplication(int &argc, char **argv);
212 
213 #ifdef ENABLE_WALLET
214  void createPaymentServer();
216 #endif
217  void parameterSetup();
220  void createOptionsModel(bool resetSettings);
222  void createWindow(const NetworkStyle *networkStyle);
224  void createSplashScreen(const NetworkStyle *networkStyle);
225 
227  void requestInitialize();
229  void requestShutdown();
230 
232  int getReturnValue() const { return returnValue; }
233 
235  WId getMainWinId() const;
236 
237 public Q_SLOTS:
238  void initializeResult(bool success);
239  void shutdownResult();
241  void handleRunawayException(const QString &message);
242 
243 Q_SIGNALS:
244  void requestedInitialize();
245  void requestedRestart(QStringList args);
246  void requestedShutdown();
247  void stopThread();
248  void splashFinished(QWidget *window);
249 
250 private:
251  QThread *coreThread;
256 #ifdef ENABLE_WALLET
257  PaymentServer* paymentServer;
258  WalletModel *walletModel;
259 #endif
261  std::unique_ptr<QWidget> shutdownWindow;
262 
263  void startThread();
264 };
265 
266 #include <qt/dash.moc>
267 
269  QObject()
270 {
271 }
272 
273 void BitcoinCore::handleRunawayException(const std::exception_ptr e)
274 {
275  PrintExceptionContinue(e, "Runaway exception");
276  Q_EMIT runawayException(QString::fromStdString(GetWarnings("gui")));
277 }
278 
280 {
281  if (!AppInitBasicSetup())
282  {
283  return false;
284  }
286  {
287  return false;
288  }
289  if (!AppInitSanityChecks())
290  {
291  return false;
292  }
294  {
295  return false;
296  }
297  return true;
298 }
299 
301 {
302  try
303  {
304  qDebug() << __func__ << ": Running initialization in thread";
305  bool rv = AppInitMain();
306  Q_EMIT initializeResult(rv);
307  } catch (...) {
308  handleRunawayException(std::current_exception());
309  }
310 }
311 
312 void BitcoinCore::restart(QStringList args)
313 {
314  static bool executing_restart{false};
315 
316  if(!executing_restart) { // Only restart 1x, no matter how often a user clicks on a restart-button
317  executing_restart = true;
318  try
319  {
320  qDebug() << __func__ << ": Running Restart in thread";
321  Interrupt();
322  StartRestart();
323  PrepareShutdown();
324  qDebug() << __func__ << ": Shutdown finished";
325  Q_EMIT shutdownResult();
327  QProcess::startDetached(QApplication::applicationFilePath(), args);
328  qDebug() << __func__ << ": Restart initiated...";
329  QApplication::quit();
330  } catch (...) {
331  handleRunawayException(std::current_exception());
332  }
333  }
334 }
335 
337 {
338  try
339  {
340  qDebug() << __func__ << ": Running Shutdown in thread";
341  Interrupt();
342  Shutdown();
343  qDebug() << __func__ << ": Shutdown finished";
344  Q_EMIT shutdownResult();
345  } catch (...) {
346  handleRunawayException(std::current_exception());
347  }
348 }
349 
351  QApplication(argc, argv),
352  coreThread(0),
353  optionsModel(0),
354  clientModel(0),
355  window(0),
356  pollShutdownTimer(0),
357 #ifdef ENABLE_WALLET
358  paymentServer(0),
359  walletModel(0),
360 #endif
361  returnValue(0)
362 {
363  setQuitOnLastWindowClosed(false);
364 }
365 
367 {
368  if(coreThread)
369  {
370  qDebug() << __func__ << ": Stopping thread";
371  Q_EMIT stopThread();
372  coreThread->wait();
373  qDebug() << __func__ << ": Stopped thread";
374  }
375 
376  delete window;
377  window = 0;
378 #ifdef ENABLE_WALLET
379  delete paymentServer;
380  paymentServer = 0;
381 #endif
382  // Delete Qt-settings if user clicked on "Reset Options"
383  QSettings settings;
385  settings.clear();
386  settings.sync();
387  }
388  delete optionsModel;
389  optionsModel = 0;
390 }
391 
392 #ifdef ENABLE_WALLET
393 void BitcoinApplication::createPaymentServer()
394 {
395  paymentServer = new PaymentServer(this);
396 }
397 #endif
398 
400 {
401  optionsModel = new OptionsModel(nullptr, resetSettings);
402 }
403 
405 {
406  window = new BitcoinGUI(networkStyle, 0);
407 
409 
410  pollShutdownTimer = new QTimer(window);
411  connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
412 }
413 
415 {
416  SplashScreen *splash = new SplashScreen(0, networkStyle);
417  // We don't hold a direct pointer to the splash screen after creation, but the splash
418  // screen will take care of deleting itself when slotFinish happens.
419  splash->show();
420  connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
421  connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close()));
422 }
423 
425 {
426  if(coreThread)
427  return;
428  coreThread = new QThread(this);
429  BitcoinCore *executor = new BitcoinCore();
430  executor->moveToThread(coreThread);
431 
432  /* communication to and from thread */
433  connect(executor, SIGNAL(initializeResult(bool)), this, SLOT(initializeResult(bool)));
434  connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult()));
435  connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
436  connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
437  connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
438  connect(window, SIGNAL(requestedRestart(QStringList)), executor, SLOT(restart(QStringList)));
439  /* make sure executor object is deleted in its own thread */
440  connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
441  connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
442 
443  coreThread->start();
444 }
445 
447 {
448  InitLogging();
450 }
451 
453 {
454  qDebug() << __func__ << ": Requesting initialize";
455  startThread();
456  Q_EMIT requestedInitialize();
457 }
458 
460 {
461  // Show a simple window indicating shutdown status
462  // Do this first as some of the steps may take some time below,
463  // for example the RPC console may still be executing a command.
465 
466  qDebug() << __func__ << ": Requesting shutdown";
467  startThread();
468  window->hide();
470  pollShutdownTimer->stop();
471 
472 #ifdef ENABLE_WALLET
473  window->removeAllWallets();
474  delete walletModel;
475  walletModel = 0;
476 #endif
477  delete clientModel;
478  clientModel = 0;
479 
480  StartShutdown();
481 
482  // Request shutdown from core thread
483  Q_EMIT requestedShutdown();
484 }
485 
487 {
488  qDebug() << __func__ << ": Initialization result: " << success;
489  // Set exit result.
490  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
491  if(success)
492  {
493  // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
494  qWarning() << "Platform customization:" << gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM).c_str();
495 #ifdef ENABLE_WALLET
497  paymentServer->setOptionsModel(optionsModel);
498 #endif
499 
502 
503 #ifdef ENABLE_WALLET
504  // TODO: Expose secondary wallets
505  if (HasWallets())
506  {
507  walletModel = new WalletModel(GetWallets()[0], optionsModel);
508 
509  window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
510  window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
511 
512  connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
513  paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
514  }
515 #endif
516 
517  // If -min option passed, start window minimized.
518  if(gArgs.GetBoolArg("-min", false))
519  {
520  window->showMinimized();
521  }
522  else
523  {
524  window->show();
525  }
526  Q_EMIT splashFinished(window);
527 
528  // Let the users setup their prefered appearance if there are no settings for it defined yet.
530 
531 #ifdef ENABLE_WALLET
532  // Now that initialization/startup is done, process any command-line
533  // dash: URIs or payment requests:
534  connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
535  window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
536  connect(window, SIGNAL(receivedURI(QString)),
537  paymentServer, SLOT(handleURIOrFile(QString)));
538  connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
539  window, SLOT(message(QString,QString,unsigned int)));
540  QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
541 #endif
542  pollShutdownTimer->start(200);
543  } else {
544  Q_EMIT splashFinished(window); // Make sure splash screen doesn't stick around during shutdown
545  quit(); // Exit first main loop invocation
546  }
547 }
548 
550 {
551  quit(); // Exit second main loop invocation after shutdown finished
552 }
553 
554 void BitcoinApplication::handleRunawayException(const QString &message)
555 {
556  QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Dash Core can no longer continue safely and will quit.") + QString("\n\n") + message);
557  ::exit(EXIT_FAILURE);
558 }
559 
561 {
562  if (!window)
563  return 0;
564 
565  return window->winId();
566 }
567 
568 #ifndef BITCOIN_QT_TEST
569 int main(int argc, char *argv[])
570 {
573 
575 
577  // Command-line options take precedence:
578  gArgs.ParseParameters(argc, argv);
579 
580  // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
581 
583 #if QT_VERSION < 0x050000
584  // Internal string conversion is all UTF-8
585  QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
586  QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
587 #endif
588 
589  Q_INIT_RESOURCE(dash);
590  Q_INIT_RESOURCE(dash_locale);
591 
592 #if QT_VERSION > 0x050100
593  // Generate high-dpi pixmaps
594  QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
595 #endif
596 #if QT_VERSION >= 0x050600
597  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
598 #endif
599 #ifdef Q_OS_MAC
600  QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
601 #endif
602 
603  BitcoinApplication app(argc, argv);
604 
605  // Register meta types used for QMetaObject::invokeMethod
606  qRegisterMetaType< bool* >();
607  // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
608  // IMPORTANT if it is no longer a typedef use the normal variant above
609  qRegisterMetaType< CAmount >("CAmount");
610  qRegisterMetaType< std::function<void(void)> >("std::function<void(void)>");
611 
613  // must be set before OptionsModel is initialized or translations are loaded,
614  // as it is used to locate QSettings
615  QApplication::setOrganizationName(QAPP_ORG_NAME);
616  QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
617  QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
619 
621  // Now that QSettings are accessible, initialize translations
622  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
623  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
625 
626  if (gArgs.IsArgSet("-printcrashinfo")) {
627  auto crashInfo = GetCrashInfoStrFromSerializedStr(gArgs.GetArg("-printcrashinfo", ""));
628  std::cout << crashInfo << std::endl;
629  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QString::fromStdString(crashInfo));
630  return EXIT_SUCCESS;
631  }
632 
633  // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
634  // but before showing splash screen.
635  if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version"))
636  {
638  help.showOrPrint();
639  return EXIT_SUCCESS;
640  }
641 
643  // User language is set up: pick a data directory
645  return EXIT_SUCCESS;
646 
649  if (!fs::is_directory(GetDataDir(false)))
650  {
651  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
652  QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
653  return EXIT_FAILURE;
654  }
655  try {
657  } catch (const std::exception& e) {
658  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
659  QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
660  return EXIT_FAILURE;
661  }
662 
664  // - Do not call Params() before this step
665  // - Do this after parsing the configuration file, as the network can be switched there
666  // - QSettings() will use the new application name after this, resulting in network-specific settings
667  // - Needs to be done before createOptionsModel
668 
669  // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
670  try {
672  } catch(std::exception &e) {
673  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what()));
674  return EXIT_FAILURE;
675  }
676 #ifdef ENABLE_WALLET
677  // Parse URIs on command line -- this can affect Params()
679 #endif
680 
681  QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
682  assert(!networkStyle.isNull());
683  // Allow for separate UI settings for testnets
684  // QApplication::setApplicationName(networkStyle->getAppName()); // moved to NetworkStyle::NetworkStyle
685  // Re-initialize translations after changing application name (language in network-specific settings can be different)
686  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
687 
688 #ifdef ENABLE_WALLET
689  // - Do this early as we don't want to bother initializing if we are just calling IPC
691  // - Do this *after* setting up the data directory, as the data directory hash is used in the name
692  // of the server.
693  // - Do this after creating app and setting up translations, so errors are
694  // translated properly.
696  exit(EXIT_SUCCESS);
697 
698  // Start up the payment server early, too, so impatient users that click on
699  // dash: links repeatedly have their payment requests routed to this process:
700  app.createPaymentServer();
701 #endif
702 
704  // Install global event filter that makes sure that long tooltips can be word-wrapped
705  app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
706 #if QT_VERSION < 0x050000
707  // Install qDebug() message handler to route to debug.log
708  qInstallMsgHandler(DebugMessageHandler);
709 #else
710 #if defined(Q_OS_WIN)
711  // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
712  qApp->installNativeEventFilter(new WinShutdownMonitor());
713 #endif
714  // Install qDebug() message handler to route to debug.log
715  qInstallMessageHandler(DebugMessageHandler);
716 #endif
717  // Allow parameter interaction before we create the options model
718  app.parameterSetup();
719  // Load GUI settings from QSettings
720  app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
721  // Load custom application fonts and setup font management
722  if (!GUIUtil::loadFonts()) {
723  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
724  QObject::tr("Error: Failed to load application fonts."));
725  return EXIT_FAILURE;
726  }
727  // Validate/set font family
728  if (gArgs.IsArgSet("-font-family")) {
729  GUIUtil::FontFamily family;
730  QString strFamily = gArgs.GetArg("-font-family", GUIUtil::fontFamilyToString(GUIUtil::getFontFamilyDefault()).toStdString()).c_str();
731  try {
732  family = GUIUtil::fontFamilyFromString(strFamily);
733  } catch (const std::exception& e) {
734  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
735  QObject::tr("Error: Specified font-family invalid. Valid values: %1.").arg("SystemDefault, Montserrat"));
736  return EXIT_FAILURE;
737  }
738  GUIUtil::setFontFamily(family);
739  }
740  // Validate/set normal font weight
741  if (gArgs.IsArgSet("-font-weight-normal")) {
742  QFont::Weight weight;
743  if (!GUIUtil::weightFromArg(gArgs.GetArg("-font-weight-normal", GUIUtil::weightToArg(GUIUtil::getFontWeightNormal())), weight)) {
744  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
745  QObject::tr("Error: Specified font-weight-normal invalid. Valid range %1 to %2.").arg(0).arg(8));
746  return EXIT_FAILURE;
747  }
749  }
750  // Validate/set bold font weight
751  if (gArgs.IsArgSet("-font-weight-bold")) {
752  QFont::Weight weight;
753  if (!GUIUtil::weightFromArg(gArgs.GetArg("-font-weight-bold", GUIUtil::weightToArg(GUIUtil::getFontWeightBold())), weight)) {
754  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
755  QObject::tr("Error: Specified font-weight-bold invalid. Valid range %1 to %2.").arg(0).arg(8));
756  return EXIT_FAILURE;
757  }
759  }
760  // Validate/set font scale
761  if (gArgs.IsArgSet("-font-scale")) {
762  const int nScaleMin = -100, nScaleMax = 100;
763  int nScale = gArgs.GetArg("-font-scale", GUIUtil::getFontScale());
764  if (nScale < nScaleMin || nScale > nScaleMax) {
765  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
766  QObject::tr("Error: Specified font-scale invalid. Valid range %1 to %2.").arg(nScaleMin).arg(nScaleMax));
767  return EXIT_FAILURE;
768  }
769  GUIUtil::setFontScale(nScale);
770  }
771  // Validate/set custom css directory
772  if (gArgs.IsArgSet("-custom-css-dir")) {
773  fs::path customDir = fs::path(gArgs.GetArg("-custom-css-dir", ""));
774  QString strCustomDir = QString::fromStdString(customDir.string());
775  std::vector<QString> vecRequiredFiles = GUIUtil::listStyleSheets();
776  QString strFile;
777 
778  if (!fs::is_directory(customDir)) {
779  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
780  QObject::tr("Error: Invalid -custom-css-dir path.") + "\n\n" + strCustomDir);
781  return EXIT_FAILURE;
782  }
783 
784  for (auto itCustomDir = fs::directory_iterator(customDir); itCustomDir != fs::directory_iterator(); ++itCustomDir) {
785  if (fs::is_regular_file(*itCustomDir) && itCustomDir->path().extension() == ".css") {
786  strFile = QString::fromStdString(itCustomDir->path().filename().string());
787  auto itFile = std::find(vecRequiredFiles.begin(), vecRequiredFiles.end(), strFile);
788  if (itFile != vecRequiredFiles.end()) {
789  vecRequiredFiles.erase(itFile);
790  }
791  }
792  }
793 
794  if (vecRequiredFiles.size()) {
795  QString strMissingFiles;
796  for (const auto& strMissingFile : vecRequiredFiles) {
797  strMissingFiles += strMissingFile + "\n";
798  }
799  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
800  QObject::tr("Error: %1 CSS file(s) missing in -custom-css-dir path.").arg(vecRequiredFiles.size()) + "\n\n" + strMissingFiles);
801  return EXIT_FAILURE;
802  }
803 
804  GUIUtil::setStyleSheetDirectory(strCustomDir);
805  }
806  // Validate -debug-ui
807  if (gArgs.GetBoolArg("-debug-ui", false)) {
808  QMessageBox::warning(0, QObject::tr(PACKAGE_NAME),
809  "Warning: UI debug mode (-debug-ui) enabled" + QString(gArgs.IsArgSet("-custom-css-dir") ? "." : " without a custom css directory set with -custom-css-dir."));
810  }
811 
812  // Subscribe to global signals from core
814 
815  if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
816  app.createSplashScreen(networkStyle.data());
817 
818  int rv = EXIT_SUCCESS;
819  try
820  {
821  app.createWindow(networkStyle.data());
822  // Perform base initialization before spinning up initialization/shutdown thread
823  // This is acceptable because this function only contains steps that are quick to execute,
824  // so the GUI thread won't be held up.
826  app.requestInitialize();
827 #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
828  WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), (HWND)app.getMainWinId());
829 #endif
830  app.exec();
831  app.requestShutdown();
832  app.exec();
833  rv = app.getReturnValue();
834  } else {
835  // A dialog with detailed error will have been shown by InitError()
836  rv = EXIT_FAILURE;
837  }
838  } catch (...) {
839  PrintExceptionContinue(std::current_exception(), "Runaway exception");
840  app.handleRunawayException(QString::fromStdString(GetWarnings("gui")));
841  }
842  return rv;
843 }
844 #endif // BITCOIN_QT_TEST
OptionsModel * optionsModel
Definition: dash.cpp:252
void SubstituteFonts(const QString &language)
Definition: guiutil.cpp:679
static void LoadRootCAs(X509_STORE *store=nullptr)
FontFamily
Definition: guiutil.h:277
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:784
bool weightFromArg(int nArg, QFont::Weight &weight)
Convert weight value from args (0-8) to QFont::Weight.
Definition: guiutil.cpp:1313
QFont::Weight getFontWeightNormal()
Definition: guiutil.cpp:1361
FontFamily getFontFamilyDefault()
set/get font family: GUIUtil::fontFamily
Definition: guiutil.cpp:1303
static const QString DEFAULT_WALLET
Display name for default wallet name.
Definition: bitcoingui.h:54
void setFontWeightBold(QFont::Weight weight)
Definition: guiutil.cpp:1382
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:730
int weightToArg(const QFont::Weight weight)
Convert QFont::Weight to an arg value (0-8)
Definition: guiutil.cpp:1334
void InitLogging()
Initialize the logging infrastructure.
Definition: init.cpp:1024
const char *const BITCOIN_CONF_FILENAME
Definition: util.cpp:104
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:20
Class encapsulating Dash Core startup and shutdown.
Definition: dash.cpp:179
bool AppInitMain()
Dash Core main initialization.
Definition: init.cpp:1586
FontFamily fontFamilyFromString(const QString &strFamily)
Definition: guiutil.cpp:1273
void parameterSetup()
parameter interaction/setup based on rules
Definition: dash.cpp:446
void setFontWeightNormal(QFont::Weight weight)
Definition: guiutil.cpp:1366
BitcoinApplication(int &argc, char **argv)
Definition: dash.cpp:350
void handleRunawayException(const std::exception_ptr e)
Pass fatal exception message to UI thread.
Definition: dash.cpp:273
void handleRunawayException(const QString &message)
Handle runaway exceptions. Shows a message box with the problem and quits the program.
Definition: dash.cpp:554
void StartShutdown()
Definition: init.cpp:171
std::string GetCrashInfoStrFromSerializedStr(const std::string &ciStr)
void loadTheme(QWidget *widget, bool fForce)
Load the theme and update all UI elements according to the appearance settings.
Definition: guiutil.cpp:1782
const std::vector< QString > listStyleSheets()
Return a list of all required css files.
Definition: guiutil.cpp:1130
void requestInitialize()
Request core initialization.
Definition: dash.cpp:452
static QString GetLangTerritory()
Definition: dash.cpp:101
void requestedRestart(QStringList args)
void Interrupt()
Interrupt threads.
Definition: init.cpp:215
OptionsModel * getOptionsModel()
Definition: box.hpp:161
static void InitMessage(const std::string &message)
Definition: dash.cpp:88
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:197
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:824
Bitcoin GUI main class.
Definition: bitcoingui.h:49
std::string GetWarnings(const std::string &strFor)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:41
void createOptionsModel(bool resetSettings)
Create options model.
Definition: dash.cpp:399
bool AppInitBasicSetup()
Initialize Dash Core: Basic context setup.
Definition: init.cpp:1059
void requestedInitialize()
void initializeResult(bool success)
static bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread.
Definition: dash.cpp:279
void ReadConfigFile(const std::string &confPath)
Definition: util.cpp:1000
void PrepareShutdown()
Preparing steps before shutting down or restarting the wallet.
Definition: init.cpp:228
void setupAppearance(QWidget *parent, OptionsModel *model)
Definition: guiutil.cpp:309
static const bool DEFAULT_SPLASHSCREEN
Definition: guiconstants.h:21
static void ipcParseCommandLine(int argc, char *argv[])
static bool ipcSendCommandLine()
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
void InitParameterInteraction()
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:923
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: bitcoingui.cpp:705
void shutdown()
Definition: dash.cpp:336
CTranslationInterface translationInterface
Definition: util.cpp:117
std::vector< CWallet * > GetWallets()
Definition: wallet.cpp:79
QFont::Weight getFontWeightBold()
Definition: guiutil.cpp:1377
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:1553
void restart(QStringList args)
Definition: dash.cpp:312
#define QAPP_ORG_NAME
Definition: guiconstants.h:44
#define LogPrintf(...)
Definition: util.h:203
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Definition: dash.cpp:414
Main Dash application object.
Definition: dash.cpp:206
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
QString fontFamilyToString(FontFamily family)
Definition: guiutil.cpp:1284
void Shutdown()
Shutdown is split into 2 parts: Part 1: shut down everything but the main wallet instance (done in Pr...
Definition: init.cpp:375
int main(int argc, char *argv[])
Definition: dash.cpp:569
void splashFinished(QWidget *window)
std::unique_ptr< QWidget > shutdownWindow
Definition: dash.cpp:261
UniValue help(const JSONRPCRequest &jsonRequest)
Definition: server.cpp:263
void initialize()
Definition: dash.cpp:300
void RegisterPrettyTerminateHander()
Model for Dash network client.
Definition: clientmodel.h:42
void shutdownResult()
Definition: dash.cpp:549
void DebugMessageHandler(QtMsgType type, const char *msg)
Definition: dash.cpp:156
void setStyleSheetDirectory(const QString &path)
Change the stylesheet directory.
Definition: guiutil.cpp:1120
BitcoinGUI * window
Definition: dash.cpp:254
void requestShutdown()
Request core shutdown.
Definition: dash.cpp:459
bool AppInitParameterInteraction()
Initialization: parameter interaction.
Definition: init.cpp:1109
QThread * coreThread
Definition: dash.cpp:251
#define LogPrint(category,...)
Definition: util.h:214
void PrintExceptionContinue(const std::exception_ptr pex, const char *pszExceptionOrigin)
Definition: util.cpp:891
#define QAPP_APP_NAME_DEFAULT
Definition: guiconstants.h:46
ArgsManager gArgs
Definition: util.cpp:108
bool loadFonts()
Load dash specific appliciation fonts.
Definition: guiutil.cpp:1409
void createWindow(const NetworkStyle *networkStyle)
Create main window.
Definition: dash.cpp:404
static const int TOOLTIP_WRAP_THRESHOLD
Definition: guiconstants.h:33
BitcoinCore()
Definition: dash.cpp:268
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:25
#define QAPP_ORG_DOMAIN
Definition: guiconstants.h:45
void initializeResult(bool success)
Definition: dash.cpp:486
const CChainParams & Params()
Return the currently selected parameters.
boost::signals2::signal< std::string(const char *psz)> Translate
Translate a message to the native language of the user.
Definition: util.h:70
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:100
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:808
void StartRestart()
Definition: init.cpp:175
static QWidget * showShutdownWindow(BitcoinGUI *window)
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:715
void RegisterPrettySignalHandlers()
static std::string Translate(const char *psz)
Definition: dash.cpp:96
void setFontScale(int nScale)
Definition: guiutil.cpp:1398
void startThread()
Definition: dash.cpp:424
"Help message" dialog box
Definition: utilitydialog.h:18
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: util.cpp:1026
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:928
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
Definition: dash.cpp:117
bool AppInitLockDataDirectory()
Lock Dash Core data directory.
Definition: init.cpp:1574
int getFontScale()
Definition: guiutil.cpp:1393
bool resetSettingsOnShutdown
Definition: optionsmodel.h:93
CClientUIInterface uiInterface
Definition: ui_interface.cpp:8
static void callCleanup()
Definition: net.cpp:3133
void SetupEnvironment()
Definition: util.cpp:1314
void shutdownResult()
bool HasWallets()
Definition: wallet.cpp:73
void setFontFamily(FontFamily family)
Definition: guiutil.cpp:1296
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:55
void runawayException(const QString &message)
static bool pickDataDirectory()
Determine data directory.
Definition: intro.cpp:190
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
Definition: dash.cpp:560
ClientModel * clientModel
Definition: dash.cpp:253
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:82
static const NetworkStyle * instantiate(const QString &networkId)
Get style associated with provided BIP70 network id, or 0 if not known.
int getReturnValue() const
Get process return value.
Definition: dash.cpp:232
QTimer * pollShutdownTimer
Definition: dash.cpp:255
Released under the MIT license