Browse Source

Add advanced explorer settings

pull/72/head
Yusuf Sahin HAMZA 5 years ago
parent
commit
cbdd74a848
  1. 194
      src/mainwindow.cpp
  2. 57
      src/settings.cpp
  3. 28
      src/settings.h
  4. 124
      src/settings.ui

194
src/mainwindow.cpp

@ -34,8 +34,8 @@ MainWindow::MainWindow(QWidget *parent) :
// Status Bar
setupStatusBar();
// Settings editor
// Settings editor
setupSettingsModal();
// Set up exit action
@ -102,7 +102,7 @@ MainWindow::MainWindow(QWidget *parent) :
QString version = QString("Version ") % QString(APP_VERSION) % " (" % QString(__DATE__) % ")";
about.versionLabel->setText(version);
aboutDialog.exec();
});
@ -130,7 +130,7 @@ MainWindow::MainWindow(QWidget *parent) :
createWebsocket(wormholecode);
}
}
void MainWindow::createWebsocket(QString wormholecode) {
// Create the websocket server, for listening to direct connections
int wsport = 8777;
@ -207,12 +207,12 @@ void MainWindow::turnstileProgress() {
// 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);
@ -224,12 +224,12 @@ void MainWindow::turnstileProgress() {
}
progress.nextTx->setText(txt);
} else {
progress.nextTx->setText(QString("Next transaction in ")
progress.nextTx->setText(QString("Next transaction in ")
% QString::number(nextTxBlock < 0 ? 0 : nextTxBlock)
% " blocks via " % curProgress.via % "\n"
% " blocks via " % curProgress.via % "\n"
% (nextTxBlock <= 0 ? "(waiting for confirmations)" : ""));
}
} else {
progress.progressTxt->setText("");
progress.progressBar->setValue(0);
@ -237,11 +237,11 @@ void MainWindow::turnstileProgress() {
}
};
QTimer progressTimer(this);
QTimer progressTimer(this);
QObject::connect(&progressTimer, &QTimer::timeout, fnUpdateProgressUI);
progressTimer.start(Settings::updateSpeed);
fnUpdateProgressUI();
auto curProgress = rpc->getTurnstile()->getPlanProgress();
// Abort button
@ -264,11 +264,11 @@ void MainWindow::turnstileProgress() {
}
});
d.exec();
d.exec();
if (migrationFinished || curProgress.step == curProgress.totalSteps) {
// Finished, so delete the file
rpc->getTurnstile()->removeFile();
}
}
}
void MainWindow::turnstileDoMigration(QString fromAddr) {
@ -324,12 +324,12 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
} else {
bal = rpc->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 "
turnstile.fromBalance->setText(balTxt % " [You need at least "
% Settings::getZECDisplayFormat(Turnstile::minMigrationAmount)
% " for automatic migration]");
turnstile.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
@ -343,14 +343,14 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
if (!fromAddr.isEmpty())
turnstile.migrateZaddList->setCurrentText(fromAddr);
fnUpdateSproutBalance(turnstile.migrateZaddList->currentText());
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;
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));
@ -367,30 +367,30 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
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.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::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() {
void MainWindow::setupTurnstileDialog() {
// Turnstile migration
QObject::connect(ui->actionTurnstile_Migration, &QAction::triggered, [=] () {
// If there is current migration that is present, show the progress button
if (rpc->getTurnstile()->isMigrationPresent())
turnstileProgress();
else
turnstileDoMigration();
else
turnstileDoMigration();
});
}
@ -420,11 +420,12 @@ void MainWindow::setupStatusBar() {
});
menu.addAction("View tx on block explorer", [=]() {
QString url;
auto explorer = Settings::getInstance()->getExplorer();
if (Settings::getInstance()->isTestnet()) {
url = "https://explorer.testnet.z.cash/tx/" + txid;
url = explorer.testnetTxExplorerUrl + txid;
}
else {
url = "https://explorer.myhush.org/tx/" + txid;
url = explorer.txExplorerUrl + txid;
}
QDesktopServices::openUrl(QUrl(url));
});
@ -444,7 +445,7 @@ void MainWindow::setupStatusBar() {
ui->statusBar->addPermanentWidget(statusIcon);
}
void MainWindow::setupSettingsModal() {
void MainWindow::setupSettingsModal() {
// Set up File -> Settings action
QObject::connect(ui->actionSettings, &QAction::triggered, [=]() {
QDialog settingsDialog(this);
@ -517,13 +518,21 @@ void MainWindow::setupSettingsModal() {
settings.rpcpassword->setEnabled(true);
}
// Load current values into the dialog
// Load current values into the dialog
// 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);
// Load current explorer values into the dialog
auto explorer = Settings::getInstance()->getExplorer();
settings.txExplorerUrl->setText(explorer.txExplorerUrl);
settings.addressExplorerUrl->setText(explorer.addressExplorerUrl);
settings.testnetTxExplorerUrl->setText(explorer.testnetTxExplorerUrl);
settings.testnetAddressExplorerUrl->setText(explorer.testnetAddressExplorerUrl);
// Connection tab by default
settings.tabWidget->setCurrentIndex(0);
@ -558,8 +567,8 @@ void MainWindow::setupSettingsModal() {
Settings::addToZcashConf(zcashConfLocation, "proxy=127.0.0.1:9050");
rpc->getConnection()->config->proxy = "proxy=127.0.0.1:9050";
QMessageBox::information(this, tr("Enable Tor"),
tr("Connection over Tor has been enabled. To use this feature, you need to restart SilentDragon."),
QMessageBox::information(this, tr("Enable Tor"),
tr("Connection over Tor has been enabled. To use this feature, you need to restart SilentDragon."),
QMessageBox::Ok);
}
@ -580,11 +589,18 @@ void MainWindow::setupSettingsModal() {
settings.port->text(),
settings.rpcuser->text(),
settings.rpcpassword->text());
auto cl = new ConnectionLoader(this, rpc);
cl->loadConnection();
}
// Save explorer
Settings::getInstance()->saveExplorer(
settings.txExplorerUrl->text(),
settings.addressExplorerUrl->text(),
settings.testnetTxExplorerUrl->text(),
settings.testnetAddressExplorerUrl->text());
// Check to see if rescan or reindex have been enabled
bool showRestartInfo = false;
if (settings.chkRescan->isChecked()) {
@ -599,7 +615,7 @@ void MainWindow::setupSettingsModal() {
if (showRestartInfo) {
auto desc = tr("SilentDragon needs to restart to rescan/reindex. SilentDragon will now close, please restart SilentDragon to continue");
QMessageBox::information(this, tr("Restart SilentDragon"), desc, QMessageBox::Ok);
QTimer::singleShot(1, [=]() { this->close(); });
}
@ -655,7 +671,7 @@ void MainWindow::validateAddress() {
// First thing is ask the user for an address
bool ok;
auto address = QInputDialog::getText(this, tr("Enter Address to validate"),
auto address = QInputDialog::getText(this, tr("Enter Address to validate"),
tr("Transparent or Shielded Address:") + QString(" ").repeated(140), // Pad the label so the dialog box is wide enough
QLineEdit::Normal, "", &ok);
if (!ok)
@ -770,7 +786,7 @@ void MainWindow::postToZBoard() {
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()) {
@ -790,16 +806,16 @@ void MainWindow::postToZBoard() {
rpc->executeTransaction(tx, [=] (QString opid) {
ui->statusBar->showMessage(tr("Computing Tx: ") % opid);
},
[=] (QString /*opid*/, QString txid) {
[=] (QString /*opid*/, QString txid) {
ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid);
},
[=] (QString opid, QString errStr) {
ui->statusBar->showMessage(QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000);
if (!opid.isEmpty())
errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr;
errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr;
QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok);
QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok);
});
}
}
@ -823,14 +839,14 @@ void MainWindow::doImport(QList<QString>* keys) {
if (key.startsWith("SK") ||
key.startsWith("secret")) { // Z key
rpc->importZPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
rpc->importZPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
} else {
rpc->importTPrivKey(key, rescan, [=] (auto) { this->doImport(keys); });
}
}
// Callback invoked when the RPC has finished loading all the balances, and the UI
// Callback invoked when the RPC has finished loading all the balances, and the UI
// is now ready to send transactions.
void MainWindow::balancesReady() {
// First-time check
@ -889,7 +905,7 @@ void MainWindow::payZcashURI(QString uri, QString myAddr) {
qDebug() << "Received URI " << uri;
PaymentURI paymentInfo = Settings::parseURI(uri);
if (!paymentInfo.error.isEmpty()) {
QMessageBox::critical(this, tr("Error paying Hush URI"),
QMessageBox::critical(this, tr("Error paying Hush URI"),
tr("URI should be of the form 'hush:<addr>?amt=x&memo=y") + "\n" + paymentInfo.error);
return;
}
@ -926,7 +942,7 @@ void MainWindow::importPrivKey() {
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
pui.helpLbl->setText(QString() %
tr("Please paste your private keys here, one per line") % ".\n" %
tr("The keys will be imported into your connected Hush node"));
tr("The keys will be imported into your connected Hush node"));
if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) {
auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n");
@ -942,8 +958,8 @@ void MainWindow::importPrivKey() {
return key.trimmed().split(" ")[0];
});
// Special case.
// Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have
// Special case.
// Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have
// been pasted like that. So check to see if the whole thing is one big private key
if (Settings::getInstance()->isValidSaplingPrivateKey(keys->join(""))) {
auto multiline = keys;
@ -955,31 +971,31 @@ void MainWindow::importPrivKey() {
// Start the import. The function takes ownership of keys
QTimer::singleShot(1, [=]() {doImport(keys);});
// Show the dialog that keys will be imported.
// Show the dialog that keys will be imported.
QMessageBox::information(this,
"Imported", tr("The keys were imported! It may take several minutes to rescan the blockchain. Until then, functionality may be limited"),
QMessageBox::Ok);
}
}
/**
/**
* Export transaction history into a CSV file
*/
void MainWindow::exportTransactions() {
// First, get the export file name
QString exportName = "hush-transactions-" + QDateTime::currentDateTime().toString("yyyyMMdd") + ".csv";
QUrl csvName = QFileDialog::getSaveFileUrl(this,
QUrl csvName = QFileDialog::getSaveFileUrl(this,
tr("Export transactions"), exportName, "CSV file (*.csv)");
if (csvName.isEmpty())
return;
if (!rpc->getTransactionsModel()->exportToCsv(csvName.toLocalFile())) {
QMessageBox::critical(this, tr("Error"),
QMessageBox::critical(this, tr("Error"),
tr("Error exporting transactions, file was not saved"), QMessageBox::Ok);
}
}
}
/**
* Backup the wallet.dat file. This is kind of a hack, since it has to read from the filesystem rather than an RPC call
@ -996,20 +1012,20 @@ void MainWindow::backupWalletDat() {
zcashdir.cd("testnet3");
backupDefaultName = "testnet-" + backupDefaultName;
}
QFile wallet(zcashdir.filePath("wallet.dat"));
if (!wallet.exists()) {
QMessageBox::critical(this, tr("No wallet.dat"), tr("Couldn't find the wallet.dat on this computer") + "\n" +
tr("You need to back it up from the machine hushd is running on"), QMessageBox::Ok);
return;
}
QUrl backupName = QFileDialog::getSaveFileUrl(this, tr("Backup wallet.dat"), backupDefaultName, "Data file (*.dat)");
if (backupName.isEmpty())
return;
if (!wallet.copy(backupName.toLocalFile())) {
QMessageBox::critical(this, tr("Couldn't backup"), tr("Couldn't backup the wallet.dat file.") +
QMessageBox::critical(this, tr("Couldn't backup"), tr("Couldn't backup the wallet.dat file.") +
tr("You need to back it up manually."), QMessageBox::Ok);
}
}
@ -1024,7 +1040,7 @@ void MainWindow::exportKeys(QString addr) {
QDialog d(this);
Ui_PrivKey pui;
pui.setupUi(&d);
// Make the window big by default
auto ps = this->geometry();
QMargins margin = QMargins() + 50;
@ -1053,7 +1069,7 @@ void MainWindow::exportKeys(QString addr) {
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
}
QTextStream out(&file);
out << pui.privKeyTxt->toPlainText();
});
@ -1077,7 +1093,7 @@ void MainWindow::exportKeys(QString addr) {
if (allKeys) {
rpc->getAllPrivKeys(fnUpdateUIWithKeys);
}
else {
else {
auto fnAddKey = [=](json key) {
QList<QPair<QString, QString>> singleAddrKey;
singleAddrKey.push_back(QPair<QString, QString>(addr, QString::fromStdString(key.get<json::string_t>())));
@ -1089,9 +1105,9 @@ void MainWindow::exportKeys(QString addr) {
}
else {
rpc->getTPrivKey(addr, fnAddKey);
}
}
}
d.exec();
*isDialogAlive = false;
}
@ -1130,7 +1146,7 @@ void MainWindow::setupBalancesTab() {
QObject::connect(ui->balancesTable, &QTableView::doubleClicked, [=](auto index) {
index = index.sibling(index.row(), 0);
auto addr = AddressBook::addressFromAddressLabel(ui->balancesTable->model()->data(index).toString());
fnDoSendFrom(addr);
});
@ -1148,7 +1164,7 @@ void MainWindow::setupBalancesTab() {
menu.addAction(tr("Copy address"), [=] () {
QClipboard *clipboard = QGuiApplication::clipboard();
clipboard->setText(addr);
clipboard->setText(addr);
ui->statusBar->showMessage(tr("Copied to clipboard"), 3 * 1000);
});
@ -1170,11 +1186,12 @@ void MainWindow::setupBalancesTab() {
menu.addAction(tr("View on block explorer"), [=] () {
QString url;
auto explorer = Settings::getInstance()->getExplorer();
if (Settings::getInstance()->isTestnet()) {
//TODO
url = "https://explorer.testnet.myhush.org/address/" + addr;
url = explorer.testnetAddressExplorerUrl + addr;
} else {
url = "https://explorer.myhush.org/address/" + addr;
url = explorer.addressExplorerUrl + addr;
}
QDesktopServices::openUrl(QUrl(url));
});
@ -1199,11 +1216,11 @@ void MainWindow::setupBalancesTab() {
});
}
menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos));
menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos));
});
}
void MainWindow::setupZcashdTab() {
void MainWindow::setupZcashdTab() {
ui->hushlogo->setBasePixmap(QPixmap(":/img/res/zcashdlogo.gif"));
}
@ -1236,7 +1253,7 @@ void MainWindow::setupTransactionsTab() {
QString memo = txModel->getMemo(index.row());
QString addr = txModel->getAddr(index.row());
menu.addAction(tr("Copy txid"), [=] () {
menu.addAction(tr("Copy txid"), [=] () {
QGuiApplication::clipboard()->setText(txid);
ui->statusBar->showMessage(tr("Copied to clipboard"), 3 * 1000);
});
@ -1250,10 +1267,11 @@ void MainWindow::setupTransactionsTab() {
menu.addAction(tr("View on block explorer"), [=] () {
QString url;
auto explorer = Settings::getInstance()->getExplorer();
if (Settings::getInstance()->isTestnet()) {
url = "https://explorer.testnet.myhush.org/tx/" + txid;
url = explorer.testnetTxExplorerUrl + txid;
} else {
url = "https://explorer.myhush.org/tx/" + txid;
url = explorer.txExplorerUrl + txid;
}
QDesktopServices::openUrl(QUrl(url));
});
@ -1267,7 +1285,7 @@ void MainWindow::setupTransactionsTab() {
// View Memo
if (!memo.isEmpty()) {
menu.addAction(tr("View Memo"), [=] () {
menu.addAction(tr("View Memo"), [=] () {
QMessageBox mb(QMessageBox::Information, tr("Memo"), memo, QMessageBox::Ok, this);
mb.setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
mb.exec();
@ -1278,8 +1296,8 @@ void MainWindow::setupTransactionsTab() {
if (!memo.isEmpty()) {
int lastPost = memo.trimmed().lastIndexOf(QRegExp("[\r\n]+"));
QString lastWord = memo.right(memo.length() - lastPost - 1);
if (Settings::getInstance()->isSaplingAddress(lastWord) ||
if (Settings::getInstance()->isSaplingAddress(lastWord) ||
Settings::getInstance()->isSproutAddress(lastWord)) {
menu.addAction(tr("Reply to ") + lastWord.left(25) + "...", [=]() {
// First, cancel any pending stuff in the send tab by pretending to click
@ -1302,7 +1320,7 @@ void MainWindow::setupTransactionsTab() {
}
}
menu.exec(ui->transactionsTable->viewport()->mapToGlobal(pos));
menu.exec(ui->transactionsTable->viewport()->mapToGlobal(pos));
});
}
@ -1314,11 +1332,11 @@ void MainWindow::addNewZaddr(bool sapling) {
// Just double make sure the z-address is still checked
if ( sapling && ui->rdioZSAddr->isChecked() ) {
ui->listReceiveAddresses->insertItem(0, addr);
ui->listReceiveAddresses->insertItem(0, addr);
ui->listReceiveAddresses->setCurrentIndex(0);
ui->statusBar->showMessage(QString::fromStdString("Created new zAddr") %
(sapling ? "(Sapling)" : "(Sprout)"),
(sapling ? "(Sapling)" : "(Sprout)"),
10 * 1000);
}
});
@ -1328,8 +1346,8 @@ void MainWindow::addNewZaddr(bool sapling) {
// Adds sapling or sprout z-addresses to the combo box. Technically, returns a
// lambda, which can be connected to the appropriate signal
std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
return [=] (bool checked) {
if (checked && this->rpc->getAllZAddresses() != nullptr) {
return [=] (bool checked) {
if (checked && this->rpc->getAllZAddresses() != nullptr) {
auto addrs = this->rpc->getAllZAddresses();
ui->listReceiveAddresses->clear();
@ -1341,13 +1359,13 @@ std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
ui->listReceiveAddresses->addItem(addr, bal);
}
}
});
});
// If z-addrs are empty, then create a new one.
if (addrs->isEmpty()) {
addNewZaddr(sapling);
}
}
}
};
}
@ -1370,11 +1388,11 @@ void MainWindow::setupReceiveTab() {
};
// Connect t-addr radio button
QObject::connect(ui->rdioTAddr, &QRadioButton::toggled, [=] (bool checked) {
QObject::connect(ui->rdioTAddr, &QRadioButton::toggled, [=] (bool checked) {
qDebug() << "taddr radio toggled";
if (checked && this->rpc->getUTXOs() != nullptr) {
if (checked && this->rpc->getUTXOs() != nullptr) {
updateTAddrCombo(checked);
}
}
// Toggle the "View all addresses" button as well
ui->btnViewAllAddresses->setVisible(checked);
@ -1407,7 +1425,7 @@ void MainWindow::setupReceiveTab() {
QString addr = viewaddrs.tblAddresses->model()->data(index).toString();
QMenu menu(this);
menu.addAction(tr("Export Private Key"), [=] () {
menu.addAction(tr("Export Private Key"), [=] () {
if (addr.isEmpty())
return;
@ -1442,7 +1460,7 @@ void MainWindow::setupReceiveTab() {
// Switched to receive tab, select the z-addr radio button
ui->rdioZSAddr->setChecked(true);
ui->btnViewAllAddresses->setVisible(false);
// And then select the first one
ui->listReceiveAddresses->setCurrentIndex(0);
}
@ -1453,7 +1471,7 @@ void MainWindow::setupReceiveTab() {
ui->rcvLabel->setValidator(v);
// Select item in address list
QObject::connect(ui->listReceiveAddresses,
QObject::connect(ui->listReceiveAddresses,
QOverload<int>::of(&QComboBox::currentIndexChanged), [=] (int index) {
QString addr = ui->listReceiveAddresses->itemText(index);
if (addr.isEmpty()) {
@ -1473,18 +1491,18 @@ void MainWindow::setupReceiveTab() {
else {
ui->rcvUpdateLabel->setText("Update Label");
}
ui->rcvLabel->setText(label);
ui->rcvBal->setText(Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(addr)));
ui->txtReceive->setPlainText(addr);
ui->txtReceive->setPlainText(addr);
ui->qrcodeDisplay->setQrcodeString(addr);
if (rpc->getUsedAddresses()->value(addr, false)) {
ui->rcvBal->setToolTip(tr("Address has been previously used"));
} else {
ui->rcvBal->setToolTip(tr("Address is unused"));
}
});
});
// Receive tab add/update label
QObject::connect(ui->rcvUpdateLabel, &QPushButton::clicked, [=]() {

57
src/settings.cpp

@ -3,8 +3,8 @@
Settings* Settings::instance = nullptr;
Settings* Settings::init() {
if (instance == nullptr)
Settings* Settings::init() {
if (instance == nullptr)
instance = new Settings();
return instance;
@ -30,15 +30,34 @@ void Settings::setAllowFetchPrices(bool allow) {
QSettings().setValue("options/allowfetchprices", allow);
}
Explorer Settings::getExplorer() {
// Load from the QT Settings.
QSettings s;
auto txExplorerUrl = s.value("explorer/txExplorerUrl").toString();
auto addressExplorerUrl = s.value("explorer/addressExplorerUrl").toString();
auto testnetTxExplorerUrl = s.value("explorer/testnetTxExplorerUrl").toString();
auto testnetAddressExplorerUrl = s.value("explorer/testnetAddressExplorerUrl").toString();
return Explorer{txExplorerUrl, addressExplorerUrl, testnetTxExplorerUrl, testnetAddressExplorerUrl};
}
void Settings::saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& testnetTxExplorerUrl, const QString& testnetAddressExplorerUrl) {
QSettings s;
s.setValue("explorer/txExplorerUrl", txExplorerUrl);
s.setValue("explorer/addressExplorerUrl", addressExplorerUrl);
s.setValue("explorer/testnetTxExplorerUrl", testnetTxExplorerUrl);
s.setValue("explorer/testnetAddressExplorerUrl", testnetAddressExplorerUrl);
}
Config Settings::getSettings() {
// Load from the QT Settings.
// Load from the QT Settings.
QSettings s;
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();
auto password = s.value("connection/rpcpassword").toString();
return Config{host, port, username, password};
}
@ -90,21 +109,21 @@ bool Settings::isSaplingAddress(QString addr) {
bool Settings::isSproutAddress(QString addr) {
if (!isValidAddress(addr))
return false;
return isZAddress(addr) && !isSaplingAddress(addr);
}
bool Settings::isZAddress(QString addr) {
if (!isValidAddress(addr))
return false;
return addr.startsWith("z");
}
bool Settings::isTAddress(QString addr) {
if (!isValidAddress(addr))
return false;
return addr.startsWith("t");
}
@ -136,8 +155,8 @@ bool Settings::isSaplingActive() {
return (isTestnet() && getBlockNumber() > 0) || (!isTestnet() && getBlockNumber() > 0);
}
double Settings::getZECPrice() {
return zecPrice;
double Settings::getZECPrice() {
return zecPrice;
}
bool Settings::getAutoShield() {
@ -150,7 +169,7 @@ void Settings::setAutoShield(bool allow) {
}
bool Settings::getAllowCustomFees() {
// Load from the QT Settings.
// Load from the QT Settings.
return QSettings().value("options/customfees", false).toBool();
}
@ -159,7 +178,7 @@ void Settings::setAllowCustomFees(bool allow) {
}
bool Settings::getSaveZtxs() {
// Load from the QT Settings.
// Load from the QT Settings.
return QSettings().value("options/savesenttx", true).toBool();
}
@ -235,7 +254,7 @@ bool Settings::addToZcashConf(QString confLocation, QString line) {
QFile file(confLocation);
if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
return false;
QTextStream out(&file);
out << line << "\n";
@ -250,9 +269,9 @@ bool Settings::removeFromZcashConf(QString confLocation, QString option) {
// To remove an option, we'll create a new file, and copy over everything but the option.
QFile file(confLocation);
if (!file.open(QIODevice::ReadOnly))
if (!file.open(QIODevice::ReadOnly))
return false;
QList<QString> lines;
QTextStream in(&file);
while (!in.atEnd()) {
@ -262,9 +281,9 @@ bool Settings::removeFromZcashConf(QString confLocation, QString option) {
if (name != option) {
lines.append(line);
}
}
}
file.close();
QFile newfile(confLocation);
if (!newfile.open(QIODevice::ReadWrite | QIODevice::Truncate))
return false;
@ -316,7 +335,7 @@ bool Settings::isValidAddress(QString addr) {
// Get a pretty string representation of this Payment URI
QString Settings::paymentURIPretty(PaymentURI uri) {
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + getZECDisplayFormat(uri.amt.toDouble())
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + getZECDisplayFormat(uri.amt.toDouble())
+ "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8());
}
@ -330,7 +349,7 @@ PaymentURI Settings::parseURI(QString uri) {
}
uri = uri.right(uri.length() - QString("hush:").length());
QRegExp re("([a-zA-Z0-9]+)");
int pos;
if ( (pos = re.indexIn(uri)) == -1 ) {

28
src/settings.h

@ -10,6 +10,13 @@ struct Config {
QString rpcpassword;
};
struct Explorer {
QString txExplorerUrl;
QString addressExplorerUrl;
QString testnetTxExplorerUrl;
QString testnetAddressExplorerUrl;
};
struct ToFields;
struct Tx;
@ -28,15 +35,18 @@ public:
static Settings* init();
static Settings* getInstance();
Explorer getExplorer();
void saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& testnetTxExplorerUrl, const QString& testnetAddressExplorerUrl);
Config getSettings();
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
bool isTestnet();
void setTestnet(bool isTestnet);
bool isSaplingAddress(QString addr);
bool isSproutAddress(QString addr);
bool isValidSaplingPrivateKey(QString pk);
bool isSyncing();
@ -44,7 +54,7 @@ public:
int getZcashdVersion();
void setZcashdVersion(int version);
void setUseEmbedded(bool r) { _useEmbedded = r; }
bool useEmbedded() { return _useEmbedded; }
@ -53,7 +63,7 @@ public:
int getBlockNumber();
void setBlockNumber(int number);
bool getSaveZtxs();
void setSaveZtxs(bool save);
@ -68,7 +78,7 @@ public:
bool getCheckForUpdates();
void setCheckForUpdates(bool allow);
bool isSaplingActive();
void setUsingZcashConf(QString confLocation);
@ -79,10 +89,10 @@ public:
void setPeers(int peers);
int getPeers();
// Static stuff
static const QString txidStatusMessage;
static void saveRestore(QDialog* d);
static void saveRestoreTableHeader(QTableView* table, QDialog* d, QString tablename) ;
@ -105,7 +115,7 @@ public:
static QString getZboardAddr();
static int getMaxMobileAppTxns() { return 30; }
static bool isValidAddress(QString addr);
static bool addToZcashConf(QString confLocation, QString line);
@ -133,7 +143,7 @@ private:
bool _useEmbedded = false;
bool _headless = false;
int _peerConnections = 0;
double zecPrice = 0.0;
};

124
src/settings.ui

@ -26,7 +26,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>2</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -283,6 +283,128 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Explorer</string>
</attribute>
<widget class="QLabel" name="label_14">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>491</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Tx Explorer URL</string>
</property>
</widget>
<widget class="Line" name="line_5">
<property name="geometry">
<rect>
<x>9</x>
<y>105</y>
<width>491</width>
<height>3</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLineEdit" name="txExplorerUrl">
<property name="geometry">
<rect>
<x>9</x>
<y>28</y>
<width>491</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string notr="true">https://explorer.myhush.org/tx/</string>
</property>
</widget>
<widget class="QLabel" name="label_15">
<property name="geometry">
<rect>
<x>9</x>
<y>54</y>
<width>491</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Address Explorer URL</string>
</property>
</widget>
<widget class="QLineEdit" name="addressExplorerUrl">
<property name="geometry">
<rect>
<x>9</x>
<y>73</y>
<width>491</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string notr="true">https://explorer.myhush.org/address/</string>
</property>
</widget>
<widget class="QLabel" name="label_16">
<property name="geometry">
<rect>
<x>9</x>
<y>112</y>
<width>491</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Testnet Tx Explorer URL</string>
</property>
</widget>
<widget class="QLineEdit" name="testnetTxExplorerUrl">
<property name="geometry">
<rect>
<x>9</x>
<y>131</y>
<width>491</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string notr="true">https://explorer.testnet.z.cash/tx/</string>
</property>
</widget>
<widget class="QLabel" name="label_17">
<property name="geometry">
<rect>
<x>9</x>
<y>160</y>
<width>501</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Testnet Address Explorer URL</string>
</property>
</widget>
<widget class="QLineEdit" name="testnetAddressExplorerUrl">
<property name="geometry">
<rect>
<x>9</x>
<y>180</y>
<width>491</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string notr="true">https://explorer.testnet.myhush.org/address/</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Troubleshooting</string>

Loading…
Cancel
Save