mirror of
https://github.com/monero-project/monero-gui.git
synced 2025-03-20 22:28:53 +00:00
Merge pull request #709
62e1dc4
Setttings: blockchain folder location (Jaquee)9037eed
DaemonManager: support dataDir parameter + validator (Jaquee)
This commit is contained in:
commit
ecaa1a8e23
4 changed files with 145 additions and 6 deletions
3
main.qml
3
main.qml
|
@ -405,7 +405,7 @@ ApplicationWindow {
|
||||||
currentWallet.pauseRefresh();
|
currentWallet.pauseRefresh();
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
||||||
daemonManager.start(flags, persistentSettings.testnet);
|
daemonManager.start(flags, persistentSettings.testnet, persistentSettings.blockchainDataDir);
|
||||||
persistentSettings.daemonFlags = flags
|
persistentSettings.daemonFlags = flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,6 +884,7 @@ ApplicationWindow {
|
||||||
property string daemonUsername: ""
|
property string daemonUsername: ""
|
||||||
property string daemonPassword: ""
|
property string daemonPassword: ""
|
||||||
property bool transferShowAdvanced: false
|
property bool transferShowAdvanced: false
|
||||||
|
property string blockchainDataDir: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Information dialog
|
// Information dialog
|
||||||
|
|
|
@ -247,11 +247,38 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
|
id: blockchainFolderRow
|
||||||
|
Label {
|
||||||
|
id: blockchainFolderLabel
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Blockchain location") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
LineEdit {
|
||||||
|
id: blockchainFolder
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: persistentSettings.blockchainDataDir
|
||||||
|
placeholderText: qsTr("(optional)") + translationManager.emptyString
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
mouse.accepted = false
|
||||||
|
if(persistentSettings.blockchainDataDir != "")
|
||||||
|
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir
|
||||||
|
blockchainFileDialog.open()
|
||||||
|
blockchainFolder.focus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
id: daemonFlagsRow
|
id: daemonFlagsRow
|
||||||
Label {
|
Label {
|
||||||
id: daemonFlagsLabel
|
id: daemonFlagsLabel
|
||||||
|
@ -540,6 +567,62 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Choose blockchain folder
|
||||||
|
FileDialog {
|
||||||
|
id: blockchainFileDialog
|
||||||
|
title: qsTr("Please choose a folder") + translationManager.emptyString;
|
||||||
|
selectFolder: true
|
||||||
|
folder: "file://" + persistentSettings.blockchainDataDir
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
|
||||||
|
var validator = daemonManager.validateDataDir(dataDir);
|
||||||
|
if(!validator.valid) {
|
||||||
|
|
||||||
|
confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = "";
|
||||||
|
if(validator.readOnly) {
|
||||||
|
confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if(validator.storageAvailable < 20) {
|
||||||
|
confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
|
||||||
|
} else {
|
||||||
|
confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!validator.lmdbExists) {
|
||||||
|
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.cancelText = qsTr("Cancel")
|
||||||
|
|
||||||
|
// Continue
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
persistentSettings.blockchainDataDir = dataDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
confirmationDialog.onRejectedCallback = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
} else {
|
||||||
|
persistentSettings.blockchainDataDir = dataDir
|
||||||
|
}
|
||||||
|
|
||||||
|
delete validator;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("data dir selection canceled")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// fires on every page load
|
// fires on every page load
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("Settings page loaded");
|
console.log("Settings page loaded");
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <QStorageInfo>
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
|
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
|
||||||
|
@ -28,7 +32,7 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
|
||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonManager::start(const QString &flags, bool testnet)
|
bool DaemonManager::start(const QString &flags, bool testnet, const QString &dataDir)
|
||||||
{
|
{
|
||||||
// prepare command line arguments and pass to monerod
|
// prepare command line arguments and pass to monerod
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
|
@ -54,8 +58,19 @@ bool DaemonManager::start(const QString &flags, bool testnet)
|
||||||
arguments << str;
|
arguments << str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom data-dir
|
||||||
|
if(!dataDir.isEmpty()) {
|
||||||
|
if(testnet)
|
||||||
|
arguments << "--testnet-data-dir";
|
||||||
|
else
|
||||||
|
arguments << "--data-dir";
|
||||||
|
arguments << dataDir;
|
||||||
|
}
|
||||||
|
|
||||||
arguments << "--check-updates" << "disabled";
|
arguments << "--check-updates" << "disabled";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
qDebug() << "starting monerod " + m_monerod;
|
qDebug() << "starting monerod " + m_monerod;
|
||||||
qDebug() << "With command line arguments " << arguments;
|
qDebug() << "With command line arguments " << arguments;
|
||||||
|
|
||||||
|
@ -236,6 +251,44 @@ void DaemonManager::exit()
|
||||||
m_app_exit = true;
|
m_app_exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap DaemonManager::validateDataDir(const QString &dataDir) const
|
||||||
|
{
|
||||||
|
QVariantMap result;
|
||||||
|
bool valid = true;
|
||||||
|
bool readOnly = false;
|
||||||
|
int storageAvailable = 0;
|
||||||
|
bool lmdbExists = true;
|
||||||
|
|
||||||
|
QStorageInfo storage(dataDir);
|
||||||
|
if (storage.isValid() && storage.isReady()) {
|
||||||
|
if (storage.isReadOnly()) {
|
||||||
|
readOnly = true;
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there is 20GB storage available
|
||||||
|
storageAvailable = storage.bytesAvailable()/1000/1000/1000;
|
||||||
|
if (storageAvailable < 20) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!QDir(dataDir+"/lmdb").exists()) {
|
||||||
|
lmdbExists = false;
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.insert("valid", valid);
|
||||||
|
result.insert("lmdbExists", lmdbExists);
|
||||||
|
result.insert("readOnly", readOnly);
|
||||||
|
result.insert("storageAvailable", storageAvailable);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DaemonManager::DaemonManager(QObject *parent)
|
DaemonManager::DaemonManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
class DaemonManager : public QObject
|
class DaemonManager : public QObject
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ public:
|
||||||
|
|
||||||
static DaemonManager * instance(const QStringList *args);
|
static DaemonManager * instance(const QStringList *args);
|
||||||
|
|
||||||
Q_INVOKABLE bool start(const QString &flags, bool testnet);
|
Q_INVOKABLE bool start(const QString &flags, bool testnet, const QString &dataDir = "");
|
||||||
Q_INVOKABLE bool stop(bool testnet);
|
Q_INVOKABLE bool stop(bool testnet);
|
||||||
|
|
||||||
// return true if daemon process is started
|
// return true if daemon process is started
|
||||||
|
@ -21,6 +22,7 @@ public:
|
||||||
// Send daemon command from qml and prints output in console window.
|
// Send daemon command from qml and prints output in console window.
|
||||||
Q_INVOKABLE bool sendCommand(const QString &cmd, bool testnet) const;
|
Q_INVOKABLE bool sendCommand(const QString &cmd, bool testnet) const;
|
||||||
Q_INVOKABLE void exit();
|
Q_INVOKABLE void exit();
|
||||||
|
Q_INVOKABLE QVariantMap validateDataDir(const QString &dataDir) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue