2014-02-08 22:50:24 +01:00
// Copyright (c) 2011-2014 The Bitcoin developers
2013-11-04 16:20:43 +01:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2013-01-23 21:51:02 +01:00
2014-01-11 18:56:24 +01:00
# if defined(HAVE_CONFIG_H)
2014-06-23 20:04:24 +02:00
# include "config/bitcoin-config.h"
2014-01-11 18:56:24 +01:00
# endif
2011-05-12 14:49:42 +02:00
# include "bitcoingui.h"
2013-04-13 07:13:08 +02:00
2011-05-22 17:19:43 +02:00
# include "clientmodel.h"
2012-04-13 17:10:50 +02:00
# include "guiconstants.h"
2013-04-13 07:13:08 +02:00
# include "guiutil.h"
# include "intro.h"
# include "optionsmodel.h"
2013-04-14 11:35:37 +02:00
# include "splashscreen.h"
2014-01-16 16:05:44 +01:00
# include "utilitydialog.h"
2014-04-10 08:19:58 +02:00
# include "winshutdownmonitor.h"
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
# include "paymentserver.h"
2013-04-13 07:13:08 +02:00
# include "walletmodel.h"
2013-12-11 15:00:56 +01:00
# endif
2013-04-13 07:13:08 +02:00
# include "init.h"
# include "main.h"
2014-01-17 16:32:35 +01:00
# include "rpcserver.h"
2013-04-13 07:13:08 +02:00
# include "ui_interface.h"
# include "util.h"
2014-03-31 06:13:40 +02:00
# ifdef ENABLE_WALLET
2013-12-13 16:14:48 +01:00
# include "wallet.h"
2014-03-31 06:13:40 +02:00
# endif
2011-05-07 22:13:39 +02:00
2013-04-13 07:13:08 +02:00
# include <stdint.h>
# include <boost/filesystem/operations.hpp>
2013-07-23 08:52:24 +02:00
# include <QApplication>
2013-04-13 07:13:08 +02:00
# include <QLibraryInfo>
# include <QLocale>
2011-06-05 16:03:29 +02:00
# include <QMessageBox>
2013-04-13 07:13:08 +02:00
# include <QSettings>
# include <QTimer>
# include <QTranslator>
2014-01-07 11:30:17 +01:00
# include <QThread>
2013-04-13 07:13:08 +02:00
2013-12-02 22:54:19 +01:00
# if defined(QT_STATICPLUGIN)
2012-03-24 16:52:43 +01:00
# include <QtPlugin>
2013-12-02 22:54:19 +01:00
# if QT_VERSION < 0x050000
2012-03-24 16:52:43 +01:00
Q_IMPORT_PLUGIN ( qcncodecs )
Q_IMPORT_PLUGIN ( qjpcodecs )
Q_IMPORT_PLUGIN ( qtwcodecs )
Q_IMPORT_PLUGIN ( qkrcodecs )
Q_IMPORT_PLUGIN ( qtaccessiblewidgets )
2013-12-02 22:54:19 +01:00
# else
Q_IMPORT_PLUGIN ( AccessibleFactory )
Q_IMPORT_PLUGIN ( QWindowsIntegrationPlugin ) ;
# endif
# endif
# if QT_VERSION < 0x050000
# include <QTextCodec>
2012-03-24 16:52:43 +01:00
# endif
2013-04-14 18:50:40 +02:00
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE ( bool * )
2012-05-06 19:40:58 +02:00
static void InitMessage ( const std : : string & message )
2011-08-02 21:48:59 +02:00
{
2014-01-16 16:15:27 +01:00
LogPrintf ( " init message: %s \n " , message ) ;
2011-08-02 21:48:59 +02:00
}
2011-06-13 16:56:37 +02:00
/*
Translate string to current locale using Qt .
*/
2012-05-06 19:40:58 +02:00
static std : : string Translate ( const char * psz )
2011-06-13 16:56:37 +02:00
{
return QCoreApplication : : translate ( " bitcoin-core " , psz ) . toStdString ( ) ;
}
2013-05-19 17:36:01 +02:00
/** Set up translations */
static void initTranslations ( QTranslator & qtTranslatorBase , QTranslator & qtTranslator , QTranslator & translatorBase , QTranslator & translator )
{
QSettings settings ;
2014-03-11 08:32:07 +01:00
// Remove old translators
QApplication : : removeTranslator ( & qtTranslatorBase ) ;
QApplication : : removeTranslator ( & qtTranslator ) ;
QApplication : : removeTranslator ( & translatorBase ) ;
QApplication : : removeTranslator ( & translator ) ;
2013-05-19 17:36:01 +02:00
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = QLocale : : system ( ) . name ( ) ;
// 2) Language from QSettings
QString lang_territory_qsettings = settings . value ( " language " , " " ) . toString ( ) ;
if ( ! lang_territory_qsettings . isEmpty ( ) )
lang_territory = lang_territory_qsettings ;
// 3) -lang command line argument
lang_territory = QString : : fromStdString ( GetArg ( " -lang " , lang_territory . toStdString ( ) ) ) ;
// Convert to "de" only by truncating "_DE"
QString lang = lang_territory ;
lang . truncate ( lang_territory . lastIndexOf ( ' _ ' ) ) ;
// Load language files for configured locale:
// - First load the translator for the base language, without territory
// - Then load the more specific locale translator
// Load e.g. qt_de.qm
if ( qtTranslatorBase . load ( " qt_ " + lang , QLibraryInfo : : location ( QLibraryInfo : : TranslationsPath ) ) )
QApplication : : installTranslator ( & qtTranslatorBase ) ;
// Load e.g. qt_de_DE.qm
if ( qtTranslator . load ( " qt_ " + lang_territory , QLibraryInfo : : location ( QLibraryInfo : : TranslationsPath ) ) )
QApplication : : installTranslator ( & qtTranslator ) ;
// Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
if ( translatorBase . load ( lang , " :/translations/ " ) )
QApplication : : installTranslator ( & translatorBase ) ;
// Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
if ( translator . load ( lang_territory , " :/translations/ " ) )
QApplication : : installTranslator ( & translator ) ;
}
2013-07-23 09:01:08 +02:00
/* qDebug() message handler --> debug.log */
# if QT_VERSION < 0x050000
2013-12-03 09:25:24 +01:00
void DebugMessageHandler ( QtMsgType type , const char * msg )
2013-07-23 09:01:08 +02:00
{
2014-07-01 14:57:45 +02:00
const char * category = ( type = = QtDebugMsg ) ? " qt " : NULL ;
LogPrint ( category , " GUI: %s \n " , msg ) ;
2013-07-23 09:01:08 +02:00
}
# else
void DebugMessageHandler ( QtMsgType type , const QMessageLogContext & context , const QString & msg )
{
2013-09-28 19:29:44 +02:00
Q_UNUSED ( context ) ;
2014-07-01 14:57:45 +02:00
const char * category = ( type = = QtDebugMsg ) ? " qt " : NULL ;
LogPrint ( category , " GUI: %s \n " , QString : : toStdString ( msg ) ) ;
2013-07-23 09:01:08 +02:00
}
# endif
2014-01-07 11:30:17 +01:00
/** Class encapsulating Bitcoin Core startup and shutdown.
* Allows running startup and shutdown in a different thread from the UI thread .
*/
class BitcoinCore : public QObject
{
Q_OBJECT
public :
explicit BitcoinCore ( ) ;
public slots :
void initialize ( ) ;
void shutdown ( ) ;
signals :
void initializeResult ( int retval ) ;
void shutdownResult ( int retval ) ;
void runawayException ( const QString & message ) ;
private :
boost : : thread_group threadGroup ;
/// Pass fatal exception message to UI thread
void handleRunawayException ( std : : exception * e ) ;
} ;
/** Main Bitcoin application object */
class BitcoinApplication : public QApplication
{
Q_OBJECT
public :
explicit BitcoinApplication ( int & argc , char * * argv ) ;
~ BitcoinApplication ( ) ;
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-01-07 11:30:17 +01:00
/// Create payment server
void createPaymentServer ( ) ;
2013-12-11 15:00:56 +01:00
# endif
2014-01-07 11:30:17 +01:00
/// Create options model
void createOptionsModel ( ) ;
/// Create main window
void createWindow ( bool isaTestNet ) ;
2014-01-08 08:59:24 +01:00
/// Create splash screen
void createSplashScreen ( bool isaTestNet ) ;
2014-01-07 11:30:17 +01:00
/// Request core initialization
void requestInitialize ( ) ;
/// Request core shutdown
void requestShutdown ( ) ;
/// Get process return value
int getReturnValue ( ) { return returnValue ; }
2014-04-10 08:19:58 +02:00
/// Get window identifier of QMainWindow (BitcoinGUI)
WId getMainWinId ( ) const ;
2014-01-07 11:30:17 +01:00
public slots :
void initializeResult ( int retval ) ;
void shutdownResult ( int retval ) ;
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
void handleRunawayException ( const QString & message ) ;
signals :
void requestedInitialize ( ) ;
void requestedShutdown ( ) ;
void stopThread ( ) ;
2014-01-08 08:59:24 +01:00
void splashFinished ( QWidget * window ) ;
2014-01-07 11:30:17 +01:00
private :
QThread * coreThread ;
OptionsModel * optionsModel ;
ClientModel * clientModel ;
BitcoinGUI * window ;
2014-01-08 10:45:00 +01:00
QTimer * pollShutdownTimer ;
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
PaymentServer * paymentServer ;
WalletModel * walletModel ;
# endif
2014-01-07 11:30:17 +01:00
int returnValue ;
void startThread ( ) ;
} ;
# include "bitcoin.moc"
BitcoinCore : : BitcoinCore ( ) :
QObject ( )
{
}
void BitcoinCore : : handleRunawayException ( std : : exception * e )
{
PrintExceptionContinue ( e , " Runaway exception " ) ;
emit runawayException ( QString : : fromStdString ( strMiscWarning ) ) ;
}
void BitcoinCore : : initialize ( )
{
try
{
LogPrintf ( " Running AppInit2 in thread \n " ) ;
int rv = AppInit2 ( threadGroup ) ;
2014-01-17 16:32:35 +01:00
if ( rv )
{
/* Start a dummy RPC thread if no RPC thread is active yet
* to handle timeouts .
*/
StartDummyRPCThread ( ) ;
}
2014-01-07 11:30:17 +01:00
emit initializeResult ( rv ) ;
} catch ( std : : exception & e ) {
handleRunawayException ( & e ) ;
} catch ( . . . ) {
handleRunawayException ( NULL ) ;
}
}
void BitcoinCore : : shutdown ( )
{
try
{
LogPrintf ( " Running Shutdown in thread \n " ) ;
threadGroup . interrupt_all ( ) ;
threadGroup . join_all ( ) ;
Shutdown ( ) ;
LogPrintf ( " Shutdown finished \n " ) ;
emit shutdownResult ( 1 ) ;
} catch ( std : : exception & e ) {
handleRunawayException ( & e ) ;
} catch ( . . . ) {
handleRunawayException ( NULL ) ;
}
}
BitcoinApplication : : BitcoinApplication ( int & argc , char * * argv ) :
QApplication ( argc , argv ) ,
coreThread ( 0 ) ,
optionsModel ( 0 ) ,
clientModel ( 0 ) ,
window ( 0 ) ,
2014-01-08 10:45:00 +01:00
pollShutdownTimer ( 0 ) ,
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
paymentServer ( 0 ) ,
walletModel ( 0 ) ,
# endif
2014-01-07 11:30:17 +01:00
returnValue ( 0 )
{
setQuitOnLastWindowClosed ( false ) ;
startThread ( ) ;
}
BitcoinApplication : : ~ BitcoinApplication ( )
{
LogPrintf ( " Stopping thread \n " ) ;
emit stopThread ( ) ;
coreThread - > wait ( ) ;
LogPrintf ( " Stopped thread \n " ) ;
2014-01-08 08:59:24 +01:00
delete window ;
2013-12-11 15:00:56 +01:00
window = 0 ;
# ifdef ENABLE_WALLET
2014-01-08 08:59:24 +01:00
delete paymentServer ;
2013-12-11 15:00:56 +01:00
paymentServer = 0 ;
# endif
2014-01-08 08:59:24 +01:00
delete optionsModel ;
2013-12-11 15:00:56 +01:00
optionsModel = 0 ;
2014-01-07 11:30:17 +01:00
}
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-01-07 11:30:17 +01:00
void BitcoinApplication : : createPaymentServer ( )
{
paymentServer = new PaymentServer ( this ) ;
}
2013-12-11 15:00:56 +01:00
# endif
2014-01-07 11:30:17 +01:00
void BitcoinApplication : : createOptionsModel ( )
{
optionsModel = new OptionsModel ( ) ;
}
void BitcoinApplication : : createWindow ( bool isaTestNet )
{
window = new BitcoinGUI ( isaTestNet , 0 ) ;
2014-01-08 10:45:00 +01:00
pollShutdownTimer = new QTimer ( window ) ;
2014-01-07 11:30:17 +01:00
connect ( pollShutdownTimer , SIGNAL ( timeout ( ) ) , window , SLOT ( detectShutdown ( ) ) ) ;
pollShutdownTimer - > start ( 200 ) ;
}
2014-01-08 08:59:24 +01:00
void BitcoinApplication : : createSplashScreen ( bool isaTestNet )
{
SplashScreen * splash = new SplashScreen ( QPixmap ( ) , 0 , isaTestNet ) ;
splash - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
splash - > show ( ) ;
connect ( this , SIGNAL ( splashFinished ( QWidget * ) ) , splash , SLOT ( slotFinish ( QWidget * ) ) ) ;
}
2014-01-07 11:30:17 +01:00
void BitcoinApplication : : startThread ( )
{
coreThread = new QThread ( this ) ;
BitcoinCore * executor = new BitcoinCore ( ) ;
executor - > moveToThread ( coreThread ) ;
/* communication to and from thread */
connect ( executor , SIGNAL ( initializeResult ( int ) ) , this , SLOT ( initializeResult ( int ) ) ) ;
connect ( executor , SIGNAL ( shutdownResult ( int ) ) , this , SLOT ( shutdownResult ( int ) ) ) ;
connect ( executor , SIGNAL ( runawayException ( QString ) ) , this , SLOT ( handleRunawayException ( QString ) ) ) ;
connect ( this , SIGNAL ( requestedInitialize ( ) ) , executor , SLOT ( initialize ( ) ) ) ;
connect ( this , SIGNAL ( requestedShutdown ( ) ) , executor , SLOT ( shutdown ( ) ) ) ;
/* make sure executor object is deleted in its own thread */
connect ( this , SIGNAL ( stopThread ( ) ) , executor , SLOT ( deleteLater ( ) ) ) ;
connect ( this , SIGNAL ( stopThread ( ) ) , coreThread , SLOT ( quit ( ) ) ) ;
coreThread - > start ( ) ;
}
void BitcoinApplication : : requestInitialize ( )
{
LogPrintf ( " Requesting initialize \n " ) ;
emit requestedInitialize ( ) ;
}
void BitcoinApplication : : requestShutdown ( )
{
LogPrintf ( " Requesting shutdown \n " ) ;
window - > hide ( ) ;
window - > setClientModel ( 0 ) ;
2014-01-08 10:45:00 +01:00
pollShutdownTimer - > stop ( ) ;
2014-01-07 16:04:47 +01:00
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
window - > removeAllWallets ( ) ;
2014-01-07 11:30:17 +01:00
delete walletModel ;
2014-01-08 08:59:24 +01:00
walletModel = 0 ;
2013-12-11 15:00:56 +01:00
# endif
2014-01-08 08:59:24 +01:00
delete clientModel ;
clientModel = 0 ;
2014-01-07 16:04:47 +01:00
// Show a simple window indicating shutdown status
2014-01-16 16:05:44 +01:00
ShutdownWindow : : showShutdownWindow ( window ) ;
2014-01-07 16:04:47 +01:00
// Request shutdown from core thread
2014-01-07 11:30:17 +01:00
emit requestedShutdown ( ) ;
}
void BitcoinApplication : : initializeResult ( int retval )
{
LogPrintf ( " Initialization result: %i \n " , retval ) ;
2014-01-07 16:04:47 +01:00
// Set exit result: 0 if successful, 1 if failure
2014-01-07 11:30:17 +01:00
returnValue = retval ? 0 : 1 ;
if ( retval )
{
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-01-07 11:30:17 +01:00
PaymentServer : : LoadRootCAs ( ) ;
paymentServer - > setOptionsModel ( optionsModel ) ;
2013-12-11 15:00:56 +01:00
# endif
2014-01-07 11:30:17 +01:00
2014-01-08 08:59:24 +01:00
emit splashFinished ( window ) ;
2014-01-07 11:30:17 +01:00
clientModel = new ClientModel ( optionsModel ) ;
window - > setClientModel ( clientModel ) ;
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-01-07 11:30:17 +01:00
if ( pwalletMain )
{
walletModel = new WalletModel ( pwalletMain , optionsModel ) ;
window - > addWallet ( " ~Default " , walletModel ) ;
window - > setCurrentWallet ( " ~Default " ) ;
connect ( walletModel , SIGNAL ( coinsSent ( CWallet * , SendCoinsRecipient , QByteArray ) ) ,
paymentServer , SLOT ( fetchPaymentACK ( CWallet * , const SendCoinsRecipient & , QByteArray ) ) ) ;
}
2013-12-11 15:00:56 +01:00
# endif
2014-01-07 11:30:17 +01:00
// If -min option passed, start window minimized.
if ( GetBoolArg ( " -min " , false ) )
{
window - > showMinimized ( ) ;
}
else
{
window - > show ( ) ;
}
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-01-07 11:30:17 +01:00
// Now that initialization/startup is done, process any command-line
// bitcoin: URIs or payment requests:
connect ( paymentServer , SIGNAL ( receivedPaymentRequest ( SendCoinsRecipient ) ) ,
window , SLOT ( handlePaymentRequest ( SendCoinsRecipient ) ) ) ;
connect ( window , SIGNAL ( receivedURI ( QString ) ) ,
paymentServer , SLOT ( handleURIOrFile ( QString ) ) ) ;
connect ( paymentServer , SIGNAL ( message ( QString , QString , unsigned int ) ) ,
window , SLOT ( message ( QString , QString , unsigned int ) ) ) ;
QTimer : : singleShot ( 100 , paymentServer , SLOT ( uiReady ( ) ) ) ;
2013-12-11 15:00:56 +01:00
# endif
2014-01-07 11:30:17 +01:00
} else {
quit ( ) ; // Exit main loop
}
}
void BitcoinApplication : : shutdownResult ( int retval )
{
LogPrintf ( " Shutdown result: %i \n " , retval ) ;
quit ( ) ; // Exit main loop after shutdown finished
}
void BitcoinApplication : : handleRunawayException ( const QString & message )
{
QMessageBox : : critical ( 0 , " Runaway exception " , BitcoinGUI : : tr ( " A fatal error occurred. Bitcoin can no longer continue safely and will quit. " ) + QString ( " \n \n " ) + message ) ;
: : exit ( 1 ) ;
}
2014-04-10 08:19:58 +02:00
WId BitcoinApplication : : getMainWinId ( ) const
{
if ( ! window )
return 0 ;
return window - > winId ( ) ;
}
2012-02-10 23:25:36 +01:00
# ifndef BITCOIN_QT_TEST
2011-05-07 22:13:39 +02:00
int main ( int argc , char * argv [ ] )
{
2014-05-13 12:15:00 +02:00
SetupEnvironment ( ) ;
2014-01-05 12:37:51 +01:00
/// 1. Parse command-line options. These take precedence over anything else.
2013-01-03 22:06:18 +01:00
// Command-line options take precedence:
ParseParameters ( argc , argv ) ;
2014-01-05 12:37:51 +01:00
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
2013-01-03 22:06:18 +01:00
2014-01-05 12:37:51 +01:00
/// 2. Basic Qt initialization (not dependent on parameters or configuration)
2013-05-31 14:02:24 +02:00
# if QT_VERSION < 0x050000
2011-11-12 12:20:34 +01:00
// Internal string conversion is all UTF-8
2011-08-28 14:12:26 +02:00
QTextCodec : : setCodecForTr ( QTextCodec : : codecForName ( " UTF-8 " ) ) ;
QTextCodec : : setCodecForCStrings ( QTextCodec : : codecForTr ( ) ) ;
2013-05-31 14:02:24 +02:00
# endif
2011-08-28 14:12:26 +02:00
2011-06-18 14:25:24 +02:00
Q_INIT_RESOURCE ( bitcoin ) ;
2014-06-10 21:43:02 +02:00
Q_INIT_RESOURCE ( bitcoin_locale ) ;
2014-01-07 11:30:17 +01:00
BitcoinApplication app ( argc , argv ) ;
2013-11-21 17:59:31 +01:00
# if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication : : setAttribute ( Qt : : AA_UseHighDpiPixmaps ) ;
# endif
# ifdef Q_OS_MAC
QApplication : : setAttribute ( Qt : : AA_DontShowIconsInMenus ) ;
# endif
2011-06-23 22:35:30 +02:00
2013-04-14 18:50:40 +02:00
// Register meta types used for QMetaObject::invokeMethod
qRegisterMetaType < bool * > ( ) ;
2014-01-05 12:37:51 +01:00
/// 3. Application identification
// must be set before OptionsModel is initialized or translations are loaded,
// as it is used to locate QSettings
2014-03-11 08:32:07 +01:00
QApplication : : setOrganizationName ( QAPP_ORG_NAME ) ;
QApplication : : setOrganizationDomain ( QAPP_ORG_DOMAIN ) ;
QApplication : : setApplicationName ( QAPP_APP_NAME_DEFAULT ) ;
2013-05-19 17:36:01 +02:00
2014-01-05 12:37:51 +01:00
/// 4. Initialization of translations, so that intro dialog is in user's language
2013-05-19 17:36:01 +02:00
// Now that QSettings are accessible, initialize translations
QTranslator qtTranslatorBase , qtTranslator , translatorBase , translator ;
initTranslations ( qtTranslatorBase , qtTranslator , translatorBase , translator ) ;
2014-01-08 08:59:24 +01:00
uiInterface . Translate . connect ( Translate ) ;
2013-05-19 17:36:01 +02:00
2014-01-05 12:37:51 +01:00
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
// but before showing splash screen.
2014-06-03 16:12:19 +02:00
if ( mapArgs . count ( " -? " ) | | mapArgs . count ( " -help " ) | | mapArgs . count ( " -version " ) )
2014-01-05 12:37:51 +01:00
{
2014-06-03 16:12:19 +02:00
HelpMessageDialog help ( NULL , mapArgs . count ( " -version " ) ) ;
2014-01-05 12:37:51 +01:00
help . showOrPrint ( ) ;
2013-06-23 18:04:44 +02:00
return 1 ;
}
2014-01-05 12:37:51 +01:00
/// 5. Now that settings and translations are available, ask user for data directory
// User language is set up: pick a data directory
2014-03-11 08:32:07 +01:00
Intro : : pickDataDirectory ( ) ;
2014-01-05 12:37:51 +01:00
/// 6. Determine availability of data directory and parse bitcoin.conf
2014-03-11 08:32:07 +01:00
/// - Do not call GetDataDir(true) before this step finishes
2014-01-05 12:37:51 +01:00
if ( ! boost : : filesystem : : is_directory ( GetDataDir ( false ) ) )
{
QMessageBox : : critical ( 0 , QObject : : tr ( " Bitcoin " ) ,
QObject : : tr ( " Error: Specified data directory \" %1 \" does not exist. " ) . arg ( QString : : fromStdString ( mapArgs [ " -datadir " ] ) ) ) ;
return 1 ;
}
2014-04-07 10:10:01 +02:00
try {
ReadConfigFile ( mapArgs , mapMultiArgs ) ;
} catch ( std : : exception & e ) {
QMessageBox : : critical ( 0 , QObject : : tr ( " Bitcoin " ) ,
QObject : : tr ( " Error: Cannot parse configuration file: %1. Only use key=value syntax. " ) . arg ( e . what ( ) ) ) ;
return false ;
}
2014-01-05 12:37:51 +01:00
2014-03-11 08:32:07 +01:00
/// 7. Determine network (and switch to network specific options)
// - Do not call Params() before this step
// - Do this after parsing the configuration file, as the network can be switched there
// - QSettings() will use the new application name after this, resulting in network-specific settings
// - Needs to be done before createOptionsModel
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
if ( ! SelectParamsFromCommandLine ( ) ) {
QMessageBox : : critical ( 0 , QObject : : tr ( " Bitcoin " ) , QObject : : tr ( " Error: Invalid combination of -regtest and -testnet. " ) ) ;
return 1 ;
}
# ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
if ( ! PaymentServer : : ipcParseCommandLine ( argc , argv ) )
exit ( 0 ) ;
# endif
2014-06-19 15:10:04 +02:00
bool isaTestNet = Params ( ) . NetworkID ( ) ! = CBaseChainParams : : MAIN ;
2014-03-11 08:32:07 +01:00
// Allow for separate UI settings for testnets
if ( isaTestNet )
QApplication : : setApplicationName ( QAPP_APP_NAME_TESTNET ) ;
else
QApplication : : setApplicationName ( QAPP_APP_NAME_DEFAULT ) ;
// Re-initialize translations after changing application name (language in network-specific settings can be different)
initTranslations ( qtTranslatorBase , qtTranslator , translatorBase , translator ) ;
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2014-03-11 08:32:07 +01:00
/// 8. URI IPC sending
2014-01-05 12:37:51 +01:00
// - Do this early as we don't want to bother initializing if we are just calling IPC
// - Do this *after* setting up the data directory, as the data directory hash is used in the name
// of the server.
// - Do this after creating app and setting up translations, so errors are
// translated properly.
if ( PaymentServer : : ipcSendCommandLine ( ) )
exit ( 0 ) ;
2013-07-18 08:50:17 +02:00
// Start up the payment server early, too, so impatient users that click on
// bitcoin: links repeatedly have their payment requests routed to this process:
2014-01-07 11:30:17 +01:00
app . createPaymentServer ( ) ;
2013-12-11 15:00:56 +01:00
# endif
2013-07-18 08:50:17 +02:00
2014-03-11 08:32:07 +01:00
/// 9. Main GUI initialization
2012-04-13 17:10:50 +02:00
// Install global event filter that makes sure that long tooltips can be word-wrapped
app . installEventFilter ( new GUIUtil : : ToolTipToRichTextFilter ( TOOLTIP_WRAP_THRESHOLD , & app ) ) ;
2013-08-31 15:32:35 +02:00
# if QT_VERSION < 0x050000
2014-04-10 08:19:58 +02:00
// Install qDebug() message handler to route to debug.log
2013-08-31 15:32:35 +02:00
qInstallMsgHandler ( DebugMessageHandler ) ;
# else
2014-04-10 08:19:58 +02:00
# if defined(Q_OS_WIN)
// Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
qApp - > installNativeEventFilter ( new WinShutdownMonitor ( ) ) ;
# endif
// Install qDebug() message handler to route to debug.log
2013-08-31 15:32:35 +02:00
qInstallMessageHandler ( DebugMessageHandler ) ;
# endif
2014-01-05 12:37:51 +01:00
// Load GUI settings from QSettings
2014-01-07 11:30:17 +01:00
app . createOptionsModel ( ) ;
2012-02-17 03:09:41 +01:00
2012-05-06 19:40:58 +02:00
// Subscribe to global signals from core
uiInterface . InitMessage . connect ( InitMessage ) ;
2014-01-07 11:30:17 +01:00
if ( GetBoolArg ( " -splash " , true ) & & ! GetBoolArg ( " -min " , false ) )
2014-01-08 08:59:24 +01:00
app . createSplashScreen ( isaTestNet ) ;
2011-05-07 22:13:39 +02:00
2011-06-07 18:59:01 +02:00
try
{
2014-01-07 11:30:17 +01:00
app . createWindow ( isaTestNet ) ;
app . requestInitialize ( ) ;
2014-04-10 08:19:58 +02:00
# if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
2014-05-07 14:53:23 +02:00
WinShutdownMonitor : : registerShutdownBlockReason ( QObject : : tr ( " Bitcoin Core didn't yet exit safely... " ) , ( HWND ) app . getMainWinId ( ) ) ;
2014-04-10 08:19:58 +02:00
# endif
2014-01-07 11:30:17 +01:00
app . exec ( ) ;
app . requestShutdown ( ) ;
app . exec ( ) ;
2011-05-22 17:19:43 +02:00
} catch ( std : : exception & e ) {
2014-01-07 11:30:17 +01:00
PrintExceptionContinue ( & e , " Runaway exception " ) ;
app . handleRunawayException ( QString : : fromStdString ( strMiscWarning ) ) ;
2011-05-22 17:19:43 +02:00
} catch ( . . . ) {
2014-01-07 11:30:17 +01:00
PrintExceptionContinue ( NULL , " Runaway exception " ) ;
app . handleRunawayException ( QString : : fromStdString ( strMiscWarning ) ) ;
2011-05-22 17:19:43 +02:00
}
2014-01-07 11:30:17 +01:00
return app . getReturnValue ( ) ;
2011-05-07 22:13:39 +02:00
}
2012-02-10 23:25:36 +01:00
# endif // BITCOIN_QT_TEST