diff --git a/application.qrc b/application.qrc
index faab39d..0f7de37 100644
--- a/application.qrc
+++ b/application.qrc
@@ -6,5 +6,8 @@
res/connected.gif
res/loading.gif
res/icon.ico
-
+
+
+ res/zcashdlogo.gif
+
diff --git a/res/zcashdlogo.gif b/res/zcashdlogo.gif
new file mode 100644
index 0000000..bde1631
Binary files /dev/null and b/res/zcashdlogo.gif differ
diff --git a/src/connection.cpp b/src/connection.cpp
index 3919584..f1f1f26 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -15,48 +15,287 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
d = new QDialog(main);
connD = new Ui_ConnectionDialog();
connD->setupUi(d);
-
- // Center on screen
- QRect screenGeometry = QApplication::desktop()->screenGeometry(d);
- int x = (screenGeometry.width() - d->width()) / 2;
- int y = (screenGeometry.height() - d->height()) / 2;
- d->move(x, y);
- connD->buttonBox->setEnabled(false);
+ connD->topIcon->setBasePixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256));
}
-ConnectionLoader::~ConnectionLoader() {
+ConnectionLoader::~ConnectionLoader() {
delete d;
delete connD;
}
-void ConnectionLoader::loadConnection() {
+void ConnectionLoader::loadConnection() {
+ QTimer::singleShot(1, [=]() { this->doAutoConnect(); });
+ d->exec();
+}
+
+void ConnectionLoader::doAutoConnect() {
// Priority 1: Try to connect to detect zcash.conf and connect to it.
auto config = autoDetectZcashConf();
- // If not autodetected, go and read the UI Settings
- if (config.get() == nullptr) {
- config = loadFromSettings();
+ if (config.get() != nullptr) {
+ auto connection = makeConnection(config);
+
+ refreshZcashdState(connection, [=] () {
+ // Refused connection. So try and start embedded zcashd
+ if (Settings::getInstance()->useEmbedded()) {
+ this->showInformation("Starting Embedded zcashd");
+ if (this->startEmbeddedZcashd()) {
+ // Embedded zcashd started up. Wait a second and then refresh the connection
+ QTimer::singleShot(1000, [=]() { doAutoConnect(); } );
+ } else {
+ // Errored out, show error and exit
+ QString explanation = QString() % "Couldn't start the embedded zcashd.\n\n" %
+ "Maybe the zcash-params are corrupt? Please delete your zcash-params directory and restart.\n\n" %
+ (ezcashd ? "The process returned:\n\n" % ezcashd->errorString() : QString(""));
+ this->showError(explanation);
+ }
+ } else {
+ // zcash.conf exists, there's no connection, and the user asked us not to start zcashd. Error!
+ QString explanation = QString() % "Couldn't connect to zcashd configured in zcash.conf.\n\n" %
+ "Not starting embedded zcashd because --no-embedded was passed";
+ this->showError(explanation);
+ }
+ });
+ } else {
+ if (Settings::getInstance()->useEmbedded()) {
+ // zcash.conf was not found, so create one
+ createZcashConf();
+ } else {
+ // Fall back to manual connect
+ doManualConnect();
+ }
+ }
+}
- if (config.get() == nullptr) {
- // Nothing configured, show an error
- QString explanation = QString()
- % "A zcash.conf was not found on this machine.\n\n"
- % "If you are connecting to a remote/non-standard node "
- % "please set the host/port and user/password in the Edit->Settings menu.";
+QString randomPassword() {
+ static const char alphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
- showError(explanation);
- doRPCSetConnection(nullptr);
+ const int passwordLength = 10;
+ char* s = new char[passwordLength + 1];
+ for (int i = 0; i < passwordLength; ++i) {
+ s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
+ }
+
+ s[passwordLength] = 0;
+ return QString::fromStdString(s);
+}
+
+/**
+ * This will create a new zcash.conf, download zcash parameters.
+ */
+void ConnectionLoader::createZcashConf() {
+ // Fetch params. After params are fetched, create the zcash.conf file and
+ // try loading the connection again
+ downloadParams([=] () {
+ auto confLocation = zcashConfWritableLocation();
+ qDebug() << "Creating file " << confLocation;
+
+ QFileInfo fi(confLocation);
+ QDir().mkdir(fi.dir().absolutePath());
+
+ QFile file(confLocation);
+ if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
+ qDebug() << "Could not create zcash.conf, returning";
return;
}
+
+ QTextStream out(&file);
+
+ out << "server=1\n";
+ out << "rpcuser=zec-qt-wallet\n";
+ out << "rpcpassword=" % randomPassword() << "\n";
+ file.close();
+
+ this->doAutoConnect();
+ });
+}
+
+
+void ConnectionLoader::downloadParams(std::function cb) {
+ // Add all the files to the download queue
+ downloadQueue = new QQueue();
+ client = new QNetworkAccessManager(main);
+
+ downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-output.params"));
+ downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-spend.params"));
+ downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-proving.key"));
+ downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-verifying.key"));
+ downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-groth16.params"));
+
+ doNextDownload(cb);
+}
+
+void ConnectionLoader::doNextDownload(std::function cb) {
+ auto fnSaveFileName = [&] (QUrl url) {
+ QString path = url.path();
+ QString basename = QFileInfo(path).fileName();
+
+ return basename;
+ };
+
+ if (downloadQueue->isEmpty()) {
+ delete downloadQueue;
+ client->deleteLater();
+
+ this->showInformation("All Downloads Finished Successfully!");
+ cb();
+ return;
+ }
+
+ QUrl url = downloadQueue->dequeue();
+ int filesRemaining = downloadQueue->size();
+
+ QString filename = fnSaveFileName(url);
+ QString paramsDir = zcashParamsDir();
+
+ if (QFile(QDir(paramsDir).filePath(filename)).exists()) {
+ qDebug() << filename << " already exists, skipping ";
+ doNextDownload(cb);
+
+ return;
+ }
+
+ // The downloaded file is written to a new name, and then renamed when the operation completes.
+ currentOutput = new QFile(QDir(paramsDir).filePath(filename + ".part"));
+
+ if (!currentOutput->open(QIODevice::WriteOnly)) {
+ this->showError("Couldn't download params. Please check the help site for more info.");
+ }
+ qDebug() << "Downloading " << url << " to " << filename;
+
+ QNetworkRequest request(url);
+ request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ currentDownload = client->get(request);
+ downloadTime.start();
+
+ // Download Progress
+ QObject::connect(currentDownload, &QNetworkReply::downloadProgress, [=] (auto done, auto total) {
+ // calculate the download speed
+ double speed = done * 1000.0 / downloadTime.elapsed();
+ QString unit;
+ if (speed < 1024) {
+ unit = "bytes/sec";
+ } else if (speed < 1024*1024) {
+ speed /= 1024;
+ unit = "kB/s";
+ } else {
+ speed /= 1024*1024;
+ unit = "MB/s";
+ }
+
+ this->showInformation(
+ "Downloading " % filename % (filesRemaining > 1 ? " ( +" % QString::number(filesRemaining) % " more remaining )" : QString("")),
+ QString::number(done/1024/1024, 'f', 0) % "MB of " % QString::number(total/1024/1024, 'f', 0) + "MB at " % QString::number(speed, 'f', 2) % unit);
+ });
+
+ // Download Finished
+ QObject::connect(currentDownload, &QNetworkReply::finished, [=] () {
+ // Rename file
+ currentOutput->rename(QDir(paramsDir).filePath(filename));
+
+ currentOutput->close();
+ currentDownload->deleteLater();
+ currentOutput->deleteLater();
+
+ if (currentDownload->error()) {
+ this->showError("Downloading " + filename + " failed/ Please check the help site for more info");
+ } else {
+ doNextDownload(cb);
+ }
+ });
+
+ // Download new data available.
+ QObject::connect(currentDownload, &QNetworkReply::readyRead, [=] () {
+ currentOutput->write(currentDownload->readAll());
+ });
+}
+
+bool ConnectionLoader::startEmbeddedZcashd() {
+ if (!Settings::getInstance()->useEmbedded())
+ return false;
+
+ if (ezcashd != nullptr) {
+ if (ezcashd->state() == QProcess::NotRunning) {
+ qDebug() << "Process started and then crashed";
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // Finally, start zcashd
+ qDebug() << "Starting zcashd";
+ QFileInfo fi(Settings::getInstance()->getExecName());
+#ifdef Q_OS_LINUX
+ auto zcashdProgram = fi.dir().absoluteFilePath("zcashd");
+#elif defined(Q_OS_DARWIN)
+ auto zcashdProgram = fi.dir().absoluteFilePath("zcashd");
+#else
+ auto zcashdProgram = fi.dir().absoluteFilePath("zcashd.exe");
+#endif
+
+ if (!QFile(zcashdProgram).exists()) {
+ qDebug() << "Can't find zcashd at " << zcashdProgram;
+ return false;
+ }
+
+ ezcashd = new QProcess(main);
+ QObject::connect(ezcashd, &QProcess::started, [=] () {
+ qDebug() << "zcashd started";
+ });
+
+ QObject::connect(ezcashd, QOverload::of(&QProcess::finished),
+ [=](int exitCode, QProcess::ExitStatus exitStatus) {
+ qDebug() << "zcashd finished with code " << exitCode << "," << exitStatus;
+ });
+
+ QObject::connect(ezcashd, &QProcess::errorOccurred, [&] (auto error) mutable {
+ qDebug() << "Couldn't start zcashd: " << error;
+ });
+
+ ezcashd->start(zcashdProgram);
+
+ return true;
+}
+
+void ConnectionLoader::doManualConnect() {
+ auto config = loadFromSettings();
+
+ if (!config) {
+ // Nothing configured, show an error
+ QString explanation = QString()
+ % "A manual connection was requested, but the settings are not configured.\n\n"
+ % "Please set the host/port and user/password in the Edit->Settings menu.";
+
+ showError(explanation);
+ doRPCSetConnection(nullptr);
+
+ return;
}
auto connection = makeConnection(config);
- refreshZcashdState(connection);
+ refreshZcashdState(connection, [=] () {
+ QString explanation = QString()
+ % "Could not connect to zcashd configured in settings.\n\n"
+ % "Please set the host/port and user/password in the Edit->Settings menu.";
+
+ showError(explanation);
+ doRPCSetConnection(nullptr);
+
+ return;
+ });
}
void ConnectionLoader::doRPCSetConnection(Connection* conn) {
+ rpc->setEZcashd(ezcashd);
rpc->setConnection(conn);
+
+ d->accept();
+
delete this;
}
@@ -79,7 +318,7 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr c
return new Connection(main, client, request, config);
}
-void ConnectionLoader::refreshZcashdState(Connection* connection) {
+void ConnectionLoader::refreshZcashdState(Connection* connection, std::function refused) {
json payload = {
{"jsonrpc", "1.0"},
{"id", "someid"},
@@ -91,53 +330,49 @@ void ConnectionLoader::refreshZcashdState(Connection* connection) {
d->hide();
this->doRPCSetConnection(connection);
},
- [=] (auto reply, auto res) {
- auto err = reply->error();
+ [=] (auto reply, auto res) {
// Failed, see what it is.
+ auto err = reply->error();
//qDebug() << err << ":" << QString::fromStdString(res.dump());
- if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
- auto isZcashConfFound = connection->config.get()->usingZcashConf;
- QString explanation = QString()
- % (isZcashConfFound ? "A zcash.conf file was found, but a" : "A")
- % " connection to zcashd could not be established.\n\n"
- % "If you are connecting to a remote/non-standard node "
- % "please set the host/port and user/password in the Edit->Settings menu";
-
- this->showError(explanation);
+ if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
+ refused();
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
QString explanation = QString()
% "Authentication failed. The username / password you specified was "
% "not accepted by zcashd. Try changing it in the Edit->Settings menu";
this->showError(explanation);
- } else if (err == QNetworkReply::NetworkError::InternalServerError && !res.is_discarded()) {
- d->show();
-
+ } else if (err == QNetworkReply::NetworkError::InternalServerError &&
+ !res.is_discarded()) {
// The server is loading, so just poll until it succeeds
- QString status = QString::fromStdString(res["error"]["message"]);
-
- QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
- connD->icon->setPixmap(icon.pixmap(128, 128));
- connD->status->setText("Your zcashd is starting up. Please wait.\n\n" % status);
+ QString status = QString::fromStdString(res["error"]["message"]);
+ this->showInformation("Your zcashd is starting up. Please wait.", status);
// Refresh after one second
- QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection); });
+ QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection, refused); });
}
}
);
}
-void ConnectionLoader::showError(QString explanation) {
- QMessageBox::critical(main, "Connection Error", explanation, QMessageBox::Ok);
+void ConnectionLoader::showInformation(QString info, QString detail) {
+ connD->status->setText(info);
+ connD->statusDetail->setText(detail);
}
-
/**
- * Try to automatically detect a zcash.conf file in the correct location and load parameters
- */
-std::shared_ptr ConnectionLoader::autoDetectZcashConf() {
+ * Show error will close the loading dialog and show an error.
+*/
+void ConnectionLoader::showError(QString explanation) {
+ rpc->setEZcashd(nullptr);
+ rpc->noConnection();
+
+ QMessageBox::critical(main, "Connection Error", explanation, QMessageBox::Ok);
+ d->close();
+}
+QString ConnectionLoader::locateZcashConfFile() {
#ifdef Q_OS_LINUX
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf");
#elif defined(Q_OS_DARWIN)
@@ -145,8 +380,42 @@ std::shared_ptr ConnectionLoader::autoDetectZcashConf() {
#else
auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Zcash/zcash.conf");
#endif
+ return QDir::cleanPath(confLocation);
+}
+
+QString ConnectionLoader::zcashConfWritableLocation() {
+#ifdef Q_OS_LINUX
+ auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".zcash/zcash.conf");
+#elif defined(Q_OS_DARWIN)
+ auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath("/Library/Application Support/Zcash/zcash.conf");
+#else
+ auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Zcash/zcash.conf");
+#endif
- confLocation = QDir::cleanPath(confLocation);
+ return confLocation;
+}
+
+QString ConnectionLoader::zcashParamsDir() {
+ #ifdef Q_OS_LINUX
+ auto paramsLocation = QDir(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".zcash-params"));
+#elif defined(Q_OS_DARWIN)
+ //auto paramsLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath("/Library/Application Support/Zcash/zcash.conf");
+#else
+ auto paramsLocation = QDir(QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../ZcashParams"));
+#endif
+
+ if (!paramsLocation.exists()) {
+ QDir().mkpath(paramsLocation.absolutePath());
+ }
+
+ return paramsLocation.absolutePath();
+}
+
+/**
+ * Try to automatically detect a zcash.conf file in the correct location and load parameters
+ */
+std::shared_ptr ConnectionLoader::autoDetectZcashConf() {
+ auto confLocation = locateZcashConfFile();
if (confLocation.isNull()) {
// No zcash file, just return with nothing
@@ -240,10 +509,19 @@ Connection::~Connection() {
void Connection::doRPC(const json& payload, const std::function& cb,
const std::function& ne) {
+ if (shutdownInProgress) {
+ qDebug() << "Ignoring RPC because shutdown in progress";
+ return;
+ }
+
QNetworkReply *reply = restclient->post(*request, QByteArray::fromStdString(payload.dump()));
QObject::connect(reply, &QNetworkReply::finished, [=] {
reply->deleteLater();
+ if (shutdownInProgress) {
+ qDebug() << "Ignoring callback because shutdown in progress";
+ return;
+ }
if (reply->error() != QNetworkReply::NoError) {
auto parsed = json::parse(reply->readAll(), nullptr, false);
@@ -283,3 +561,10 @@ void Connection::showTxError(const QString& error) {
QMessageBox::critical(main, "Transaction Error", "There was an error sending the transaction. The error was: \n\n"
+ error, QMessageBox::StandardButton::Ok);
}
+
+/**
+ * Prevent all future calls from going through
+ */
+void Connection::shutdown() {
+ shutdownInProgress = true;
+}
diff --git a/src/connection.h b/src/connection.h
index d6c26a9..f416653 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -41,18 +41,39 @@ private:
Connection* makeConnection(std::shared_ptr config);
- void refreshZcashdState(Connection* connection);
- int getProgressFromStatus(QString status);
+ void doAutoConnect();
+ void doManualConnect();
+
+ void createZcashConf();
+ QString locateZcashConfFile();
+ QString zcashConfWritableLocation();
+ QString zcashParamsDir();
+
+ void downloadParams(std::function cb);
+ void doNextDownload(std::function cb);
+ bool startEmbeddedZcashd();
+
+ void refreshZcashdState(Connection* connection, std::function refused);
void showError(QString explanation);
+ void showInformation(QString info, QString detail = "");
void doRPCSetConnection(Connection* conn);
+ QProcess* ezcashd = nullptr;
+
QDialog* d;
Ui_ConnectionDialog* connD;
MainWindow* main;
RPC* rpc;
+
+ QNetworkReply* currentDownload = nullptr;
+ QFile* currentOutput = nullptr;
+ QQueue* downloadQueue = nullptr;
+
+ QNetworkAccessManager* client = nullptr;
+ QTime downloadTime;
};
/**
@@ -69,6 +90,8 @@ public:
std::shared_ptr config;
MainWindow* main;
+ void shutdown();
+
void doRPC(const json& payload, const std::function& cb,
const std::function& ne);
void doRPCWithDefaultErrorHandling(const json& payload, const std::function& cb);
@@ -122,6 +145,9 @@ public:
});
waitTimer->start(100);
}
+
+private:
+ bool shutdownInProgress = false;
};
#endif
diff --git a/src/connection.ui b/src/connection.ui
index a4d98af..9a33ed6 100644
--- a/src/connection.ui
+++ b/src/connection.ui
@@ -2,6 +2,9 @@
ConnectionDialog
+
+ Qt::ApplicationModal
+
0
@@ -16,98 +19,75 @@
true
-
- -
-
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
Qt::Horizontal
-
- QDialogButtonBox::Close
-
- -
-
+
-
+
- TextLabel
+ Starting Up
Qt::AlignCenter
-
- 20
-
-
-
- -
-
-
- Qt::Horizontal
+
+ true
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
+
-
+
- Connection Status
+
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+ Qt::AlignCenter
-
- true
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ FilledIconLabel
+ QLabel
+
+
+
-
-
- buttonBox
- accepted()
- ConnectionDialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- ConnectionDialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
+
diff --git a/src/fillediconlabel.cpp b/src/fillediconlabel.cpp
new file mode 100644
index 0000000..0982cab
--- /dev/null
+++ b/src/fillediconlabel.cpp
@@ -0,0 +1,27 @@
+#include "fillediconlabel.h"
+
+FilledIconLabel::FilledIconLabel(QWidget* parent) :
+ QLabel(parent) {
+ this->setMinimumSize(1, 1);
+ setScaledContents(false);
+}
+
+void FilledIconLabel::setBasePixmap(QPixmap pm) {
+ basePm = pm;
+}
+
+/**
+ * When resized, we re-draw the whole pixmap, resizing it as needed.
+ */
+void FilledIconLabel::resizeEvent(QResizeEvent*) {
+ QSize sz = size();
+
+ QPixmap scaled = basePm.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ QPixmap p(sz);
+ p.fill(Qt::white);
+ QPainter painter(&p);
+ painter.drawPixmap((sz.width() - scaled.width()) / 2, (sz.height() - scaled.height()) / 2, scaled);
+
+ QLabel::setPixmap(p);
+}
\ No newline at end of file
diff --git a/src/fillediconlabel.h b/src/fillediconlabel.h
new file mode 100644
index 0000000..d5de800
--- /dev/null
+++ b/src/fillediconlabel.h
@@ -0,0 +1,21 @@
+#ifndef FILLEDICONLABEL_H
+#define FILLEDICONLABEL_H
+
+#include "precompiled.h"
+
+class FilledIconLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ explicit FilledIconLabel(QWidget *parent = 0);
+ void setBasePixmap(QPixmap pm);
+
+public slots:
+ void resizeEvent(QResizeEvent *);
+
+private:
+ QPixmap basePm;
+};
+
+
+#endif // FILLEDICONLABEL_H
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index eb518f3..76fcd14 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,6 +20,13 @@ int main(int argc, char *argv[])
std::srand(static_cast(std::time(nullptr)));
Settings::init();
+ Settings::getInstance()->setExecName(argv[0]);
+
+ if (argc >= 2 && QString::fromStdString(argv[1]) == "--no-embedded") {
+ Settings::getInstance()->setUseEmbedded(false);
+ } else {
+ Settings::getInstance()->setUseEmbedded(true);
+ }
QCoreApplication::setOrganizationName("zec-qt-wallet-org");
QCoreApplication::setApplicationName("zec-qt-wallet");
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 52f51dc..cd97d07 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -75,6 +75,7 @@ MainWindow::MainWindow(QWidget *parent) :
setupRecieveTab();
setupBalancesTab();
setupTurnstileDialog();
+ setupZcashdTab();
rpc = new RPC(this);
@@ -97,6 +98,10 @@ void MainWindow::closeEvent(QCloseEvent* event) {
s.setValue("baltablegeometry", ui->balancesTable->horizontalHeader()->saveState());
s.setValue("tratablegeometry", ui->transactionsTable->horizontalHeader()->saveState());
+ // Let the RPC know to shutdown any running service.
+ rpc->shutdownZcashd();
+
+ // Bubble up
QMainWindow::closeEvent(event);
}
@@ -369,13 +374,6 @@ void MainWindow::setupSettingsModal() {
QIntValidator validator(0, 65535);
settings.port->setValidator(&validator);
- // Load current values into the dialog
- auto conf = Settings::getInstance()->getSettings();
- settings.hostname->setText(conf.host);
- settings.port->setText(conf.port);
- settings.rpcuser->setText(conf.rpcuser);
- settings.rpcpassword->setText(conf.rpcpassword);
-
// If values are coming from zcash.conf, then disable all the fields
auto zcashConfLocation = Settings::getInstance()->getZcashdConfLocation();
if (!zcashConfLocation.isEmpty()) {
@@ -386,6 +384,13 @@ void MainWindow::setupSettingsModal() {
settings.rpcpassword->setEnabled(false);
}
else {
+ // Load current values into the dialog
+ auto conf = Settings::getInstance()->getSettings();
+ settings.hostname->setText(conf.host);
+ settings.port->setText(conf.port);
+ settings.rpcuser->setText(conf.rpcuser);
+ settings.rpcpassword->setText(conf.rpcpassword);
+
settings.confMsg->setText("No local zcash.conf found. Please configure connection manually.");
settings.hostname->setEnabled(true);
settings.port->setEnabled(true);
@@ -739,6 +744,10 @@ void MainWindow::setupBalancesTab() {
});
}
+void MainWindow::setupZcashdTab() {
+ ui->zcashdlogo->setBasePixmap(QPixmap(":/img/res/zcashdlogo.gif"));
+}
+
void MainWindow::setupTransactionsTab() {
// Double click opens up memo if one exists
QObject::connect(ui->transactionsTable, &QTableView::doubleClicked, [=] (auto index) {
diff --git a/src/mainwindow.h b/src/mainwindow.h
index a8521ed..33d8f53 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -51,6 +51,7 @@ private:
void setupTransactionsTab();
void setupRecieveTab();
void setupBalancesTab();
+ void setupZcashdTab();
void setupTurnstileDialog();
void setupSettingsModal();
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 838cd52..0a4aacd 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -6,8 +6,8 @@
0
0
- 889
- 603
+ 968
+ 616
@@ -22,7 +22,7 @@
-
- 1
+ 4
@@ -316,8 +316,8 @@
0
0
- 841
- 321
+ 922
+ 376
@@ -715,6 +715,145 @@
+
+
+ zcashd
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ false
+
+
+
+ -
+
+
+
+
+
+
-
+
+
+ You are currently not mining
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Loading...
+
+
+
+ -
+
+
+ Block height
+
+
+
+ -
+
+
+ Loading...
+
+
+
+ -
+
+
+ Network solution rate
+
+
+
+ -
+
+
+ Connections
+
+
+
+ -
+
+
+ Loading...
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ |
+
+
+
+ -
+
+
+ |
+
+
+
+ -
+
+
+ |
+
+
+
+
+
+
+
+
+
+
@@ -724,8 +863,8 @@
0
0
- 889
- 22
+ 968
+ 21