diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 11e4b59..5ee7aa3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -262,6 +262,48 @@ void MainWindow::setupTransactionsTab() { }); } +void MainWindow::addNewZaddr(bool sapling) { + rpc->newZaddr(sapling, [=] (json reply) { + QString addr = QString::fromStdString(reply.get()); + // Make sure the RPC class reloads the Z-addrs for future use + rpc->refreshAddresses(); + + // Just double make sure the Z-address is still checked + if (( sapling && ui->rdioZSAddr->isChecked()) || + (!sapling && ui->rdioZAddr->isChecked())) { + ui->listRecieveAddresses->insertItem(0, addr); + ui->listRecieveAddresses->setCurrentIndex(0); + + ui->statusBar->showMessage(QString::fromStdString("Created new zAddr") % + (sapling ? "(Sapling)" : "(Sprout)"), + 10 * 1000); + } + }); +} + + +// Adds sapling or sprout z-addresses to the combo box. Technically, returns a +// lambda, which can be connected to the appropriate signal +std::function MainWindow::addZAddrsToComboList(bool sapling) { + return [=] (bool checked) { + if (checked && this->rpc->getAllZAddresses() != nullptr) { + auto addrs = this->rpc->getAllZAddresses(); + ui->listRecieveAddresses->clear(); + + std::for_each(addrs->begin(), addrs->end(), [=] (auto addr) { + if ( (sapling && settings->isSaplingAddress(addr)) || + (!sapling && !settings->isSaplingAddress(addr))) + ui->listRecieveAddresses->addItem(addr); + }); + + // If z-addrs are empty, then create a new one. + if (addrs->isEmpty()) { + addNewZaddr(sapling); + } + } + }; +} + void MainWindow::setupRecieveTab() { auto addNewTAddr = [=] () { rpc->newTaddr([=] (json reply) { @@ -296,45 +338,17 @@ void MainWindow::setupRecieveTab() { } }); - auto addNewZaddr = [=] () { - rpc->newZaddr([=] (json reply) { - QString addr = QString::fromStdString(reply.get()); - // Make sure the RPC class reloads the Z-addrs for future use - rpc->refreshAddresses(); - // Just double make sure the Z-address is still checked - if (ui->rdioZAddr->isChecked()) { - ui->listRecieveAddresses->insertItem(0, addr); - ui->listRecieveAddresses->setCurrentIndex(0); - - ui->statusBar->showMessage("Created new zAddr", 10 * 1000); - } - }); - }; - - auto addZAddrsToComboList = [=] (bool checked) { - if (checked && this->rpc->getAllZAddresses() != nullptr) { - auto addrs = this->rpc->getAllZAddresses(); - ui->listRecieveAddresses->clear(); - - std::for_each(addrs->begin(), addrs->end(), [=] (auto addr) { - ui->listRecieveAddresses->addItem(addr); - }); - - // If z-addrs are empty, then create a new one. - if (addrs->isEmpty()) { - addNewZaddr(); - } - } - }; - - // zAddr toggle button - QObject::connect(ui->rdioZAddr, &QRadioButton::toggled, addZAddrsToComboList); + // zAddr toggle button, one for sprout and one for sapling + QObject::connect(ui->rdioZAddr, &QRadioButton::toggled, addZAddrsToComboList(false)); + QObject::connect(ui->rdioZSAddr, &QRadioButton::toggled, addZAddrsToComboList(true)); // Explicitly get new address button. QObject::connect(ui->btnRecieveNewAddr, &QPushButton::clicked, [=] () { if (ui->rdioZAddr->isChecked()) { - addNewZaddr(); + addNewZaddr(false); + } else if (ui->rdioZSAddr->isChecked()) { + addNewZaddr(true); } else if (ui->rdioTAddr->isChecked()) { addNewTAddr(); } @@ -344,15 +358,23 @@ void MainWindow::setupRecieveTab() { QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int tab) { if (tab == 2) { // Switched to recieve tab, so update everything. - - // Set the radio button to "Z-Addr", which should update the Address combo - ui->rdioZAddr->setChecked(true); + // Hide Sapling radio button if sapling is not active + if (Settings::getInstance()->isSaplingActive()) { + ui->rdioZSAddr->setVisible(true); + ui->rdioZSAddr->setChecked(true); + } else { + ui->rdioZSAddr->setVisible(false); + ui->rdioZAddr->setChecked(true); + ui->rdioZAddr->setText("z-Addr"); // Don't use the "Sprout" label + } + // And then select the first one ui->listRecieveAddresses->setCurrentIndex(0); } }); + // Select item in address list QObject::connect(ui->listRecieveAddresses, QOverload::of(&QComboBox::currentIndexChanged), [=] (const QString& addr) { if (addr.isEmpty()) { diff --git a/src/mainwindow.h b/src/mainwindow.h index ba7dbac..bc11696 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -54,6 +54,9 @@ private: void addressChanged(int number, const QString& text); void amountChanged (int numer, const QString& text); + void addNewZaddr(bool sapling); + std::function addZAddrsToComboList(bool sapling); + void memoButtonClicked(int number); void setMemoEnabled(int number, bool enabled); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index c24a352..5b05d0e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -562,10 +562,17 @@ + + + + z-Addr(Sapling) + + + - z-Addr + z-Addr(Sprout) diff --git a/src/rpc.cpp b/src/rpc.cpp index c366653..07988a6 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -136,13 +136,14 @@ void RPC::getZUnspent(const std::function& cb) { doRPC(payload, cb); } -void RPC::newZaddr(const std::function& cb) { +void RPC::newZaddr(bool sapling, const std::function& cb) { json payload = { {"jsonrpc", "1.0"}, {"id", "someid"}, {"method", "z_getnewaddress"}, + {"params", { sapling ? "sapling" : "sprout" }}, }; - + doRPC(payload, cb); } @@ -321,13 +322,19 @@ void RPC::getInfoThenRefresh() { }; doRPC(payload, [=](const json& reply) { - auto progress = reply["verificationprogress"].get(); + auto progress = reply["verificationprogress"].get(); + bool isSyncing = progress < 0.999; // 99.9% + int blockNumber = reply["blocks"].get(); + + Settings::getInstance()->setSyncing(isSyncing); + Settings::getInstance()->setBlockNumber(blockNumber); + QString statusText = QString() % - (progress < 0.99 ? "Syncing" : "Connected") % + (isSyncing ? "Syncing" : "Connected") % " (" % (Settings::getInstance()->isTestnet() ? "testnet:" : "") % - QString::number(reply["blocks"].get()) % - (progress < 0.99 ? ("/" % QString::number(progress*100, 'f', 0) % "%") : QString()) % + QString::number(blockNumber) % + (isSyncing ? ("/" % QString::number(progress*100, 'f', 0) % "%") : QString()) % ")"; main->statusLabel->setText(statusText); auto zecPrice = Settings::getInstance()->getUSDFormat(1); diff --git a/src/rpc.h b/src/rpc.h index 52754a2..9936c55 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -31,7 +31,7 @@ public: void reloadConnectionInfo(); - void newZaddr (const std::function& cb); + void newZaddr (bool sapling, const std::function& cb); void newTaddr (const std::function& cb); private: diff --git a/src/settings.cpp b/src/settings.cpp index 149213e..ed9ce53 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -152,6 +152,11 @@ void Settings::setTestnet(bool isTestnet) { this->_isTestnet = isTestnet; } +bool Settings::isSaplingAddress(QString addr) { + return ( isTestnet() && addr.startsWith("ztestsapling")) || + (!isTestnet() && addr.startsWith("zs")); +} + bool Settings::isSyncing() { return _isSyncing; } @@ -160,6 +165,19 @@ void Settings::setSyncing(bool syncing) { this->_isSyncing = syncing; } +int Settings::getBlockNumber() { + return this->_blockNumber; +} + +void Settings::setBlockNumber(int number) { + this->_blockNumber = number; +} + +bool Settings::isSaplingActive() { + return (isTestnet() && getBlockNumber() > 280000) || + (!isTestnet() && getBlockNumber() > 419200); +} + double Settings::getZECPrice() { return zecPrice; } diff --git a/src/settings.h b/src/settings.h index 8f3ea80..123259e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -28,9 +28,16 @@ public: bool isTestnet(); void setTestnet(bool isTestnet); + bool isSaplingAddress(QString addr); + bool isSyncing(); void setSyncing(bool syncing); + int getBlockNumber(); + void setBlockNumber(int number); + + bool isSaplingActive(); + const QString& getZcashdConfLocation() { return confLocation; } void setZECPrice(double p) { zecPrice = p; } @@ -55,8 +62,9 @@ private: QString confLocation; - bool _isTestnet = false; - bool _isSyncing = false; + bool _isTestnet = false; + bool _isSyncing = false; + int _blockNumber = 0; double zecPrice = 0.0; }; diff --git a/src/ui_mainwindow.h b/src/ui_mainwindow.h index 54a12e8..e656a24 100644 --- a/src/ui_mainwindow.h +++ b/src/ui_mainwindow.h @@ -118,6 +118,7 @@ public: QGroupBox *groupBox_6; QVBoxLayout *verticalLayout_9; QHBoxLayout *horizontalLayout_9; + QRadioButton *rdioZSAddr; QRadioButton *rdioZAddr; QRadioButton *rdioTAddr; QHBoxLayout *horizontalLayout_10; @@ -525,6 +526,11 @@ public: horizontalLayout_9 = new QHBoxLayout(); horizontalLayout_9->setSpacing(6); horizontalLayout_9->setObjectName(QStringLiteral("horizontalLayout_9")); + rdioZSAddr = new QRadioButton(groupBox_6); + rdioZSAddr->setObjectName(QStringLiteral("rdioZSAddr")); + + horizontalLayout_9->addWidget(rdioZSAddr); + rdioZAddr = new QRadioButton(groupBox_6); rdioZAddr->setObjectName(QStringLiteral("rdioZAddr")); @@ -650,7 +656,7 @@ public: retranslateUi(MainWindow); - tabWidget->setCurrentIndex(1); + tabWidget->setCurrentIndex(2); QMetaObject::connectSlotsByName(MainWindow); @@ -699,7 +705,8 @@ public: cancelSendButton->setText(QApplication::translate("MainWindow", "Cancel", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("MainWindow", "Send", nullptr)); groupBox_6->setTitle(QApplication::translate("MainWindow", "Address Type", nullptr)); - rdioZAddr->setText(QApplication::translate("MainWindow", "z-Addr", nullptr)); + rdioZSAddr->setText(QApplication::translate("MainWindow", "z-Addr(Sapling)", nullptr)); + rdioZAddr->setText(QApplication::translate("MainWindow", "z-Addr(Sprout)", nullptr)); rdioTAddr->setText(QApplication::translate("MainWindow", "t-Addr", nullptr)); btnRecieveNewAddr->setText(QApplication::translate("MainWindow", "New Address", nullptr)); qrcodeDisplay->setText(QString());