|
|
@ -4,92 +4,107 @@ |
|
|
|
#include "settings.h" |
|
|
|
#include "sd.h" |
|
|
|
|
|
|
|
extern bool isdragonx; |
|
|
|
extern bool isHSC; |
|
|
|
extern std::string HSC_explorer; |
|
|
|
extern std::string HSC_ticker; |
|
|
|
|
|
|
|
Settings* Settings::instance = nullptr; |
|
|
|
Settings *Settings::instance = nullptr; |
|
|
|
|
|
|
|
Settings* Settings::init() { |
|
|
|
Settings *Settings::init() |
|
|
|
{ |
|
|
|
if (instance == nullptr) |
|
|
|
instance = new Settings(); |
|
|
|
|
|
|
|
return instance; |
|
|
|
} |
|
|
|
|
|
|
|
Settings* Settings::getInstance() { |
|
|
|
Settings *Settings::getInstance() |
|
|
|
{ |
|
|
|
return instance; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::getCheckForUpdates() { |
|
|
|
bool Settings::getCheckForUpdates() |
|
|
|
{ |
|
|
|
return QSettings().value("options/allowcheckupdates", true).toBool(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setCheckForUpdates(bool allow) { |
|
|
|
QSettings().setValue("options/allowcheckupdates", allow); |
|
|
|
void Settings::setCheckForUpdates(bool allow) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/allowcheckupdates", allow); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::getAllowFetchPrices() { |
|
|
|
bool Settings::getAllowFetchPrices() |
|
|
|
{ |
|
|
|
// now defaults to OFF, used to be ON
|
|
|
|
return QSettings().value("options/allowfetchprices", false).toBool(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setAllowFetchPrices(bool allow) { |
|
|
|
QSettings().setValue("options/allowfetchprices", allow); |
|
|
|
void Settings::setAllowFetchPrices(bool allow) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/allowfetchprices", allow); |
|
|
|
} |
|
|
|
|
|
|
|
Explorer Settings::getExplorer() { |
|
|
|
Explorer Settings::getExplorer() |
|
|
|
{ |
|
|
|
// Load from the QT Settings.
|
|
|
|
QSettings s; |
|
|
|
//TODO: make it easy for people to use other explorers
|
|
|
|
// TODO: make it easy for people to use other explorers
|
|
|
|
QString explorer = "https://explorer.hush.is"; |
|
|
|
|
|
|
|
if(isdragonx) { |
|
|
|
explorer = "https://explorer.dragonx.is"; |
|
|
|
if (isHSC) |
|
|
|
{ |
|
|
|
explorer = QString::fromStdString(HSC_explorer); |
|
|
|
} |
|
|
|
|
|
|
|
QString onionExplorer = "http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion"; |
|
|
|
auto txExplorerUrl = s.value("explorer/txExplorerUrl", explorer + "/tx/").toString(); |
|
|
|
auto addressExplorerUrl = s.value("explorer/addressExplorerUrl", explorer + "/address/").toString(); |
|
|
|
auto onionTxExplorerUrl = s.value("explorer/onionTxExplorerUrl", onionExplorer + "/tx/").toString(); |
|
|
|
QString onionExplorer = "http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion"; |
|
|
|
auto txExplorerUrl = s.value("explorer/txExplorerUrl", explorer + "/tx/").toString(); |
|
|
|
auto addressExplorerUrl = s.value("explorer/addressExplorerUrl", explorer + "/address/").toString(); |
|
|
|
auto onionTxExplorerUrl = s.value("explorer/onionTxExplorerUrl", onionExplorer + "/tx/").toString(); |
|
|
|
auto onionAddressExplorerUrl = s.value("explorer/onionAddressExplorerUrl", onionExplorer + "/address/").toString(); |
|
|
|
|
|
|
|
// Some users have the old malicious explorer URL saved in their config file, help them out
|
|
|
|
if (txExplorerUrl == "https://explorer.myhush.org/tx/") { |
|
|
|
if (txExplorerUrl == "https://explorer.myhush.org/tx/") |
|
|
|
{ |
|
|
|
txExplorerUrl = explorer + "/tx/"; |
|
|
|
saveExplorer(txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl); |
|
|
|
} |
|
|
|
if (addressExplorerUrl == "https://explorer.myhush.org/address/") { |
|
|
|
if (addressExplorerUrl == "https://explorer.myhush.org/address/") |
|
|
|
{ |
|
|
|
addressExplorerUrl = explorer + "/address/"; |
|
|
|
saveExplorer(txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl); |
|
|
|
} |
|
|
|
|
|
|
|
//DEBUG("explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
|
|
|
|
// DEBUG("explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
|
|
|
|
DEBUG("onionTxExplorerUrl=" % onionTxExplorerUrl); |
|
|
|
DEBUG("onionAddressExplorerUrl=" % onionAddressExplorerUrl); |
|
|
|
return Explorer{txExplorerUrl, addressExplorerUrl, onionTxExplorerUrl, onionAddressExplorerUrl}; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::saveExplorer(const QString& txExplorerUrl, const QString& addressExplorerUrl, const QString& onionTxExplorerUrl, const QString& onionAddressExplorerUrl) { |
|
|
|
void Settings::saveExplorer(const QString &txExplorerUrl, const QString &addressExplorerUrl, const QString &onionTxExplorerUrl, const QString &onionAddressExplorerUrl) |
|
|
|
{ |
|
|
|
QSettings s; |
|
|
|
s.setValue("explorer/txExplorerUrl", txExplorerUrl); |
|
|
|
s.setValue("explorer/addressExplorerUrl", addressExplorerUrl); |
|
|
|
s.setValue("explorer/onionTxExplorerUrl", onionTxExplorerUrl); |
|
|
|
s.setValue("explorer/onionAddressExplorerUrl", onionAddressExplorerUrl); |
|
|
|
//DEBUG("saving explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
|
|
|
|
// DEBUG("saving explorer values: " << txExplorerUrl << " " << addressExplorerUrl << " " << onionTxExplorerUrl << " " << onionAddressExplorerUrl );
|
|
|
|
} |
|
|
|
|
|
|
|
Config Settings::getSettings() { |
|
|
|
Config Settings::getSettings() |
|
|
|
{ |
|
|
|
// 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 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(); |
|
|
|
|
|
|
|
return Config{host, port, username, password}; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::saveSettings(const QString& host, const QString& port, const QString& username, const QString& password) { |
|
|
|
void Settings::saveSettings(const QString &host, const QString &port, const QString &username, const QString &password) |
|
|
|
{ |
|
|
|
QSettings s; |
|
|
|
|
|
|
|
s.setValue("connection/host", host); |
|
|
@ -103,218 +118,262 @@ void Settings::saveSettings(const QString& host, const QString& port, const QStr |
|
|
|
init(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::saveRestoreTableHeader(QTableView* table, QDialog* d, QString tablename) { |
|
|
|
void Settings::saveRestoreTableHeader(QTableView *table, QDialog *d, QString tablename) |
|
|
|
{ |
|
|
|
table->horizontalHeader()->restoreState(QSettings().value(tablename).toByteArray()); |
|
|
|
table->horizontalHeader()->setStretchLastSection(true); |
|
|
|
|
|
|
|
QObject::connect(d, &QDialog::finished, [=](auto) { |
|
|
|
QSettings().setValue(tablename, table->horizontalHeader()->saveState()); |
|
|
|
}); |
|
|
|
QObject::connect(d, &QDialog::finished, [=](auto) |
|
|
|
{ QSettings().setValue(tablename, table->horizontalHeader()->saveState()); }); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setUsingHushConf(QString confLocation) { |
|
|
|
void Settings::setUsingHushConf(QString confLocation) |
|
|
|
{ |
|
|
|
if (!confLocation.isEmpty()) |
|
|
|
_confLocation = confLocation; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isTestnet() { |
|
|
|
bool Settings::isTestnet() |
|
|
|
{ |
|
|
|
return _isTestnet; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setTestnet(bool isTestnet) { |
|
|
|
void Settings::setTestnet(bool isTestnet) |
|
|
|
{ |
|
|
|
this->_isTestnet = isTestnet; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isSaplingAddress(QString addr) { |
|
|
|
bool Settings::isSaplingAddress(QString addr) |
|
|
|
{ |
|
|
|
if (!isValidAddress(addr)) |
|
|
|
return false; |
|
|
|
|
|
|
|
return ( isTestnet() && addr.startsWith("ztestsapling")) || |
|
|
|
return (isTestnet() && addr.startsWith("ztestsapling")) || |
|
|
|
(!isTestnet() && addr.startsWith("zs1")); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isSproutAddress(QString addr) { |
|
|
|
bool Settings::isSproutAddress(QString addr) |
|
|
|
{ |
|
|
|
if (!isValidAddress(addr)) |
|
|
|
return false; |
|
|
|
|
|
|
|
return isZAddress(addr) && !isSaplingAddress(addr); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isZAddress(QString addr) { |
|
|
|
bool Settings::isZAddress(QString addr) |
|
|
|
{ |
|
|
|
if (!isValidAddress(addr)) |
|
|
|
return false; |
|
|
|
|
|
|
|
return addr.startsWith("z"); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isTAddress(QString addr) { |
|
|
|
bool Settings::isTAddress(QString addr) |
|
|
|
{ |
|
|
|
if (!isValidAddress(addr)) |
|
|
|
return false; |
|
|
|
|
|
|
|
return addr.startsWith("R"); |
|
|
|
} |
|
|
|
|
|
|
|
int Settings::getHushdVersion() { |
|
|
|
int Settings::getHushdVersion() |
|
|
|
{ |
|
|
|
return _hushdVersion; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setHushdVersion(int version) { |
|
|
|
void Settings::setHushdVersion(int version) |
|
|
|
{ |
|
|
|
_hushdVersion = version; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isSyncing() { |
|
|
|
bool Settings::isSyncing() |
|
|
|
{ |
|
|
|
return _isSyncing; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setSyncing(bool syncing) { |
|
|
|
void Settings::setSyncing(bool syncing) |
|
|
|
{ |
|
|
|
this->_isSyncing = syncing; |
|
|
|
} |
|
|
|
|
|
|
|
int Settings::getBlockNumber() { |
|
|
|
int Settings::getBlockNumber() |
|
|
|
{ |
|
|
|
return this->_blockNumber; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setBlockNumber(int number) { |
|
|
|
void Settings::setBlockNumber(int number) |
|
|
|
{ |
|
|
|
this->_blockNumber = number; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isSaplingActive() { |
|
|
|
return (isTestnet() && getBlockNumber() > 0) || (!isTestnet() && getBlockNumber() > 0); |
|
|
|
bool Settings::isSaplingActive() |
|
|
|
{ |
|
|
|
return (isTestnet() && getBlockNumber() > 0) || (!isTestnet() && getBlockNumber() > 0); |
|
|
|
} |
|
|
|
|
|
|
|
double Settings::getHUSHPrice() { |
|
|
|
double Settings::getHUSHPrice() |
|
|
|
{ |
|
|
|
return hushPrice; |
|
|
|
} |
|
|
|
|
|
|
|
double Settings::get_price(QString currency) { |
|
|
|
double Settings::get_price(QString currency) |
|
|
|
{ |
|
|
|
currency = currency.toLower(); |
|
|
|
QString ticker = currency; |
|
|
|
auto search = prices.find(currency); |
|
|
|
if (search != prices.end()) { |
|
|
|
if (search != prices.end()) |
|
|
|
{ |
|
|
|
qDebug() << "Found price of " << ticker << " = " << search->second; |
|
|
|
return search->second; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
qDebug() << "Could not find price of" << ticker << "!!!"; |
|
|
|
return 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_price(QString curr, double price) { |
|
|
|
void Settings::set_price(QString curr, double price) |
|
|
|
{ |
|
|
|
QString ticker = curr; |
|
|
|
qDebug() << "Setting price of " << ticker << "=" << QString::number(price); |
|
|
|
prices.insert( std::make_pair(curr, price) ); |
|
|
|
prices.insert( std::make_pair(curr, price) ); |
|
|
|
prices.insert(std::make_pair(curr, price)); |
|
|
|
prices.insert(std::make_pair(curr, price)); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_volume(QString curr, double volume) { |
|
|
|
void Settings::set_volume(QString curr, double volume) |
|
|
|
{ |
|
|
|
QString ticker = curr; |
|
|
|
qDebug() << "Setting volume of " << ticker << "=" << QString::number(volume); |
|
|
|
volumes.insert( std::make_pair(curr, volume) ); |
|
|
|
volumes.insert(std::make_pair(curr, volume)); |
|
|
|
} |
|
|
|
|
|
|
|
double Settings::get_volume(QString currency) { |
|
|
|
double Settings::get_volume(QString currency) |
|
|
|
{ |
|
|
|
currency = currency.toLower(); |
|
|
|
QString ticker = currency; |
|
|
|
auto search = volumes.find(currency); |
|
|
|
if (search != volumes.end()) { |
|
|
|
if (search != volumes.end()) |
|
|
|
{ |
|
|
|
qDebug() << "Found volume of " << ticker << " = " << search->second; |
|
|
|
return search->second; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
qDebug() << "Could not find volume of" << ticker << "!!!"; |
|
|
|
return 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_marketcap(QString curr, double marketcap) { |
|
|
|
void Settings::set_marketcap(QString curr, double marketcap) |
|
|
|
{ |
|
|
|
QString ticker = curr; |
|
|
|
qDebug() << "Setting marketcap of " << ticker << "=" << QString::number(marketcap); |
|
|
|
marketcaps.insert( std::make_pair(curr, marketcap) ); |
|
|
|
marketcaps.insert(std::make_pair(curr, marketcap)); |
|
|
|
} |
|
|
|
|
|
|
|
double Settings::get_marketcap(QString currency) { |
|
|
|
double Settings::get_marketcap(QString currency) |
|
|
|
{ |
|
|
|
currency = currency.toLower(); |
|
|
|
QString ticker = currency; |
|
|
|
auto search = marketcaps.find(currency); |
|
|
|
if (search != marketcaps.end()) { |
|
|
|
if (search != marketcaps.end()) |
|
|
|
{ |
|
|
|
qDebug() << "Found marketcap of " << ticker << " = " << search->second; |
|
|
|
return search->second; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
qDebug() << "Could not find marketcap of" << ticker << "!!!"; |
|
|
|
return -1.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int Settings::getBTCPrice() { |
|
|
|
unsigned int Settings::getBTCPrice() |
|
|
|
{ |
|
|
|
// in satoshis
|
|
|
|
return btcPrice; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::getAutoShield() { |
|
|
|
bool Settings::getAutoShield() |
|
|
|
{ |
|
|
|
// Load from Qt settings
|
|
|
|
return QSettings().value("options/autoshield", true).toBool(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setAutoShield(bool allow) { |
|
|
|
void Settings::setAutoShield(bool allow) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/autoshield", allow); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::getAllowCustomFees() { |
|
|
|
bool Settings::getAllowCustomFees() |
|
|
|
{ |
|
|
|
// Load from the QT Settings.
|
|
|
|
return QSettings().value("options/customfees", true).toBool(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setAllowCustomFees(bool allow) { |
|
|
|
void Settings::setAllowCustomFees(bool allow) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/customfees", allow); |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::get_theme_name() { |
|
|
|
QString Settings::get_theme_name() |
|
|
|
{ |
|
|
|
// Load from the QT Settings.
|
|
|
|
QString theme_name = QSettings().value("options/theme_name", false).toString(); |
|
|
|
//qDebug() << __func__ << ": theme_name=" << theme_name;
|
|
|
|
// qDebug() << __func__ << ": theme_name=" << theme_name;
|
|
|
|
return theme_name; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_theme_name(QString theme_name) { |
|
|
|
void Settings::set_theme_name(QString theme_name) |
|
|
|
{ |
|
|
|
qDebug() << __func__ << ": settings theme_name=" << theme_name; |
|
|
|
QSettings().setValue("options/theme_name", theme_name); |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::getSaveZtxs() { |
|
|
|
bool Settings::getSaveZtxs() |
|
|
|
{ |
|
|
|
// Load from the QT Settings.
|
|
|
|
return QSettings().value("options/savesenttx", true).toBool(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setSaveZtxs(bool save) { |
|
|
|
void Settings::setSaveZtxs(bool save) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/savesenttx", save); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::setPeers(int peers) { |
|
|
|
void Settings::setPeers(int peers) |
|
|
|
{ |
|
|
|
_peerConnections = peers; |
|
|
|
} |
|
|
|
|
|
|
|
int Settings::getPeers() { |
|
|
|
int Settings::getPeers() |
|
|
|
{ |
|
|
|
return _peerConnections; |
|
|
|
} |
|
|
|
//=================================
|
|
|
|
// Static Stuff
|
|
|
|
//=================================
|
|
|
|
void Settings::saveRestore(QDialog* d) { |
|
|
|
void Settings::saveRestore(QDialog *d) |
|
|
|
{ |
|
|
|
d->restoreGeometry(QSettings().value(d->objectName() % "geometry").toByteArray()); |
|
|
|
|
|
|
|
QObject::connect(d, &QDialog::finished, [=](auto) { |
|
|
|
QSettings().setValue(d->objectName() % "geometry", d->saveGeometry()); |
|
|
|
}); |
|
|
|
QObject::connect(d, &QDialog::finished, [=](auto) |
|
|
|
{ QSettings().setValue(d->objectName() % "geometry", d->saveGeometry()); }); |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::getUSDFormat(double bal) { |
|
|
|
//TODO: respect current locale!
|
|
|
|
return QLocale(QLocale::English).toString(bal * Settings::getInstance()->getHUSHPrice(), 'f', 8) + " " +Settings::getInstance()->get_currency_name(); |
|
|
|
QString Settings::getUSDFormat(double bal) |
|
|
|
{ |
|
|
|
// TODO: respect current locale!
|
|
|
|
return QLocale(QLocale::English).toString(bal * Settings::getInstance()->getHUSHPrice(), 'f', 8) + " " + Settings::getInstance()->get_currency_name(); |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::getDecimalString(double amt) { |
|
|
|
QString Settings::getDecimalString(double amt) |
|
|
|
{ |
|
|
|
QString f = QString::number(amt, 'f', 8); |
|
|
|
|
|
|
|
while (f.contains(".") && (f.right(1) == "0" || f.right(1) == ".")) { |
|
|
|
while (f.contains(".") && (f.right(1) == "0" || f.right(1) == ".")) |
|
|
|
{ |
|
|
|
f = f.left(f.length() - 1); |
|
|
|
} |
|
|
|
if (f == "-0") |
|
|
@ -323,12 +382,14 @@ QString Settings::getDecimalString(double amt) { |
|
|
|
return f; |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::getDisplayFormat(double bal) { |
|
|
|
QString Settings::getDisplayFormat(double bal) |
|
|
|
{ |
|
|
|
// This is idiotic. Why doesn't QString have a way to do this?
|
|
|
|
return getDecimalString(bal) % " " % Settings::getTokenName(); |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::getHUSHUSDDisplayFormat(double bal) { |
|
|
|
QString Settings::getHUSHUSDDisplayFormat(double bal) |
|
|
|
{ |
|
|
|
auto usdFormat = getUSDFormat(bal); |
|
|
|
if (!usdFormat.isEmpty()) |
|
|
|
return getDisplayFormat(bal) % " (" % getUSDFormat(bal) % ")"; |
|
|
@ -338,32 +399,39 @@ QString Settings::getHUSHUSDDisplayFormat(double bal) { |
|
|
|
|
|
|
|
const QString Settings::txidStatusMessage = QString(QObject::tr("Transaction submitted (right click to copy) txid:")); |
|
|
|
|
|
|
|
QString Settings::getTokenName() { |
|
|
|
if (isdragonx) { |
|
|
|
return "DRGX"; |
|
|
|
QString Settings::getTokenName() |
|
|
|
{ |
|
|
|
if (isHSC) |
|
|
|
{ |
|
|
|
return QString::fromStdString(HSC_ticker); |
|
|
|
} |
|
|
|
if (Settings::getInstance()->isTestnet()) { |
|
|
|
if (Settings::getInstance()->isTestnet()) |
|
|
|
{ |
|
|
|
return "TUSH"; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return "HUSH"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//TODO: this isn't used for donations
|
|
|
|
QString Settings::getDonationAddr() { |
|
|
|
if (Settings::getInstance()->isTestnet()) { |
|
|
|
return "ztestsaplingXXX"; |
|
|
|
// TODO: this isn't used for donations
|
|
|
|
QString Settings::getDonationAddr() |
|
|
|
{ |
|
|
|
if (Settings::getInstance()->isTestnet()) |
|
|
|
{ |
|
|
|
return "ztestsaplingXXX"; |
|
|
|
} |
|
|
|
// This is used for user feedback
|
|
|
|
return "zs1aq4xnrkjlnxx0zesqye7jz3dfrf3rjh7q5z6u8l6mwyqqaam3gx3j2fkqakp33v93yavq46j83q"; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::addToHushConf(QString confLocation, QString line) { |
|
|
|
bool Settings::addToHushConf(QString confLocation, QString line) |
|
|
|
{ |
|
|
|
QFile file(confLocation); |
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Append)) |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
QTextStream out(&file); |
|
|
|
out << line << "\n"; |
|
|
|
file.close(); |
|
|
@ -371,32 +439,36 @@ bool Settings::addToHushConf(QString confLocation, QString line) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::get_currency_name() { |
|
|
|
QString Settings::get_currency_name() |
|
|
|
{ |
|
|
|
// Load from the QT Settings.
|
|
|
|
return QSettings().value("options/currency_name", "BTC").toString(); |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_currency_name(QString currency_name) { |
|
|
|
void Settings::set_currency_name(QString currency_name) |
|
|
|
{ |
|
|
|
QSettings().setValue("options/currency_name", currency_name); |
|
|
|
} |
|
|
|
|
|
|
|
QString Settings::get_language() { |
|
|
|
QString Settings::get_language() |
|
|
|
{ |
|
|
|
// use the default system language if none is set
|
|
|
|
QString locale = QLocale::system().name(); |
|
|
|
// remove country data, i.e. en_US => en
|
|
|
|
locale.truncate( locale.lastIndexOf("_")); |
|
|
|
locale.truncate(locale.lastIndexOf("_")); |
|
|
|
auto lang = QSettings().value("options/language", locale).toString(); |
|
|
|
qDebug() << __func__ << ": found lang=" << lang << " in config file"; |
|
|
|
return lang; |
|
|
|
} |
|
|
|
|
|
|
|
void Settings::set_language(QString lang) { |
|
|
|
void Settings::set_language(QString lang) |
|
|
|
{ |
|
|
|
qDebug() << __func__ << ": setting lang=" << lang << " in config file"; |
|
|
|
QSettings().setValue("options/language", lang); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool Settings::removeFromHushConf(QString confLocation, QString option) { |
|
|
|
bool Settings::removeFromHushConf(QString confLocation, QString option) |
|
|
|
{ |
|
|
|
if (confLocation.isEmpty()) |
|
|
|
return false; |
|
|
|
|
|
|
@ -407,11 +479,13 @@ bool Settings::removeFromHushConf(QString confLocation, QString option) { |
|
|
|
|
|
|
|
QList<QString> lines; |
|
|
|
QTextStream in(&file); |
|
|
|
while (!in.atEnd()) { |
|
|
|
while (!in.atEnd()) |
|
|
|
{ |
|
|
|
QString line = in.readLine(); |
|
|
|
auto s = line.indexOf("="); |
|
|
|
QString name = line.left(s).trimmed().toLower(); |
|
|
|
if (name != option) { |
|
|
|
if (name != option) |
|
|
|
{ |
|
|
|
lines.append(line); |
|
|
|
} |
|
|
|
} |
|
|
@ -422,7 +496,8 @@ bool Settings::removeFromHushConf(QString confLocation, QString option) { |
|
|
|
return false; |
|
|
|
|
|
|
|
QTextStream out(&newfile); |
|
|
|
for (QString line : lines) { |
|
|
|
for (QString line : lines) |
|
|
|
{ |
|
|
|
out << line << endl; |
|
|
|
} |
|
|
|
newfile.close(); |
|
|
@ -430,90 +505,115 @@ bool Settings::removeFromHushConf(QString confLocation, QString option) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
double Settings::getMinerFee() { |
|
|
|
double Settings::getMinerFee() |
|
|
|
{ |
|
|
|
return 0.0001; |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isValidSaplingPrivateKey(QString pk) { |
|
|
|
if (isTestnet()) { |
|
|
|
bool Settings::isValidSaplingPrivateKey(QString pk) |
|
|
|
{ |
|
|
|
if (isTestnet()) |
|
|
|
{ |
|
|
|
QRegExp zspkey("^secret-extended-key-test[0-9a-z]{278}$", Qt::CaseInsensitive); |
|
|
|
return zspkey.exactMatch(pk); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
QRegExp zspkey("^secret-extended-key-main[0-9a-z]{278}$", Qt::CaseInsensitive); |
|
|
|
return zspkey.exactMatch(pk); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool Settings::isValidAddress(QString addr) { |
|
|
|
QRegExp zsexp("^zs1[a-z0-9]{75}$", Qt::CaseInsensitive); |
|
|
|
bool Settings::isValidAddress(QString addr) |
|
|
|
{ |
|
|
|
QRegExp zsexp("^zs1[a-z0-9]{75}$", Qt::CaseInsensitive); |
|
|
|
QRegExp ztsexp("^ztestsapling[a-z0-9]{76}", Qt::CaseInsensitive); |
|
|
|
QRegExp texp("^R[a-z0-9]{33}$", Qt::CaseInsensitive); |
|
|
|
//qDebug() << "isValidAddress(" << addr << ")";
|
|
|
|
// qDebug() << "isValidAddress(" << addr << ")";
|
|
|
|
|
|
|
|
return texp.exactMatch(addr) || ztsexp.exactMatch(addr) || zsexp.exactMatch(addr); |
|
|
|
return texp.exactMatch(addr) || ztsexp.exactMatch(addr) || zsexp.exactMatch(addr); |
|
|
|
} |
|
|
|
|
|
|
|
// Get a pretty string representation of this Payment URI
|
|
|
|
QString Settings::paymentURIPretty(PaymentURI uri) { |
|
|
|
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + getDisplayFormat(uri.amt.toDouble()) |
|
|
|
+ "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8()); |
|
|
|
QString Settings::paymentURIPretty(PaymentURI uri) |
|
|
|
{ |
|
|
|
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + getDisplayFormat(uri.amt.toDouble()) + "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8()); |
|
|
|
} |
|
|
|
|
|
|
|
// Parse a payment URI string into its components
|
|
|
|
PaymentURI Settings::parseURI(QString uri) { |
|
|
|
PaymentURI Settings::parseURI(QString uri) |
|
|
|
{ |
|
|
|
PaymentURI ans; |
|
|
|
|
|
|
|
auto proto=""; |
|
|
|
if (isdragonx) { |
|
|
|
proto ="drgx:"; |
|
|
|
if (!uri.startsWith(proto % QString(":"))) { |
|
|
|
ans.error = "Not a DRGX payment URI"; |
|
|
|
auto proto = ""; |
|
|
|
if (isHSC) |
|
|
|
{ |
|
|
|
std::string ticker = HSC_ticker + ":"; |
|
|
|
proto = ((ticker.c_str())); |
|
|
|
if (!uri.startsWith(proto % QString(":"))) |
|
|
|
{ |
|
|
|
|
|
|
|
std::string not_a_uri = "Not a " + HSC_ticker + " payment URI"; |
|
|
|
ans.error = (not_a_uri.c_str()); |
|
|
|
return ans; |
|
|
|
} |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
proto = "hush:"; |
|
|
|
if (!uri.startsWith(proto % QString(":"))) { |
|
|
|
if (!uri.startsWith(proto % QString(":"))) |
|
|
|
{ |
|
|
|
ans.error = "Not a HUSH payment URI"; |
|
|
|
return ans; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uri = uri.right(uri.length() - QString("hush:").length()); |
|
|
|
if(isdragonx) { |
|
|
|
uri = uri.right(uri.length() - QString("drgx:").length()); |
|
|
|
if (isHSC) |
|
|
|
{ |
|
|
|
uri = uri.right((uri.length() - QString(QString::fromStdString(HSC_ticker) % ":").length())); |
|
|
|
} |
|
|
|
|
|
|
|
QRegExp re("([a-zA-Z0-9]+)"); |
|
|
|
int pos; |
|
|
|
if ( (pos = re.indexIn(uri)) == -1 ) { |
|
|
|
if ((pos = re.indexIn(uri)) == -1) |
|
|
|
{ |
|
|
|
ans.error = "Couldn't find an address"; |
|
|
|
return ans; |
|
|
|
} |
|
|
|
|
|
|
|
ans.addr = re.cap(1); |
|
|
|
if (!Settings::isValidAddress(ans.addr)) { |
|
|
|
if (!Settings::isValidAddress(ans.addr)) |
|
|
|
{ |
|
|
|
ans.error = "Could not understand address"; |
|
|
|
return ans; |
|
|
|
} |
|
|
|
|
|
|
|
uri = uri.right(uri.length() - ans.addr.length()-1); // swallow '?'
|
|
|
|
uri = uri.right(uri.length() - ans.addr.length() - 1); // swallow '?'
|
|
|
|
QUrlQuery query(uri); |
|
|
|
|
|
|
|
|
|
|
|
// parse out amt / amount
|
|
|
|
if (query.hasQueryItem("amt")) { |
|
|
|
ans.amt = query.queryItemValue("amt"); |
|
|
|
} else if (query.hasQueryItem("amount")) { |
|
|
|
ans.amt = query.queryItemValue("amount"); |
|
|
|
if (query.hasQueryItem("amt")) |
|
|
|
{ |
|
|
|
ans.amt = query.queryItemValue("amt"); |
|
|
|
} |
|
|
|
else if (query.hasQueryItem("amount")) |
|
|
|
{ |
|
|
|
ans.amt = query.queryItemValue("amount"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// parse out memo / msg / message
|
|
|
|
if (query.hasQueryItem("memo")) { |
|
|
|
ans.memo = query.queryItemValue("memo"); |
|
|
|
} else if (query.hasQueryItem("msg")) { |
|
|
|
ans.memo = query.queryItemValue("msg"); |
|
|
|
} else if (query.hasQueryItem("message")) { |
|
|
|
ans.memo = query.queryItemValue("message"); |
|
|
|
if (query.hasQueryItem("memo")) |
|
|
|
{ |
|
|
|
ans.memo = query.queryItemValue("memo"); |
|
|
|
} |
|
|
|
else if (query.hasQueryItem("msg")) |
|
|
|
{ |
|
|
|
ans.memo = query.queryItemValue("msg"); |
|
|
|
} |
|
|
|
else if (query.hasQueryItem("message")) |
|
|
|
{ |
|
|
|
ans.memo = query.queryItemValue("message"); |
|
|
|
} |
|
|
|
|
|
|
|
return ans; |
|
|
|