LCOV - code coverage report
Current view: top level - src/qt - bitcoin.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 228 0.0 %
Date: 2015-10-12 22:39:14 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2014 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #if defined(HAVE_CONFIG_H)
       6             : #include "config/bitcoin-config.h"
       7             : #endif
       8             : 
       9             : #include "bitcoingui.h"
      10             : 
      11             : #include "chainparams.h"
      12             : #include "clientmodel.h"
      13             : #include "guiconstants.h"
      14             : #include "guiutil.h"
      15             : #include "intro.h"
      16             : #include "networkstyle.h"
      17             : #include "optionsmodel.h"
      18             : #include "platformstyle.h"
      19             : #include "splashscreen.h"
      20             : #include "utilitydialog.h"
      21             : #include "winshutdownmonitor.h"
      22             : 
      23             : #ifdef ENABLE_WALLET
      24             : #include "paymentserver.h"
      25             : #include "walletmodel.h"
      26             : #endif
      27             : 
      28             : #include "init.h"
      29             : #include "rpcserver.h"
      30             : #include "scheduler.h"
      31             : #include "ui_interface.h"
      32             : #include "util.h"
      33             : 
      34             : #ifdef ENABLE_WALLET
      35             : #include "wallet/wallet.h"
      36             : #endif
      37             : 
      38             : #include <stdint.h>
      39             : 
      40             : #include <boost/filesystem/operations.hpp>
      41             : #include <boost/thread.hpp>
      42             : 
      43             : #include <QApplication>
      44             : #include <QDebug>
      45             : #include <QLibraryInfo>
      46             : #include <QLocale>
      47             : #include <QMessageBox>
      48             : #include <QSettings>
      49             : #include <QThread>
      50             : #include <QTimer>
      51             : #include <QTranslator>
      52             : #include <QSslConfiguration>
      53             : 
      54             : #if defined(QT_STATICPLUGIN)
      55             : #include <QtPlugin>
      56             : #if QT_VERSION < 0x050000
      57             : Q_IMPORT_PLUGIN(qcncodecs)
      58             : Q_IMPORT_PLUGIN(qjpcodecs)
      59             : Q_IMPORT_PLUGIN(qtwcodecs)
      60             : Q_IMPORT_PLUGIN(qkrcodecs)
      61             : Q_IMPORT_PLUGIN(qtaccessiblewidgets)
      62             : #else
      63             : #if QT_VERSION < 0x050400
      64             : Q_IMPORT_PLUGIN(AccessibleFactory)
      65             : #endif
      66             : #if defined(QT_QPA_PLATFORM_XCB)
      67             : Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
      68             : #elif defined(QT_QPA_PLATFORM_WINDOWS)
      69             : Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
      70             : #elif defined(QT_QPA_PLATFORM_COCOA)
      71             : Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
      72             : #endif
      73             : #endif
      74             : #endif
      75             : 
      76             : #if QT_VERSION < 0x050000
      77             : #include <QTextCodec>
      78             : #endif
      79             : 
      80             : // Declare meta types used for QMetaObject::invokeMethod
      81           0 : Q_DECLARE_METATYPE(bool*)
      82             : Q_DECLARE_METATYPE(CAmount)
      83             : 
      84           0 : static void InitMessage(const std::string &message)
      85             : {
      86           0 :     LogPrintf("init message: %s\n", message);
      87           0 : }
      88             : 
      89             : /*
      90             :    Translate string to current locale using Qt.
      91             :  */
      92           0 : static std::string Translate(const char* psz)
      93             : {
      94           0 :     return QCoreApplication::translate("bitcoin-core", psz).toStdString();
      95             : }
      96             : 
      97           0 : static QString GetLangTerritory()
      98             : {
      99           0 :     QSettings settings;
     100             :     // Get desired locale (e.g. "de_DE")
     101             :     // 1) System default language
     102           0 :     QString lang_territory = QLocale::system().name();
     103             :     // 2) Language from QSettings
     104           0 :     QString lang_territory_qsettings = settings.value("language", "").toString();
     105           0 :     if(!lang_territory_qsettings.isEmpty())
     106           0 :         lang_territory = lang_territory_qsettings;
     107             :     // 3) -lang command line argument
     108           0 :     lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
     109           0 :     return lang_territory;
     110             : }
     111             : 
     112             : /** Set up translations */
     113           0 : static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
     114             : {
     115             :     // Remove old translators
     116           0 :     QApplication::removeTranslator(&qtTranslatorBase);
     117           0 :     QApplication::removeTranslator(&qtTranslator);
     118           0 :     QApplication::removeTranslator(&translatorBase);
     119           0 :     QApplication::removeTranslator(&translator);
     120             : 
     121             :     // Get desired locale (e.g. "de_DE")
     122             :     // 1) System default language
     123           0 :     QString lang_territory = GetLangTerritory();
     124             : 
     125             :     // Convert to "de" only by truncating "_DE"
     126           0 :     QString lang = lang_territory;
     127           0 :     lang.truncate(lang_territory.lastIndexOf('_'));
     128             : 
     129             :     // Load language files for configured locale:
     130             :     // - First load the translator for the base language, without territory
     131             :     // - Then load the more specific locale translator
     132             : 
     133             :     // Load e.g. qt_de.qm
     134           0 :     if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
     135           0 :         QApplication::installTranslator(&qtTranslatorBase);
     136             : 
     137             :     // Load e.g. qt_de_DE.qm
     138           0 :     if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
     139           0 :         QApplication::installTranslator(&qtTranslator);
     140             : 
     141             :     // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
     142           0 :     if (translatorBase.load(lang, ":/translations/"))
     143           0 :         QApplication::installTranslator(&translatorBase);
     144             : 
     145             :     // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
     146           0 :     if (translator.load(lang_territory, ":/translations/"))
     147           0 :         QApplication::installTranslator(&translator);
     148           0 : }
     149             : 
     150             : /* qDebug() message handler --> debug.log */
     151             : #if QT_VERSION < 0x050000
     152           0 : void DebugMessageHandler(QtMsgType type, const char *msg)
     153             : {
     154           0 :     const char *category = (type == QtDebugMsg) ? "qt" : NULL;
     155           0 :     LogPrint(category, "GUI: %s\n", msg);
     156           0 : }
     157             : #else
     158             : void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
     159             : {
     160             :     Q_UNUSED(context);
     161             :     const char *category = (type == QtDebugMsg) ? "qt" : NULL;
     162             :     LogPrint(category, "GUI: %s\n", msg.toStdString());
     163             : }
     164             : #endif
     165             : 
     166             : /** Class encapsulating Bitcoin Core startup and shutdown.
     167             :  * Allows running startup and shutdown in a different thread from the UI thread.
     168             :  */
     169           0 : class BitcoinCore: public QObject
     170             : {
     171             :     Q_OBJECT
     172             : public:
     173             :     explicit BitcoinCore();
     174             : 
     175             : public Q_SLOTS:
     176             :     void initialize();
     177             :     void shutdown();
     178             : 
     179             : Q_SIGNALS:
     180             :     void initializeResult(int retval);
     181             :     void shutdownResult(int retval);
     182             :     void runawayException(const QString &message);
     183             : 
     184             : private:
     185             :     boost::thread_group threadGroup;
     186             :     CScheduler scheduler;
     187             : 
     188             :     /// Pass fatal exception message to UI thread
     189             :     void handleRunawayException(const std::exception *e);
     190             : };
     191             : 
     192             : /** Main Bitcoin application object */
     193             : class BitcoinApplication: public QApplication
     194             : {
     195             :     Q_OBJECT
     196             : public:
     197             :     explicit BitcoinApplication(int &argc, char **argv);
     198             :     ~BitcoinApplication();
     199             : 
     200             : #ifdef ENABLE_WALLET
     201             :     /// Create payment server
     202             :     void createPaymentServer();
     203             : #endif
     204             :     /// Create options model
     205             :     void createOptionsModel();
     206             :     /// Create main window
     207             :     void createWindow(const NetworkStyle *networkStyle);
     208             :     /// Create splash screen
     209             :     void createSplashScreen(const NetworkStyle *networkStyle);
     210             : 
     211             :     /// Request core initialization
     212             :     void requestInitialize();
     213             :     /// Request core shutdown
     214             :     void requestShutdown();
     215             : 
     216             :     /// Get process return value
     217           0 :     int getReturnValue() { return returnValue; }
     218             : 
     219             :     /// Get window identifier of QMainWindow (BitcoinGUI)
     220             :     WId getMainWinId() const;
     221             : 
     222             : public Q_SLOTS:
     223             :     void initializeResult(int retval);
     224             :     void shutdownResult(int retval);
     225             :     /// Handle runaway exceptions. Shows a message box with the problem and quits the program.
     226             :     void handleRunawayException(const QString &message);
     227             : 
     228             : Q_SIGNALS:
     229             :     void requestedInitialize();
     230             :     void requestedShutdown();
     231             :     void stopThread();
     232             :     void splashFinished(QWidget *window);
     233             : 
     234             : private:
     235             :     QThread *coreThread;
     236             :     OptionsModel *optionsModel;
     237             :     ClientModel *clientModel;
     238             :     BitcoinGUI *window;
     239             :     QTimer *pollShutdownTimer;
     240             : #ifdef ENABLE_WALLET
     241             :     PaymentServer* paymentServer;
     242             :     WalletModel *walletModel;
     243             : #endif
     244             :     int returnValue;
     245             :     const PlatformStyle *platformStyle;
     246             : 
     247             :     void startThread();
     248             : };
     249             : 
     250             : #include "bitcoin.moc"
     251             : 
     252           0 : BitcoinCore::BitcoinCore():
     253           0 :     QObject()
     254             : {
     255           0 : }
     256             : 
     257           0 : void BitcoinCore::handleRunawayException(const std::exception *e)
     258             : {
     259           0 :     PrintExceptionContinue(e, "Runaway exception");
     260           0 :     Q_EMIT runawayException(QString::fromStdString(strMiscWarning));
     261           0 : }
     262             : 
     263           0 : void BitcoinCore::initialize()
     264             : {
     265             :     try
     266             :     {
     267           0 :         qDebug() << __func__ << ": Running AppInit2 in thread";
     268           0 :         int rv = AppInit2(threadGroup, scheduler);
     269             :         Q_EMIT initializeResult(rv);
     270           0 :     } catch (const std::exception& e) {
     271           0 :         handleRunawayException(&e);
     272           0 :     } catch (...) {
     273           0 :         handleRunawayException(NULL);
     274             :     }
     275           0 : }
     276             : 
     277           0 : void BitcoinCore::shutdown()
     278             : {
     279             :     try
     280             :     {
     281           0 :         qDebug() << __func__ << ": Running Shutdown in thread";
     282           0 :         Interrupt(threadGroup);
     283           0 :         threadGroup.join_all();
     284           0 :         Shutdown();
     285           0 :         qDebug() << __func__ << ": Shutdown finished";
     286             :         Q_EMIT shutdownResult(1);
     287           0 :     } catch (const std::exception& e) {
     288           0 :         handleRunawayException(&e);
     289           0 :     } catch (...) {
     290           0 :         handleRunawayException(NULL);
     291             :     }
     292           0 : }
     293             : 
     294           0 : BitcoinApplication::BitcoinApplication(int &argc, char **argv):
     295             :     QApplication(argc, argv),
     296             :     coreThread(0),
     297             :     optionsModel(0),
     298             :     clientModel(0),
     299             :     window(0),
     300             :     pollShutdownTimer(0),
     301             : #ifdef ENABLE_WALLET
     302             :     paymentServer(0),
     303             :     walletModel(0),
     304             : #endif
     305           0 :     returnValue(0)
     306             : {
     307           0 :     setQuitOnLastWindowClosed(false);
     308             : 
     309             :     // UI per-platform customization
     310             :     // This must be done inside the BitcoinApplication constructor, or after it, because
     311             :     // PlatformStyle::instantiate requires a QApplication
     312             : #if defined(Q_OS_MAC)
     313             :     std::string platformName = "macosx";
     314             : #elif defined(Q_OS_WIN)
     315             :     std::string platformName = "windows";
     316             : #else
     317           0 :     std::string platformName = "other";
     318             : #endif
     319           0 :     platformName = GetArg("-uiplatform", platformName);
     320           0 :     platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
     321           0 :     if (!platformStyle) // Fall back to "other" if specified name not found
     322           0 :         platformStyle = PlatformStyle::instantiate("other");
     323           0 :     assert(platformStyle);
     324           0 : }
     325             : 
     326           0 : BitcoinApplication::~BitcoinApplication()
     327             : {
     328           0 :     if(coreThread)
     329             :     {
     330           0 :         qDebug() << __func__ << ": Stopping thread";
     331             :         Q_EMIT stopThread();
     332           0 :         coreThread->wait();
     333           0 :         qDebug() << __func__ << ": Stopped thread";
     334             :     }
     335             : 
     336           0 :     delete window;
     337           0 :     window = 0;
     338             : #ifdef ENABLE_WALLET
     339           0 :     delete paymentServer;
     340           0 :     paymentServer = 0;
     341             : #endif
     342           0 :     delete optionsModel;
     343           0 :     optionsModel = 0;
     344           0 :     delete platformStyle;
     345           0 :     platformStyle = 0;
     346           0 : }
     347             : 
     348             : #ifdef ENABLE_WALLET
     349           0 : void BitcoinApplication::createPaymentServer()
     350             : {
     351           0 :     paymentServer = new PaymentServer(this);
     352           0 : }
     353             : #endif
     354             : 
     355           0 : void BitcoinApplication::createOptionsModel()
     356             : {
     357           0 :     optionsModel = new OptionsModel();
     358           0 : }
     359             : 
     360           0 : void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
     361             : {
     362           0 :     window = new BitcoinGUI(platformStyle, networkStyle, 0);
     363             : 
     364           0 :     pollShutdownTimer = new QTimer(window);
     365           0 :     connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
     366           0 :     pollShutdownTimer->start(200);
     367           0 : }
     368             : 
     369           0 : void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle)
     370             : {
     371           0 :     SplashScreen *splash = new SplashScreen(0, networkStyle);
     372             :     // We don't hold a direct pointer to the splash screen after creation, so use
     373             :     // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
     374           0 :     splash->setAttribute(Qt::WA_DeleteOnClose);
     375           0 :     splash->show();
     376           0 :     connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
     377           0 : }
     378             : 
     379           0 : void BitcoinApplication::startThread()
     380             : {
     381           0 :     if(coreThread)
     382           0 :         return;
     383           0 :     coreThread = new QThread(this);
     384           0 :     BitcoinCore *executor = new BitcoinCore();
     385           0 :     executor->moveToThread(coreThread);
     386             : 
     387             :     /*  communication to and from thread */
     388           0 :     connect(executor, SIGNAL(initializeResult(int)), this, SLOT(initializeResult(int)));
     389           0 :     connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int)));
     390           0 :     connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
     391           0 :     connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
     392           0 :     connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
     393             :     /*  make sure executor object is deleted in its own thread */
     394           0 :     connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
     395           0 :     connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
     396             : 
     397           0 :     coreThread->start();
     398             : }
     399             : 
     400           0 : void BitcoinApplication::requestInitialize()
     401             : {
     402           0 :     qDebug() << __func__ << ": Requesting initialize";
     403           0 :     startThread();
     404             :     Q_EMIT requestedInitialize();
     405           0 : }
     406             : 
     407           0 : void BitcoinApplication::requestShutdown()
     408             : {
     409           0 :     qDebug() << __func__ << ": Requesting shutdown";
     410           0 :     startThread();
     411           0 :     window->hide();
     412           0 :     window->setClientModel(0);
     413           0 :     pollShutdownTimer->stop();
     414             : 
     415             : #ifdef ENABLE_WALLET
     416           0 :     window->removeAllWallets();
     417           0 :     delete walletModel;
     418           0 :     walletModel = 0;
     419             : #endif
     420           0 :     delete clientModel;
     421           0 :     clientModel = 0;
     422             : 
     423             :     // Show a simple window indicating shutdown status
     424           0 :     ShutdownWindow::showShutdownWindow(window);
     425             : 
     426             :     // Request shutdown from core thread
     427             :     Q_EMIT requestedShutdown();
     428           0 : }
     429             : 
     430           0 : void BitcoinApplication::initializeResult(int retval)
     431             : {
     432           0 :     qDebug() << __func__ << ": Initialization result: " << retval;
     433             :     // Set exit result: 0 if successful, 1 if failure
     434           0 :     returnValue = retval ? 0 : 1;
     435           0 :     if(retval)
     436             :     {
     437             :         // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete
     438           0 :         qWarning() << "Platform customization:" << platformStyle->getName();
     439             : #ifdef ENABLE_WALLET
     440           0 :         PaymentServer::LoadRootCAs();
     441           0 :         paymentServer->setOptionsModel(optionsModel);
     442             : #endif
     443             : 
     444           0 :         clientModel = new ClientModel(optionsModel);
     445           0 :         window->setClientModel(clientModel);
     446             : 
     447             : #ifdef ENABLE_WALLET
     448           0 :         if(pwalletMain)
     449             :         {
     450           0 :             walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel);
     451             : 
     452           0 :             window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
     453           0 :             window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
     454             : 
     455             :             connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
     456           0 :                              paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
     457             :         }
     458             : #endif
     459             : 
     460             :         // If -min option passed, start window minimized.
     461           0 :         if(GetBoolArg("-min", false))
     462             :         {
     463           0 :             window->showMinimized();
     464             :         }
     465             :         else
     466             :         {
     467           0 :             window->show();
     468             :         }
     469           0 :         Q_EMIT splashFinished(window);
     470             : 
     471             : #ifdef ENABLE_WALLET
     472             :         // Now that initialization/startup is done, process any command-line
     473             :         // bitcoin: URIs or payment requests:
     474             :         connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
     475           0 :                          window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
     476             :         connect(window, SIGNAL(receivedURI(QString)),
     477           0 :                          paymentServer, SLOT(handleURIOrFile(QString)));
     478             :         connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
     479           0 :                          window, SLOT(message(QString,QString,unsigned int)));
     480           0 :         QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
     481             : #endif
     482             :     } else {
     483           0 :         quit(); // Exit main loop
     484             :     }
     485           0 : }
     486             : 
     487           0 : void BitcoinApplication::shutdownResult(int retval)
     488             : {
     489           0 :     qDebug() << __func__ << ": Shutdown result: " << retval;
     490           0 :     quit(); // Exit main loop after shutdown finished
     491           0 : }
     492             : 
     493           0 : void BitcoinApplication::handleRunawayException(const QString &message)
     494             : {
     495           0 :     QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message);
     496           0 :     ::exit(1);
     497             : }
     498             : 
     499           0 : WId BitcoinApplication::getMainWinId() const
     500             : {
     501           0 :     if (!window)
     502             :         return 0;
     503             : 
     504           0 :     return window->winId();
     505             : }
     506             : 
     507             : #ifndef BITCOIN_QT_TEST
     508           0 : int main(int argc, char *argv[])
     509             : {
     510           0 :     SetupEnvironment();
     511             : 
     512             :     /// 1. Parse command-line options. These take precedence over anything else.
     513             :     // Command-line options take precedence:
     514           0 :     ParseParameters(argc, argv);
     515             : 
     516             :     // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
     517             : 
     518             :     /// 2. Basic Qt initialization (not dependent on parameters or configuration)
     519             : #if QT_VERSION < 0x050000
     520             :     // Internal string conversion is all UTF-8
     521           0 :     QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
     522           0 :     QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
     523             : #endif
     524             : 
     525           0 :     Q_INIT_RESOURCE(bitcoin);
     526           0 :     Q_INIT_RESOURCE(bitcoin_locale);
     527             : 
     528           0 :     BitcoinApplication app(argc, argv);
     529             : #if QT_VERSION > 0x050100
     530             :     // Generate high-dpi pixmaps
     531             :     QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
     532             : #endif
     533             : #ifdef Q_OS_MAC
     534             :     QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
     535             : #endif
     536             : #if QT_VERSION >= 0x050500
     537             :     // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/),
     538             :     // so set SSL protocols to TLS1.0+.
     539             :     QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
     540             :     sslconf.setProtocol(QSsl::TlsV1_0OrLater);
     541             :     QSslConfiguration::setDefaultConfiguration(sslconf);
     542             : #endif
     543             : 
     544             :     // Register meta types used for QMetaObject::invokeMethod
     545           0 :     qRegisterMetaType< bool* >();
     546             :     //   Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
     547             :     //   IMPORTANT if it is no longer a typedef use the normal variant above
     548           0 :     qRegisterMetaType< CAmount >("CAmount");
     549             : 
     550             :     /// 3. Application identification
     551             :     // must be set before OptionsModel is initialized or translations are loaded,
     552             :     // as it is used to locate QSettings
     553           0 :     QApplication::setOrganizationName(QAPP_ORG_NAME);
     554           0 :     QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
     555           0 :     QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
     556           0 :     GUIUtil::SubstituteFonts(GetLangTerritory());
     557             : 
     558             :     /// 4. Initialization of translations, so that intro dialog is in user's language
     559             :     // Now that QSettings are accessible, initialize translations
     560           0 :     QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
     561           0 :     initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
     562           0 :     translationInterface.Translate.connect(Translate);
     563             : 
     564             :     // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
     565             :     // but before showing splash screen.
     566           0 :     if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
     567             :     {
     568           0 :         HelpMessageDialog help(NULL, mapArgs.count("-version"));
     569           0 :         help.showOrPrint();
     570           0 :         return 1;
     571             :     }
     572             : 
     573             :     /// 5. Now that settings and translations are available, ask user for data directory
     574             :     // User language is set up: pick a data directory
     575           0 :     Intro::pickDataDirectory();
     576             : 
     577             :     /// 6. Determine availability of data directory and parse bitcoin.conf
     578             :     /// - Do not call GetDataDir(true) before this step finishes
     579           0 :     if (!boost::filesystem::is_directory(GetDataDir(false)))
     580             :     {
     581             :         QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
     582           0 :                               QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
     583           0 :         return 1;
     584             :     }
     585             :     try {
     586           0 :         ReadConfigFile(mapArgs, mapMultiArgs);
     587           0 :     } catch (const std::exception& e) {
     588             :         QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
     589           0 :                               QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
     590             :         return false;
     591             :     }
     592             : 
     593             :     /// 7. Determine network (and switch to network specific options)
     594             :     // - Do not call Params() before this step
     595             :     // - Do this after parsing the configuration file, as the network can be switched there
     596             :     // - QSettings() will use the new application name after this, resulting in network-specific settings
     597             :     // - Needs to be done before createOptionsModel
     598             : 
     599             :     // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
     600           0 :     if (!SelectParamsFromCommandLine()) {
     601           0 :         QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
     602           0 :         return 1;
     603             :     }
     604             : #ifdef ENABLE_WALLET
     605             :     // Parse URIs on command line -- this can affect Params()
     606           0 :     PaymentServer::ipcParseCommandLine(argc, argv);
     607             : #endif
     608             : 
     609           0 :     QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
     610           0 :     assert(!networkStyle.isNull());
     611             :     // Allow for separate UI settings for testnets
     612           0 :     QApplication::setApplicationName(networkStyle->getAppName());
     613             :     // Re-initialize translations after changing application name (language in network-specific settings can be different)
     614           0 :     initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
     615             : 
     616             : #ifdef ENABLE_WALLET
     617             :     /// 8. URI IPC sending
     618             :     // - Do this early as we don't want to bother initializing if we are just calling IPC
     619             :     // - Do this *after* setting up the data directory, as the data directory hash is used in the name
     620             :     // of the server.
     621             :     // - Do this after creating app and setting up translations, so errors are
     622             :     // translated properly.
     623           0 :     if (PaymentServer::ipcSendCommandLine())
     624           0 :         exit(0);
     625             : 
     626             :     // Start up the payment server early, too, so impatient users that click on
     627             :     // bitcoin: links repeatedly have their payment requests routed to this process:
     628           0 :     app.createPaymentServer();
     629             : #endif
     630             : 
     631             :     /// 9. Main GUI initialization
     632             :     // Install global event filter that makes sure that long tooltips can be word-wrapped
     633           0 :     app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
     634             : #if QT_VERSION < 0x050000
     635             :     // Install qDebug() message handler to route to debug.log
     636           0 :     qInstallMsgHandler(DebugMessageHandler);
     637             : #else
     638             : #if defined(Q_OS_WIN)
     639             :     // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
     640             :     qApp->installNativeEventFilter(new WinShutdownMonitor());
     641             : #endif
     642             :     // Install qDebug() message handler to route to debug.log
     643             :     qInstallMessageHandler(DebugMessageHandler);
     644             : #endif
     645             :     // Load GUI settings from QSettings
     646           0 :     app.createOptionsModel();
     647             : 
     648             :     // Subscribe to global signals from core
     649           0 :     uiInterface.InitMessage.connect(InitMessage);
     650             : 
     651           0 :     if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
     652           0 :         app.createSplashScreen(networkStyle.data());
     653             : 
     654             :     try
     655             :     {
     656           0 :         app.createWindow(networkStyle.data());
     657           0 :         app.requestInitialize();
     658             : #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
     659             :         WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Bitcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId());
     660             : #endif
     661           0 :         app.exec();
     662           0 :         app.requestShutdown();
     663           0 :         app.exec();
     664           0 :     } catch (const std::exception& e) {
     665           0 :         PrintExceptionContinue(&e, "Runaway exception");
     666           0 :         app.handleRunawayException(QString::fromStdString(strMiscWarning));
     667           0 :     } catch (...) {
     668           0 :         PrintExceptionContinue(NULL, "Runaway exception");
     669           0 :         app.handleRunawayException(QString::fromStdString(strMiscWarning));
     670             :     }
     671           0 :     return app.getReturnValue();
     672           0 : }
     673             : #endif // BITCOIN_QT_TEST

Generated by: LCOV version 1.11