Line data Source code
1 : // Copyright (c) 2011-2014 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)
6 : #include "config/bitcoin-config.h"
7 : #endif
8 :
9 : #include "optionsmodel.h"
10 :
11 : #include "bitcoinunits.h"
12 : #include "guiutil.h"
13 :
14 : #include "amount.h"
15 : #include "init.h"
16 : #include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS
17 : #include "net.h"
18 : #include "txdb.h" // for -dbcache defaults
19 :
20 : #ifdef ENABLE_WALLET
21 : #include "wallet/wallet.h"
22 : #include "wallet/walletdb.h"
23 : #endif
24 :
25 : #include <QNetworkProxy>
26 : #include <QSettings>
27 : #include <QStringList>
28 :
29 1 : OptionsModel::OptionsModel(QObject *parent) :
30 3 : QAbstractListModel(parent)
31 : {
32 1 : Init();
33 1 : }
34 :
35 0 : void OptionsModel::addOverriddenOption(const std::string &option)
36 : {
37 0 : strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(mapArgs[option]) + " ";
38 0 : }
39 :
40 : // Writes all missing QSettings with their default values
41 1 : void OptionsModel::Init()
42 : {
43 1 : QSettings settings;
44 :
45 : // Ensure restart flag is unset on client startup
46 1 : setRestartRequired(false);
47 :
48 : // These are Qt-only settings:
49 :
50 : // Window
51 1 : if (!settings.contains("fMinimizeToTray"))
52 0 : settings.setValue("fMinimizeToTray", false);
53 1 : fMinimizeToTray = settings.value("fMinimizeToTray").toBool();
54 :
55 1 : if (!settings.contains("fMinimizeOnClose"))
56 0 : settings.setValue("fMinimizeOnClose", false);
57 1 : fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
58 :
59 : // Display
60 1 : if (!settings.contains("nDisplayUnit"))
61 0 : settings.setValue("nDisplayUnit", BitcoinUnits::BTC);
62 1 : nDisplayUnit = settings.value("nDisplayUnit").toInt();
63 :
64 1 : if (!settings.contains("strThirdPartyTxUrls"))
65 0 : settings.setValue("strThirdPartyTxUrls", "");
66 2 : strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
67 :
68 1 : if (!settings.contains("fCoinControlFeatures"))
69 0 : settings.setValue("fCoinControlFeatures", false);
70 2 : fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
71 :
72 : // These are shared with the core or have a command-line parameter
73 : // and we want command-line parameters to overwrite the GUI settings.
74 : //
75 : // If setting doesn't exist create it with defaults.
76 : //
77 : // If SoftSetArg() or SoftSetBoolArg() return false we were overridden
78 : // by command-line and show this in the UI.
79 :
80 : // Main
81 1 : if (!settings.contains("nDatabaseCache"))
82 0 : settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
83 4 : if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString()))
84 0 : addOverriddenOption("-dbcache");
85 :
86 1 : if (!settings.contains("nThreadsScriptVerif"))
87 0 : settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS);
88 4 : if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
89 0 : addOverriddenOption("-par");
90 :
91 : // Wallet
92 : #ifdef ENABLE_WALLET
93 1 : if (!settings.contains("bSpendZeroConfChange"))
94 0 : settings.setValue("bSpendZeroConfChange", true);
95 3 : if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool()))
96 0 : addOverriddenOption("-spendzeroconfchange");
97 : #endif
98 :
99 : // Network
100 1 : if (!settings.contains("fUseUPnP"))
101 0 : settings.setValue("fUseUPnP", DEFAULT_UPNP);
102 3 : if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
103 0 : addOverriddenOption("-upnp");
104 :
105 1 : if (!settings.contains("fListen"))
106 0 : settings.setValue("fListen", DEFAULT_LISTEN);
107 3 : if (!SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
108 0 : addOverriddenOption("-listen");
109 :
110 1 : if (!settings.contains("fUseProxy"))
111 0 : settings.setValue("fUseProxy", false);
112 1 : if (!settings.contains("addrProxy"))
113 0 : settings.setValue("addrProxy", "127.0.0.1:9050");
114 : // Only try to set -proxy, if user has enabled fUseProxy
115 3 : if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()))
116 0 : addOverriddenOption("-proxy");
117 9 : else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty())
118 0 : addOverriddenOption("-proxy");
119 :
120 1 : if (!settings.contains("fUseSeparateProxyTor"))
121 0 : settings.setValue("fUseSeparateProxyTor", false);
122 1 : if (!settings.contains("addrSeparateProxyTor"))
123 0 : settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050");
124 : // Only try to set -onion, if user has enabled fUseSeparateProxyTor
125 3 : if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString()))
126 0 : addOverriddenOption("-onion");
127 9 : else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty())
128 0 : addOverriddenOption("-onion");
129 :
130 : // Display
131 1 : if (!settings.contains("language"))
132 0 : settings.setValue("language", "");
133 4 : if (!SoftSetArg("-lang", settings.value("language").toString().toStdString()))
134 0 : addOverriddenOption("-lang");
135 :
136 1 : language = settings.value("language").toString();
137 1 : }
138 :
139 0 : void OptionsModel::Reset()
140 : {
141 0 : QSettings settings;
142 :
143 : // Remove all entries from our QSettings object
144 0 : settings.clear();
145 :
146 : // default setting for OptionsModel::StartAtStartup - disabled
147 0 : if (GUIUtil::GetStartOnSystemStartup())
148 0 : GUIUtil::SetStartOnSystemStartup(false);
149 0 : }
150 :
151 0 : int OptionsModel::rowCount(const QModelIndex & parent) const
152 : {
153 0 : return OptionIDRowCount;
154 : }
155 :
156 : // read QSettings values and return them
157 0 : QVariant OptionsModel::data(const QModelIndex & index, int role) const
158 : {
159 0 : if(role == Qt::EditRole)
160 : {
161 0 : QSettings settings;
162 0 : switch(index.row())
163 : {
164 : case StartAtStartup:
165 0 : return GUIUtil::GetStartOnSystemStartup();
166 : case MinimizeToTray:
167 0 : return fMinimizeToTray;
168 : case MapPortUPnP:
169 : #ifdef USE_UPNP
170 0 : return settings.value("fUseUPnP");
171 : #else
172 : return false;
173 : #endif
174 : case MinimizeOnClose:
175 0 : return fMinimizeOnClose;
176 :
177 : // default proxy
178 : case ProxyUse:
179 0 : return settings.value("fUseProxy", false);
180 : case ProxyIP: {
181 : // contains IP at index 0 and port at index 1
182 0 : QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
183 0 : return strlIpPort.at(0);
184 : }
185 : case ProxyPort: {
186 : // contains IP at index 0 and port at index 1
187 0 : QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
188 0 : return strlIpPort.at(1);
189 : }
190 :
191 : // separate Tor proxy
192 : case ProxyUseTor:
193 0 : return settings.value("fUseSeparateProxyTor", false);
194 : case ProxyIPTor: {
195 : // contains IP at index 0 and port at index 1
196 0 : QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
197 0 : return strlIpPort.at(0);
198 : }
199 : case ProxyPortTor: {
200 : // contains IP at index 0 and port at index 1
201 0 : QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
202 0 : return strlIpPort.at(1);
203 : }
204 :
205 : #ifdef ENABLE_WALLET
206 : case SpendZeroConfChange:
207 0 : return settings.value("bSpendZeroConfChange");
208 : #endif
209 : case DisplayUnit:
210 0 : return nDisplayUnit;
211 : case ThirdPartyTxUrls:
212 0 : return strThirdPartyTxUrls;
213 : case Language:
214 0 : return settings.value("language");
215 : case CoinControlFeatures:
216 0 : return fCoinControlFeatures;
217 : case DatabaseCache:
218 0 : return settings.value("nDatabaseCache");
219 : case ThreadsScriptVerif:
220 0 : return settings.value("nThreadsScriptVerif");
221 : case Listen:
222 0 : return settings.value("fListen");
223 : default:
224 : return QVariant();
225 0 : }
226 : }
227 : return QVariant();
228 : }
229 :
230 : // write QSettings values
231 0 : bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
232 : {
233 0 : bool successful = true; /* set to false on parse error */
234 0 : if(role == Qt::EditRole)
235 : {
236 0 : QSettings settings;
237 0 : switch(index.row())
238 : {
239 : case StartAtStartup:
240 0 : successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
241 : break;
242 : case MinimizeToTray:
243 0 : fMinimizeToTray = value.toBool();
244 0 : settings.setValue("fMinimizeToTray", fMinimizeToTray);
245 0 : break;
246 : case MapPortUPnP: // core option - can be changed on-the-fly
247 0 : settings.setValue("fUseUPnP", value.toBool());
248 0 : MapPort(value.toBool());
249 : break;
250 : case MinimizeOnClose:
251 0 : fMinimizeOnClose = value.toBool();
252 0 : settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
253 0 : break;
254 :
255 : // default proxy
256 : case ProxyUse:
257 0 : if (settings.value("fUseProxy") != value) {
258 0 : settings.setValue("fUseProxy", value.toBool());
259 0 : setRestartRequired(true);
260 : }
261 : break;
262 : case ProxyIP: {
263 : // contains current IP at index 0 and current port at index 1
264 0 : QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
265 : // if that key doesn't exist or has a changed IP
266 0 : if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) {
267 : // construct new value from new IP and current port
268 0 : QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
269 0 : settings.setValue("addrProxy", strNewValue);
270 0 : setRestartRequired(true);
271 : }
272 : }
273 0 : break;
274 : case ProxyPort: {
275 : // contains current IP at index 0 and current port at index 1
276 0 : QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
277 : // if that key doesn't exist or has a changed port
278 0 : if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) {
279 : // construct new value from current IP and new port
280 0 : QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
281 0 : settings.setValue("addrProxy", strNewValue);
282 0 : setRestartRequired(true);
283 : }
284 : }
285 0 : break;
286 :
287 : // separate Tor proxy
288 : case ProxyUseTor:
289 0 : if (settings.value("fUseSeparateProxyTor") != value) {
290 0 : settings.setValue("fUseSeparateProxyTor", value.toBool());
291 0 : setRestartRequired(true);
292 : }
293 : break;
294 : case ProxyIPTor: {
295 : // contains current IP at index 0 and current port at index 1
296 0 : QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
297 : // if that key doesn't exist or has a changed IP
298 0 : if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) {
299 : // construct new value from new IP and current port
300 0 : QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
301 0 : settings.setValue("addrSeparateProxyTor", strNewValue);
302 0 : setRestartRequired(true);
303 : }
304 : }
305 0 : break;
306 : case ProxyPortTor: {
307 : // contains current IP at index 0 and current port at index 1
308 0 : QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
309 : // if that key doesn't exist or has a changed port
310 0 : if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) {
311 : // construct new value from current IP and new port
312 0 : QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
313 0 : settings.setValue("addrSeparateProxyTor", strNewValue);
314 0 : setRestartRequired(true);
315 : }
316 : }
317 0 : break;
318 :
319 : #ifdef ENABLE_WALLET
320 : case SpendZeroConfChange:
321 0 : if (settings.value("bSpendZeroConfChange") != value) {
322 0 : settings.setValue("bSpendZeroConfChange", value);
323 0 : setRestartRequired(true);
324 : }
325 : break;
326 : #endif
327 : case DisplayUnit:
328 0 : setDisplayUnit(value);
329 : break;
330 : case ThirdPartyTxUrls:
331 0 : if (strThirdPartyTxUrls != value.toString()) {
332 0 : strThirdPartyTxUrls = value.toString();
333 0 : settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
334 0 : setRestartRequired(true);
335 : }
336 : break;
337 : case Language:
338 0 : if (settings.value("language") != value) {
339 0 : settings.setValue("language", value);
340 0 : setRestartRequired(true);
341 : }
342 : break;
343 : case CoinControlFeatures:
344 0 : fCoinControlFeatures = value.toBool();
345 0 : settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
346 0 : Q_EMIT coinControlFeaturesChanged(fCoinControlFeatures);
347 : break;
348 : case DatabaseCache:
349 0 : if (settings.value("nDatabaseCache") != value) {
350 0 : settings.setValue("nDatabaseCache", value);
351 0 : setRestartRequired(true);
352 : }
353 : break;
354 : case ThreadsScriptVerif:
355 0 : if (settings.value("nThreadsScriptVerif") != value) {
356 0 : settings.setValue("nThreadsScriptVerif", value);
357 0 : setRestartRequired(true);
358 : }
359 : break;
360 : case Listen:
361 0 : if (settings.value("fListen") != value) {
362 0 : settings.setValue("fListen", value);
363 0 : setRestartRequired(true);
364 : }
365 : break;
366 : default:
367 : break;
368 0 : }
369 : }
370 :
371 0 : Q_EMIT dataChanged(index, index);
372 :
373 0 : return successful;
374 : }
375 :
376 : /** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */
377 0 : void OptionsModel::setDisplayUnit(const QVariant &value)
378 : {
379 0 : if (!value.isNull())
380 : {
381 0 : QSettings settings;
382 0 : nDisplayUnit = value.toInt();
383 0 : settings.setValue("nDisplayUnit", nDisplayUnit);
384 0 : Q_EMIT displayUnitChanged(nDisplayUnit);
385 : }
386 0 : }
387 :
388 1 : bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
389 : {
390 : // Directly query current base proxy, because
391 : // GUI settings can be overridden with -proxy.
392 : proxyType curProxy;
393 1 : if (GetProxy(NET_IPV4, curProxy)) {
394 0 : proxy.setType(QNetworkProxy::Socks5Proxy);
395 0 : proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP()));
396 0 : proxy.setPort(curProxy.proxy.GetPort());
397 :
398 : return true;
399 : }
400 : else
401 1 : proxy.setType(QNetworkProxy::NoProxy);
402 :
403 : return false;
404 : }
405 :
406 1 : void OptionsModel::setRestartRequired(bool fRequired)
407 : {
408 1 : QSettings settings;
409 2 : return settings.setValue("fRestartRequired", fRequired);
410 : }
411 :
412 0 : bool OptionsModel::isRestartRequired()
413 : {
414 0 : QSettings settings;
415 0 : return settings.value("fRestartRequired", false).toBool();
416 3 : }
|