Split rpc and controller
This commit is contained in:
@@ -223,207 +223,16 @@ void MainWindow::closeEvent(QCloseEvent* event) {
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::turnstileProgress() {
|
||||
Ui_TurnstileProgress progress;
|
||||
QDialog d(this);
|
||||
progress.setupUi(&d);
|
||||
Settings::saveRestore(&d);
|
||||
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
progress.msgIcon->setPixmap(icon.pixmap(64, 64));
|
||||
|
||||
bool migrationFinished = false;
|
||||
auto fnUpdateProgressUI = [=, &migrationFinished] () mutable {
|
||||
// Get the plan progress
|
||||
if (rpc->getTurnstile()->isMigrationPresent()) {
|
||||
auto curProgress = rpc->getTurnstile()->getPlanProgress();
|
||||
|
||||
progress.progressTxt->setText(QString::number(curProgress.step) % QString(" / ") % QString::number(curProgress.totalSteps));
|
||||
progress.progressBar->setValue(100 * curProgress.step / curProgress.totalSteps);
|
||||
|
||||
auto nextTxBlock = curProgress.nextBlock - Settings::getInstance()->getBlockNumber();
|
||||
|
||||
progress.fromAddr->setText(curProgress.from);
|
||||
progress.toAddr->setText(curProgress.to);
|
||||
|
||||
if (curProgress.step == curProgress.totalSteps) {
|
||||
migrationFinished = true;
|
||||
auto txt = QString("Turnstile migration finished");
|
||||
if (curProgress.hasErrors) {
|
||||
txt = txt + ". There were some errors.\n\nYour funds are all in your wallet, so you should be able to finish moving them manually.";
|
||||
}
|
||||
progress.nextTx->setText(txt);
|
||||
} else {
|
||||
progress.nextTx->setText(QString("Next transaction in ")
|
||||
% QString::number(nextTxBlock < 0 ? 0 : nextTxBlock)
|
||||
% " blocks via " % curProgress.via % "\n"
|
||||
% (nextTxBlock <= 0 ? "(waiting for confirmations)" : ""));
|
||||
}
|
||||
|
||||
} else {
|
||||
progress.progressTxt->setText("");
|
||||
progress.progressBar->setValue(0);
|
||||
progress.nextTx->setText("No turnstile migration is in progress");
|
||||
}
|
||||
};
|
||||
|
||||
QTimer progressTimer(this);
|
||||
QObject::connect(&progressTimer, &QTimer::timeout, fnUpdateProgressUI);
|
||||
progressTimer.start(Settings::updateSpeed);
|
||||
fnUpdateProgressUI();
|
||||
|
||||
auto curProgress = rpc->getTurnstile()->getPlanProgress();
|
||||
|
||||
// Abort button
|
||||
if (curProgress.step != curProgress.totalSteps)
|
||||
progress.buttonBox->button(QDialogButtonBox::Discard)->setText("Abort");
|
||||
else
|
||||
progress.buttonBox->button(QDialogButtonBox::Discard)->setVisible(false);
|
||||
|
||||
// Abort button clicked
|
||||
QObject::connect(progress.buttonBox->button(QDialogButtonBox::Discard), &QPushButton::clicked, [&] () {
|
||||
if (curProgress.step != curProgress.totalSteps) {
|
||||
auto abort = QMessageBox::warning(this, "Are you sure you want to Abort?",
|
||||
"Are you sure you want to abort the migration?\nAll further transactions will be cancelled.\nAll your funds are still in your wallet.",
|
||||
QMessageBox::Yes, QMessageBox::No);
|
||||
if (abort == QMessageBox::Yes) {
|
||||
rpc->getTurnstile()->removeFile();
|
||||
d.close();
|
||||
ui->statusBar->showMessage("Automatic Sapling turnstile migration aborted.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
d.exec();
|
||||
if (migrationFinished || curProgress.step == curProgress.totalSteps) {
|
||||
// Finished, so delete the file
|
||||
rpc->getTurnstile()->removeFile();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::turnstileDoMigration(QString fromAddr) {
|
||||
// If a migration is already in progress, show the progress dialog instead
|
||||
if (rpc->getTurnstile()->isMigrationPresent()) {
|
||||
turnstileProgress();
|
||||
return;
|
||||
}
|
||||
|
||||
Ui_Turnstile turnstile;
|
||||
QDialog d(this);
|
||||
turnstile.setupUi(&d);
|
||||
Settings::saveRestore(&d);
|
||||
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
|
||||
turnstile.msgIcon->setPixmap(icon.pixmap(64, 64));
|
||||
|
||||
auto fnGetAllSproutBalance = [=] () {
|
||||
double bal = 0;
|
||||
for (auto addr : rpc->getModel()->getAllZAddresses()) {
|
||||
if (Settings::getInstance()->isSproutAddress(addr)) {
|
||||
bal += rpc->getModel()->getAllBalances().value(addr);
|
||||
}
|
||||
}
|
||||
|
||||
return bal;
|
||||
};
|
||||
|
||||
turnstile.fromBalance->setText(Settings::getZECUSDDisplayFormat(fnGetAllSproutBalance()));
|
||||
for (auto addr : rpc->getModel()->getAllZAddresses()) {
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
if (Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
turnstile.migrateTo->addItem(addr, bal);
|
||||
} else {
|
||||
turnstile.migrateZaddList->addItem(addr, bal);
|
||||
}
|
||||
}
|
||||
|
||||
auto fnUpdateSproutBalance = [=] (QString addr) {
|
||||
double bal = 0;
|
||||
|
||||
// The currentText contains the balance as well, so strip that.
|
||||
if (addr.contains("(")) {
|
||||
addr = addr.left(addr.indexOf("("));
|
||||
}
|
||||
|
||||
if (addr.startsWith("All")) {
|
||||
bal = fnGetAllSproutBalance();
|
||||
} else {
|
||||
bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
}
|
||||
|
||||
auto balTxt = Settings::getZECUSDDisplayFormat(bal);
|
||||
|
||||
if (bal < Turnstile::minMigrationAmount) {
|
||||
turnstile.fromBalance->setStyleSheet("color: red;");
|
||||
turnstile.fromBalance->setText(balTxt % " [You need at least "
|
||||
% Settings::getZECDisplayFormat(Turnstile::minMigrationAmount)
|
||||
% " for automatic migration]");
|
||||
turnstile.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
} else {
|
||||
turnstile.fromBalance->setStyleSheet("");
|
||||
turnstile.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
turnstile.fromBalance->setText(balTxt);
|
||||
}
|
||||
};
|
||||
|
||||
if (!fromAddr.isEmpty())
|
||||
turnstile.migrateZaddList->setCurrentText(fromAddr);
|
||||
|
||||
fnUpdateSproutBalance(turnstile.migrateZaddList->currentText());
|
||||
|
||||
// Combo box selection event
|
||||
QObject::connect(turnstile.migrateZaddList, &QComboBox::currentTextChanged, fnUpdateSproutBalance);
|
||||
|
||||
// Privacy level combobox
|
||||
// Num tx over num blocks
|
||||
QList<std::tuple<int, int>> privOptions;
|
||||
privOptions.push_back(std::make_tuple<int, int>(3, 576));
|
||||
privOptions.push_back(std::make_tuple<int, int>(5, 1152));
|
||||
privOptions.push_back(std::make_tuple<int, int>(10, 2304));
|
||||
|
||||
QObject::connect(turnstile.privLevel, QOverload<int>::of(&QComboBox::currentIndexChanged), [=] (auto idx) {
|
||||
// Update the fees
|
||||
turnstile.minerFee->setText(
|
||||
Settings::getZECUSDDisplayFormat(std::get<0>(privOptions[idx]) * Settings::getMinerFee()));
|
||||
});
|
||||
|
||||
for (auto i : privOptions) {
|
||||
turnstile.privLevel->addItem(QString::number((int)(std::get<1>(i) / 24 / 24)) % " days (" % // 24 blks/hr * 24 hrs per day
|
||||
QString::number(std::get<1>(i)) % " blocks, ~" %
|
||||
QString::number(std::get<0>(i)) % " txns)"
|
||||
);
|
||||
}
|
||||
|
||||
turnstile.buttonBox->button(QDialogButtonBox::Ok)->setText("Start");
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
auto privLevel = privOptions[turnstile.privLevel->currentIndex()];
|
||||
rpc->getTurnstile()->planMigration(
|
||||
turnstile.migrateZaddList->currentText(),
|
||||
turnstile.migrateTo->currentText(),
|
||||
std::get<0>(privLevel), std::get<1>(privLevel));
|
||||
|
||||
QMessageBox::information(this, "Backup your wallet.dat",
|
||||
"The migration will now start. You can check progress in the File -> Sapling Turnstile menu.\n\nYOU MUST BACKUP YOUR wallet.dat NOW!\n\nNew Addresses have been added to your wallet which will be used for the migration.",
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setupTurnstileDialog() {
|
||||
// Turnstile migration
|
||||
QObject::connect(ui->actionTurnstile_Migration, &QAction::triggered, [=] () {
|
||||
// If the underlying zcashd has support for the migration and there is no existing migration
|
||||
// in progress, use that.
|
||||
if (rpc->getMigrationStatus()->available && !rpc->getTurnstile()->isMigrationPresent()) {
|
||||
if (rpc->getMigrationStatus()->available) {
|
||||
Turnstile::showZcashdMigration(this);
|
||||
} else {
|
||||
// Else, show the ZecWallet turnstile tool
|
||||
|
||||
// If there is current migration that is present, show the progress button
|
||||
if (rpc->getTurnstile()->isMigrationPresent())
|
||||
turnstileProgress();
|
||||
else
|
||||
turnstileDoMigration();
|
||||
// Else, do nothing
|
||||
}
|
||||
});
|
||||
|
||||
@@ -718,109 +527,6 @@ void MainWindow::validateAddress() {
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::postToZBoard() {
|
||||
QDialog d(this);
|
||||
Ui_zboard zb;
|
||||
zb.setupUi(&d);
|
||||
Settings::saveRestore(&d);
|
||||
|
||||
if (rpc->getConnection() == nullptr)
|
||||
return;
|
||||
|
||||
// Fill the from field with sapling addresses.
|
||||
for (auto i = rpc->getModel()->getAllBalances().keyBegin(); i != rpc->getModel()->getAllBalances().keyEnd(); i++) {
|
||||
if (Settings::getInstance()->isSaplingAddress(*i) && rpc->getModel()->getAllBalances().value(*i) > 0) {
|
||||
zb.fromAddr->addItem(*i);
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, QString> topics;
|
||||
// Insert the main topic automatically
|
||||
topics.insert("#Main_Area", Settings::getInstance()->isTestnet() ? Settings::getDonationAddr() : Settings::getZboardAddr());
|
||||
zb.topicsList->addItem(topics.firstKey());
|
||||
// Then call the API to get topics, and if it returns successfully, then add the rest of the topics
|
||||
rpc->getZboardTopics([&](QMap<QString, QString> topicsMap) {
|
||||
for (auto t : topicsMap.keys()) {
|
||||
topics.insert(t, Settings::getInstance()->isTestnet() ? Settings::getDonationAddr() : topicsMap[t]);
|
||||
zb.topicsList->addItem(t);
|
||||
}
|
||||
});
|
||||
|
||||
// Testnet warning
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
zb.testnetWarning->setText(tr("You are on testnet, your post won't actually appear on z-board.net"));
|
||||
}
|
||||
else {
|
||||
zb.testnetWarning->setText("");
|
||||
}
|
||||
|
||||
QRegExpValidator v(QRegExp("^[a-zA-Z0-9_]{3,20}$"), zb.postAs);
|
||||
zb.postAs->setValidator(&v);
|
||||
|
||||
zb.feeAmount->setText(Settings::getZECUSDDisplayFormat(Settings::getZboardAmount() + Settings::getMinerFee()));
|
||||
|
||||
auto fnBuildNameMemo = [=]() -> QString {
|
||||
auto memo = zb.memoTxt->toPlainText().trimmed();
|
||||
if (!zb.postAs->text().trimmed().isEmpty())
|
||||
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
||||
return memo;
|
||||
};
|
||||
|
||||
auto fnUpdateMemoSize = [=]() {
|
||||
QString txt = fnBuildNameMemo();
|
||||
zb.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512");
|
||||
|
||||
if (txt.toUtf8().size() <= 512) {
|
||||
// Everything is fine
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
zb.memoSize->setStyleSheet("");
|
||||
}
|
||||
else {
|
||||
// Overweight
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
zb.memoSize->setStyleSheet("color: red;");
|
||||
}
|
||||
|
||||
// Disallow blank memos
|
||||
if (zb.memoTxt->toPlainText().trimmed().isEmpty()) {
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Memo text changed
|
||||
QObject::connect(zb.memoTxt, &QPlainTextEdit::textChanged, fnUpdateMemoSize);
|
||||
QObject::connect(zb.postAs, &QLineEdit::textChanged, fnUpdateMemoSize);
|
||||
|
||||
zb.memoTxt->setFocus();
|
||||
fnUpdateMemoSize();
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
// Create a transaction.
|
||||
Tx tx;
|
||||
|
||||
// Send from your first sapling address that has a balance.
|
||||
tx.fromAddr = zb.fromAddr->currentText();
|
||||
if (tx.fromAddr.isEmpty()) {
|
||||
QMessageBox::critical(this, "Error Posting Message", tr("You need a sapling address with available balance to post"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
auto memo = zb.memoTxt->toPlainText().trimmed();
|
||||
if (!zb.postAs->text().trimmed().isEmpty())
|
||||
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
||||
|
||||
auto toAddr = topics[zb.topicsList->currentText()];
|
||||
tx.toAddrs.push_back(ToFields{ toAddr, Settings::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
||||
tx.fee = Settings::getMinerFee();
|
||||
|
||||
// And send the Tx
|
||||
rpc->executeStandardUITransaction(tx);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::doImport(QList<QString>* keys) {
|
||||
if (rpc->getConnection() == nullptr) {
|
||||
// No connection, just return
|
||||
@@ -1095,7 +801,7 @@ void MainWindow::exportKeys(QString addr) {
|
||||
};
|
||||
|
||||
if (allKeys) {
|
||||
rpc->getAllPrivKeys(fnUpdateUIWithKeys);
|
||||
rpc->fetchAllPrivKeys(fnUpdateUIWithKeys);
|
||||
}
|
||||
else {
|
||||
auto fnAddKey = [=](json key) {
|
||||
@@ -1105,10 +811,10 @@ void MainWindow::exportKeys(QString addr) {
|
||||
};
|
||||
|
||||
if (Settings::getInstance()->isZAddress(addr)) {
|
||||
rpc->getZPrivKey(addr, fnAddKey);
|
||||
rpc->fetchZPrivKey(addr, fnAddKey);
|
||||
}
|
||||
else {
|
||||
rpc->getTPrivKey(addr, fnAddKey);
|
||||
rpc->fetchTPrivKey(addr, fnAddKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,12 +901,6 @@ void MainWindow::setupBalancesTab() {
|
||||
});
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->isSproutAddress(addr)) {
|
||||
menu.addAction(tr("Migrate to Sapling"), [=] () {
|
||||
this->turnstileDoMigration(addr);
|
||||
});
|
||||
}
|
||||
|
||||
menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos));
|
||||
});
|
||||
}
|
||||
@@ -1303,7 +1003,7 @@ void MainWindow::setupTransactionsTab() {
|
||||
}
|
||||
|
||||
void MainWindow::addNewZaddr(bool sapling) {
|
||||
rpc->newZaddr(sapling, [=] (json reply) {
|
||||
rpc->createNewZaddr(sapling, [=] (json reply) {
|
||||
QString addr = QString::fromStdString(reply.get<json::string_t>());
|
||||
// Make sure the RPC class reloads the z-addrs for future use
|
||||
rpc->refreshAddresses();
|
||||
@@ -1354,7 +1054,7 @@ std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
|
||||
|
||||
void MainWindow::setupReceiveTab() {
|
||||
auto addNewTAddr = [=] () {
|
||||
rpc->newTaddr([=] (json reply) {
|
||||
rpc->createNewTaddr([=] (json reply) {
|
||||
QString addr = QString::fromStdString(reply.get<json::string_t>());
|
||||
// Make sure the RPC class reloads the t-addrs for future use
|
||||
rpc->refreshAddresses();
|
||||
|
||||
Reference in New Issue
Block a user