mirror of
https://github.com/monero-project/monero-gui
synced 2024-11-22 12:14:00 +01:00
start daemon automatically and detached
This commit is contained in:
parent
c6688dc876
commit
faacd3d6a1
@ -39,12 +39,14 @@ Window {
|
||||
id: root
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window | Qt.FramelessWindowHint
|
||||
|
||||
property int countDown: 5;
|
||||
signal rejected()
|
||||
signal started();
|
||||
|
||||
function open() {
|
||||
show()
|
||||
countDown = 5;
|
||||
timer.start();
|
||||
}
|
||||
|
||||
// TODO: implement without hardcoding sizes
|
||||
@ -61,15 +63,29 @@ Window {
|
||||
//anchors {fill: parent; margins: 16 }
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Label {
|
||||
text: qsTr("Daemon doesn't appear to be running")
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 1000;
|
||||
running: false;
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
countDown--;
|
||||
if(countDown < 0){
|
||||
running = false;
|
||||
// Start daemon
|
||||
root.close()
|
||||
appWindow.startDaemon(persistentSettings.daemonFlags);
|
||||
root.started();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Starting Monero daemon in %1 seconds").arg(countDown);
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 24
|
||||
font.family: "Arial"
|
||||
color: "#555555"
|
||||
}
|
||||
|
||||
}
|
||||
@ -81,58 +97,40 @@ Window {
|
||||
|
||||
MoneroComponents.StandardButton {
|
||||
id: okButton
|
||||
width: 120
|
||||
visible:false
|
||||
fontSize: 14
|
||||
shadowReleasedColor: "#FF4304"
|
||||
shadowPressedColor: "#B32D00"
|
||||
releasedColor: "#FF6C3C"
|
||||
pressedColor: "#FF4304"
|
||||
text: qsTr("Start daemon")
|
||||
text: qsTr("Start daemon (%1)").arg(countDown)
|
||||
KeyNavigation.tab: cancelButton
|
||||
onClicked: {
|
||||
timer.stop();
|
||||
root.close()
|
||||
appWindow.startDaemon(daemonFlags.text);
|
||||
appWindow.startDaemon(persistentSettings.daemonFlags);
|
||||
root.started()
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.StandardButton {
|
||||
id: cancelButton
|
||||
width: 120
|
||||
fontSize: 14
|
||||
shadowReleasedColor: "#FF4304"
|
||||
shadowPressedColor: "#B32D00"
|
||||
releasedColor: "#FF6C3C"
|
||||
pressedColor: "#FF4304"
|
||||
text: qsTr("Cancel")
|
||||
text: qsTr("Use custom settings")
|
||||
|
||||
onClicked: {
|
||||
timer.stop();
|
||||
root.close()
|
||||
root.rejected()
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
id: advancedRow
|
||||
MoneroComponents.Label {
|
||||
id: daemonFlagsLabel
|
||||
color: "#4A4949"
|
||||
text: qsTr("Daemon startup flags") + translationManager.emptyString
|
||||
fontSize: 16
|
||||
}
|
||||
|
||||
MoneroComponents.LineEdit {
|
||||
id: daemonFlags
|
||||
Layout.preferredWidth: 200
|
||||
Layout.fillWidth: true
|
||||
text: appWindow.persistentSettings.daemonFlags;
|
||||
placeholderText: qsTr("(optional)")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ Window {
|
||||
id: messageTitle
|
||||
text: "Please wait..."
|
||||
font {
|
||||
pointSize: 22
|
||||
pixelSize: 22
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
@ -72,7 +72,7 @@ Window {
|
||||
Text {
|
||||
id: heightProgress
|
||||
font {
|
||||
pointSize: 18
|
||||
pixelSize: 18
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
|
2
main.cpp
2
main.cpp
@ -64,6 +64,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Monero::Wallet::init(argv[0], "monero-wallet-gui");
|
||||
|
||||
qInstallMessageHandler(messageHandler);
|
||||
QApplication app(argc, argv);
|
||||
@ -141,7 +142,6 @@ int main(int argc, char *argv[])
|
||||
// Exclude daemon manager from IOS
|
||||
#ifndef Q_OS_IOS
|
||||
DaemonManager * daemonManager = DaemonManager::instance(&arguments);
|
||||
QObject::connect(&app, SIGNAL(aboutToQuit()), daemonManager, SLOT(closing()));
|
||||
engine.rootContext()->setContextProperty("daemonManager", daemonManager);
|
||||
#endif
|
||||
|
||||
|
26
main.qml
26
main.qml
@ -147,6 +147,11 @@ ApplicationWindow {
|
||||
function mousePressed(obj, mouseX, mouseY) {}
|
||||
function mouseReleased(obj, mouseX, mouseY) {}
|
||||
|
||||
function loadPage(page) {
|
||||
middlePanel.state = page;
|
||||
leftPanel.selectItem(page);
|
||||
}
|
||||
|
||||
function openWalletFromFile(){
|
||||
persistentSettings.restore_height = 0
|
||||
restoreHeight = 0;
|
||||
@ -274,7 +279,7 @@ ApplicationWindow {
|
||||
leftPanel.progressBar.visible = (status === Wallet.ConnectionStatus_Connected) && !daemonSynced
|
||||
|
||||
// If wallet isnt connected and no daemon is running - Ask
|
||||
if(!walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running()){
|
||||
if(!walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
|
||||
daemonManagerDialog.open();
|
||||
}
|
||||
// initialize transaction history once wallet is initialized first time;
|
||||
@ -341,7 +346,7 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
// Daemon connected
|
||||
leftPanel.networkStatus.connected = currentWallet.connected
|
||||
leftPanel.networkStatus.connected = currentWallet.connected()
|
||||
|
||||
// Check daemon status
|
||||
var dCurrentBlock = currentWallet.daemonBlockChainHeight();
|
||||
@ -352,9 +357,9 @@ ApplicationWindow {
|
||||
daemonSynced = dCurrentBlock >= dTargetBlock
|
||||
// Update daemon sync progress
|
||||
leftPanel.progressBar.updateProgress(dCurrentBlock,dTargetBlock);
|
||||
leftPanel.progressBar.visible = !daemonSynced && currentWallet.connected !== Wallet.ConnectionStatus_Disconnected
|
||||
leftPanel.progressBar.visible = !daemonSynced && currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected
|
||||
// Update wallet sync progress
|
||||
updateSyncing((currentWallet.connected !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced)
|
||||
updateSyncing((currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced)
|
||||
// Update transfer page status
|
||||
middlePanel.updateStatus();
|
||||
|
||||
@ -380,23 +385,25 @@ ApplicationWindow {
|
||||
|
||||
function startDaemon(flags){
|
||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
||||
daemonManager.start(flags);
|
||||
daemonManager.start(flags, persistentSettings.testnet);
|
||||
persistentSettings.daemonFlags = flags
|
||||
}
|
||||
|
||||
function stopDaemon(){
|
||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to stop..."))
|
||||
daemonManager.stop();
|
||||
daemonManager.stop(persistentSettings.testnet);
|
||||
}
|
||||
|
||||
function onDaemonStarted(){
|
||||
console.log("daemon started");
|
||||
daemonRunning = true;
|
||||
hideProcessingSplash();
|
||||
}
|
||||
function onDaemonStopped(){
|
||||
console.log("daemon stopped");
|
||||
hideProcessingSplash();
|
||||
daemonRunning = false;
|
||||
currentWallet.connected(true);
|
||||
}
|
||||
|
||||
function onWalletNewBlock(blockHeight, targetHeight) {
|
||||
@ -438,7 +445,7 @@ ApplicationWindow {
|
||||
if (transaction.status !== PendingTransaction.Status_Ok) {
|
||||
console.error("Can't create transaction: ", transaction.errorString);
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
if (currentWallet.connected == Wallet.ConnectionStatus_WrongVersion)
|
||||
if (currentWallet.connected() == Wallet.ConnectionStatus_WrongVersion)
|
||||
informationPopup.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString
|
||||
else
|
||||
informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
|
||||
@ -870,6 +877,9 @@ ApplicationWindow {
|
||||
|
||||
DaemonManagerDialog {
|
||||
id: daemonManagerDialog
|
||||
onRejected: {
|
||||
loadPage("Settings");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1220,7 +1230,5 @@ ApplicationWindow {
|
||||
onClosing: {
|
||||
// Close wallet non async on exit
|
||||
walletManager.closeWallet();
|
||||
// Stop daemon and pool miner
|
||||
daemonManager.stop();
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ Rectangle {
|
||||
setTrackingLineText("-")
|
||||
return
|
||||
}
|
||||
if (appWindow.currentWallet.connected == Wallet.ConnectionStatus_Disconnected) {
|
||||
if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) {
|
||||
setTrackingLineText(qsTr("WARNING: no connection to daemon"))
|
||||
return
|
||||
}
|
||||
|
@ -171,23 +171,10 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
visible: true
|
||||
id: daemonConsolePopupButton
|
||||
text: qsTr("Show log") + translationManager.emptyString
|
||||
shadowReleasedColor: "#FF4304"
|
||||
shadowPressedColor: "#B32D00"
|
||||
releasedColor: "#FF6C3C"
|
||||
pressedColor: "#FF4304"
|
||||
onClicked: {
|
||||
daemonConsolePopup.open();
|
||||
}
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
visible: true
|
||||
id: daemonStatusButton
|
||||
text: qsTr("Status") + translationManager.emptyString
|
||||
text: qsTr("Show status") + translationManager.emptyString
|
||||
shadowReleasedColor: "#FF4304"
|
||||
shadowPressedColor: "#B32D00"
|
||||
releasedColor: "#FF6C3C"
|
||||
@ -420,6 +407,7 @@ Rectangle {
|
||||
console.log("Settings page loaded");
|
||||
initSettings();
|
||||
viewOnly = currentWallet.viewOnly;
|
||||
daemonManager.running(persistentSettings.testnet)
|
||||
}
|
||||
|
||||
// fires only once
|
||||
|
@ -700,7 +700,7 @@ Rectangle {
|
||||
}
|
||||
pageRoot.enabled = false;
|
||||
|
||||
switch (currentWallet.connected) {
|
||||
switch (currentWallet.connected()) {
|
||||
case Wallet.ConnectionStatus_Disconnected:
|
||||
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
|
||||
break
|
||||
|
@ -23,10 +23,14 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
bool DaemonManager::start(const QString &flags)
|
||||
bool DaemonManager::start(const QString &flags, bool testnet)
|
||||
{
|
||||
// prepare command line arguments and pass to monerod
|
||||
QStringList arguments;
|
||||
arguments << "--detach";
|
||||
if(testnet)
|
||||
arguments << "--testnet";
|
||||
|
||||
foreach (const QString &str, m_clArgs) {
|
||||
qDebug() << QString(" [%1] ").arg(str);
|
||||
if (!str.isEmpty())
|
||||
@ -52,8 +56,7 @@ bool DaemonManager::start(const QString &flags)
|
||||
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError()));
|
||||
|
||||
// Start monerod
|
||||
m_daemon->start(m_monerod, arguments);
|
||||
bool started = m_daemon->waitForStarted();
|
||||
bool started = m_daemon->startDetached(m_monerod, arguments);
|
||||
|
||||
// add state changed listener
|
||||
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState)));
|
||||
@ -67,16 +70,14 @@ bool DaemonManager::start(const QString &flags)
|
||||
return started;
|
||||
}
|
||||
|
||||
bool DaemonManager::stop()
|
||||
bool DaemonManager::stop(bool testnet)
|
||||
{
|
||||
if (initialized) {
|
||||
qDebug() << "stopping daemon";
|
||||
// we can't use QProcess::terminate() on windows console process
|
||||
// write exit command to stdin
|
||||
m_daemon->write("exit\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
QString message;
|
||||
bool stopped = sendCommand("exit",testnet,message);
|
||||
qDebug() << message;
|
||||
if(stopped)
|
||||
emit daemonStopped();
|
||||
return stopped;
|
||||
}
|
||||
|
||||
void DaemonManager::stateChanged(QProcess::ProcessState state)
|
||||
@ -109,40 +110,42 @@ void DaemonManager::printError()
|
||||
}
|
||||
}
|
||||
|
||||
bool DaemonManager::running() const
|
||||
bool DaemonManager::running(bool testnet) const
|
||||
{
|
||||
if (initialized) {
|
||||
qDebug() << m_daemon->state();
|
||||
qDebug() << QProcess::NotRunning;
|
||||
// m_daemon->write("status\n");
|
||||
return m_daemon->state() > QProcess::NotRunning;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DaemonManager::sendCommand(const QString &cmd,bool testnet)
|
||||
{
|
||||
// If daemon is started by GUI - interactive mode
|
||||
if (initialized && running()) {
|
||||
m_daemon->write(cmd.toUtf8() +"\n");
|
||||
QString status;
|
||||
sendCommand("status",testnet, status);
|
||||
qDebug() << status;
|
||||
// `./monerod status` returns BUSY when syncing.
|
||||
// Treat busy as connected, until fixed upstream.
|
||||
if (status.contains("Height:") || status.contains("BUSY") ) {
|
||||
emit daemonStarted();
|
||||
return true;
|
||||
}
|
||||
emit daemonStopped();
|
||||
return false;
|
||||
}
|
||||
bool DaemonManager::sendCommand(const QString &cmd,bool testnet) const
|
||||
{
|
||||
QString message;
|
||||
return sendCommand(cmd, testnet, message);
|
||||
}
|
||||
|
||||
// else send external command
|
||||
bool DaemonManager::sendCommand(const QString &cmd,bool testnet, QString &message) const
|
||||
{
|
||||
QProcess p;
|
||||
QString external_cmd = m_monerod + " " + cmd;
|
||||
qDebug() << "sending external cmd: " << external_cmd;
|
||||
|
||||
// Add nestnet flag if needed
|
||||
// Add testnet flag if needed
|
||||
if (testnet)
|
||||
external_cmd += " --testnet";
|
||||
external_cmd += "\n";
|
||||
|
||||
p.start(external_cmd);
|
||||
bool started = p.waitForFinished(-1);
|
||||
QString p_stdout = p.readAllStandardOutput();
|
||||
qDebug() << p_stdout;
|
||||
emit daemonConsoleUpdated(p_stdout);
|
||||
|
||||
bool started = p.waitForFinished(-1);
|
||||
message = p.readAllStandardOutput();
|
||||
emit daemonConsoleUpdated(message);
|
||||
return started;
|
||||
}
|
||||
|
||||
@ -162,13 +165,3 @@ DaemonManager::DaemonManager(QObject *parent)
|
||||
m_has_daemon = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DaemonManager::closing()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
stop();
|
||||
// Wait for daemon to stop before exiting (max 10 secs)
|
||||
if (initialized) {
|
||||
m_daemon->waitForFinished(10000);
|
||||
}
|
||||
}
|
||||
|
@ -13,26 +13,27 @@ public:
|
||||
|
||||
static DaemonManager * instance(const QStringList *args);
|
||||
|
||||
Q_INVOKABLE bool start(const QString &flags);
|
||||
Q_INVOKABLE bool stop();
|
||||
Q_INVOKABLE bool start(const QString &flags, bool testnet);
|
||||
Q_INVOKABLE bool stop(bool testnet);
|
||||
|
||||
// return true if daemon process is started
|
||||
Q_INVOKABLE bool running() const;
|
||||
Q_INVOKABLE bool sendCommand(const QString &cmd, bool testnet);
|
||||
Q_INVOKABLE bool running(bool testnet) const;
|
||||
// Send daemon command from qml and prints output in console window.
|
||||
Q_INVOKABLE bool sendCommand(const QString &cmd, bool testnet) const;
|
||||
|
||||
private:
|
||||
bool sendCommand(const QString &cmd, bool testnet, QString &message) const;
|
||||
signals:
|
||||
void daemonStarted();
|
||||
void daemonStopped();
|
||||
void daemonConsoleUpdated(QString message);
|
||||
void daemonStarted() const;
|
||||
void daemonStopped() const;
|
||||
void daemonConsoleUpdated(QString message) const;
|
||||
|
||||
public slots:
|
||||
void printOutput();
|
||||
void printError();
|
||||
void closing();
|
||||
void stateChanged(QProcess::ProcessState state);
|
||||
|
||||
private:
|
||||
|
||||
explicit DaemonManager(QObject *parent = 0);
|
||||
static DaemonManager * m_instance;
|
||||
static QStringList m_clArgs;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <QMutexLocker>
|
||||
|
||||
namespace {
|
||||
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10;
|
||||
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 5;
|
||||
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 60;
|
||||
static const int WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS = 5;
|
||||
}
|
||||
@ -118,6 +118,7 @@ void Wallet::updateConnectionStatusAsync()
|
||||
if (newStatus != m_connectionStatus || !m_initialized) {
|
||||
m_initialized = true;
|
||||
m_connectionStatus = newStatus;
|
||||
qDebug() << "NEW STATUS " << newStatus;
|
||||
emit connectionStatusChanged(newStatus);
|
||||
}
|
||||
// Release lock
|
||||
|
@ -28,7 +28,7 @@ class Wallet : public QObject
|
||||
Q_PROPERTY(QString seedLanguage READ getSeedLanguage)
|
||||
Q_PROPERTY(Status status READ status)
|
||||
Q_PROPERTY(bool testnet READ testnet)
|
||||
Q_PROPERTY(ConnectionStatus connected READ connected)
|
||||
// Q_PROPERTY(ConnectionStatus connected READ connected)
|
||||
Q_PROPERTY(bool synchronized READ synchronized)
|
||||
Q_PROPERTY(QString errorString READ errorString)
|
||||
Q_PROPERTY(QString address READ address)
|
||||
@ -77,7 +77,7 @@ public:
|
||||
bool testnet() const;
|
||||
|
||||
//! returns whether the wallet is connected, and version status
|
||||
ConnectionStatus connected(bool forceCheck = false);
|
||||
Q_INVOKABLE ConnectionStatus connected(bool forceCheck = false);
|
||||
void updateConnectionStatusAsync();
|
||||
|
||||
//! returns true if wallet was ever synchronized
|
||||
|
Loading…
Reference in New Issue
Block a user