Browse Source

Merge pull request #3347

7e195e8 [Qt] massive options/settings rework (no core changes) (Philip Kaufmann)
metaverse
Wladimir J. van der Laan 11 years ago
parent
commit
a036b796d1
No known key found for this signature in database GPG Key ID: 74810B012346C9A6
  1. 219
      src/qt/forms/optionsdialog.ui
  2. 132
      src/qt/optionsdialog.cpp
  3. 27
      src/qt/optionsdialog.h
  4. 287
      src/qt/optionsmodel.cpp
  5. 17
      src/qt/optionsmodel.h

219
src/qt/forms/optionsdialog.ui

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>540</width> <width>560</width>
<height>380</height> <height>400</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -19,9 +19,6 @@
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
@ -86,21 +83,44 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer_Main">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2_Main"> <layout class="QHBoxLayout" name="horizontalLayout_2_Main">
<item>
<widget class="QLabel" name="databaseCacheLabel">
<property name="text">
<string>Size of &amp;database cache</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="buddy">
<cstring>databaseCache</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="databaseCache">
<property name="toolTip">
<string>Set database cache size in megabytes (default: 25)</string>
</property>
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>25</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="databaseCacheUnitLabel">
<property name="text">
<string>MB</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_2_Main"> <spacer name="horizontalSpacer_2_Main">
<property name="orientation"> <property name="orientation">
@ -114,21 +134,64 @@
</property> </property>
</spacer> </spacer>
</item> </item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3_Main">
<item>
<widget class="QLabel" name="threadsScriptVerifLabel">
<property name="text">
<string>Number of script &amp;verification threads</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="buddy">
<cstring>threadsScriptVerif</cstring>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="resetButton"> <widget class="QSpinBox" name="threadsScriptVerif">
<property name="toolTip"> <property name="toolTip">
<string>Reset all client options to default.</string> <string>Set the number of script verification threads (up to 16, 0 = auto, &lt;0 = leave that many cores free, default: 0)</string>
</property> </property>
<property name="text"> <property name="minimum">
<string>&amp;Reset Options</string> <number>-16</number>
</property> </property>
<property name="autoDefault"> <property name="maximum">
<bool>false</bool> <number>16</number>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer_3_Main">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
<item>
<spacer name="verticalSpacer_Main">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabNetwork"> <widget class="QWidget" name="tabNetwork">
@ -149,15 +212,15 @@
<item> <item>
<widget class="QCheckBox" name="connectSocks"> <widget class="QCheckBox" name="connectSocks">
<property name="toolTip"> <property name="toolTip">
<string>Connect to the Bitcoin network through a SOCKS proxy (e.g. when connecting through Tor).</string> <string>Connect to the Bitcoin network through a SOCKS proxy.</string>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Connect through SOCKS proxy:</string> <string>&amp;Connect through SOCKS proxy (default proxy):</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_Network"> <layout class="QHBoxLayout" name="horizontalLayout_1_Network">
<item> <item>
<widget class="QLabel" name="proxyIpLabel"> <widget class="QLabel" name="proxyIpLabel">
<property name="text"> <property name="text">
@ -173,6 +236,12 @@
</item> </item>
<item> <item>
<widget class="QValidatedLineEdit" name="proxyIp"> <widget class="QValidatedLineEdit" name="proxyIp">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>140</width> <width>140</width>
@ -180,7 +249,7 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>IP address of the proxy (e.g. 127.0.0.1)</string> <string>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -199,6 +268,12 @@
</item> </item>
<item> <item>
<widget class="QLineEdit" name="proxyPort"> <widget class="QLineEdit" name="proxyPort">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>55</width> <width>55</width>
@ -231,7 +306,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_Network"> <spacer name="horizontalSpacer_1_Network">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -390,8 +465,67 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item>
<widget class="QFrame" name="frame">
<layout class="QVBoxLayout" name="verticalLayout_Bottom">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_Bottom">
<item>
<widget class="QLabel" name="overriddenByCommandLineInfoLabel">
<property name="text">
<string>Active command-line options that override above options: </string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_Bottom">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="overriddenByCommandLineLabel">
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_Buttons"> <layout class="QHBoxLayout" name="horizontalLayout_Buttons">
<item>
<widget class="QPushButton" name="resetButton">
<property name="toolTip">
<string>Reset all client options to default.</string>
</property>
<property name="text">
<string>&amp;Reset Options</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_1"> <spacer name="horizontalSpacer_1">
<property name="orientation"> <property name="orientation">
@ -407,6 +541,12 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="statusLabel"> <widget class="QLabel" name="statusLabel">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -454,16 +594,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>&amp;Apply</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -473,17 +603,18 @@
<class>BitcoinAmountField</class> <class>BitcoinAmountField</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>bitcoinamountfield.h</header> <header>bitcoinamountfield.h</header>
</customwidget> <container>1</container>
<customwidget>
<class>QValueComboBox</class>
<extends>QComboBox</extends>
<header>qvaluecombobox.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>QValidatedLineEdit</class> <class>QValidatedLineEdit</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>qvalidatedlineedit.h</header> <header>qvalidatedlineedit.h</header>
</customwidget> </customwidget>
<customwidget>
<class>QValueComboBox</class>
<extends>QComboBox</extends>
<header>qvaluecombobox.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>

132
src/qt/optionsdialog.cpp

@ -10,6 +10,7 @@
#include "ui_optionsdialog.h" #include "ui_optionsdialog.h"
#include "bitcoinunits.h" #include "bitcoinunits.h"
#include "guiutil.h"
#include "monitoreddatamapper.h" #include "monitoreddatamapper.h"
#include "optionsmodel.h" #include "optionsmodel.h"
@ -19,17 +20,20 @@
#include <QIntValidator> #include <QIntValidator>
#include <QLocale> #include <QLocale>
#include <QMessageBox> #include <QMessageBox>
#include <QTimer>
OptionsDialog::OptionsDialog(QWidget *parent) : OptionsDialog::OptionsDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::OptionsDialog), ui(new Ui::OptionsDialog),
model(0), model(0),
mapper(0), mapper(0),
fRestartWarningDisplayed_Proxy(false),
fRestartWarningDisplayed_Lang(false),
fProxyIpValid(true) fProxyIpValid(true)
{ {
ui->setupUi(this); ui->setupUi(this);
GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
/* Main elements init */
ui->databaseCache->setMaximum(sizeof(void*) > 4 ? 4096 : 1024);
/* Network elements init */ /* Network elements init */
#ifndef USE_UPNP #ifndef USE_UPNP
@ -40,6 +44,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
ui->proxyPort->setEnabled(false); ui->proxyPort->setEnabled(false);
ui->proxyPort->setValidator(new QIntValidator(1, 65535, this)); ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));
/** SOCKS version is only selectable for default proxy and is always 5 for IPv6 and Tor */
ui->socksVersion->setEnabled(false); ui->socksVersion->setEnabled(false);
ui->socksVersion->addItem("5", 5); ui->socksVersion->addItem("5", 5);
ui->socksVersion->addItem("4", 4); ui->socksVersion->addItem("4", 4);
@ -95,16 +100,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical); mapper->setOrientation(Qt::Vertical);
/* enable apply button when data modified */
connect(mapper, SIGNAL(viewModified()), this, SLOT(enableApplyButton()));
/* disable apply button when new data loaded */
connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableApplyButton()));
/* setup/change UI elements when proxy IP is invalid/valid */ /* setup/change UI elements when proxy IP is invalid/valid */
connect(this, SIGNAL(proxyIpValid(QValidatedLineEdit *, bool)), this, SLOT(handleProxyIpValid(QValidatedLineEdit *, bool))); connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int)));
} }
OptionsDialog::~OptionsDialog() OptionsDialog::~OptionsDialog()
{ {
GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
delete ui; delete ui;
} }
@ -114,6 +116,15 @@ void OptionsDialog::setModel(OptionsModel *model)
if(model) if(model)
{ {
/* check if client restart is needed and show persistent message */
if (model->isRestartRequired())
showRestartWarning(true);
QString strLabel = model->getOverriddenByCommandLine();
if (strLabel.isEmpty())
strLabel = tr("none");
ui->overriddenByCommandLineLabel->setText(strLabel);
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
mapper->setModel(model); mapper->setModel(model);
@ -124,11 +135,15 @@ void OptionsDialog::setModel(OptionsModel *model)
/* update the display unit, to not use the default ("BTC") */ /* update the display unit, to not use the default ("BTC") */
updateDisplayUnit(); updateDisplayUnit();
/* warn only when language selection changes by user action (placed here so init via mapper doesn't trigger this) */ /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning_Lang()));
/* disable apply button after settings are loaded as there is nothing to save */ /* Main */
disableApplyButton(); connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
/* Network */
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
/* Display */
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
} }
void OptionsDialog::setMapper() void OptionsDialog::setMapper()
@ -136,6 +151,8 @@ void OptionsDialog::setMapper()
/* Main */ /* Main */
mapper->addMapping(ui->transactionFee, OptionsModel::Fee); mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup); mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
/* Network */ /* Network */
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP); mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
@ -158,31 +175,20 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);
} }
void OptionsDialog::enableApplyButton() void OptionsDialog::enableOkButton()
{
ui->applyButton->setEnabled(true);
}
void OptionsDialog::disableApplyButton()
{
ui->applyButton->setEnabled(false);
}
void OptionsDialog::enableSaveButtons()
{ {
/* prevent enabling of the save buttons when data modified, if there is an invalid proxy address present */ /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
if(fProxyIpValid) if(fProxyIpValid)
setSaveButtonState(true); setOkButtonState(true);
} }
void OptionsDialog::disableSaveButtons() void OptionsDialog::disableOkButton()
{ {
setSaveButtonState(false); setOkButtonState(false);
} }
void OptionsDialog::setSaveButtonState(bool fState) void OptionsDialog::setOkButtonState(bool fState)
{ {
ui->applyButton->setEnabled(fState);
ui->okButton->setEnabled(fState); ui->okButton->setEnabled(fState);
} }
@ -192,24 +198,15 @@ void OptionsDialog::on_resetButton_clicked()
{ {
// confirmation dialog // confirmation dialog
QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"), QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
tr("Some settings may require a client restart to take effect.") + "<br><br>" + tr("Do you want to proceed?"), tr("Client restart required to activate changes.") + "<br><br>" + tr("Client will be shutdown, do you want to proceed?"),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
if(btnRetVal == QMessageBox::Cancel) if(btnRetVal == QMessageBox::Cancel)
return; return;
disableApplyButton(); /* reset all options and close Bitcoin-Qt */
/* disable restart warning messages display */
fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = true;
/* reset all options and save the default values (QSettings) */
model->Reset(); model->Reset();
mapper->toFirst(); QApplication::quit();
mapper->submit();
/* re-enable restart warning messages display */
fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = false;
} }
} }
@ -224,28 +221,26 @@ void OptionsDialog::on_cancelButton_clicked()
reject(); reject();
} }
void OptionsDialog::on_applyButton_clicked() void OptionsDialog::showRestartWarning(bool fPersistent)
{ {
mapper->submit(); ui->statusLabel->setStyleSheet("QLabel { color: red; }");
disableApplyButton();
}
void OptionsDialog::showRestartWarning_Proxy() if(fPersistent)
{ {
if(!fRestartWarningDisplayed_Proxy) ui->statusLabel->setText(tr("Client restart required to activate changes."));
}
else
{ {
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok); ui->statusLabel->setText(tr("This change would require a client restart."));
fRestartWarningDisplayed_Proxy = true; // clear non-persistent status label after 10 seconds
// Todo: should perhaps be a class attribute, if we extend the use of statusLabel
QTimer::singleShot(10000, this, SLOT(clearStatusLabel()));
} }
} }
void OptionsDialog::showRestartWarning_Lang() void OptionsDialog::clearStatusLabel()
{ {
if(!fRestartWarningDisplayed_Lang) ui->statusLabel->clear();
{
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok);
fRestartWarningDisplayed_Lang = true;
}
} }
void OptionsDialog::updateDisplayUnit() void OptionsDialog::updateDisplayUnit()
@ -257,22 +252,25 @@ void OptionsDialog::updateDisplayUnit()
} }
} }
void OptionsDialog::handleProxyIpValid(QValidatedLineEdit *object, bool fState) void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort)
{ {
// this is used in a check before re-enabling the save buttons Q_UNUSED(nProxyPort);
fProxyIpValid = fState;
if(fProxyIpValid) const std::string strAddrProxy = pUiProxyIp->text().toStdString();
CService addrProxy;
/* Check for a valid IPv4 / IPv6 address */
if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy)))
{ {
enableSaveButtons(); disableOkButton();
ui->statusLabel->clear(); pUiProxyIp->setValid(false);
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
} }
else else
{ {
disableSaveButtons(); enableOkButton();
object->setValid(fProxyIpValid); ui->statusLabel->clear();
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
} }
} }
@ -282,9 +280,7 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
{ {
if(object == ui->proxyIp) if(object == ui->proxyIp)
{ {
CService addr; emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt());
/* Check proxyIp for a valid IPv4/IPv6 address and emit the proxyIpValid signal */
emit proxyIpValid(ui->proxyIp, LookupNumeric(ui->proxyIp->text().toStdString().c_str(), addr));
} }
} }
return QDialog::eventFilter(object, event); return QDialog::eventFilter(object, event);

