Changeset View
Changeset View
Standalone View
Standalone View
src/qt/bitcoin.cpp
Show First 20 Lines • Show All 179 Lines • ▼ Show 20 Lines | void BitcoinABC::shutdown() { | ||||
} catch (...) { | } catch (...) { | ||||
handleRunawayException(nullptr); | handleRunawayException(nullptr); | ||||
} | } | ||||
} | } | ||||
static int qt_argc = 1; | static int qt_argc = 1; | ||||
static const char *qt_argv = "bitcoin-qt"; | static const char *qt_argv = "bitcoin-qt"; | ||||
BitcoinApplication::BitcoinApplication(interfaces::Node &node) | BitcoinApplication::BitcoinApplication() | ||||
: QApplication(qt_argc, const_cast<char **>(&qt_argv)), coreThread(nullptr), | : QApplication(qt_argc, const_cast<char **>(&qt_argv)), coreThread(nullptr), | ||||
m_node(node), optionsModel(nullptr), clientModel(nullptr), | optionsModel(nullptr), clientModel(nullptr), window(nullptr), | ||||
window(nullptr), pollShutdownTimer(nullptr), returnValue(0), | pollShutdownTimer(nullptr), returnValue(0), platformStyle(nullptr) { | ||||
platformStyle(nullptr) { | |||||
setQuitOnLastWindowClosed(false); | setQuitOnLastWindowClosed(false); | ||||
} | } | ||||
void BitcoinApplication::setupPlatformStyle() { | void BitcoinApplication::setupPlatformStyle() { | ||||
// UI per-platform customization | // UI per-platform customization | ||||
// This must be done inside the BitcoinApplication constructor, or after it, | // This must be done inside the BitcoinApplication constructor, or after it, | ||||
// because PlatformStyle::instantiate requires a QApplication. | // because PlatformStyle::instantiate requires a QApplication. | ||||
std::string platformName; | std::string platformName; | ||||
Show All 25 Lines | |||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
void BitcoinApplication::createPaymentServer() { | void BitcoinApplication::createPaymentServer() { | ||||
paymentServer = new PaymentServer(this); | paymentServer = new PaymentServer(this); | ||||
} | } | ||||
#endif | #endif | ||||
void BitcoinApplication::createOptionsModel(bool resetSettings) { | void BitcoinApplication::createOptionsModel(bool resetSettings) { | ||||
optionsModel = new OptionsModel(m_node, nullptr, resetSettings); | optionsModel = new OptionsModel(nullptr, resetSettings); | ||||
optionsModel->setNode(node()); | |||||
} | } | ||||
void BitcoinApplication::createWindow(const Config *config, | void BitcoinApplication::createWindow(const Config *config, | ||||
const NetworkStyle *networkStyle) { | const NetworkStyle *networkStyle) { | ||||
window = | window = | ||||
new BitcoinGUI(m_node, config, platformStyle, networkStyle, nullptr); | new BitcoinGUI(node(), config, platformStyle, networkStyle, nullptr); | ||||
pollShutdownTimer = new QTimer(window); | pollShutdownTimer = new QTimer(window); | ||||
connect(pollShutdownTimer, &QTimer::timeout, window, | connect(pollShutdownTimer, &QTimer::timeout, window, | ||||
&BitcoinGUI::detectShutdown); | &BitcoinGUI::detectShutdown); | ||||
} | } | ||||
void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { | void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { | ||||
SplashScreen *splash = new SplashScreen(m_node, networkStyle); | assert(!m_splash); | ||||
m_splash = new SplashScreen(networkStyle); | |||||
m_splash->setNode(node()); | |||||
// We don't hold a direct pointer to the splash screen after creation, but | // We don't hold a direct pointer to the splash screen after creation, but | ||||
// the splash screen will take care of deleting itself when finish() | // the splash screen will take care of deleting itself when finish() | ||||
// happens. | // happens. | ||||
splash->show(); | m_splash->show(); | ||||
connect(this, &BitcoinApplication::splashFinished, splash, | connect(this, &BitcoinApplication::splashFinished, m_splash, | ||||
&SplashScreen::finish); | &SplashScreen::finish); | ||||
connect(this, &BitcoinApplication::requestedShutdown, splash, | connect(this, &BitcoinApplication::requestedShutdown, m_splash, | ||||
&QWidget::close); | &QWidget::close); | ||||
} | } | ||||
void BitcoinApplication::setNode(interfaces::Node &node) { | |||||
assert(!m_node); | |||||
m_node = &node; | |||||
} | |||||
bool BitcoinApplication::baseInitialize(Config &config) { | bool BitcoinApplication::baseInitialize(Config &config) { | ||||
return m_node.baseInitialize(config); | return node().baseInitialize(config); | ||||
} | } | ||||
void BitcoinApplication::startThread() { | void BitcoinApplication::startThread() { | ||||
if (coreThread) { | if (coreThread) { | ||||
return; | return; | ||||
} | } | ||||
coreThread = new QThread(this); | coreThread = new QThread(this); | ||||
BitcoinABC *executor = new BitcoinABC(m_node); | BitcoinABC *executor = new BitcoinABC(node()); | ||||
executor->moveToThread(coreThread); | executor->moveToThread(coreThread); | ||||
/* communication to and from thread */ | /* communication to and from thread */ | ||||
connect(executor, &BitcoinABC::initializeResult, this, | connect(executor, &BitcoinABC::initializeResult, this, | ||||
&BitcoinApplication::initializeResult); | &BitcoinApplication::initializeResult); | ||||
connect(executor, &BitcoinABC::shutdownResult, this, | connect(executor, &BitcoinABC::shutdownResult, this, | ||||
&BitcoinApplication::shutdownResult); | &BitcoinApplication::shutdownResult); | ||||
connect(executor, &BitcoinABC::runawayException, this, | connect(executor, &BitcoinABC::runawayException, this, | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | void BitcoinApplication::requestShutdown(Config &config) { | ||||
qDebug() << __func__ << ": Requesting shutdown"; | qDebug() << __func__ << ": Requesting shutdown"; | ||||
startThread(); | startThread(); | ||||
window->hide(); | window->hide(); | ||||
// Must disconnect node signals otherwise current thread can deadlock since | // Must disconnect node signals otherwise current thread can deadlock since | ||||
// no event loop is running. | // no event loop is running. | ||||
window->unsubscribeFromCoreSignals(); | window->unsubscribeFromCoreSignals(); | ||||
// Request node shutdown, which can interrupt long operations, like | // Request node shutdown, which can interrupt long operations, like | ||||
// rescanning a wallet. | // rescanning a wallet. | ||||
m_node.startShutdown(); | node().startShutdown(); | ||||
// Unsetting the client model can cause the current thread to wait for node | // Unsetting the client model can cause the current thread to wait for node | ||||
// to complete an operation, like wait for a RPC execution to complete. | // to complete an operation, like wait for a RPC execution to complete. | ||||
window->setClientModel(nullptr); | window->setClientModel(nullptr); | ||||
pollShutdownTimer->stop(); | pollShutdownTimer->stop(); | ||||
delete clientModel; | delete clientModel; | ||||
clientModel = nullptr; | clientModel = nullptr; | ||||
Show All 9 Lines | if (!success) { | ||||
Q_EMIT splashFinished(); | Q_EMIT splashFinished(); | ||||
// Exit first main loop invocation. | // Exit first main loop invocation. | ||||
quit(); | quit(); | ||||
return; | return; | ||||
} | } | ||||
// Log this only after AppInitMain finishes, as then logging setup is | // Log this only after AppInitMain finishes, as then logging setup is | ||||
// guaranteed complete. | // guaranteed complete. | ||||
qInfo() << "Platform customization:" << platformStyle->getName(); | qInfo() << "Platform customization:" << platformStyle->getName(); | ||||
clientModel = new ClientModel(m_node, optionsModel); | clientModel = new ClientModel(node(), optionsModel); | ||||
window->setClientModel(clientModel); | window->setClientModel(clientModel); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
if (WalletModel::isWalletEnabled()) { | if (WalletModel::isWalletEnabled()) { | ||||
m_wallet_controller = | m_wallet_controller = | ||||
new WalletController(m_node, platformStyle, optionsModel, this); | new WalletController(node(), platformStyle, optionsModel, this); | ||||
window->setWalletController(m_wallet_controller); | window->setWalletController(m_wallet_controller); | ||||
if (paymentServer) { | if (paymentServer) { | ||||
paymentServer->setOptionsModel(optionsModel); | paymentServer->setOptionsModel(optionsModel); | ||||
#ifdef ENABLE_BIP70 | #ifdef ENABLE_BIP70 | ||||
PaymentServer::LoadRootCAs(); | PaymentServer::LoadRootCAs(); | ||||
connect(m_wallet_controller, &WalletController::coinsSent, | connect(m_wallet_controller, &WalletController::coinsSent, | ||||
paymentServer, &PaymentServer::fetchPaymentACK); | paymentServer, &PaymentServer::fetchPaymentACK); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | #endif | ||||
// Generate high-dpi pixmaps | // Generate high-dpi pixmaps | ||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); | QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); | ||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | ||||
#ifdef Q_OS_MAC | #ifdef Q_OS_MAC | ||||
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); | QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); | ||||
#endif | #endif | ||||
BitcoinApplication app(*node); | BitcoinApplication app; | ||||
app.setNode(*node); | |||||
// Register meta types used for QMetaObject::invokeMethod and | // Register meta types used for QMetaObject::invokeMethod and | ||||
// Qt::QueuedConnection | // Qt::QueuedConnection | ||||
qRegisterMetaType<bool *>(); | qRegisterMetaType<bool *>(); | ||||
qRegisterMetaType<SynchronizationState>(); | qRegisterMetaType<SynchronizationState>(); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
qRegisterMetaType<WalletModel *>(); | qRegisterMetaType<WalletModel *>(); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | #if defined(Q_OS_WIN) | ||||
(HWND)app.getMainWinId()); | (HWND)app.getMainWinId()); | ||||
#endif | #endif | ||||
app.exec(); | app.exec(); | ||||
app.requestShutdown(config); | app.requestShutdown(config); | ||||
app.exec(); | app.exec(); | ||||
return app.getReturnValue(); | return app.getReturnValue(); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
PrintExceptionContinue(&e, "Runaway exception"); | PrintExceptionContinue(&e, "Runaway exception"); | ||||
app.handleRunawayException(QString::fromStdString(node->getWarnings())); | app.handleRunawayException( | ||||
QString::fromStdString(app.node().getWarnings())); | |||||
} catch (...) { | } catch (...) { | ||||
PrintExceptionContinue(nullptr, "Runaway exception"); | PrintExceptionContinue(nullptr, "Runaway exception"); | ||||
app.handleRunawayException(QString::fromStdString(node->getWarnings())); | app.handleRunawayException( | ||||
QString::fromStdString(app.node().getWarnings())); | |||||
} | } | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } |