Fabcoin Core  0.16.2
P2P Digital Currency
optionsmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <optionsmodel.h>
10 
11 #include <fabcoinunits.h>
12 #include <wallet/wallet.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 
23 #ifdef ENABLE_WALLET
24 #include <wallet/wallet.h>
25 #include <wallet/walletdb.h>
26 #endif
27 
28 #include <QNetworkProxy>
29 #include <QSettings>
30 #include <QStringList>
31 #include <utilmoneystr.h>
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", FabcoinUnits::FAB);
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  // These are shared with the core or have a command-line parameter
87  // and we want command-line parameters to overwrite the GUI settings.
88  //
89  // If setting doesn't exist create it with defaults.
90  //
91  // If gArgs.SoftSetArg() or gArgs.SoftSetBoolArg() return false we were overridden
92  // by command-line and show this in the UI.
93 
94  // Main
95  if (!settings.contains("nDatabaseCache"))
96  settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
97  if (!gArgs.SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString()))
98  addOverriddenOption("-dbcache");
99 
100  if (!settings.contains("fLogEvents"))
101  settings.setValue("fLogEvents", fLogEvents);
102  if (!gArgs.SoftSetBoolArg("-logevents", settings.value("fLogEvents").toBool()))
103  addOverriddenOption("-logevents");
104 
105  if (!settings.contains("nReserveBalance"))
106  settings.setValue("nReserveBalance", (qint64)nReserveBalance);
107  if (!gArgs.SoftSetArg("-reservebalance", FormatMoney(settings.value("nReserveBalance").toLongLong())))
108  ParseMoney(gArgs.GetArg("-reservebalance", ""), nReserveBalance);
109  else
110  nReserveBalance = settings.value("nReserveBalance").toLongLong();
111 
112  Q_EMIT reserveBalanceChanged(nReserveBalance);
113 
114  if (!settings.contains("nThreadsScriptVerif"))
115  settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS);
116  if (!gArgs.SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
117  addOverriddenOption("-par");
118 
119  if (!settings.contains("strDataDir"))
120  settings.setValue("strDataDir", Intro::getDefaultDataDirectory());
121 
122  // Wallet
123 #ifdef ENABLE_WALLET
124  if (!settings.contains("bSpendZeroConfChange"))
125  settings.setValue("bSpendZeroConfChange", true);
126  if (!gArgs.SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool()))
127  addOverriddenOption("-spendzeroconfchange");
128 #endif
129  if (!settings.contains("bZeroBalanceAddressToken"))
130  settings.setValue("bZeroBalanceAddressToken", true);
131  if (!gArgs.SoftSetBoolArg("-zerobalanceaddresstoken", settings.value("bZeroBalanceAddressToken").toBool()))
132  addOverriddenOption("-zerobalanceaddresstoken");
133 
134  if (!settings.contains("fCheckForUpdates"))
135  settings.setValue("fCheckForUpdates", DEFAULT_CHECK_FOR_UPDATES);
136  fCheckForUpdates = settings.value("fCheckForUpdates").toBool();
137 
138  // Network
139  if (!settings.contains("fUseUPnP"))
140  settings.setValue("fUseUPnP", DEFAULT_UPNP);
141  if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
142  addOverriddenOption("-upnp");
143 
144  if (!settings.contains("fListen"))
145  settings.setValue("fListen", DEFAULT_LISTEN);
146  if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
147  addOverriddenOption("-listen");
148 
149  if (!settings.contains("fNotUseChangeAddress"))
150  settings.setValue("fNotUseChangeAddress", DEFAULT_NOT_USE_CHANGE_ADDRESS);
151  fNotUseChangeAddress = settings.value("fNotUseChangeAddress").toBool();
152 
153  if (!settings.contains("fUseProxy"))
154  settings.setValue("fUseProxy", false);
155  if (!settings.contains("addrProxy"))
156  settings.setValue("addrProxy", "127.0.0.1:9050");
157  // Only try to set -proxy, if user has enabled fUseProxy
158  if (settings.value("fUseProxy").toBool() && !gArgs.SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()))
159  addOverriddenOption("-proxy");
160  else if(!settings.value("fUseProxy").toBool() && !gArgs.GetArg("-proxy", "").empty())
161  addOverriddenOption("-proxy");
162 
163  if (!settings.contains("fUseSeparateProxyTor"))
164  settings.setValue("fUseSeparateProxyTor", false);
165  if (!settings.contains("addrSeparateProxyTor"))
166  settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050");
167  // Only try to set -onion, if user has enabled fUseSeparateProxyTor
168  if (settings.value("fUseSeparateProxyTor").toBool() && !gArgs.SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString()))
169  addOverriddenOption("-onion");
170  else if(!settings.value("fUseSeparateProxyTor").toBool() && !gArgs.GetArg("-onion", "").empty())
171  addOverriddenOption("-onion");
172 
173  // Display
174  if (!settings.contains("language"))
175  settings.setValue("language", "");
176  if (!gArgs.SoftSetArg("-lang", settings.value("language").toString().toStdString()))
177  addOverriddenOption("-lang");
178 
179  language = settings.value("language").toString();
180 }
181 
185 static void CopySettings(QSettings& dst, const QSettings& src)
186 {
187  for (const QString& key : src.allKeys()) {
188  dst.setValue(key, src.value(key));
189  }
190 }
191 
193 static void BackupSettings(const fs::path& filename, const QSettings& src)
194 {
195  qWarning() << "Backing up GUI settings to" << GUIUtil::boostPathToQString(filename);
196  QSettings dst(GUIUtil::boostPathToQString(filename), QSettings::IniFormat);
197  dst.clear();
198  CopySettings(dst, src);
199 }
200 
202 {
203  QSettings settings;
204 
205  // Backup old settings to chain-specific datadir for troubleshooting
206  BackupSettings(GetDataDir(true) / "guisettings.ini.bak", settings);
207 
208  // Save the strDataDir setting
209  QString dataDir = Intro::getDefaultDataDirectory();
210  dataDir = settings.value("strDataDir", dataDir).toString();
211 
212  // Remove all entries from our QSettings object
213  settings.clear();
214 
215  // Set strDataDir
216  settings.setValue("strDataDir", dataDir);
217 
218  // Set that this was reset
219  settings.setValue("fReset", true);
220 
221  // default setting for OptionsModel::StartAtStartup - disabled
224 }
225 
226 int OptionsModel::rowCount(const QModelIndex & parent) const
227 {
228  return OptionIDRowCount;
229 }
230 
231 // read QSettings values and return them
232 QVariant OptionsModel::data(const QModelIndex & index, int role) const
233 {
234  if(role == Qt::EditRole)
235  {
236  QSettings settings;
237  switch(index.row())
238  {
239  case StartAtStartup:
241  case HideTrayIcon:
242  return fHideTrayIcon;
243  case MinimizeToTray:
244  return fMinimizeToTray;
245  case MapPortUPnP:
246 #ifdef USE_UPNP
247  return settings.value("fUseUPnP");
248 #else
249  return false;
250 #endif
251  case MinimizeOnClose:
252  return fMinimizeOnClose;
253 
254  // default proxy
255  case ProxyUse:
256  return settings.value("fUseProxy", false);
257  case ProxyIP: {
258  // contains IP at index 0 and port at index 1
259  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
260  return strlIpPort.at(0);
261  }
262  case ProxyPort: {
263  // contains IP at index 0 and port at index 1
264  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
265  return strlIpPort.at(1);
266  }
267 
268  // separate Tor proxy
269  case ProxyUseTor:
270  return settings.value("fUseSeparateProxyTor", false);
271  case ProxyIPTor: {
272  // contains IP at index 0 and port at index 1
273  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
274  return strlIpPort.at(0);
275  }
276  case ProxyPortTor: {
277  // contains IP at index 0 and port at index 1
278  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
279  return strlIpPort.at(1);
280  }
281 
282 #ifdef ENABLE_WALLET
283  case SpendZeroConfChange:
284  return settings.value("bSpendZeroConfChange");
285 #endif
287  return settings.value("bZeroBalanceAddressToken");
288  case ReserveBalance:
289  return (qint64) nReserveBalance;
290  case DisplayUnit:
291  return nDisplayUnit;
292  case ThirdPartyTxUrls:
293  return strThirdPartyTxUrls;
294  case Language:
295  return settings.value("language");
296  case CoinControlFeatures:
297  return fCoinControlFeatures;
298  case DatabaseCache:
299  return settings.value("nDatabaseCache");
300  case LogEvents:
301  return settings.value("fLogEvents");
302  case ThreadsScriptVerif:
303  return settings.value("nThreadsScriptVerif");
304  case Listen:
305  return settings.value("fListen");
306  case NotUseChangeAddress:
307  return settings.value("fNotUseChangeAddress");
308  case CheckForUpdates:
309  return settings.value("fCheckForUpdates");
310  default:
311  return QVariant();
312  }
313  }
314  return QVariant();
315 }
316 
317 // write QSettings values
318 bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
319 {
320  bool successful = true; /* set to false on parse error */
321  if(role == Qt::EditRole)
322  {
323  QSettings settings;
324  switch(index.row())
325  {
326  case StartAtStartup:
327  successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
328  break;
329  case HideTrayIcon:
330  fHideTrayIcon = value.toBool();
331  settings.setValue("fHideTrayIcon", fHideTrayIcon);
333  break;
334  case MinimizeToTray:
335  fMinimizeToTray = value.toBool();
336  settings.setValue("fMinimizeToTray", fMinimizeToTray);
337  break;
338  case MapPortUPnP: // core option - can be changed on-the-fly
339  settings.setValue("fUseUPnP", value.toBool());
340  MapPort(value.toBool());
341  break;
342  case MinimizeOnClose:
343  fMinimizeOnClose = value.toBool();
344  settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
345  break;
346 
347  // default proxy
348  case ProxyUse:
349  if (settings.value("fUseProxy") != value) {
350  settings.setValue("fUseProxy", value.toBool());
351  setRestartRequired(true);
352  }
353  break;
354  case ProxyIP: {
355  // contains current IP at index 0 and current port at index 1
356  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
357  // if that key doesn't exist or has a changed IP
358  if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) {
359  // construct new value from new IP and current port
360  QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
361  settings.setValue("addrProxy", strNewValue);
362  setRestartRequired(true);
363  }
364  }
365  break;
366  case ProxyPort: {
367  // contains current IP at index 0 and current port at index 1
368  QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
369  // if that key doesn't exist or has a changed port
370  if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) {
371  // construct new value from current IP and new port
372  QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
373  settings.setValue("addrProxy", strNewValue);
374  setRestartRequired(true);
375  }
376  }
377  break;
378 
379  // separate Tor proxy
380  case ProxyUseTor:
381  if (settings.value("fUseSeparateProxyTor") != value) {
382  settings.setValue("fUseSeparateProxyTor", value.toBool());
383  setRestartRequired(true);
384  }
385  break;
386  case ProxyIPTor: {
387  // contains current IP at index 0 and current port at index 1
388  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
389  // if that key doesn't exist or has a changed IP
390  if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) {
391  // construct new value from new IP and current port
392  QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
393  settings.setValue("addrSeparateProxyTor", strNewValue);
394  setRestartRequired(true);
395  }
396  }
397  break;
398  case ProxyPortTor: {
399  // contains current IP at index 0 and current port at index 1
400  QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
401  // if that key doesn't exist or has a changed port
402  if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) {
403  // construct new value from current IP and new port
404  QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
405  settings.setValue("addrSeparateProxyTor", strNewValue);
406  setRestartRequired(true);
407  }
408  }
409  break;
410 
411 #ifdef ENABLE_WALLET
412  case SpendZeroConfChange:
413  if (settings.value("bSpendZeroConfChange") != value) {
414  settings.setValue("bSpendZeroConfChange", value);
415  setRestartRequired(true);
416  }
417  break;
418 #endif
420  bZeroBalanceAddressToken = value.toBool();
421  settings.setValue("bZeroBalanceAddressToken", bZeroBalanceAddressToken);
423  break;
424  case DisplayUnit:
425  setDisplayUnit(value);
426  break;
427  case ThirdPartyTxUrls:
428  if (strThirdPartyTxUrls != value.toString()) {
429  strThirdPartyTxUrls = value.toString();
430  settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
431  setRestartRequired(true);
432  }
433  break;
434  case Language:
435  if (settings.value("language") != value) {
436  settings.setValue("language", value);
437  setRestartRequired(true);
438  }
439  break;
440  case CoinControlFeatures:
441  fCoinControlFeatures = value.toBool();
442  settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
444  break;
445  case DatabaseCache:
446  if (settings.value("nDatabaseCache") != value) {
447  settings.setValue("nDatabaseCache", value);
448  setRestartRequired(true);
449  }
450  break;
451  case LogEvents:
452  if (settings.value("fLogEvents") != value) {
453  settings.setValue("fLogEvents", value);
454  setRestartRequired(true);
455  }
456  break;
457  case ReserveBalance:
458  if (settings.value("nReserveBalance") != value) {
459  settings.setValue("nReserveBalance", value);
460  nReserveBalance = value.toLongLong();
462  }
463  break;
464  case ThreadsScriptVerif:
465  if (settings.value("nThreadsScriptVerif") != value) {
466  settings.setValue("nThreadsScriptVerif", value);
467  setRestartRequired(true);
468  }
469  break;
470  case Listen:
471  if (settings.value("fListen") != value) {
472  settings.setValue("fListen", value);
473  setRestartRequired(true);
474  }
475  break;
476  case NotUseChangeAddress:
477  if (settings.value("fNotUseChangeAddress") != value) {
478  settings.setValue("fNotUseChangeAddress", value);
479  fNotUseChangeAddress = value.toBool();
480  }
481  break;
482  case CheckForUpdates:
483  if (settings.value("fCheckForUpdates") != value) {
484  settings.setValue("fCheckForUpdates", value);
485  fCheckForUpdates = value.toBool();
486  }
487  break;
488  default:
489  break;
490  }
491  }
492 
493  Q_EMIT dataChanged(index, index);
494 
495  return successful;
496 }
497 
499 void OptionsModel::setDisplayUnit(const QVariant &value)
500 {
501  if (!value.isNull())
502  {
503  QSettings settings;
504  nDisplayUnit = value.toInt();
505  settings.setValue("nDisplayUnit", nDisplayUnit);
507  }
508 }
509 
510 bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
511 {
512  // Directly query current base proxy, because
513  // GUI settings can be overridden with -proxy.
514  proxyType curProxy;
515  if (GetProxy(NET_IPV4, curProxy)) {
516  proxy.setType(QNetworkProxy::Socks5Proxy);
517  proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP()));
518  proxy.setPort(curProxy.proxy.GetPort());
519 
520  return true;
521  }
522  else
523  proxy.setType(QNetworkProxy::NoProxy);
524 
525  return false;
526 }
527 
529 {
530  QSettings settings;
531  return settings.setValue("fRestartRequired", fRequired);
532 }
533 
535 {
536  QSettings settings;
537  return settings.value("fRestartRequired", false).toBool();
538 }
539 
541 {
542  // Migration of default values
543  // Check if the QSettings container was already loaded with this client version
544  QSettings settings;
545  static const char strSettingsVersionKey[] = "nSettingsVersion";
546  int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0;
547  if (settingsVersion < CLIENT_VERSION)
548  {
549  // -dbcache was bumped from 100 to 300 in 0.13
550  // see https://github.com/blockchaingate/fabcoin/pull/8273
551  // force people to upgrade to the new value if they are using 100MB
552  if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100)
553  settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
554 
555  settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
556  }
557 }
bool fLogEvents
Definition: validation.cpp:88
unsigned short GetPort() const
Definition: netaddress.cpp:522
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:537
std::string ToStringIP() const
Definition: netaddress.cpp:263
CAmount nReserveBalance
Settings.
Definition: wallet.cpp:55
QString language
Definition: optionsmodel.h:85
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:853
void coinControlFeaturesChanged(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:528
bool fMinimizeOnClose
Definition: optionsmodel.h:84
void MapPort(bool)
Definition: net.cpp:1544
static QString getDefaultDataDirectory()
Determine default data directory for operating system.
Definition: intro.cpp:184
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)
int rowCount(const QModelIndex &parent=QModelIndex()) const
bool getProxySettings(QNetworkProxy &proxy) const
bool fMinimizeToTray
Definition: optionsmodel.h:83
void zeroBalanceAddressTokenChanged(bool)
bool ParseMoney(const std::string &str, CAmount &nRet)
void Init(bool resetSettings=false)
void displayUnitChanged(int unit)
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool fCoinControlFeatures
Definition: optionsmodel.h:88
bool fCheckForUpdates
Definition: wallet.cpp:49
void checkAndMigrate()
ArgsManager gArgs
Definition: util.cpp:94
CService proxy
Definition: netbase.h:36
void setRestartRequired(bool fRequired)
void reserveBalanceChanged(CAmount)
QString strThirdPartyTxUrls
Definition: optionsmodel.h:87
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:504
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:556
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:854
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:623
bool isRestartRequired()
QString boostPathToQString(const fs::path &path)
Definition: guiutil.cpp:869
bool fNotUseChangeAddress
Definition: wallet.cpp:48
bool bZeroBalanceAddressToken
Definition: wallet.cpp:46
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
QString strOverriddenByCommandLine
Definition: optionsmodel.h:90