27
src/qt/optionsdialog.h

@ -31,35 +31,28 @@ protected:
bool eventFilter(QObject *object, QEvent *event); bool eventFilter(QObject *object, QEvent *event);
private slots: private slots:
/* enable only apply button */ /* enable OK button */
void enableApplyButton(); void enableOkButton();
/* disable only apply button */ /* disable OK button */
void disableApplyButton(); void disableOkButton();
/* enable apply button and OK button */ /* set OK button state (enabled / disabled) */
void enableSaveButtons(); void setOkButtonState(bool fState);
/* disable apply button and OK button */
void disableSaveButtons();
/* set apply button and OK button state (enabled / disabled) */
void setSaveButtonState(bool fState);
void on_resetButton_clicked(); void on_resetButton_clicked();
void on_okButton_clicked(); void on_okButton_clicked();
void on_cancelButton_clicked(); void on_cancelButton_clicked();
void on_applyButton_clicked();
void showRestartWarning_Proxy(); void showRestartWarning(bool fPersistent = false);
void showRestartWarning_Lang(); void clearStatusLabel();
void updateDisplayUnit(); void updateDisplayUnit();
void handleProxyIpValid(QValidatedLineEdit *object, bool fState); void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
signals: signals:
void proxyIpValid(QValidatedLineEdit *object, bool fValid); void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
private: private:
Ui::OptionsDialog *ui; Ui::OptionsDialog *ui;
OptionsModel *model; OptionsModel *model;
MonitoredDataMapper *mapper; MonitoredDataMapper *mapper;
bool fRestartWarningDisplayed_Proxy;
bool fRestartWarningDisplayed_Lang;
bool fProxyIpValid; bool fProxyIpValid;
}; };

287
src/qt/optionsmodel.cpp

@ -18,6 +18,7 @@
#include "walletdb.h" #include "walletdb.h"
#include <QSettings> #include <QSettings>
#include <QStringList>
OptionsModel::OptionsModel(QObject *parent) : OptionsModel::OptionsModel(QObject *parent) :
QAbstractListModel(parent) QAbstractListModel(parent)
@ -25,79 +26,114 @@ OptionsModel::OptionsModel(QObject *parent) :
Init(); Init();
} }
bool static ApplyProxySettings() // Writes all missing QSettings with their default values
{
QSettings settings;
CService addrProxy(settings.value("addrProxy", "127.0.0.1:9050").toString().toStdString());
int nSocksVersion(settings.value("nSocksVersion", 5).toInt());
if (!settings.value("fUseProxy", false).toBool()) {
addrProxy = CService();
nSocksVersion = 0;
return false;
}
if (nSocksVersion && !addrProxy.IsValid())
return false;
if (!IsLimited(NET_IPV4))
SetProxy(NET_IPV4, addrProxy, nSocksVersion);
if (nSocksVersion > 4) {
#ifdef USE_IPV6
if (!IsLimited(NET_IPV6))
SetProxy(NET_IPV6, addrProxy, nSocksVersion);
#endif
SetNameProxy(addrProxy, nSocksVersion);
}
return true;
}
void OptionsModel::Init() void OptionsModel::Init()
{ {
QSettings settings; QSettings settings;
// Ensure restart flag is unset on client startup
setRestartRequired(false);
// These are Qt-only settings: // These are Qt-only settings:
nDisplayUnit = settings.value("nDisplayUnit", BitcoinUnits::BTC).toInt();
// Window
if (!settings.contains("fMinimizeToTray"))
settings.setValue("fMinimizeToTray", false);
fMinimizeToTray = settings.value("fMinimizeToTray").toBool();
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("bDisplayAddresses"))
settings.setValue("bDisplayAddresses", false);
bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool(); bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool();
fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool();
fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool(); if (!settings.contains("fCoinControlFeatures"))
nTransactionFee = settings.value("nTransactionFee").toLongLong(); settings.setValue("fCoinControlFeatures", false);
language = settings.value("language", "").toString();
fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
// These are shared with core Bitcoin; we want // These are shared with the core or have a command-line parameter
// command-line options to override the GUI settings: // and we want command-line parameters to overwrite the GUI settings.
if (settings.contains("fUseUPnP")) //
SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()); // If setting doesn't exist create it with defaults.
if (settings.contains("addrProxy") && settings.value("fUseProxy").toBool()) //
SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()); // If SoftSetArg() or SoftSetBoolArg() return false we were overridden
if (settings.contains("nSocksVersion") && settings.value("fUseProxy").toBool()) // by command-line and show this in the UI.
SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString());
if (!language.isEmpty()) // Main
SoftSetArg("-lang", language.toStdString()); if (!settings.contains("nTransactionFee"))
settings.setValue("nTransactionFee", 0);
if (!settings.contains("nDatabaseCache"))
settings.setValue("nDatabaseCache", 25);
if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString()))
strOverriddenByCommandLine += "-dbcache ";
if (!settings.contains("nThreadsScriptVerif"))
settings.setValue("nThreadsScriptVerif", 0);
if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
strOverriddenByCommandLine += "-par ";
// Network
if (!settings.contains("fUseUPnP"))
#ifdef USE_UPNP
settings.setValue("fUseUPnP", true);
#else
settings.setValue("fUseUPnP", false);
#endif
if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
strOverriddenByCommandLine += "-upnp ";
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()))
strOverriddenByCommandLine += "-proxy ";
if (!settings.contains("nSocksVersion"))
settings.setValue("nSocksVersion", 5);
// Only try to set -socks, if user has enabled fUseProxy
if (settings.value("fUseProxy").toBool() && !SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString()))
strOverriddenByCommandLine += "-socks ";
// Display
if (!settings.contains("language"))
settings.setValue("language", "");
if (!SoftSetArg("-lang", settings.value("language").toString().toStdString()))
strOverriddenByCommandLine += "-lang";
language = settings.value("language").toString();
} }
void OptionsModel::Reset() void OptionsModel::Reset()
{ {
QSettings settings; QSettings settings;
// Remove all entries in this QSettings object // Remove all entries from our QSettings object
settings.clear(); settings.clear();
// default setting for OptionsModel::StartAtStartup - disabled // default setting for OptionsModel::StartAtStartup - disabled
if (GUIUtil::GetStartOnSystemStartup()) if (GUIUtil::GetStartOnSystemStartup())
GUIUtil::SetStartOnSystemStartup(false); GUIUtil::SetStartOnSystemStartup(false);
// Re-Init to get default values
Init();
// Ensure Upgrade() is not running again by setting the bImportFinished flag // Ensure Upgrade() is not running again by setting the bImportFinished flag
settings.setValue("bImportFinished", true); settings.setValue("bImportFinished", true);
} }
bool OptionsModel::Upgrade() void OptionsModel::Upgrade()
{ {
QSettings settings; QSettings settings;
// Already upgraded
if (settings.contains("bImportFinished")) if (settings.contains("bImportFinished"))
return false; // Already upgraded return;
settings.setValue("bImportFinished", true); settings.setValue("bImportFinished", true);
@ -145,18 +181,16 @@ bool OptionsModel::Upgrade()
walletdb.EraseSetting("addrProxy"); walletdb.EraseSetting("addrProxy");
} }
} }
ApplyProxySettings();
Init();
return true; Init();
} }
int OptionsModel::rowCount(const QModelIndex & parent) const int OptionsModel::rowCount(const QModelIndex & parent) const
{ {
return OptionIDRowCount; return OptionIDRowCount;
} }
// read QSettings values and return them
QVariant OptionsModel::data(const QModelIndex & index, int role) const QVariant OptionsModel::data(const QModelIndex & index, int role) const
{ {
if(role == Qt::EditRole) if(role == Qt::EditRole)
@ -165,52 +199,55 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
switch(index.row()) switch(index.row())
{ {
case StartAtStartup: case StartAtStartup:
return QVariant(GUIUtil::GetStartOnSystemStartup()); return GUIUtil::GetStartOnSystemStartup();
case MinimizeToTray: case MinimizeToTray:
return QVariant(fMinimizeToTray); return fMinimizeToTray;
case MapPortUPnP: case MapPortUPnP:
#ifdef USE_UPNP #ifdef USE_UPNP
return settings.value("fUseUPnP", GetBoolArg("-upnp", true)); return settings.value("fUseUPnP");
#else #else
return QVariant(false); return false;
#endif #endif
case MinimizeOnClose: case MinimizeOnClose:
return QVariant(fMinimizeOnClose); return fMinimizeOnClose;
case ProxyUse: {
proxyType proxy; // default proxy
return QVariant(GetProxy(NET_IPV4, proxy)); case ProxyUse:
} return settings.value("fUseProxy", false);
case ProxyIP: { case ProxyIP: {
proxyType proxy; // contains IP at index 0 and port at index 1
if (GetProxy(NET_IPV4, proxy)) QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
return QVariant(QString::fromStdString(proxy.first.ToStringIP())); return strlIpPort.at(0);
else
return QVariant(QString::fromStdString("127.0.0.1"));
} }
case ProxyPort: { case ProxyPort: {
proxyType proxy; // contains IP at index 0 and port at index 1
if (GetProxy(NET_IPV4, proxy)) QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
return QVariant(proxy.first.GetPort()); return strlIpPort.at(1);
else
return QVariant(9050);
}
case ProxySocksVersion: {
proxyType proxy;
if (GetProxy(NET_IPV4, proxy))
return QVariant(proxy.second);
else
return QVariant(5);
} }
case ProxySocksVersion:
return settings.value("nSocksVersion", 5);
case Fee: case Fee:
return QVariant((qint64) nTransactionFee); // Attention: Init() is called before nTransactionFee is set in AppInit2()!
// To ensure we can change the fee on-the-fly update our QSetting when
// opening OptionsDialog, which queries Fee via the mapper.
if (nTransactionFee != settings.value("nTransactionFee").toLongLong())
settings.setValue("nTransactionFee", (qint64)nTransactionFee);
// Todo: Consider to revert back to use just nTransactionFee here, if we don't want
// -paytxfee to update our QSettings!
return settings.value("nTransactionFee");
case DisplayUnit: case DisplayUnit:
return QVariant(nDisplayUnit); return nDisplayUnit;
case DisplayAddresses: case DisplayAddresses:
return QVariant(bDisplayAddresses); return bDisplayAddresses;
case Language: case Language:
return settings.value("language", ""); return settings.value("language");
case CoinControlFeatures: case CoinControlFeatures:
return QVariant(fCoinControlFeatures); return fCoinControlFeatures;
case DatabaseCache:
return settings.value("nDatabaseCache");
case ThreadsScriptVerif:
return settings.value("nThreadsScriptVerif");
default: default:
return QVariant(); return QVariant();
} }
@ -218,6 +255,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return QVariant(); return QVariant();
} }
// write QSettings values
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
{ {
bool successful = true; /* set to false on parse error */ bool successful = true; /* set to false on parse error */
@ -233,7 +271,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
fMinimizeToTray = value.toBool(); fMinimizeToTray = value.toBool();
settings.setValue("fMinimizeToTray", fMinimizeToTray); settings.setValue("fMinimizeToTray", fMinimizeToTray);
break; break;
case MapPortUPnP: case MapPortUPnP: // core option - can be changed on-the-fly
settings.setValue("fUseUPnP", value.toBool()); settings.setValue("fUseUPnP", value.toBool());
MapPort(value.toBool()); MapPort(value.toBool());
break; break;
@ -241,44 +279,50 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
fMinimizeOnClose = value.toBool(); fMinimizeOnClose = value.toBool();
settings.setValue("fMinimizeOnClose", fMinimizeOnClose); settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
break; break;
// default proxy
case ProxyUse: case ProxyUse:
settings.setValue("fUseProxy", value.toBool()); if (settings.value("fUseProxy") != value) {
successful = ApplyProxySettings(); settings.setValue("fUseProxy", value.toBool());
setRestartRequired(true);
}
break; break;
case ProxyIP: { case ProxyIP: {
proxyType proxy; // contains current IP at index 0 and current port at index 1
proxy.first = CService("127.0.0.1", 9050); QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
GetProxy(NET_IPV4, proxy); // if that key doesn't exist or has a changed IP
if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) {
CNetAddr addr(value.toString().toStdString()); // construct new value from new IP and current port
proxy.first.SetIP(addr); QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); settings.setValue("addrProxy", strNewValue);
successful = ApplyProxySettings(); setRestartRequired(true);
}
} }
break; break;
case ProxyPort: { case ProxyPort: {
proxyType proxy; // contains current IP at index 0 and current port at index 1
proxy.first = CService("127.0.0.1", 9050); QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
GetProxy(NET_IPV4, proxy); // if that key doesn't exist or has a changed port
if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) {
proxy.first.SetPort(value.toInt()); // construct new value from current IP and new port
settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
successful = ApplyProxySettings(); settings.setValue("addrProxy", strNewValue);
setRestartRequired(true);
}
} }
break; break;
case ProxySocksVersion: { case ProxySocksVersion: {
proxyType proxy; if (settings.value("nSocksVersion") != value) {
proxy.second = 5; settings.setValue("nSocksVersion", value.toInt());
GetProxy(NET_IPV4, proxy); setRestartRequired(true);
}
proxy.second = value.toInt();
settings.setValue("nSocksVersion", proxy.second);
successful = ApplyProxySettings();
} }
break; break;
case Fee:
case Fee: // core option - can be changed on-the-fly
// Todo: Add is valid check and warn via message, if not
nTransactionFee = value.toLongLong(); nTransactionFee = value.toLongLong();
settings.setValue("nTransactionFee", (qint64) nTransactionFee); settings.setValue("nTransactionFee", (qint64)nTransactionFee);
emit transactionFeeChanged(nTransactionFee); emit transactionFeeChanged(nTransactionFee);
break; break;
case DisplayUnit: case DisplayUnit:
@ -291,13 +335,28 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
settings.setValue("bDisplayAddresses", bDisplayAddresses); settings.setValue("bDisplayAddresses", bDisplayAddresses);
break; break;
case Language: case Language:
settings.setValue("language", value); if (settings.value("language") != value) {
settings.setValue("language", value);
setRestartRequired(true);
}
break; break;
case CoinControlFeatures: case CoinControlFeatures:
fCoinControlFeatures = value.toBool(); fCoinControlFeatures = value.toBool();
settings.setValue("fCoinControlFeatures", fCoinControlFeatures); settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
emit coinControlFeaturesChanged(fCoinControlFeatures); emit coinControlFeaturesChanged(fCoinControlFeatures);
break; 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;
default: default:
break; break;
} }
@ -317,3 +376,15 @@ bool OptionsModel::getProxySettings(QString& proxyIP, quint16 &proxyPort) const
proxyPort = addrProxy.GetPort(); proxyPort = addrProxy.GetPort();
return true; return true;
} }
void OptionsModel::setRestartRequired(bool fRequired)
{
QSettings settings;
return settings.setValue("fRestartRequired", fRequired);
}
bool OptionsModel::isRestartRequired()
{
QSettings settings;
return settings.value("fRestartRequired", false).toBool();
}

