2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2011-2015 The Bitcoin Core developers
2021-01-20 19:21:53 +01:00
* Copyright (C) 2018-2021 Tom Zander <tom@flowee.org>
2017-11-09 19:34:51 +01:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-01-23 21:51:02 +01:00
2014-01-11 18:56:24 +01:00
# if defined(HAVE_CONFIG_H)
2018-01-16 10:47:52 +00:00
# include "config/flowee-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 00:13:08 -05:00
2015-07-05 14:17:46 +02:00
# include "chainparams.h"
2019-11-13 11:46:09 +01:00
# include <server/util.h>
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 00:13:08 -05:00
# include "guiutil.h"
# include "intro.h"
2014-10-09 11:04:49 +02:00
# include "networkstyle.h"
2013-04-13 00:13:08 -05:00
# include "optionsmodel.h"
2015-07-28 15:20:14 +02:00
# include "platformstyle.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"
2014-09-05 13:18:35 +02:00
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
# include "paymentserver.h"
2013-04-13 00:13:08 -05:00
# include "walletmodel.h"
2013-12-11 15:00:56 +01:00
# endif
2011-05-07 22:13:39 +02:00
2013-04-13 00:13:08 -05:00
# include "init.h"
2014-01-17 16:32:35 +01:00
# include "rpcserver.h"
2015-04-03 11:50:06 -04:00
# include "scheduler.h"
2018-02-12 21:19:28 +01:00
# include "UiInterface.h"
2019-08-24 13:20:37 +02:00
# include <serverutil.h>
2018-02-12 14:15:24 +01:00
# include <SettingsDefaults.h>
2014-09-05 13:18:35 +02:00
2014-03-31 06:13:40 +02:00
# ifdef ENABLE_WALLET
2015-02-03 21:09:47 +01:00
# include "wallet/wallet.h"
2014-03-31 06:13:40 +02:00
# endif
2013-04-13 00:13:08 -05:00
# include <stdint.h>
# include <boost/filesystem/operations.hpp>
2014-08-21 16:11:09 +02:00
# include <boost/thread.hpp>
2014-09-05 13:18:35 +02:00
2013-07-23 08:52:24 +02:00
# include <QApplication>
2014-07-15 10:23:28 +02:00
# include <QDebug>
2013-04-13 00:13:08 -05:00
# include <QLibraryInfo>
# include <QLocale>
2011-06-05 16:03:29 +02:00
# include <QMessageBox>
2013-04-13 00:13:08 -05:00
# include <QSettings>
2014-09-05 13:18:35 +02:00
# include <QThread>
2013-04-13 00:13:08 -05:00
# include <QTimer>
# include <QTranslator>
2015-07-06 20:06:16 +02:00
# include <QSslConfiguration>
2018-02-13 13:09:33 +01:00
# include <Application.h>
2021-03-16 15:14:13 +01:00
# include <HubApiServices.h>
2013-04-13 00:13:08 -05:00
2013-12-02 16:54:19 -05:00
# if defined(QT_STATICPLUGIN)
2012-03-24 16:52:43 +01:00
# include <QtPlugin>
2014-06-03 23:42:53 -04:00
# if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN ( QXcbIntegrationPlugin ) ;
# elif defined(QT_QPA_PLATFORM_WINDOWS)
2013-12-02 16:54:19 -05:00
Q_IMPORT_PLUGIN ( QWindowsIntegrationPlugin ) ;
2014-06-03 23:42:53 -04:00
# elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN ( QCocoaIntegrationPlugin ) ;
# endif
2013-12-02 16:54:19 -05:00
# endif
2012-03-24 16:52:43 +01:00
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
{
2017-08-29 11:42:11 +02:00
logCritical ( Log : : Bitcoin ) < < " init message: " < < message ;
2011-08-02 21:48:59 +02:00
}
2019-08-24 13:20:37 +02:00
/** Signals for translation. */
class CTranslationInterface
{
public :
/** Translate a message to the native language of the user. */
boost : : signals2 : : signal < std : : string ( const char * psz ) > Translate ;
} ;
CTranslationInterface translationInterface ;
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
{
2017-11-13 23:09:33 +01:00
return QCoreApplication : : translate ( " Flowee the Hub " , psz ) . toStdString ( ) ;
2011-06-13 16:56:37 +02:00
}
2015-01-16 16:03:48 -05:00
static QString GetLangTerritory ( )
2013-05-19 17:36:01 +02:00
{
QSettings settings ;
// 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 ( ) ) ) ;
2015-01-16 16:03:48 -05:00
return lang_territory ;
}
/** Set up translations */
static void initTranslations ( QTranslator & qtTranslatorBase , QTranslator & qtTranslator , QTranslator & translatorBase , QTranslator & translator )
{
// Remove old translators
QApplication : : removeTranslator ( & qtTranslatorBase ) ;
QApplication : : removeTranslator ( & qtTranslator ) ;
QApplication : : removeTranslator ( & translatorBase ) ;
QApplication : : removeTranslator ( & translator ) ;
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = GetLangTerritory ( ) ;
2013-05-19 17:36:01 +02:00
// 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 ) ;
}
2018-11-21 12:18:32 +01:00
/* qDebug() message handler --> hub.log */
2013-07-23 17:01:08 +10:00
void DebugMessageHandler ( QtMsgType type , const QMessageLogContext & context , const QString & msg )
{
2017-05-12 15:06:08 +02:00
Log : : Item ( context . file , context . line , context . function , Log : : QtGui , type )
< < msg . toUtf8 ( ) . constData ( ) ;
2013-07-23 17:01:08 +10:00
}
2017-11-13 23:09:33 +01:00
/** Class encapsulating the hub startup and shutdown.
2014-01-07 11:30:17 +01:00
* Allows running startup and shutdown in a different thread from the UI thread.
*/
class BitcoinCore : public QObject
{
Q_OBJECT
public :
2018-02-13 13:09:33 +01:00
BitcoinCore ( ) ;
2014-01-07 11:30:17 +01:00
2015-07-14 13:59:05 +02:00
public Q_SLOTS :
2014-01-07 11:30:17 +01:00
void initialize ( ) ;
void shutdown ( ) ;
2015-07-14 13:59:05 +02:00
Q_SIGNALS :
2014-01-07 11:30:17 +01:00
void initializeResult ( int retval ) ;
void shutdownResult ( int retval ) ;
void runawayException ( const QString & message ) ;
private :
boost : : thread_group threadGroup ;
2015-04-03 11:50:06 -04:00
CScheduler scheduler ;
2021-03-16 15:14:13 +01:00
std : : unique_ptr < HubApiServices > hubApiServices ;
2014-01-07 11:30:17 +01:00
/// Pass fatal exception message to UI thread
2014-12-07 13:29:06 +01:00
void handleRunawayException ( const std : : exception * e ) ;
2014-01-07 11:30:17 +01:00
} ;
/** 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
2015-10-08 10:01:29 +02:00
/// parameter interaction/setup based on rules
void parameterSetup ( ) ;
2017-01-23 01:56:55 -08:00
/// Create platform style
void createPlatformStyle ( ) ;
2014-01-07 11:30:17 +01:00
/// Create options model
2015-11-13 16:27:42 +01:00
void createOptionsModel ( bool resetSettings ) ;
2014-01-07 11:30:17 +01:00
/// Create main window
2017-01-30 12:17:25 +01:00
void createWindow ( const NetworkStyle & networkStyle ) ;
2014-01-08 08:59:24 +01:00
/// Create splash screen
2017-01-30 12:17:25 +01:00
void createSplashScreen ( const NetworkStyle & networkStyle ) ;
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 ;
2015-07-14 13:59:05 +02:00
public Q_SLOTS :
2014-01-07 11:30:17 +01:00
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 ) ;
2015-07-14 13:59:05 +02:00
Q_SIGNALS :
2014-01-07 11:30:17 +01:00
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 ;
2015-07-28 15:20:14 +02:00
const PlatformStyle * platformStyle ;
2014-01-07 11:30:17 +01:00
void startThread ( ) ;
} ;
# include "bitcoin.moc"
2018-02-13 13:09:33 +01:00
BitcoinCore : : BitcoinCore ( )
2014-01-07 11:30:17 +01:00
{
}
2014-12-07 13:29:06 +01:00
void BitcoinCore : : handleRunawayException ( const std : : exception * e )
2014-01-07 11:30:17 +01:00
{
PrintExceptionContinue ( e , " Runaway exception " ) ;
2015-07-14 13:59:05 +02:00
Q_EMIT runawayException ( QString : : fromStdString ( strMiscWarning ) ) ;
2014-01-07 11:30:17 +01:00
}
void BitcoinCore : : initialize ( )
{
try
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Running AppInit2 in thread " ;
2015-04-03 11:50:06 -04:00
int rv = AppInit2 ( threadGroup , scheduler ) ;
2015-07-14 13:59:05 +02:00
Q_EMIT initializeResult ( rv ) ;
2018-02-13 13:09:33 +01:00
2021-03-16 15:14:13 +01:00
if ( GetBoolArg ( " -api " , true ) )
hubApiServices . reset ( new HubApiServices ( Application : : instance ( ) - > ioService ( ) ) ) ;
2014-12-07 13:29:06 +01:00
} catch ( const std : : exception & e ) {
2014-01-07 11:30:17 +01:00
handleRunawayException ( & e ) ;
} catch ( . . . ) {
handleRunawayException ( NULL ) ;
}
}
void BitcoinCore : : shutdown ( )
{
try
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Running Shutdown in thread " ;
2021-03-16 15:14:13 +01:00
hubApiServices . reset ( ) ;
2015-01-23 07:53:17 +01:00
Interrupt ( threadGroup ) ;
2014-01-07 11:30:17 +01:00
threadGroup . join_all ( ) ;
Shutdown ( ) ;
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Shutdown finished " ;
2015-07-14 13:59:05 +02:00
Q_EMIT shutdownResult ( 1 ) ;
2014-12-07 13:29:06 +01:00
} catch ( const std : : exception & e ) {
2014-01-07 11:30:17 +01:00
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
2017-01-23 01:56:55 -08:00
returnValue ( 0 ) ,
platformStyle ( 0 )
2014-01-07 11:30:17 +01:00
{
setQuitOnLastWindowClosed ( false ) ;
}
BitcoinApplication : : ~ BitcoinApplication ( )
{
2014-07-15 16:26:16 +02:00
if ( coreThread )
{
qDebug ( ) < < __func__ < < " : Stopping thread " ;
2015-07-14 13:59:05 +02:00
Q_EMIT stopThread ( ) ;
2014-07-15 16:26:16 +02:00
coreThread - > wait ( ) ;
qDebug ( ) < < __func__ < < " : Stopped thread " ;
}
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 ;
2015-07-28 15:20:14 +02:00
delete platformStyle ;
platformStyle = 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
2017-01-23 01:56:55 -08:00
void BitcoinApplication : : createPlatformStyle ( )
{
std : : string platformName ;
2018-02-12 14:15:24 +01:00
platformName = GetArg ( " -uiplatform " , Settings : : DefaultUIPlatform ) ;
2017-01-23 01:56:55 -08:00
platformStyle = PlatformStyle : : instantiate ( QString : : fromStdString ( platformName ) ) ;
if ( ! platformStyle ) // Fall back to "other" if specified name not found
platformStyle = PlatformStyle : : instantiate ( " other " ) ;
assert ( platformStyle ) ;
}
2015-11-13 16:27:42 +01:00
void BitcoinApplication : : createOptionsModel ( bool resetSettings )
2014-01-07 11:30:17 +01:00
{
2015-11-13 16:27:42 +01:00
optionsModel = new OptionsModel ( NULL , resetSettings ) ;
2014-01-07 11:30:17 +01:00
}
2017-01-30 12:17:25 +01:00
void BitcoinApplication : : createWindow ( const NetworkStyle & networkStyle )
2014-01-07 11:30:17 +01:00
{
2017-01-30 12:17:25 +01:00
window = new BitcoinGUI ( platformStyle , networkStyle ) ;
2014-01-07 11:30:17 +01:00
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 ) ;
}
2017-01-30 12:17:25 +01:00
void BitcoinApplication : : createSplashScreen ( const NetworkStyle & networkStyle )
2014-01-08 08:59:24 +01:00
{
2017-01-30 12:17:25 +01:00
SplashScreen * splash = new SplashScreen ( networkStyle ) ;
2014-09-22 10:08:47 +02:00
// We don't hold a direct pointer to the splash screen after creation, so use
// Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
splash - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2014-01-08 08:59:24 +01:00
splash - > show ( ) ;
connect ( this , SIGNAL ( splashFinished ( QWidget * ) ) , splash , SLOT ( slotFinish ( QWidget * ) ) ) ;
}
2014-01-07 11:30:17 +01:00
void BitcoinApplication : : startThread ( )
{
2014-07-15 16:26:16 +02:00
if ( coreThread )
return ;
2014-01-07 11:30:17 +01:00
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 ( ) ;
}
2015-10-08 10:01:29 +02:00
void BitcoinApplication : : parameterSetup ( )
{
2015-11-26 14:03:27 +01:00
InitLogging ( ) ;
2015-10-08 10:01:29 +02:00
InitParameterInteraction ( ) ;
}
2014-01-07 11:30:17 +01:00
void BitcoinApplication : : requestInitialize ( )
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Requesting initialize " ;
2014-07-15 16:26:16 +02:00
startThread ( ) ;
2015-07-14 13:59:05 +02:00
Q_EMIT requestedInitialize ( ) ;
2014-01-07 11:30:17 +01:00
}
void BitcoinApplication : : requestShutdown ( )
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Requesting shutdown " ;
2017-10-03 13:03:12 +02:00
StartShutdown ( ) ; // shut down bitcoind processes (for instance reindex)
2014-07-15 16:26:16 +02:00
startThread ( ) ;
2014-01-07 11:30:17 +01:00
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
2015-07-14 13:59:05 +02:00
Q_EMIT requestedShutdown ( ) ;
2014-01-07 11:30:17 +01:00
}
void BitcoinApplication : : initializeResult ( int retval )
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Initialization result: " < < 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 )
{
2015-07-28 15:20:14 +02:00
// Log this only after AppInit2 finishes, as then logging setup is guaranteed complete
qWarning ( ) < < " Platform customization: " < < platformStyle - > getName ( ) ;
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
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 )
{
2015-07-28 15:20:14 +02:00
walletModel = new WalletModel ( platformStyle , pwalletMain , optionsModel ) ;
2014-01-07 11:30:17 +01:00
2014-08-07 09:36:02 +02:00
window - > addWallet ( BitcoinGUI : : DEFAULT_WALLET , walletModel ) ;
window - > setCurrentWallet ( BitcoinGUI : : DEFAULT_WALLET ) ;
2014-01-07 11:30:17 +01:00
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 ( ) ;
}
2015-07-14 13:59:05 +02:00
Q_EMIT splashFinished ( window ) ;
2014-09-18 13:14:38 +02:00
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 )
{
2014-07-15 10:23:28 +02:00
qDebug ( ) < < __func__ < < " : Shutdown result: " < < retval ;
2014-01-07 11:30:17 +01:00
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 ( ) ;
}
2019-05-12 11:04:04 +02:00
static bool SelectChain ( )
{
2020-09-26 14:32:12 -04:00
// Check for -testnet, -testnet4, -scalenet or -regtest parameter (Params() calls are only valid after this)
2019-05-12 11:04:04 +02:00
try {
SelectParams ( ChainNameFromCommandLine ( ) ) ;
return true ;
} catch ( std : : exception & e ) {
QMessageBox : : critical ( 0 , QObject : : tr ( " Flowee " ) , QObject : : tr ( " Error: %1 " ) . arg ( e . what ( ) ) ) ;
return false ;
}
}
2012-02-10 17:25:36 -05:00
# ifndef BITCOIN_QT_TEST
2011-05-07 22:13:39 +02:00
int main ( int argc , char * argv [ ] )
{
2014-05-13 10:15:00 +00:00
SetupEnvironment ( ) ;
2014-01-05 12:37:51 +01:00
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
2017-01-23 01:56:55 -08:00
/// 1. Basic Qt initialization (not dependent on parameters or configuration)
2014-01-07 11:30:17 +01:00
BitcoinApplication app ( argc , argv ) ;
2013-11-21 17:59:31 +01:00
// Generate high-dpi pixmaps
QApplication : : setAttribute ( Qt : : AA_UseHighDpiPixmaps ) ;
# 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 * > ( ) ;
2017-01-23 01:56:55 -08:00
/// 2. Parse command-line options. These take precedence over anything else.
// Command-line options take precedence:
try {
2019-04-02 17:45:04 +02:00
ParseParameters ( argc , argv , Settings : : HubQt ( ) ) ;
2017-01-23 01:56:55 -08:00
} catch ( const std : : exception & e ) {
2017-11-13 23:09:33 +01:00
QMessageBox : : critical ( 0 , QObject : : tr ( " Flowee " ) ,
2017-01-23 01:56:55 -08:00
QObject : : tr ( " Error: Cannot parse program options: %1. " ) . arg ( e . what ( ) ) ) ;
2020-08-26 09:36:11 +02:00
return 10 ;
2017-01-23 01:56:55 -08:00
}
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 ) ;
2015-01-16 16:03:48 -05:00
GUIUtil : : SubstituteFonts ( GetLangTerritory ( ) ) ;
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 ) ;
2015-04-16 16:20:01 +02:00
translationInterface . Translate . connect ( Translate ) ;
2013-05-19 17:36:01 +02:00
2012-05-13 11:36:10 +02:00
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
// but before showing splash screen.
2015-10-18 21:02:36 +11:00
if ( mapArgs . count ( " -? " ) | | mapArgs . count ( " -h " ) | | mapArgs . count ( " -help " ) | | mapArgs . count ( " -version " ) )
2012-05-13 11:36:10 +02:00
{
2014-06-03 16:12:19 +02:00
HelpMessageDialog help ( NULL , mapArgs . count ( " -version " ) ) ;
2012-06-14 15:06:23 +02:00
help . showOrPrint ( ) ;
2012-05-13 11:36:10 +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
2018-09-25 16:21:30 +02:00
// 6. Determine network (and switch to network specific options)
// - Do not call Params() before this step
// - QSettings() will use the new application name after this, resulting in network-specific settings
// - Needs to be done before createOptionsModel
// - Do not call GetDataDir(true) before this step finishes
// 7. Determine availability of data directory and parse flowee.conf
2017-07-31 23:12:53 +02:00
std : : string dd = GetArg ( " -datadir " , " " ) ;
if ( ! dd . empty ( ) ) {
auto path = boost : : filesystem : : system_complete ( dd ) ;
if ( ! boost : : filesystem : : is_directory ( path ) ) {
2017-11-13 23:09:33 +01:00
QMessageBox : : critical ( 0 , QObject : : tr ( " Flowee " ) ,
2017-07-31 23:12:53 +02:00
QObject : : tr ( " Error: Specified data directory \" %1 \" does not exist. " )
. arg ( QString : : fromStdString ( dd ) ) ) ;
return 1 ;
}
}
2019-05-24 22:46:14 +02:00
boost : : filesystem : : path pathConfigFile = GetArg ( " -conf " , " " ) ;
const bool confPathSet = pathConfigFile . is_complete ( ) ;
2019-05-12 11:04:04 +02:00
if ( ! confPathSet ) // first select chain, so we read the right conf file.
SelectChain ( ) ;
2014-04-07 10:10:01 +02:00
try {
ReadConfigFile ( mapArgs , mapMultiArgs ) ;
2014-12-07 13:29:06 +01:00
} catch ( const std : : exception & e ) {
2017-11-13 23:09:33 +01:00
QMessageBox : : critical ( 0 , QObject : : tr ( " Flowee " ) ,
2014-04-07 10:10:01 +02:00
QObject : : tr ( " Error: Cannot parse configuration file: %1. Only use key=value syntax. " ) . arg ( e . what ( ) ) ) ;
2020-08-26 09:36:11 +02:00
return 10 ;
2014-04-07 10:10:01 +02:00
}
2019-05-12 11:04:04 +02:00
if ( confPathSet ) // after raeding the user-indicated conf file, select chain (including conf file opts)
SelectChain ( ) ;
2014-01-05 12:37:51 +01:00
2017-01-23 01:56:55 -08:00
// UI per-platform customization
app . createPlatformStyle ( ) ;
2013-12-11 15:00:56 +01:00
# ifdef ENABLE_WALLET
2017-09-20 20:55:06 +02:00
// Parse URIs on command line
2014-11-05 11:42:51 +01:00
PaymentServer : : ipcParseCommandLine ( argc , argv ) ;
2014-03-11 08:32:07 +01:00
# endif
2014-11-05 11:42:51 +01:00
2017-01-30 12:17:25 +01:00
NetworkStyle networkStyle ( QString : : fromStdString ( Params ( ) . NetworkIDString ( ) ) ) ;
2014-03-11 08:32:07 +01:00
// Allow for separate UI settings for testnets
2017-01-30 12:17:25 +01:00
QApplication : : setApplicationName ( networkStyle . getAppName ( ) ) ;
2014-03-11 08:32:07 +01:00
// Re-initialize translations after changing application name (language in network-specific settings can be different)
initTranslations ( qtTranslatorBase , qtTranslator , translatorBase , translator ) ;
# ifdef ENABLE_WALLET
/// 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 ) ;
// 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
2014-01-05 12:37:51 +01:00
2014-03-11 08:32:07 +01:00
/// 9. Main GUI initialization
2014-01-05 12:37:51 +01:00
// Install global event filter that makes sure that long tooltips can be word-wrapped
app . installEventFilter ( new GUIUtil : : ToolTipToRichTextFilter ( TOOLTIP_WRAP_THRESHOLD , & app ) ) ;
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
2018-11-21 12:18:32 +01:00
// Install qDebug() message handler to route to hub.log
2014-01-05 12:37:51 +01:00
qInstallMessageHandler ( DebugMessageHandler ) ;
2015-10-08 10:01:29 +02:00
// Allow parameter interaction before we create the options model
app . parameterSetup ( ) ;
2014-01-05 12:37:51 +01:00
// Load GUI settings from QSettings
2017-02-18 17:58:42 -08:00
app . createOptionsModel ( GetBoolArg ( " -resetguisettings " , false ) ) ;
2014-01-05 12:37:51 +01:00
// Subscribe to global signals from core
uiInterface . InitMessage . connect ( InitMessage ) ;
2018-02-12 14:15:24 +01:00
if ( GetBoolArg ( " -splash " , Settings : : DefaultSplashscreen ) & & ! GetBoolArg ( " -min " , false ) )
2017-01-30 12:17:25 +01:00
app . createSplashScreen ( networkStyle ) ;
2011-05-07 22:13:39 +02:00
2011-06-07 18:59:01 +02:00
try
{
2017-01-30 12:17:25 +01:00
app . createWindow ( networkStyle ) ;
2014-01-07 11:30:17 +01:00
app . requestInitialize ( ) ;
2021-02-22 15:51:28 +01:00
# if defined(Q_OS_WIN)
2017-11-13 23:09:33 +01:00
WinShutdownMonitor : : registerShutdownBlockReason ( QObject : : tr ( " Flowee the Hub 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 ( ) ;
2014-12-07 13:29:06 +01:00
} catch ( const 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 17:25:36 -05:00
# endif // BITCOIN_QT_TEST