diff options
Diffstat (limited to 'src/qt/optionsmodel.cpp')
| -rw-r--r-- | src/qt/optionsmodel.cpp | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp new file mode 100644 index 000000000..f82e153b6 --- /dev/null +++ b/src/qt/optionsmodel.cpp @@ -0,0 +1,467 @@ +// Copyright (c) 2011-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include "optionsmodel.h" + +#include "bitcoinunits.h" +#include "guiutil.h" + +#include "amount.h" +#include "init.h" +#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS +#include "net.h" +#include "netbase.h" +#include "txdb.h" // for -dbcache defaults +#include "intro.h" + +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#include "wallet/walletdb.h" +#endif + +#include <QNetworkProxy> +#include <QSettings> +#include <QStringList> + +OptionsModel::OptionsModel(QObject *parent, bool resetSettings) : + QAbstractListModel(parent) +{ + Init(resetSettings); +} + +void OptionsModel::addOverriddenOption(const std::string &option) +{ + strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(mapArgs[option]) + " "; +} + +// Writes all missing QSettings with their default values +void OptionsModel::Init(bool resetSettings) +{ + if (resetSettings) + Reset(); + + checkAndMigrate(); + + QSettings settings; + + // Ensure restart flag is unset on client startup + setRestartRequired(false); + + // These are Qt-only settings: + + // Window + if (!settings.contains("fHideTrayIcon")) + settings.setValue("fHideTrayIcon", false); + fHideTrayIcon = settings.value("fHideTrayIcon").toBool(); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + + if (!settings.contains("fMinimizeToTray")) + settings.setValue("fMinimizeToTray", false); + fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon; + + if (!settings.contains("fMinimizeOnClose")) + settings.setValue("fMinimizeOnClose", false); + fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool(); + + // Display + if (!settings.contains("nDisplayUnit")) + settings.setValue("nDisplayUnit", BitcoinUnits::BTC); + nDisplayUnit = settings.value("nDisplayUnit").toInt(); + + if (!settings.contains("strThirdPartyTxUrls")) + settings.setValue("strThirdPartyTxUrls", ""); + strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString(); + + if (!settings.contains("fCoinControlFeatures")) + settings.setValue("fCoinControlFeatures", false); + fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); + + // These are shared with the core or have a command-line parameter + // and we want command-line parameters to overwrite the GUI settings. + // + // If setting doesn't exist create it with defaults. + // + // If SoftSetArg() or SoftSetBoolArg() return false we were overridden + // by command-line and show this in the UI. + + // Main + if (!settings.contains("nDatabaseCache")) + settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); + if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString())) + addOverriddenOption("-dbcache"); + + if (!settings.contains("nThreadsScriptVerif")) + settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS); + if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) + addOverriddenOption("-par"); + + if (!settings.contains("strDataDir")) + settings.setValue("strDataDir", Intro::getDefaultDataDirectory()); + + // Wallet +#ifdef ENABLE_WALLET + if (!settings.contains("bSpendZeroConfChange")) + settings.setValue("bSpendZeroConfChange", true); + if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool())) + addOverriddenOption("-spendzeroconfchange"); +#endif + + // Network + if (!settings.contains("fUseUPnP")) + settings.setValue("fUseUPnP", DEFAULT_UPNP); + if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool())) + addOverriddenOption("-upnp"); + + if (!settings.contains("fListen")) + settings.setValue("fListen", DEFAULT_LISTEN); + if (!SoftSetBoolArg("-listen", settings.value("fListen").toBool())) + addOverriddenOption("-listen"); + + if (!settings.contains("fUseProxy")) + settings.setValue("fUseProxy", false); + if (!settings.contains("addrProxy")) + settings.setValue("addrProxy", "127.0.0.1:9050"); + // Only try to set -proxy, if user has enabled fUseProxy + if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) + addOverriddenOption("-proxy"); + else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty()) + addOverriddenOption("-proxy"); + + if (!settings.contains("fUseSeparateProxyTor")) + settings.setValue("fUseSeparateProxyTor", false); + if (!settings.contains("addrSeparateProxyTor")) + settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050"); + // Only try to set -onion, if user has enabled fUseSeparateProxyTor + if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) + addOverriddenOption("-onion"); + else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty()) + addOverriddenOption("-onion"); + + // Display + if (!settings.contains("language")) + settings.setValue("language", ""); + if (!SoftSetArg("-lang", settings.value("language").toString().toStdString())) + addOverriddenOption("-lang"); + + language = settings.value("language").toString(); +} + +void OptionsModel::Reset() +{ + QSettings settings; + + // Save the strDataDir setting + QString dataDir = Intro::getDefaultDataDirectory(); + dataDir = settings.value("strDataDir", dataDir).toString(); + + // Remove all entries from our QSettings object + settings.clear(); + + // Set strDataDir + settings.setValue("strDataDir", dataDir); + + // Set that this was reset + settings.setValue("fReset", true); + + // default setting for OptionsModel::StartAtStartup - disabled + if (GUIUtil::GetStartOnSystemStartup()) + GUIUtil::SetStartOnSystemStartup(false); +} + +int OptionsModel::rowCount(const QModelIndex & parent) const +{ + return OptionIDRowCount; +} + +// read QSettings values and return them +QVariant OptionsModel::data(const QModelIndex & index, int role) const +{ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + return GUIUtil::GetStartOnSystemStartup(); + case HideTrayIcon: + return fHideTrayIcon; + case MinimizeToTray: + return fMinimizeToTray; + case MapPortUPnP: +#ifdef USE_UPNP + return settings.value("fUseUPnP"); +#else + return false; +#endif + case MinimizeOnClose: + return fMinimizeOnClose; + + // default proxy + case ProxyUse: + return settings.value("fUseProxy", false); + case ProxyIP: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(0); + } + case ProxyPort: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(1); + } + + // separate Tor proxy + case ProxyUseTor: + return settings.value("fUseSeparateProxyTor", false); + case ProxyIPTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(0); + } + case ProxyPortTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(1); + } + +#ifdef ENABLE_WALLET + case SpendZeroConfChange: + return settings.value("bSpendZeroConfChange"); +#endif + case DisplayUnit: + return nDisplayUnit; + case ThirdPartyTxUrls: + return strThirdPartyTxUrls; + case Language: + return settings.value("language"); + case CoinControlFeatures: + return fCoinControlFeatures; + case DatabaseCache: + return settings.value("nDatabaseCache"); + case ThreadsScriptVerif: + return settings.value("nThreadsScriptVerif"); + case Listen: + return settings.value("fListen"); + default: + return QVariant(); + } + } + return QVariant(); +} + +// write QSettings values +bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + bool successful = true; /* set to false on parse error */ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + successful = GUIUtil::SetStartOnSystemStartup(value.toBool()); + break; + case HideTrayIcon: + fHideTrayIcon = value.toBool(); + settings.setValue("fHideTrayIcon", fHideTrayIcon); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + break; + case MinimizeToTray: + fMinimizeToTray = value.toBool(); + settings.setValue("fMinimizeToTray", fMinimizeToTray); + break; + case MapPortUPnP: // core option - can be changed on-the-fly + settings.setValue("fUseUPnP", value.toBool()); + MapPort(value.toBool()); + break; + case MinimizeOnClose: + fMinimizeOnClose = value.toBool(); + settings.setValue("fMinimizeOnClose", fMinimizeOnClose); + break; + + // default proxy + case ProxyUse: + if (settings.value("fUseProxy") != value) { + settings.setValue("fUseProxy", value.toBool()); + setRestartRequired(true); + } + break; + case ProxyIP: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed IP + if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) { + // construct new value from new IP and current port + QString strNewValue = value.toString() + ":" + strlIpPort.at(1); + settings.setValue("addrProxy", strNewValue); + setRestartRequired(true); + } + } + break; + case ProxyPort: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed port + if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) { + // construct new value from current IP and new port + QString strNewValue = strlIpPort.at(0) + ":" + value.toString(); + settings.setValue("addrProxy", strNewValue); + setRestartRequired(true); + } + } + break; + + // separate Tor proxy + case ProxyUseTor: + if (settings.value("fUseSeparateProxyTor") != value) { + settings.setValue("fUseSeparateProxyTor", value.toBool()); + setRestartRequired(true); + } + break; + case ProxyIPTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed IP + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) { + // construct new value from new IP and current port + QString strNewValue = value.toString() + ":" + strlIpPort.at(1); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + case ProxyPortTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed port + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) { + // construct new value from current IP and new port + QString strNewValue = strlIpPort.at(0) + ":" + value.toString(); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + +#ifdef ENABLE_WALLET + case SpendZeroConfChange: + if (settings.value("bSpendZeroConfChange") != value) { + settings.setValue("bSpendZeroConfChange", value); + setRestartRequired(true); + } + break; +#endif + case DisplayUnit: + setDisplayUnit(value); + break; + case ThirdPartyTxUrls: + if (strThirdPartyTxUrls != value.toString()) { + strThirdPartyTxUrls = value.toString(); + settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls); + setRestartRequired(true); + } + break; + case Language: + if (settings.value("language") != value) { + settings.setValue("language", value); + setRestartRequired(true); + } + break; + case CoinControlFeatures: + fCoinControlFeatures = value.toBool(); + settings.setValue("fCoinControlFeatures", fCoinControlFeatures); + Q_EMIT coinControlFeaturesChanged(fCoinControlFeatures); + break; + case DatabaseCache: + if (settings.value("nDatabaseCache") != value) { + settings.setValue("nDatabaseCache", value); + setRestartRequired(true); + } + break; + case ThreadsScriptVerif: + if (settings.value("nThreadsScriptVerif") != value) { + settings.setValue("nThreadsScriptVerif", value); + setRestartRequired(true); + } + break; + case Listen: + if (settings.value("fListen") != value) { + settings.setValue("fListen", value); + setRestartRequired(true); + } + break; + default: + break; + } + } + + Q_EMIT dataChanged(index, index); + + return successful; +} + +/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */ +void OptionsModel::setDisplayUnit(const QVariant &value) +{ + if (!value.isNull()) + { + QSettings settings; + nDisplayUnit = value.toInt(); + settings.setValue("nDisplayUnit", nDisplayUnit); + Q_EMIT displayUnitChanged(nDisplayUnit); + } +} + +bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const +{ + // Directly query current base proxy, because + // GUI settings can be overridden with -proxy. + proxyType curProxy; + if (GetProxy(NET_IPV4, curProxy)) { + proxy.setType(QNetworkProxy::Socks5Proxy); + proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP())); + proxy.setPort(curProxy.proxy.GetPort()); + + return true; + } + else + proxy.setType(QNetworkProxy::NoProxy); + + return false; +} + +void OptionsModel::setRestartRequired(bool fRequired) +{ + QSettings settings; + return settings.setValue("fRestartRequired", fRequired); +} + +bool OptionsModel::isRestartRequired() +{ + QSettings settings; + return settings.value("fRestartRequired", false).toBool(); +} + +void OptionsModel::checkAndMigrate() +{ + // Migration of default values + // Check if the QSettings container was already loaded with this client version + QSettings settings; + static const char strSettingsVersionKey[] = "nSettingsVersion"; + int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0; + if (settingsVersion < CLIENT_VERSION) + { + // -dbcache was bumped from 100 to 300 in 0.13 + // see https://github.com/bitcoin/bitcoin/pull/8273 + // force people to upgrade to the new value if they are using 100MB + if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100) + settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); + + settings.setValue(strSettingsVersionKey, CLIENT_VERSION); + } +}
\ No newline at end of file |