Files
thehub/hub-qt/bitcoin.cpp
T

689 lines
22 KiB
C++
Raw Permalink Normal View History

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
#if defined(HAVE_CONFIG_H)
2018-01-16 10:47:52 +00:00
#include "config/flowee-config.h"
#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"
#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"
#include "utilitydialog.h"
#include "winshutdownmonitor.h"
2014-09-05 13:18:35 +02:00
#ifdef ENABLE_WALLET
#include "paymentserver.h"
2013-04-13 00:13:08 -05:00
#include "walletmodel.h"
#endif
2011-05-07 22:13:39 +02:00
2013-04-13 00:13:08 -05:00
#include "init.h"
#include "rpcserver.h"
#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
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#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
#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
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
#if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_WINDOWS)
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
#endif
#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
{
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;
/*
Translate string to current locale using Qt.
*/
2012-05-06 19:40:58 +02:00
static std::string Translate(const char* psz)
{
2017-11-13 23:09:33 +01:00
return QCoreApplication::translate("Flowee the Hub", psz).toStdString();
}
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()));
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.
* 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();
2015-07-14 13:59:05 +02:00
public Q_SLOTS:
void initialize();
void shutdown();
2015-07-14 13:59:05 +02:00
Q_SIGNALS:
void initializeResult(int retval);
void shutdownResult(int retval);
void runawayException(const QString &message);
private:
boost::thread_group threadGroup;
CScheduler scheduler;
2021-03-16 15:14:13 +01:00
std::unique_ptr<HubApiServices> hubApiServices;
/// Pass fatal exception message to UI thread
2014-12-07 13:29:06 +01:00
void handleRunawayException(const std::exception *e);
};
/** Main Bitcoin application object */
class BitcoinApplication: public QApplication
{
Q_OBJECT
public:
explicit BitcoinApplication(int &argc, char **argv);
~BitcoinApplication();
#ifdef ENABLE_WALLET
/// Create payment server
void createPaymentServer();
#endif
/// parameter interaction/setup based on rules
void parameterSetup();
/// Create platform style
void createPlatformStyle();
/// Create options model
void createOptionsModel(bool resetSettings);
/// 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);
/// Request core initialization
void requestInitialize();
/// Request core shutdown
void requestShutdown();
/// Get process return value
int getReturnValue() { return returnValue; }
/// Get window identifier of QMainWindow (BitcoinGUI)
WId getMainWinId() const;
2015-07-14 13:59:05 +02:00
public Q_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);
2015-07-14 13:59:05 +02:00
Q_SIGNALS:
void requestedInitialize();
void requestedShutdown();
void stopThread();
2014-01-08 08:59:24 +01:00
void splashFinished(QWidget *window);
private:
QThread *coreThread;
OptionsModel *optionsModel;
ClientModel *clientModel;
BitcoinGUI *window;
QTimer *pollShutdownTimer;
#ifdef ENABLE_WALLET
PaymentServer* paymentServer;
WalletModel *walletModel;
#endif
int returnValue;
2015-07-28 15:20:14 +02:00
const PlatformStyle *platformStyle;
void startThread();
};
#include "bitcoin.moc"
2018-02-13 13:09:33 +01:00
BitcoinCore::BitcoinCore()
{
}
2014-12-07 13:29:06 +01:00
void BitcoinCore::handleRunawayException(const std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
2015-07-14 13:59:05 +02:00
Q_EMIT runawayException(QString::fromStdString(strMiscWarning));
}
void BitcoinCore::initialize()
{
try
{
2014-07-15 10:23:28 +02:00
qDebug() << __func__ << ": Running AppInit2 in thread";
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) {
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);
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) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
}
}
BitcoinApplication::BitcoinApplication(int &argc, char **argv):
QApplication(argc, argv),
coreThread(0),
optionsModel(0),
clientModel(0),
window(0),
pollShutdownTimer(0),
#ifdef ENABLE_WALLET
paymentServer(0),
walletModel(0),
#endif
returnValue(0),
platformStyle(0)
{
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;
window = 0;
#ifdef ENABLE_WALLET
2014-01-08 08:59:24 +01:00
delete paymentServer;
paymentServer = 0;
#endif
2014-01-08 08:59:24 +01:00
delete optionsModel;
optionsModel = 0;
2015-07-28 15:20:14 +02:00
delete platformStyle;
platformStyle = 0;
}
#ifdef ENABLE_WALLET
void BitcoinApplication::createPaymentServer()
{
paymentServer = new PaymentServer(this);
}
#endif
void BitcoinApplication::createPlatformStyle()
{
std::string platformName;
2018-02-12 14:15:24 +01:00
platformName = GetArg("-uiplatform", Settings::DefaultUIPlatform);
platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
if (!platformStyle) // Fall back to "other" if specified name not found
platformStyle = PlatformStyle::instantiate("other");
assert(platformStyle);
}
void BitcoinApplication::createOptionsModel(bool resetSettings)
{
optionsModel = new OptionsModel(NULL, resetSettings);
}
2017-01-30 12:17:25 +01:00
void BitcoinApplication::createWindow(const NetworkStyle &networkStyle)
{
2017-01-30 12:17:25 +01:00
window = new BitcoinGUI(platformStyle, networkStyle);
pollShutdownTimer = new QTimer(window);
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);
// 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*)));
}
void BitcoinApplication::startThread()
{
2014-07-15 16:26:16 +02:00
if(coreThread)
return;
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::parameterSetup()
{
InitLogging();
InitParameterInteraction();
}
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();
}
void BitcoinApplication::requestShutdown()
{
2014-07-15 10:23:28 +02:00
qDebug() << __func__ << ": Requesting shutdown";
StartShutdown(); // shut down bitcoind processes (for instance reindex)
2014-07-15 16:26:16 +02:00
startThread();
window->hide();
window->setClientModel(0);
pollShutdownTimer->stop();
2014-01-07 16:04:47 +01:00
#ifdef ENABLE_WALLET
window->removeAllWallets();
delete walletModel;
2014-01-08 08:59:24 +01:00
walletModel = 0;
#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
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();
}
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
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();
#ifdef ENABLE_WALLET
PaymentServer::LoadRootCAs();
paymentServer->setOptionsModel(optionsModel);
#endif
clientModel = new ClientModel(optionsModel);
window->setClientModel(clientModel);
#ifdef ENABLE_WALLET
if(pwalletMain)
{
2015-07-28 15:20:14 +02:00
walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel);
window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
}
#endif
// 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
#ifdef ENABLE_WALLET
// 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()));
#endif
} else {
quit(); // Exit main loop
}
}
void BitcoinApplication::shutdownResult(int retval)
{
2014-07-15 10:23:28 +02:00
qDebug() << __func__ << ": Shutdown result: " << 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);
}
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;
}
}
#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
/// 1. Basic Qt initialization (not dependent on parameters or configuration)
BitcoinApplication app(argc, argv);
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#ifdef Q_OS_MAC
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
#endif
2013-04-14 18:50:40 +02:00
// Register meta types used for QMetaObject::invokeMethod
qRegisterMetaType< bool* >();
/// 2. Parse command-line options. These take precedence over anything else.
// Command-line options take precedence:
try {
ParseParameters(argc, argv, Settings::HubQt());
} catch (const std::exception& e) {
2017-11-13 23:09:33 +01:00
QMessageBox::critical(0, QObject::tr("Flowee"),
QObject::tr("Error: Cannot parse program options: %1.").arg(e.what()));
2020-08-26 09:36:11 +02:00
return 10;
}
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
QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
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);
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"));
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
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
// UI per-platform customization
app.createPlatformStyle();
#ifdef ENABLE_WALLET
// Parse URIs on command line
PaymentServer::ipcParseCommandLine(argc, argv);
#endif
2017-01-30 12:17:25 +01:00
NetworkStyle networkStyle(QString::fromStdString(Params().NetworkIDString()));
// Allow for separate UI settings for testnets
2017-01-30 12:17:25 +01:00
QApplication::setApplicationName(networkStyle.getAppName());
// 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:
app.createPaymentServer();
#endif
2014-01-05 12:37:51 +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));
#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);
// 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);
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());
#endif
app.exec();
app.requestShutdown();
app.exec();
2014-12-07 13:29:06 +01:00
} catch (const std::exception& e) {
PrintExceptionContinue(&e, "Runaway exception");
app.handleRunawayException(QString::fromStdString(strMiscWarning));
2011-05-22 17:19:43 +02:00
} catch (...) {
PrintExceptionContinue(NULL, "Runaway exception");
app.handleRunawayException(QString::fromStdString(strMiscWarning));
2011-05-22 17:19:43 +02:00
}
return app.getReturnValue();
2011-05-07 22:13:39 +02:00
}
#endif // BITCOIN_QT_TEST