Raven Core  3.0.0
P2P Digital Currency
raven.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven 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/raven-config.h"
8 #endif
9 
10 #include "ravengui.h"
11 
12 #include "chainparams.h"
13 #include "clientmodel.h"
14 #include "fs.h"
15 #include "guiconstants.h"
16 #include "guiutil.h"
17 #include "intro.h"
18 #include "net.h"
19 #include "networkstyle.h"
20 #include "optionsmodel.h"
21 #include "platformstyle.h"
22 #include "splashscreen.h"
23 #include "utilitydialog.h"
24 #include "winshutdownmonitor.h"
25 
26 #ifdef ENABLE_WALLET
27 #include "paymentserver.h"
28 #include "walletmodel.h"
29 #endif
30 
31 #include "init.h"
32 #include "rpc/server.h"
33 #include "scheduler.h"
34 #include "ui_interface.h"
35 #include "util.h"
36 #include "warnings.h"
37 
38 #ifdef ENABLE_WALLET
39 #include "wallet/wallet.h"
40 #endif
41 
42 #include <stdint.h>
43 
44 #include <boost/thread.hpp>
45 #include "darkstyle.h"
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 #include <QSslConfiguration>
58 #include <QDir>
59 #include <QFontDatabase>
60 
61 #if defined(QT_STATICPLUGIN)
62 #include <QtPlugin>
63 #if QT_VERSION < 0x050000
64 Q_IMPORT_PLUGIN(qcncodecs)
65 Q_IMPORT_PLUGIN(qjpcodecs)
66 Q_IMPORT_PLUGIN(qtwcodecs)
67 Q_IMPORT_PLUGIN(qkrcodecs)
68 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
69 #else
70 #if QT_VERSION < 0x050400
71 Q_IMPORT_PLUGIN(AccessibleFactory)
72 #endif
73 #if defined(QT_QPA_PLATFORM_XCB)
74 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
75 #elif defined(QT_QPA_PLATFORM_WINDOWS)
76 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
77 #elif defined(QT_QPA_PLATFORM_COCOA)
78 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
79 #endif
80 #endif
81 #endif
82 
83 #if QT_VERSION < 0x050000
84 #include <QTextCodec>
85 #endif
86 
87 // Declare meta types used for QMetaObject::invokeMethod
88 Q_DECLARE_METATYPE(bool*)
89 Q_DECLARE_METATYPE(CAmount)
90 
91 static void InitMessage(const std::string &message)
92 {
93  LogPrintf("init message: %s\n", message);
94 }
95 
96 /*
97  Translate string to current locale using Qt.
98  */
99 static std::string Translate(const char* psz)
100 {
101  return QCoreApplication::translate("raven-core", psz).toStdString();
102 }
103 
104 static QString GetLangTerritory()
105 {
106  QSettings settings;
107  // Get desired locale (e.g. "de_DE")
108  // 1) System default language
109  QString lang_territory = QLocale::system().name();
110  // 2) Language from QSettings
111  QString lang_territory_qsettings = settings.value("language", "").toString();
112  if(!lang_territory_qsettings.isEmpty())
113  lang_territory = lang_territory_qsettings;
114  // 3) -lang command line argument
115  lang_territory = QString::fromStdString(gArgs.GetArg("-lang", lang_territory.toStdString()));
116  return lang_territory;
117 }
118 
120 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
121 {
122  // Remove old translators
123  QApplication::removeTranslator(&qtTranslatorBase);
124  QApplication::removeTranslator(&qtTranslator);
125  QApplication::removeTranslator(&translatorBase);
126  QApplication::removeTranslator(&translator);
127 
128  // Get desired locale (e.g. "de_DE")
129  // 1) System default language
130  QString lang_territory = GetLangTerritory();
131 
132  // Convert to "de" only by truncating "_DE"
133  QString lang = lang_territory;
134  lang.truncate(lang_territory.lastIndexOf('_'));
135 
136  // Load language files for configured locale:
137  // - First load the translator for the base language, without territory
138  // - Then load the more specific locale translator
139 
140  // Load e.g. qt_de.qm
141  if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
142  QApplication::installTranslator(&qtTranslatorBase);
143 
144  // Load e.g. qt_de_DE.qm
145  if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
146  QApplication::installTranslator(&qtTranslator);
147 
148  // Load e.g. raven_de.qm (shortcut "de" needs to be defined in raven.qrc)
149  if (translatorBase.load(lang, ":/translations/"))
150  QApplication::installTranslator(&translatorBase);
151 
152  // Load e.g. raven_de_DE.qm (shortcut "de_DE" needs to be defined in raven.qrc)
153  if (translator.load(lang_territory, ":/translations/"))
154  QApplication::installTranslator(&translator);
155 }
156 
157 /* qDebug() message handler --> debug.log */
158 #if QT_VERSION < 0x050000
159 void DebugMessageHandler(QtMsgType type, const char *msg)
160 {
161  if (type == QtDebugMsg) {
162  LogPrint(BCLog::QT, "GUI: %s\n", msg);
163  } else {
164  LogPrintf("GUI: %s\n", msg);
165  }
166 }
167 #else
168 void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
169 {
170  Q_UNUSED(context);
171  if (type == QtDebugMsg) {
172  LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
173  } else {
174  LogPrintf("GUI: %s\n", msg.toStdString());
175  }
176 }
177 #endif
178 
182 class RavenCore: public QObject
183 {
184  Q_OBJECT
185 public:
186  explicit RavenCore();
190  static bool baseInitialize();
191 
192 public Q_SLOTS:
193  void initialize();
194  void shutdown();
195  void restart(QStringList args);
196 
197 Q_SIGNALS:
198  void initializeResult(bool success);
199  void shutdownResult(bool success);
200  void runawayException(const QString &message);
201 
202 private:
203  boost::thread_group threadGroup;
205 
207  void handleRunawayException(const std::exception *e);
208 };
209 
211 class RavenApplication: public QApplication
212 {
213  Q_OBJECT
214 public:
215  explicit RavenApplication(int &argc, char **argv);
216  ~RavenApplication();
217 
218 #ifdef ENABLE_WALLET
219  void createPaymentServer();
221 #endif
222  void parameterSetup();
225  void createOptionsModel(bool resetSettings);
227  void createWindow(const NetworkStyle *networkStyle);
229  void createSplashScreen(const NetworkStyle *networkStyle);
230 
232  void requestInitialize();
234  void requestShutdown();
235 
237  int getReturnValue() const { return returnValue; }
238 
240  WId getMainWinId() const;
241 
242  OptionsModel* getOptionsModel() const { return optionsModel; }
243 
244 public Q_SLOTS:
245  void initializeResult(bool success);
246  void shutdownResult(bool success);
248  void handleRunawayException(const QString &message);
249 
250 Q_SIGNALS:
251  void requestedInitialize();
252  void requestedRestart(QStringList args);
253  void requestedShutdown();
254  void stopThread();
255  void splashFinished(QWidget *window);
256 
257 private:
258  QThread *coreThread;
263 #ifdef ENABLE_WALLET
264  PaymentServer* paymentServer;
265  WalletModel *walletModel;
266 #endif
269  std::unique_ptr<QWidget> shutdownWindow;
270 
271  void startThread();
272 };
273 
274 #include "raven.moc"
275 
277  QObject()
278 {
279 }
280 
281 void RavenCore::handleRunawayException(const std::exception *e)
282 {
283  PrintExceptionContinue(e, "Runaway exception");
284  Q_EMIT runawayException(QString::fromStdString(GetWarnings("gui")));
285 }
286 
288 {
289  if (!AppInitBasicSetup())
290  {
291  return false;
292  }
294  {
295  return false;
296  }
297  if (!AppInitSanityChecks())
298  {
299  return false;
300  }
302  {
303  return false;
304  }
305  return true;
306 }
307 
309 {
310  try
311  {
312  qDebug() << __func__ << ": Running initialization in thread";
313  bool rv = AppInitMain(threadGroup, scheduler);
314  Q_EMIT initializeResult(rv);
315  } catch (const std::exception& e) {
317  } catch (...) {
318  handleRunawayException(nullptr);
319  }
320 }
321 
322 void RavenCore::restart(QStringList args)
323 {
324  static bool executing_restart{false};
325 
326  if(!executing_restart) { // Only restart 1x, no matter how often a user clicks on a restart-button
327  executing_restart = true;
328  try
329  {
330  qDebug() << __func__ << ": Running Restart in thread";
332  threadGroup.join_all();
333  StartRestart();
334  PrepareShutdown();
335  qDebug() << __func__ << ": Shutdown finished";
336  Q_EMIT shutdownResult(true);
338  QProcess::startDetached(QApplication::applicationFilePath(), args);
339  qDebug() << __func__ << ": Restart initiated...";
340  QApplication::quit();
341  } catch (std::exception& e) {
343  } catch (...) {
344  handleRunawayException(nullptr);
345  }
346  }
347 }
348 
350 {
351  try
352  {
353  qDebug() << __func__ << ": Running Shutdown in thread";
355  threadGroup.join_all();
356  Shutdown();
357  qDebug() << __func__ << ": Shutdown finished";
358  Q_EMIT shutdownResult(true);
359  } catch (const std::exception& e) {
361  } catch (...) {
362  handleRunawayException(nullptr);
363  }
364 }
365 
366 RavenApplication::RavenApplication(int &argc, char **argv):
367  QApplication(argc, argv),
368  coreThread(0),
369  optionsModel(0),
370  clientModel(0),
371  window(0),
372  pollShutdownTimer(0),
373 #ifdef ENABLE_WALLET
374  paymentServer(0),
375  walletModel(0),
376 #endif
377  returnValue(0)
378 {
379  setQuitOnLastWindowClosed(false);
380 
381  // UI per-platform customization
382  // This must be done inside the RavenApplication constructor, or after it, because
383  // PlatformStyle::instantiate requires a QApplication
384  std::string platformName;
385  platformName = gArgs.GetArg("-uiplatform", RavenGUI::DEFAULT_UIPLATFORM);
386  platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
387  if (!platformStyle) // Fall back to "other" if specified name not found
389  assert(platformStyle);
390 }
391 
393 {
394  if(coreThread)
395  {
396  qDebug() << __func__ << ": Stopping thread";
397  Q_EMIT stopThread();
398  coreThread->wait();
399  qDebug() << __func__ << ": Stopped thread";
400  }
401 
402  delete window;
403  window = 0;
404 #ifdef ENABLE_WALLET
405  delete paymentServer;
406  paymentServer = 0;
407 #endif
408  delete optionsModel;
409  optionsModel = 0;
410  delete platformStyle;
411  platformStyle = 0;
412 }
413 
414 #ifdef ENABLE_WALLET
415 void RavenApplication::createPaymentServer()
416 {
417  paymentServer = new PaymentServer(this);
418 }
419 #endif
420 
421 void RavenApplication::createOptionsModel(bool resetSettings)
422 {
423  optionsModel = new OptionsModel(nullptr, resetSettings);
424 }
425 
427 {
428  window = new RavenGUI(platformStyle, networkStyle, 0);
429  window->setMinimumSize(200,200);
430  window->setBaseSize(640,640);
431 
432  pollShutdownTimer = new QTimer(window);
433  connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
434  pollShutdownTimer->start(200);
435 }
436 
438 {
439  SplashScreen *splash = new SplashScreen(0, networkStyle);
440  // We don't hold a direct pointer to the splash screen after creation, but the splash
441  // screen will take care of deleting itself when slotFinish happens.
442  splash->show();
443  connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
444  connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close()));
445 }
446 
448 {
449  if(coreThread)
450  return;
451  coreThread = new QThread(this);
452  RavenCore *executor = new RavenCore();
453  executor->moveToThread(coreThread);
454 
455  /* communication to and from thread */
456  connect(executor, SIGNAL(initializeResult(bool)), this, SLOT(initializeResult(bool)));
457  connect(executor, SIGNAL(shutdownResult(bool)), this, SLOT(shutdownResult(bool)));
458  connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
459  connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
460  connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
461  connect(window, SIGNAL(requestedRestart(QStringList)), executor, SLOT(restart(QStringList)));
462  /* make sure executor object is deleted in its own thread */
463  connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
464  connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
465 
466  coreThread->start();
467 }
468 
470 {
471  InitLogging();
473 }
474 
476 {
477  qDebug() << __func__ << ": Requesting initialize";
478  startThread();
479  Q_EMIT requestedInitialize();
480 }
481 
483 {
484  // Show a simple window indicating shutdown status
485  // Do this first as some of the steps may take some time below,
486  // for example the RPC console may still be executing a command.
488 
489  qDebug() << __func__ << ": Requesting shutdown";
490  startThread();
491  window->hide();
493  pollShutdownTimer->stop();
494 
495 #ifdef ENABLE_WALLET
496  window->removeAllWallets();
497  delete walletModel;
498  walletModel = 0;
499 #endif
500  delete clientModel;
501  clientModel = 0;
502 
503  StartShutdown();
504 
505  // Request shutdown from core thread
506  Q_EMIT requestedShutdown();
507 }
508 
510 {
511  qDebug() << __func__ << ": Initialization result: " << success;
512  // Set exit result.
513  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
514  if(success)
515  {
516  // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
517  qWarning() << "Platform customization:" << platformStyle->getName();
518 #ifdef ENABLE_WALLET
520  paymentServer->setOptionsModel(optionsModel);
521 #endif
522 
525 
526 #ifdef ENABLE_WALLET
527  // TODO: Expose secondary wallets
528  if (!vpwallets.empty())
529  {
530  walletModel = new WalletModel(platformStyle, vpwallets[0], optionsModel);
531 
532  window->addWallet(RavenGUI::DEFAULT_WALLET, walletModel);
533  window->setCurrentWallet(RavenGUI::DEFAULT_WALLET);
534 
535  connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
536  paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
537  }
538 #endif
539 
540  // If -min option passed, start window minimized.
541  if(gArgs.GetBoolArg("-min", false))
542  {
543  window->showMinimized();
544  }
545  else
546  {
547  window->show();
548  }
549  Q_EMIT splashFinished(window);
550 
551 #ifdef ENABLE_WALLET
552  // Now that initialization/startup is done, process any command-line
553  // raven: URIs or payment requests:
554  connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
555  window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
556  connect(window, SIGNAL(receivedURI(QString)),
557  paymentServer, SLOT(handleURIOrFile(QString)));
558  connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
559  window, SLOT(message(QString,QString,unsigned int)));
560  QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
561 #endif
562  } else {
563  quit(); // Exit main loop
564  }
565 }
566 
568 {
569  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
570  qDebug() << __func__ << ": Shutdown result: " << returnValue;
571  quit(); // Exit main loop after shutdown finished
572 }
573 
574 void RavenApplication::handleRunawayException(const QString &message)
575 {
576  QMessageBox::critical(0, "Runaway exception", RavenGUI::tr("A fatal error occurred. Raven can no longer continue safely and will quit.") + QString("\n\n") + message);
577  ::exit(EXIT_FAILURE);
578 }
579 
581 {
582  if (!window)
583  return 0;
584 
585  return window->winId();
586 }
587 
588 #ifndef RAVEN_QT_TEST
589 int main(int argc, char *argv[])
590 {
592 
594  // Command-line options take precedence:
595  gArgs.ParseParameters(argc, argv);
596 
597  // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
598 
600 #if QT_VERSION < 0x050000
601  // Internal string conversion is all UTF-8
602  QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
603  QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
604 #endif
605 
606  Q_INIT_RESOURCE(raven);
607  Q_INIT_RESOURCE(raven_locale);
608 
609  RavenApplication app(argc, argv);
610 #if QT_VERSION > 0x050100
611  // Generate high-dpi pixmaps
612  QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
613 #endif
614 #if QT_VERSION >= 0x050600
615  QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
616 #endif
617 #ifdef Q_OS_MAC
618  QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
619 #endif
620 #if QT_VERSION >= 0x050500
621  // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/),
622  // so set SSL protocols to TLS1.0+.
623  QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
624  sslconf.setProtocol(QSsl::TlsV1_0OrLater);
625  QSslConfiguration::setDefaultConfiguration(sslconf);
626 #endif
627 
628  // Register meta types used for QMetaObject::invokeMethod
629  qRegisterMetaType< bool* >();
630  // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
631  // IMPORTANT if it is no longer a typedef use the normal variant above
632  qRegisterMetaType< CAmount >("CAmount");
633  qRegisterMetaType< std::function<void(void)> >("std::function<void(void)>");
634 
636  // must be set before OptionsModel is initialized or translations are loaded,
637  // as it is used to locate QSettings
638  QApplication::setOrganizationName(QAPP_ORG_NAME);
639  QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
640  QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
641  GUIUtil::SubstituteFonts(GetLangTerritory());
642 
644  // Now that QSettings are accessible, initialize translations
645  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
646  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
647  translationInterface.Translate.connect(Translate);
648 
649  // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
650  // but before showing splash screen.
651  if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version"))
652  {
653  HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version"));
654  help.showOrPrint();
655  return EXIT_SUCCESS;
656  }
657 
659  // User language is set up: pick a data directory
661  return EXIT_SUCCESS;
662 
665  if (!fs::is_directory(GetDataDir(false)))
666  {
667  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
668  QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
669  return EXIT_FAILURE;
670  }
671  try {
673  } catch (const std::exception& e) {
674  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
675  QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
676  return EXIT_FAILURE;
677  }
678 
680  // - Do not call Params() before this step
681  // - Do this after parsing the configuration file, as the network can be switched there
682  // - QSettings() will use the new application name after this, resulting in network-specific settings
683  // - Needs to be done before createOptionsModel
684 
685  // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
686  try {
688  } catch(std::exception &e) {
689  QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what()));
690  return EXIT_FAILURE;
691  }
692 #ifdef ENABLE_WALLET
693  // Parse URIs on command line -- this can affect Params()
695 #endif
696 
697  QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
698  assert(!networkStyle.isNull());
699  // Allow for separate UI settings for testnets
700  QApplication::setApplicationName(networkStyle->getAppName());
701  // Re-initialize translations after changing application name (language in network-specific settings can be different)
702  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
703 
704 #ifdef ENABLE_WALLET
705  // - Do this early as we don't want to bother initializing if we are just calling IPC
707  // - Do this *after* setting up the data directory, as the data directory hash is used in the name
708  // of the server.
709  // - Do this after creating app and setting up translations, so errors are
710  // translated properly.
712  exit(EXIT_SUCCESS);
713 
714  // Start up the payment server early, too, so impatient users that click on
715  // raven: links repeatedly have their payment requests routed to this process:
716  app.createPaymentServer();
717 #endif
718 
720  // Install global event filter that makes sure that long tooltips can be word-wrapped
721  app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
722 #if QT_VERSION < 0x050000
723  // Install qDebug() message handler to route to debug.log
724  qInstallMsgHandler(DebugMessageHandler);
725 #else
726 #if defined(Q_OS_WIN)
727  // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
728  qApp->installNativeEventFilter(new WinShutdownMonitor());
729 #endif
730  // Install qDebug() message handler to route to debug.log
731  qInstallMessageHandler(DebugMessageHandler);
732 #endif
733  // Allow parameter interaction before we create the options model
734  app.parameterSetup();
735  // Load GUI settings from QSettings
736  app.createOptionsModel(gArgs.IsArgSet("-resetguisettings"));
737 
738  if (app.getOptionsModel()->getDarkModeEnabled()) {
739  app.setStyle(new DarkStyle);
740  darkModeEnabled = true;
741  } else {
742  app.setStyle("");
743  }
744 
745  // Subscribe to global signals from core
746  uiInterface.InitMessage.connect(InitMessage);
747 
748  if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
749  app.createSplashScreen(networkStyle.data());
750 
751  int rv = EXIT_SUCCESS;
752  try
753  {
754  app.createWindow(networkStyle.data());
755  // Perform base initialization before spinning up initialization/shutdown thread
756  // This is acceptable because this function only contains steps that are quick to execute,
757  // so the GUI thread won't be held up.
759  app.requestInitialize();
760 #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
761  WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), (HWND)app.getMainWinId());
762 #endif
763  app.exec();
764  app.requestShutdown();
765  app.exec();
766  rv = app.getReturnValue();
767  } else {
768  // A dialog with detailed error will have been shown by InitError()
769  rv = EXIT_FAILURE;
770  }
771  } catch (const std::exception& e) {
772  PrintExceptionContinue(&e, "Runaway exception");
773  app.handleRunawayException(QString::fromStdString(GetWarnings("gui")));
774  } catch (...) {
775  PrintExceptionContinue(nullptr, "Runaway exception");
776  app.handleRunawayException(QString::fromStdString(GetWarnings("gui")));
777  }
778  return rv;
779 }
780 #endif // RAVEN_QT_TEST
void shutdownResult(bool success)
void SubstituteFonts(const QString &language)
Definition: guiutil.cpp:513
OptionsModel * getOptionsModel() const
Definition: raven.cpp:242
static void LoadRootCAs(X509_STORE *store=nullptr)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:448
const char *const RAVEN_CONF_FILENAME
Definition: util.cpp:91
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:404
void InitLogging()
Initialize the logging infrastructure.
Definition: init.cpp:890
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:21
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: ravengui.cpp:790
void handleRunawayException(const QString &message)
Handle runaway exceptions. Shows a message box with the problem and quits the program.
Definition: raven.cpp:574
void StartShutdown()
Definition: init.cpp:128
OptionsModel * optionsModel
Definition: raven.cpp:259
void initialize()
Definition: raven.cpp:308
Main Raven application object.
Definition: raven.cpp:211
void shutdown()
Definition: raven.cpp:349
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:44
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: util.cpp:535
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:143
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:470
std::string GetWarnings(const std::string &strFor)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:41
bool AppInitBasicSetup()
Initialize raven core: Basic context setup.
Definition: init.cpp:923
#define PACKAGE_NAME
Definition: raven-config.h:350
void ReadConfigFile(const std::string &confPath)
Definition: util.cpp:621
void PrepareShutdown()
Preparing steps before shutting down or restarting the wallet.
Definition: init.cpp:182
static void ipcParseCommandLine(int argc, char *argv[])
QTimer * pollShutdownTimer
Definition: raven.cpp:262
RavenApplication(int &argc, char **argv)
Definition: raven.cpp:366
static bool ipcSendCommandLine()
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
void InitParameterInteraction()
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:813
CTranslationInterface translationInterface
Definition: util.cpp:102
RavenCore()
Definition: raven.cpp:276
bool darkModeEnabled
void startThread()
Definition: raven.cpp:447
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:1258
#define QAPP_ORG_NAME
Definition: guiconstants.h:113
#define LogPrintf(...)
Definition: util.h:149
static const QString DEFAULT_WALLET
Display name for default wallet name.
Definition: ravengui.h:52
static QWidget * showShutdownWindow(RavenGUI *window)
static const std::string DEFAULT_UIPLATFORM
Definition: ravengui.h:53
void Interrupt(boost::thread_group &threadGroup)
Interrupt threads.
Definition: init.cpp:169
#define ENABLE_WALLET
Definition: raven-config.h:39
static bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread.
Definition: raven.cpp:287
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
CScheduler scheduler
Definition: raven.cpp:204
void initializeResult(bool success)
boost::signals2::signal< std::string(const char *psz)> Translate
Translate a message to the native language of the user.
Definition: util.h:45
void Shutdown()
Shutdown is split into 2 parts: Part 1: shut down everything but the main wallet instance (done in Pr...
Definition: init.cpp:336
void DebugMessageHandler(QtMsgType type, const char *msg)
Definition: raven.cpp:159
const PlatformStyle * platformStyle
Definition: raven.cpp:268
void requestShutdown()
Request core shutdown.
Definition: raven.cpp:482
UniValue help(const JSONRPCRequest &jsonRequest)
Definition: server.cpp:216
int main(int argc, char *argv[])
Definition: raven.cpp:589
WId getMainWinId() const
Get window identifier of QMainWindow (RavenGUI)
Definition: raven.cpp:580
std::unique_ptr< QWidget > shutdownWindow
Definition: raven.cpp:269
Model for Raven network client.
Definition: clientmodel.h:39
Class encapsulating Raven Core startup and shutdown.
Definition: raven.cpp:182
void initializeResult(bool success)
Definition: raven.cpp:509
int getReturnValue() const
Get process return value.
Definition: raven.cpp:237
bool AppInitParameterInteraction()
Initialization: parameter interaction.
Definition: init.cpp:971
#define LogPrint(category,...)
Definition: util.h:160
#define QAPP_APP_NAME_DEFAULT
Definition: guiconstants.h:115
ArgsManager gArgs
Definition: util.cpp:94
void createWindow(const NetworkStyle *networkStyle)
Create main window.
Definition: raven.cpp:426
static const PlatformStyle * instantiate(const QString &platformId)
Get style associated with provided platform name, or 0 if not known.
Interface from Qt to configuration data structure for Raven client.
Definition: optionsmodel.h:23
#define QAPP_ORG_DOMAIN
Definition: guiconstants.h:114
void shutdownResult(bool success)
Definition: raven.cpp:567
const CChainParams & Params()
Return the currently selected parameters.
const QString & getName() const
Definition: platformstyle.h:22
Interface to Raven wallet from Qt view code.
Definition: walletmodel.h:165
Raven GUI main class.
Definition: ravengui.h:47
void createOptionsModel(bool resetSettings)
Create options model.
Definition: raven.cpp:421
void restart(QStringList args)
Definition: raven.cpp:322
void requestedShutdown()
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:454
void StartRestart()
Definition: init.cpp:132
void parameterSetup()
parameter interaction/setup based on rules
Definition: raven.cpp:469
void splashFinished(QWidget *window)
std::string ChainNameFromCommandLine()
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
void requestInitialize()
Request core initialization.
Definition: raven.cpp:475
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
void runawayException(const QString &message)
"Help message" dialog box
Definition: utilitydialog.h:19
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:572
ClientModel * clientModel
Definition: raven.cpp:260
void requestedInitialize()
bool AppInitLockDataDirectory()
Lock raven core data directory.
Definition: init.cpp:1279
CClientUIInterface uiInterface
Definition: ui_interface.cpp:9
bool AppInitMain(boost::thread_group &threadGroup, CScheduler &scheduler)
Raven core main initialization.
Definition: init.cpp:1291
RavenGUI * window
Definition: raven.cpp:261
static void callCleanup()
Definition: net.cpp:2436
bool getDarkModeEnabled() const
Definition: optionsmodel.h:73
void SetupEnvironment()
Definition: util.cpp:865
void handleRunawayException(const std::exception *e)
Pass fatal exception message to UI thread.
Definition: raven.cpp:281
boost::thread_group threadGroup
Definition: raven.cpp:203
static bool pickDataDirectory()
Determine data directory.
Definition: intro.cpp:190
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Definition: raven.cpp:437
QThread * coreThread
Definition: raven.cpp:258
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.
void requestedRestart(QStringList args)