17
src/qt/optionsmodel.h

@ -34,6 +34,8 @@ public:
DisplayAddresses, // bool DisplayAddresses, // bool
Language, // QString Language, // QString
CoinControlFeatures, // bool CoinControlFeatures, // bool
ThreadsScriptVerif, // int
DatabaseCache, // int
OptionIDRowCount, OptionIDRowCount,
}; };
@ -41,7 +43,7 @@ public:
void Reset(); void Reset();
/* Migrate settings from wallet.dat after app initialization */ /* Migrate settings from wallet.dat after app initialization */
bool Upgrade(); /* returns true if settings upgraded */ void Upgrade();
int rowCount(const QModelIndex & parent = QModelIndex()) const; int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
@ -52,17 +54,24 @@ public:
bool getMinimizeOnClose() { return fMinimizeOnClose; } bool getMinimizeOnClose() { return fMinimizeOnClose; }
int getDisplayUnit() { return nDisplayUnit; } int getDisplayUnit() { return nDisplayUnit; }
bool getDisplayAddresses() { return bDisplayAddresses; } bool getDisplayAddresses() { return bDisplayAddresses; }
QString getLanguage() { return language; }
bool getProxySettings(QString& proxyIP, quint16 &proxyPort) const; bool getProxySettings(QString& proxyIP, quint16 &proxyPort) const;
bool getCoinControlFeatures() { return fCoinControlFeatures; } bool getCoinControlFeatures() { return fCoinControlFeatures; }
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
/* Restart flag helper */
void setRestartRequired(bool fRequired);
bool isRestartRequired();
private: private:
int nDisplayUnit; /* Qt-only settings */
bool bDisplayAddresses;
bool fMinimizeToTray; bool fMinimizeToTray;
bool fMinimizeOnClose; bool fMinimizeOnClose;
QString language; QString language;
int nDisplayUnit;
bool bDisplayAddresses;
bool fCoinControlFeatures; bool fCoinControlFeatures;
/* settings that were overriden by command-line */
QString strOverriddenByCommandLine;
signals: signals:
void displayUnitChanged(int unit); void displayUnitChanged(int unit);

Loading…
Cancel
Save