diff --git a/src/main.cpp b/src/main.cpp index f8c0000..4c44680 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,8 +16,6 @@ int main(int argc, char *argv[]) qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false)); #endif - QCoreApplication::setOrganizationName("adityapk"); - QCoreApplication::setOrganizationDomain("adityapk.com"); QCoreApplication::setApplicationName("zcash-qt-wallet"); Settings::init(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 163f608..d12442d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -73,25 +73,44 @@ MainWindow::MainWindow(QWidget *parent) : QIntValidator validator(0, 65535); settings.port->setValidator(&validator); - // Load previous values into the dialog - settings.hostname ->setText(Settings::getInstance()->getHost()); - settings.port ->setText(Settings::getInstance()->getPort()); - settings.rpcuser ->setText(Settings::getInstance()->getUsernamePassword().split(":")[0]); - settings.rpcpassword->setText(Settings::getInstance()->getUsernamePassword().split(":")[1]); + + // If values are coming from zcash.conf, then disable all the fields + auto zcashConfLocation = Settings::getInstance()->getZcashdConfLocation(); + if (!zcashConfLocation.isEmpty()) { + settings.confMsg->setText("Values are configured from\n" + zcashConfLocation); + settings.hostname->setEnabled(false); + settings.port->setEnabled(false); + settings.rpcuser->setEnabled(false); + settings.rpcpassword->setEnabled(false); + } + else { + settings.hostname->setEnabled(true); + settings.port->setEnabled(true); + settings.rpcuser->setEnabled(true); + settings.rpcpassword->setEnabled(true); + + // Load previous values into the dialog + settings.hostname->setText(Settings::getInstance()->getHost()); + settings.port->setText(Settings::getInstance()->getPort()); + settings.rpcuser->setText(Settings::getInstance()->getUsernamePassword().split(":")[0]); + settings.rpcpassword->setText(Settings::getInstance()->getUsernamePassword().split(":")[1]); + } if (settingsDialog.exec() == QDialog::Accepted) { - // Save settings - QSettings s; - s.setValue("connection/host", settings.hostname->text()); - s.setValue("connection/port", settings.port->text()); - s.setValue("connection/rpcuser", settings.rpcuser->text()); - s.setValue("connection/rpcpassword", settings.rpcpassword->text()); + if (zcashConfLocation.isEmpty()) { + // Save settings + QSettings s; + s.setValue("connection/host", settings.hostname->text()); + s.setValue("connection/port", settings.port->text()); + s.setValue("connection/rpcuser", settings.rpcuser->text()); + s.setValue("connection/rpcpassword", settings.rpcpassword->text()); - s.sync(); + s.sync(); - // Then refresh everything. - this->rpc->reloadConnectionInfo(); - this->rpc->refresh(); + // Then refresh everything. + this->rpc->reloadConnectionInfo(); + this->rpc->refresh(); + } }; }); diff --git a/src/precompiled.h b/src/precompiled.h index 87f7900..b63568a 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rpc.cpp b/src/rpc.cpp index 2fb3127..e143e06 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -231,11 +231,18 @@ void RPC::handleConnectionError(const QString& error) { % "rpcpassword=\n" % "\nIf you're connecting to a remote note, you can change the username/password in the " % "File->Settings menu."; - } else if (error.contains("connection", Qt::CaseInsensitive)) { - explanation = QString() - % "\n\nThis is most likely because we couldn't connect to zcashd. Is zcashd running and " - % "accepting connections from this machine? \nIf you need to change the host/port, you can set that in the " - % "File->Settings menu."; + } else if (error.contains("connection refused", Qt::CaseInsensitive)) { + auto confLocation = Settings::getInstance()->getZcashdConfLocation(); + if (confLocation.isEmpty()) { + explanation = QString() + % "\n\nA zcash.conf was not found on this machine. If you are connecting to a remote/non-standard node " + % "please set the host/port and user/password in the File->Settings menu."; + } + else { + explanation = QString() + % "\n\nA zcash.conf was found at\n" % confLocation + % "\nbut we can't connect to zcashd. Is rpcuser= and rpcpassword= set in the zcash.conf file?"; + } } else if (error.contains("bad request", Qt::CaseInsensitive)) { explanation = QString() % "\n\nThis is most likely an internal error. Are you using zcashd v2.0 or higher? You might " diff --git a/src/settings.cpp b/src/settings.cpp index 00f711a..99c13ea 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -4,18 +4,38 @@ Settings* Settings::instance = nullptr; +Settings::~Settings() { + delete defaults; + delete zcashconf; + delete uisettings; +} + Settings* Settings::init() { if (instance != nullptr) return instance; instance = new Settings(); - // Load from settings first, because if they are redefined in the zcash.conf file, - // we'll overwrite them. - instance->loadFromSettings(); -#ifdef Q_OS_LINUX - // Overwrite if any are defined in the zcash.conf - instance->loadFromFile(); -#endif + // There are 3 possible configurations + // 1. The defaults + instance->defaults = new Config{ "127.0.0.1", "8232", "", "" }; + + // 2. From the UI settings + auto settingsFound = instance->loadFromSettings(); + + // 3. From the zcash.conf file + auto confFound = instance->loadFromFile(); + + // zcash.conf (#3) is first priority if it exists + if (confFound) { + instance->currentConfig = instance->zcashconf; + } + else if (settingsFound) { + instance->currentConfig = instance->uisettings; + } + else { + instance->currentConfig = instance->defaults; + } + return instance; } @@ -23,75 +43,92 @@ Settings* Settings::getInstance() { return instance; } + QString Settings::getHost() { - if (host.isNull() || host == "") return "127.0.0.1"; - return host; + return currentConfig->host; } QString Settings::getPort() { - // If the override port is set, we'll always return it - if (!overridePort.isEmpty()) return overridePort; - - if (port.isNull() || port == "") return "8232"; - return port; + return currentConfig->port; } QString Settings::getUsernamePassword() { - return username % ":" % password; + return currentConfig->rpcuser % ":" % currentConfig->rpcpassword; } -void Settings::loadFromSettings() { - // First step is to try and load from the QT Settings. These are loaded first, because - // they could be overridden by whats in the zcash.conf, which will take precedence. +bool Settings::loadFromSettings() { + delete uisettings; + + // Load from the QT Settings. QSettings s; - host = s.value("connection/host", "127.0.0.1" ).toString(); - port = s.value("connection/port", "8232" ).toString(); - username = s.value("connection/rpcuser", "" ).toString(); - password = s.value("connection/rpcpassword", "" ).toString(); + auto host = s.value("connection/host").toString(); + auto port = s.value("connection/port").toString(); + auto username = s.value("connection/rpcuser").toString(); + auto password = s.value("connection/rpcpassword").toString(); + + uisettings = new Config{host, port, username, password}; + + if (username.isEmpty()) return false; + return true; } -void Settings::loadFromFile() { - // Nothing in QT Settings, so try to read from file. - QString zcashdconf = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf"); - if (zcashdconf.isNull()) { +bool Settings::loadFromFile() { + delete zcashconf; + +#ifdef Q_OS_LINUX + confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf"); +#else + confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../Zcash/zcash.conf"); +#endif + + confLocation = QDir::cleanPath(confLocation); + + if (confLocation.isNull()) { // No zcash file, just return with nothing - return; + return false; } - QFile file(zcashdconf); + QFile file(confLocation); if (!file.open(QIODevice::ReadOnly)) { qDebug() << file.errorString(); - return; + return false; } QTextStream in(&file); + zcashconf = new Config(); + zcashconf->host = defaults->host; + while (!in.atEnd()) { QString line = in.readLine(); - QStringList fields = line.split("="); + auto s = line.indexOf("="); + QString name = line.left(s).trimmed().toLower(); + QString value = line.right(line.length() - s - 1).trimmed(); - if (fields[0].trimmed().toLower() == "rpcuser") { - fields.removeFirst(); - username = fields.join("").trimmed(); + if (name == "rpcuser") { + zcashconf->rpcuser = value; } - if (fields[0].trimmed().toLower() == "rpcpassword") { - fields.removeFirst(); - password = fields.join("").trimmed(); + if (name == "rpcpassword") { + zcashconf->rpcpassword = value; } - if (fields[0].trimmed().toLower() == "rpcport") { - overridePort = fields[1].trimmed(); + if (name == "rpcport") { + zcashconf->port = value; } - if (fields[0].trimmed().toLower() == "testnet" && - fields[1].trimmed() == "1" && - overridePort.isEmpty()) { - overridePort = "18232"; + if (name == "testnet" && + value == "1" && + zcashconf->port.isEmpty()) { + zcashconf->port = "18232"; } } + // If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default + if (zcashconf->port.isEmpty()) zcashconf->port = defaults->port; + file.close(); + return true; } bool Settings::isTestnet() { diff --git a/src/settings.h b/src/settings.h index 41d6625..07ce65a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -3,6 +3,13 @@ #include "precompiled.h" +struct Config { + QString host; + QString port; + QString rpcuser; + QString rpcpassword; +}; + class Settings { public: @@ -13,11 +20,9 @@ public: QString getHost(); QString getPort(); - void setDefaultPort(int port) {overridePort = QString::number(port);} - double fees() { return 0.0001; } - void loadFromSettings(); - void loadFromFile(); + bool loadFromSettings(); + bool loadFromFile(); bool isTestnet(); void setTestnet(bool isTestnet); @@ -25,18 +30,22 @@ public: bool isSyncing(); void setSyncing(bool syncing); + const QString& getZcashdConfLocation() { return confLocation; } + private: // This class can only be accessed through Settings::getInstance() Settings() = default; + ~Settings(); static Settings* instance; - QString host; - QString port; - QString username; - QString password; + Config* currentConfig; - QString overridePort; + Config* defaults = nullptr; + Config* zcashconf = nullptr; + Config* uisettings = nullptr; + + QString confLocation; bool _isTestnet = false; bool _isSyncing = false; diff --git a/src/settings.ui b/src/settings.ui index 38890c1..fe0e518 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -111,9 +111,12 @@ - + - <html><head/><body><p>Values configured in ~/.zcash/zcash.conf <br/>will overwrite these values</p></body></html> + <html><head/><body><p>zcash msg</p></body></html> + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse diff --git a/src/ui_settings.h b/src/ui_settings.h index 867869b..8f334b6 100644 --- a/src/ui_settings.h +++ b/src/ui_settings.h @@ -43,7 +43,7 @@ public: QLabel *label_4; QLineEdit *rpcpassword; QLabel *label_2; - QLabel *label_5; + QLabel *confMsg; QFrame *line; QSpacerItem *verticalSpacer; QDialogButtonBox *buttonBox; @@ -113,10 +113,11 @@ public: gridLayout->addWidget(label_2, 4, 0, 1, 1); - label_5 = new QLabel(groupBox); - label_5->setObjectName(QStringLiteral("label_5")); + confMsg = new QLabel(groupBox); + confMsg->setObjectName(QStringLiteral("confMsg")); + confMsg->setTextInteractionFlags(Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse); - gridLayout->addWidget(label_5, 0, 0, 1, 1); + gridLayout->addWidget(confMsg, 0, 0, 1, 1); line = new QFrame(groupBox); line->setObjectName(QStringLiteral("line")); @@ -171,7 +172,7 @@ public: port->setPlaceholderText(QApplication::translate("Settings", "8232", nullptr)); label_4->setText(QApplication::translate("Settings", "RPC Password", nullptr)); label_2->setText(QApplication::translate("Settings", "Port", nullptr)); - label_5->setText(QApplication::translate("Settings", "

Values configured in ~/.zcash/zcash.conf
will overwrite these values

", nullptr)); + confMsg->setText(QApplication::translate("Settings", "

zcash msg

", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("Settings", "Connection", nullptr)); } // retranslateUi