Raven Core  3.0.0
P2P Digital Currency
optionsmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
7 #include "config/raven-config.h"
8 #endif
9 
10 #include "optionsmodel.h"
11 
12 #include "ravenunits.h"
13 #include "guiutil.h"
14 
15 #include "amount.h"
16 #include "init.h"
17 #include "validation.h" // For DEFAULT_SCRIPTCHECK_THREADS
18 #include "net.h"
19 #include "netbase.h"
20 #include "txdb.h" // for -dbcache defaults
21 #include "intro.h"
22 #include "platformstyle.h"
23 
24 #ifdef ENABLE_WALLET
25 #include "wallet/wallet.h"
26 #include "wallet/walletdb.h"
27 #endif
28 
29 #include <QNetworkProxy>
30 #include <QSettings>
31 #include <QStringList>
32 
33 OptionsModel::OptionsModel(QObject *parent, bool resetSettings) :
34  QAbstractListModel(parent)
35 {
36  Init(resetSettings);
37 }
38 
39 void OptionsModel::addOverriddenOption(const std::string &option)
40 {
41  strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(gArgs.GetArg(option, "")) + " ";
42 }
43 
44 // Writes all missing QSettings with their default values
45 void OptionsModel::Init(bool resetSettings)
46 {
47  if (resetSettings)
48  Reset();
49 
51 
52  QSettings settings;
53 
54  // Ensure restart flag is unset on client startup
55  setRestartRequired(false);
56 
57  // These are Qt-only settings:
58 
59  // Window
60  if (!settings.contains("fHideTrayIcon"))
61  settings.setValue("fHideTrayIcon", false);
62  fHideTrayIcon = settings.value("fHideTrayIcon").toBool();
64 
65  if (!settings.contains("fMinimizeToTray"))
66  settings.setValue("fMinimizeToTray", false);
67  fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon;
68 
69  if (!settings.contains("fMinimizeOnClose"))
70  settings.setValue("fMinimizeOnClose", false);
71  fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
72 
73  // Display
74  if (!settings.contains("nDisplayUnit"))
75  settings.setValue("nDisplayUnit", RavenUnits::RVN);
76  nDisplayUnit = settings.value("nDisplayUnit").toInt();
77 
78  if (!settings.contains("strThirdPartyTxUrls"))
79  settings.setValue("strThirdPartyTxUrls", "");
80  strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
81 
82  if (!settings.contains("fCoinControlFeatures"))
83  settings.setValue("fCoinControlFeatures", false);
84  fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
85 
86  if (!settings.contains("fCustomFeeFeatures"))
87  settings.setValue("fCustomFeeFeatures", false);
88  fCustomFeeFeatures = settings.value("fCustomFeeFeatures", false).toBool();
89 
90  if (!settings.contains("fDarkModeEnabled"))
91  settings.setValue("fDarkModeEnabled", false);
92  fDarkModeEnabled = settings.value("fDarkModeEnabled", false).toBool();
93 
94  // These are shared with the core or have a command-line parameter
95  // and we want command-line parameters to overwrite the GUI settings.
96  //
97  // If setting doesn't exist create it with defaults.
98  //
99  // If gArgs.SoftSetArg() or gArgs.SoftSetBoolArg() return false we were overridden
100  // by command-line and show this in the UI.
101 
102  // Main
103  if (!settings.contains("nDatabaseCache"))
104  settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
105  if (!gArgs.SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString()))
106  addOverriddenOption("-dbcache");
107 
108  if (!settings.contains("nThreadsScriptVerif"))
109  settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS);
110  if (!gArgs.SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
111  addOverriddenOption("-par");
112 
113  if (!settings.contains("strDataDir"))
114  settings.setValue("strDataDir", Intro::getDefaultDataDirectory());
115 
116  // Wallet
117 #ifdef ENABLE_WALLET
118  if (!settings.contains("bSpendZeroConfChange"))
119  settings.setValue("bSpendZeroConfChange", true);
120  if (!gArgs.SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool()))
121  addOverriddenOption("-spendzeroconfchange");
122 #endif
123 
124  // Network
125  if (!settings.contains("fUseUPnP"))
126  settings.setValue("fUseUPnP", DEFAULT_UPNP);
127  if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
128  addOverriddenOption("-upnp");
129 
130  if (!settings.contains("fListen"))
131  settings.setValue("fListen", DEFAULT_LISTEN);
132  if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
133  addOverriddenOption("-listen");
134 
135  if (!settings.contains("fUseProxy"))
136  settings.setValue("fUseProxy", false);
137  if (!settings.contains("addrProxy") || !settings.value("addrProxy").toString().contains(':'))
138  settings.setValue("addrProxy", "127.0.0.1:9050");
139  // Only try to set -proxy, if user has enabled fUseProxy
140  if (settings.value("fUseProxy").toBool() && !gArgs.SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()))
141  addOverriddenOption("-proxy");
142  else if(!settings.value("fUseProxy").toBool() && !gArgs.GetArg("-proxy", "").empty())
143  addOverriddenOption("-proxy");
144 
145  if (!settings.contains("fUseSeparateProxyTor"))
146  settings.setValue("fUseSeparateProxyTor", false);
147  if (!settings.contains("addrSeparateProxyTor") || !settings.value("addrSeparateProxyTor").toString().contains(':'))
148  settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050");
149  // Only try to set -onion, if user has enabled fUseSeparateProxyTor
150  if (settings.value("fUseSeparateProxyTor").toBool() && !gArgs.SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString()))
151  addOverriddenOption("-onion");
152  else if(!settings.value("fUseSeparateProxyTor").toBool() && !gArgs.GetArg("-onion", "").empty())
153  addOverriddenOption("-onion");
154 
155  // Display
156  if (!settings.contains("language"))
157  settings.setValue("language", "");
158  if (!gArgs.SoftSetArg("-lang", settings.value("language").toString().toStdString()))
159  addOverriddenOption("-lang");
160 
161  language = settings.value("language").toString();
162 }
163 
167 static void CopySettings(QSettings& dst, const QSettings& src)
168 {
169  for (const QString& key : src.allKeys()) {
170  dst.setValue(key, src.value(key));
171  }
172 }
173 
175 static void BackupSettings(const fs::path& filename, const QSettings& src)
176 {
177  qWarning() << "Backing up GUI settings to" << GUIUtil::boostPathToQString(filename);
178  QSettings dst(GUIUtil::boostPathToQString(filename), QSettings::IniFormat);
179  dst.clear();
180  CopySettings(dst, src);
181 }
182 
184 {
185  QSettings settings;
186 
187  // Backup old settings to chain-specific datadir for troubleshooting
188  BackupSettings(GetDataDir(true) / "guisettings.ini.bak", settings);
189 
190  // Save the strDataDir setting
191  QString dataDir = Intro::getDefaultDataDirectory();
192  dataDir = settings.value("strDataDir", dataDir).toString();
193 
194  // Remove all entries from our QSettings object
195  settings.clear();
196 
197  // Set strDataDir
198  settings.setValue("strDataDir", dataDir);
199 
200  // Set that this was reset
201  settings.setValue("fReset", true);
202 
203  // default setting for OptionsModel::StartAtStartup - disabled
206 }
207 
208 int OptionsModel::rowCount(const QModelIndex & parent) const
209 {
210  return OptionIDRowCount;
211 }
212 
213 // read QSettings values and return them
214 QVariant OptionsModel::data(const QModelIndex & index, int role) const
215 {
216  if(role == Qt::EditRole)
217  {
218  QSettings settings;
219  switch(index.row())
220  {
221  case StartAtStartup:
223  case HideTrayIcon:
224  return fHideTrayIcon;
225  case MinimizeToTray:
226  return fMinimizeToTray;
227  case MapPortUPnP:
228 #ifdef USE_UPNP
229  return settings.value("fUseUPnP");
230 #else
231  return false;
232 #endif
233  case MinimizeOnClose:
234  return fMinimizeOnClose;
235 
236  // default proxy
237  case ProxyUse:
238  return settings.value("fUseProxy", false);
239  case ProxyIP: {
240  // contains IP at index 0 and port at index 1
241  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
242  return strlIpPort.at(0);
243  }
244  case ProxyPort: {
245  // contains IP at index 0 and port at index 1
246  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
247  return strlIpPort.at(1);
248  }
249 
250  // separate Tor proxy
251  case ProxyUseTor:
252  return settings.value("fUseSeparateProxyTor", false);
253  case ProxyIPTor: {
254  // contains IP at index 0 and port at index 1
255  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
256  return strlIpPort.at(0);
257  }
258  case ProxyPortTor: {
259  // contains IP at index 0 and port at index 1
260  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
261  return strlIpPort.at(1);
262  }
263 
264 #ifdef ENABLE_WALLET
265  case SpendZeroConfChange:
266  return settings.value("bSpendZeroConfChange");
267 #endif
268  case DisplayUnit:
269  return nDisplayUnit;
270  case ThirdPartyTxUrls:
271  return strThirdPartyTxUrls;
272  case Language:
273  return settings.value("language");
274  case CoinControlFeatures:
275  return fCoinControlFeatures;
276  case DatabaseCache:
277  return settings.value("nDatabaseCache");
278  case ThreadsScriptVerif:
279  return settings.value("nThreadsScriptVerif");
280  case Listen:
281  return settings.value("fListen");
282  case CustomFeeFeatures:
283  return fCustomFeeFeatures;
284  case DarkModeEnabled:
285  return fDarkModeEnabled;
286  default:
287  return QVariant();
288  }
289  }
290  return QVariant();
291 }
292 
293 // write QSettings values
294 bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
295 {
296  bool successful = true; /* set to false on parse error */
297  if(role == Qt::EditRole)
298  {
299  QSettings settings;
300  switch(index.row())
301  {
302  case StartAtStartup:
303  successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
304  break;
305  case HideTrayIcon:
306  fHideTrayIcon = value.toBool();
307  settings.setValue("fHideTrayIcon", fHideTrayIcon);
309  break;
310  case MinimizeToTray:
311  fMinimizeToTray = value.toBool();
312  settings.setValue("fMinimizeToTray", fMinimizeToTray);
313  break;
314  case MapPortUPnP: // core option - can be changed on-the-fly
315  settings.setValue("fUseUPnP", value.toBool());
316  MapPort(value.toBool());
317  break;
318  case MinimizeOnClose:
319  fMinimizeOnClose = value.toBool();
320  settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
321  break;
322 
323  // default proxy
324  case ProxyUse:
325  if (settings.value("fUseProxy") != value) {
326  settings.setValue("fUseProxy", value.toBool());
327  setRestartRequired(true);
328  }
329  break;
330  case ProxyIP: {
331  // contains current IP at index 0 and current port at index 1
332  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
333  // if that key doesn't exist or has a changed IP
334  if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) {
335  // construct new value from new IP and current port
336  QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
337  settings.setValue("addrProxy", strNewValue);
338  setRestartRequired(true);
339  }
340  }
341  break;
342  case ProxyPort: {
343  // contains current IP at index 0 and current port at index 1
344  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
345  // if that key doesn't exist or has a changed port
346  if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) {
347  // construct new value from current IP and new port
348  QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
349  settings.setValue("addrProxy", strNewValue);
350  setRestartRequired(true);
351  }
352  }
353  break;
354 
355  // separate Tor proxy
356  case ProxyUseTor:
357  if (settings.value("fUseSeparateProxyTor") != value) {
358  settings.setValue("fUseSeparateProxyTor", value.toBool());
359  setRestartRequired(true);
360  }
361  break;
362  case ProxyIPTor: {
363  // contains current IP at index 0 and current port at index 1
364  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
365  // if that key doesn't exist or has a changed IP
366  if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) {
367  // construct new value from new IP and current port
368  QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
369  settings.setValue("addrSeparateProxyTor", strNewValue);
370  setRestartRequired(true);
371  }
372  }
373  break;
374  case ProxyPortTor: {
375  // contains current IP at index 0 and current port at index 1
376  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
377  // if that key doesn't exist or has a changed port
378  if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) {
379  // construct new value from current IP and new port
380  QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
381  settings.setValue("addrSeparateProxyTor", strNewValue);
382  setRestartRequired(true);
383  }
384  }
385  break;
386 
387 #ifdef ENABLE_WALLET
388  case SpendZeroConfChange:
389  if (settings.value("bSpendZeroConfChange") != value) {
390  settings.setValue("bSpendZeroConfChange", value);
391  setRestartRequired(true);
392  }
393  break;
394 #endif
395  case DisplayUnit:
396  setDisplayUnit(value);
397  break;
398  case ThirdPartyTxUrls:
399  if (strThirdPartyTxUrls != value.toString()) {
400  strThirdPartyTxUrls = value.toString();
401  settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
402  setRestartRequired(true);
403  }
404  break;
405  case Language:
406  if (settings.value("language") != value) {
407  settings.setValue("language", value);
408  setRestartRequired(true);
409  }
410  break;
411  case CoinControlFeatures:
412  fCoinControlFeatures = value.toBool();
413  settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
415  break;
416  case DatabaseCache:
417  if (settings.value("nDatabaseCache") != value) {
418  settings.setValue("nDatabaseCache", value);
419  setRestartRequired(true);
420  }
421  break;
422  case ThreadsScriptVerif:
423  if (settings.value("nThreadsScriptVerif") != value) {
424  settings.setValue("nThreadsScriptVerif", value);
425  setRestartRequired(true);
426  }
427  break;
428  case Listen:
429  if (settings.value("fListen") != value) {
430  settings.setValue("fListen", value);
431  setRestartRequired(true);
432  }
433  break;
434  case CustomFeeFeatures:
435  fCustomFeeFeatures = value.toBool();
436  settings.setValue("fCustomFeeFeatures", fCustomFeeFeatures);
438  break;
439  case DarkModeEnabled:
440  fDarkModeEnabled = value.toBool();
441  settings.setValue("fDarkModeEnabled", fDarkModeEnabled);
442  break;
443  default:
444  break;
445  }
446  }
447 
448  Q_EMIT dataChanged(index, index);
449 
450  return successful;
451 }
452 
454 void OptionsModel::setDisplayUnit(const QVariant &value)
455 {
456  if (!value.isNull())
457  {
458  QSettings settings;
459  nDisplayUnit = value.toInt();
460  settings.setValue("nDisplayUnit", nDisplayUnit);
462  }
463 }
464 
465 bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
466 {
467  // Directly query current base proxy, because
468  // GUI settings can be overridden with -proxy.
469  proxyType curProxy;
470  if (GetProxy(NET_IPV4, curProxy)) {
471  proxy.setType(QNetworkProxy::Socks5Proxy);
472  proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP()));
473  proxy.setPort(curProxy.proxy.GetPort());
474 
475  return true;
476  }
477  else
478  proxy.setType(QNetworkProxy::NoProxy);
479 
480  return false;
481 }
482 
484 {
485  QSettings settings;
486  return settings.setValue("fRestartRequired", fRequired);
487 }
488 
490 {
491  QSettings settings;
492  return settings.value("fRestartRequired", false).toBool();
493 }
494 
496 {
497  // Migration of default values
498  // Check if the QSettings container was already loaded with this client version
499  QSettings settings;
500  static const char strSettingsVersionKey[] = "nSettingsVersion";
501  int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0;
502  if (settingsVersion < CLIENT_VERSION)
503  {
504  // -dbcache was bumped from 100 to 300 in 0.13
505  // see https://github.com/RavenProject/Ravencoin/pull/8273
506  // force people to upgrade to the new value if they are using 100MB
507  if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100)
508  settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
509 
510  settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
511  }
512 }
unsigned short GetPort() const
Definition: netaddress.cpp:523
bool fDarkModeEnabled
Definition: optionsmodel.h:91
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
void addOverriddenOption(const std::string &option)
void hideTrayIconChanged(bool)
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: util.cpp:486
bool getProxySettings(QNetworkProxy &proxy) const
QString language
Definition: optionsmodel.h:85
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:940
void coinControlFeaturesChanged(bool)
void customFeeFeaturesChanged(bool)
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn&#39;t already have a value.
Definition: util.cpp:478
bool fMinimizeOnClose
Definition: optionsmodel.h:84
void MapPort(bool)
Definition: net.cpp:1572
bool isRestartRequired() const
static QString getDefaultDataDirectory()
Determine default data directory for operating system.
Definition: intro.cpp:185
void setDisplayUnit(const QVariant &value)
Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal.
bool fHideTrayIcon
Definition: optionsmodel.h:82
OptionsModel(QObject *parent=0, bool resetSettings=false)
std::string ToStringIP() const
Definition: netaddress.cpp:264
bool fMinimizeToTray
Definition: optionsmodel.h:83
void Init(bool resetSettings=false)
void displayUnitChanged(int unit)
bool fCoinControlFeatures
Definition: optionsmodel.h:88
void checkAndMigrate()
bool fCustomFeeFeatures
RVN START.
Definition: optionsmodel.h:90
ArgsManager gArgs
Definition: util.cpp:94
CService proxy
Definition: netbase.h:37
void setRestartRequired(bool fRequired)
QString strThirdPartyTxUrls
Definition: optionsmodel.h:87
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:454
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:552
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:941
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:572
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:956
int rowCount(const QModelIndex &parent=QModelIndex()) const
QString strOverriddenByCommandLine
RVN END.
Definition: optionsmodel.h:94