From 7e195e8459ad741368db6bb574981fccb1707268 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Tue, 3 Dec 2013 09:10:10 +0100 Subject: [PATCH] [Qt] massive options/settings rework (no core changes) - add new options for database cache and script verification threads - add label which displays options that are overridden by command-line parameters - proxy settings are not applied on-the-fly anymore and require a client restart (ApplyProxySettings() was removed and was not working very well anyway) - re-work options reset and require a client shutdown (as it is much easier to do it this way without having to mess with what can be changed on-the-fly and what needs a restart anyway) - options reset now writes default values for every single option - when changing an option which requires a client restart display a 10 second warning message in statusLabel (via a QTimer) - when applying the changes via ok change that to a persistent message, which is displayed even after closing optionsdialog and re-open it, when no client restart was made - remove dialog boxes used when changing language or proxy settings - add setRestartRequired() and isRestartRequired() to OptionsModel and use the set function when updating options to signal OptionsDialog when a restart is needed - resize optionsdialog a little and add some min sizes for certain GUI elements - remove apply button from optionsdialog - save and restore optionsdialog window position - update nTransactionFee in QSettings with a set -paytxfee value when opening optionsdialog (I'm not sure about this yet, perhaps revert to not updating QSettings and just display current -paytxfee value in optionsdialog.) --- src/qt/forms/optionsdialog.ui | 221 ++++++++++++++++++++------ src/qt/optionsdialog.cpp | 132 ++++++++-------- src/qt/optionsdialog.h | 27 ++-- src/qt/optionsmodel.cpp | 287 +++++++++++++++++++++------------- src/qt/optionsmodel.h | 17 +- 5 files changed, 442 insertions(+), 242 deletions(-) diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 28b629b38..9056ab769 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -6,8 +6,8 @@ 0 0 - 540 - 380 + 560 + 400 @@ -19,9 +19,6 @@ - - QTabWidget::North - 0 @@ -86,21 +83,44 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + + Size of &database cache + + + Qt::PlainText + + + databaseCache + + + + + + + Set database cache size in megabytes (default: 25) + + + 1024 + + + 25 + + + + + + + MB + + + Qt::PlainText + + + @@ -114,21 +134,64 @@ + + + + - - - Reset all client options to default. - + - &Reset Options + Number of script &verification threads - - false + + Qt::PlainText + + + threadsScriptVerif + + + + Set the number of script verification threads (up to 16, 0 = auto, <0 = leave that many cores free, default: 0) + + + -16 + + + 16 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -149,15 +212,15 @@ - Connect to the Bitcoin network through a SOCKS proxy (e.g. when connecting through Tor). + Connect to the Bitcoin network through a SOCKS proxy. - &Connect through SOCKS proxy: + &Connect through SOCKS proxy (default proxy): - + @@ -173,6 +236,12 @@ + + + 140 + 0 + + 140 @@ -180,7 +249,7 @@ - IP address of the proxy (e.g. 127.0.0.1) + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) @@ -199,6 +268,12 @@ + + + 55 + 0 + + 55 @@ -231,7 +306,7 @@ - + Qt::Horizontal @@ -390,8 +465,67 @@ + + + + + + + + + Active command-line options that override above options: + + + Qt::PlainText + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::PlainText + + + true + + + + + + + + + + Reset all client options to default. + + + &Reset Options + + + false + + + @@ -407,6 +541,12 @@ + + + 200 + 0 + + 75 @@ -454,16 +594,6 @@ - - - - &Apply - - - false - - - @@ -473,17 +603,18 @@ BitcoinAmountField QLineEdit
bitcoinamountfield.h
- - - QValueComboBox - QComboBox -
qvaluecombobox.h
+ 1
QValidatedLineEdit QLineEdit
qvalidatedlineedit.h
+ + QValueComboBox + QComboBox +
qvaluecombobox.h
+
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 0a569d16f..d024e3b7a 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -10,6 +10,7 @@ #include "ui_optionsdialog.h" #include "bitcoinunits.h" +#include "guiutil.h" #include "monitoreddatamapper.h" #include "optionsmodel.h" @@ -19,17 +20,20 @@ #include #include #include +#include OptionsDialog::OptionsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::OptionsDialog), model(0), mapper(0), - fRestartWarningDisplayed_Proxy(false), - fRestartWarningDisplayed_Lang(false), fProxyIpValid(true) { ui->setupUi(this); + GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this); + + /* Main elements init */ + ui->databaseCache->setMaximum(sizeof(void*) > 4 ? 4096 : 1024); /* Network elements init */ #ifndef USE_UPNP @@ -40,6 +44,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) : ui->proxyPort->setEnabled(false); 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->addItem("5", 5); ui->socksVersion->addItem("4", 4); @@ -95,16 +100,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) : mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); 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 */ - connect(this, SIGNAL(proxyIpValid(QValidatedLineEdit *, bool)), this, SLOT(handleProxyIpValid(QValidatedLineEdit *, bool))); + connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); } OptionsDialog::~OptionsDialog() { + GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this); delete ui; } @@ -114,6 +116,15 @@ void OptionsDialog::setModel(OptionsModel *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())); mapper->setModel(model); @@ -124,11 +135,15 @@ void OptionsDialog::setModel(OptionsModel *model) /* update the display unit, to not use the default ("BTC") */ updateDisplayUnit(); - /* warn only when language selection changes by user action (placed here so init via mapper doesn't trigger this) */ - connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning_Lang())); + /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ - /* disable apply button after settings are loaded as there is nothing to save */ - disableApplyButton(); + /* Main */ + 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() @@ -136,6 +151,8 @@ void OptionsDialog::setMapper() /* Main */ mapper->addMapping(ui->transactionFee, OptionsModel::Fee); mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup); + mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif); + mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache); /* Network */ mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP); @@ -158,31 +175,20 @@ void OptionsDialog::setMapper() 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) - 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); } @@ -192,24 +198,15 @@ void OptionsDialog::on_resetButton_clicked() { // confirmation dialog QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"), - tr("Some settings may require a client restart to take effect.") + "

" + tr("Do you want to proceed?"), + tr("Client restart required to activate changes.") + "

" + tr("Client will be shutdown, do you want to proceed?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(btnRetVal == QMessageBox::Cancel) return; - disableApplyButton(); - - /* disable restart warning messages display */ - fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = true; - - /* reset all options and save the default values (QSettings) */ + /* reset all options and close Bitcoin-Qt */ model->Reset(); - mapper->toFirst(); - mapper->submit(); - - /* re-enable restart warning messages display */ - fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = false; + QApplication::quit(); } } @@ -224,28 +221,26 @@ void OptionsDialog::on_cancelButton_clicked() reject(); } -void OptionsDialog::on_applyButton_clicked() +void OptionsDialog::showRestartWarning(bool fPersistent) { - mapper->submit(); - disableApplyButton(); -} + ui->statusLabel->setStyleSheet("QLabel { color: red; }"); -void OptionsDialog::showRestartWarning_Proxy() -{ - if(!fRestartWarningDisplayed_Proxy) + if(fPersistent) { - QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok); - fRestartWarningDisplayed_Proxy = true; + ui->statusLabel->setText(tr("Client restart required to activate changes.")); + } + else + { + ui->statusLabel->setText(tr("This change would require a client restart.")); + // 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) - { - QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok); - fRestartWarningDisplayed_Lang = true; - } + ui->statusLabel->clear(); } 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 - fProxyIpValid = fState; + Q_UNUSED(nProxyPort); - 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(); - ui->statusLabel->clear(); + disableOkButton(); + pUiProxyIp->setValid(false); + ui->statusLabel->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); } else { - disableSaveButtons(); - object->setValid(fProxyIpValid); - ui->statusLabel->setStyleSheet("QLabel { color: red; }"); - ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); + enableOkButton(); + ui->statusLabel->clear(); } } @@ -282,9 +280,7 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event) { if(object == ui->proxyIp) { - CService addr; - /* 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)); + emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); } } return QDialog::eventFilter(object, event); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 0181905a8..6b6206966 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -31,35 +31,28 @@ protected: bool eventFilter(QObject *object, QEvent *event); private slots: - /* enable only apply button */ - void enableApplyButton(); - /* disable only apply button */ - void disableApplyButton(); - /* enable apply button and OK button */ - void enableSaveButtons(); - /* disable apply button and OK button */ - void disableSaveButtons(); - /* set apply button and OK button state (enabled / disabled) */ - void setSaveButtonState(bool fState); + /* enable OK button */ + void enableOkButton(); + /* disable OK button */ + void disableOkButton(); + /* set OK button state (enabled / disabled) */ + void setOkButtonState(bool fState); void on_resetButton_clicked(); void on_okButton_clicked(); void on_cancelButton_clicked(); - void on_applyButton_clicked(); - void showRestartWarning_Proxy(); - void showRestartWarning_Lang(); + void showRestartWarning(bool fPersistent = false); + void clearStatusLabel(); void updateDisplayUnit(); - void handleProxyIpValid(QValidatedLineEdit *object, bool fState); + void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); signals: - void proxyIpValid(QValidatedLineEdit *object, bool fValid); + void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); private: Ui::OptionsDialog *ui; OptionsModel *model; MonitoredDataMapper *mapper; - bool fRestartWarningDisplayed_Proxy; - bool fRestartWarningDisplayed_Lang; bool fProxyIpValid; }; diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index b64b0dff8..c7817a94a 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -18,6 +18,7 @@ #include "walletdb.h" #include +#include OptionsModel::OptionsModel(QObject *parent) : QAbstractListModel(parent) @@ -25,79 +26,114 @@ OptionsModel::OptionsModel(QObject *parent) : Init(); } -bool static ApplyProxySettings() -{ - 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; -} - +// Writes all missing QSettings with their default values void OptionsModel::Init() { QSettings settings; + // Ensure restart flag is unset on client startup + setRestartRequired(false); + // 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(); - fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool(); - fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool(); - nTransactionFee = settings.value("nTransactionFee").toLongLong(); - language = settings.value("language", "").toString(); + + if (!settings.contains("fCoinControlFeatures")) + settings.setValue("fCoinControlFeatures", false); fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); - // These are shared with core Bitcoin; we want - // command-line options to override the GUI settings: - if (settings.contains("fUseUPnP")) - SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()); - if (settings.contains("addrProxy") && settings.value("fUseProxy").toBool()) - SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()); - if (settings.contains("nSocksVersion") && settings.value("fUseProxy").toBool()) - SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString()); - if (!language.isEmpty()) - SoftSetArg("-lang", language.toStdString()); + // These are shared with the core or have a command-line parameter + // and we want command-line parameters to overwrite the GUI settings. + // + // If setting doesn't exist create it with defaults. + // + // If SoftSetArg() or SoftSetBoolArg() return false we were overridden + // by command-line and show this in the UI. + + // Main + if (!settings.contains("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() { QSettings settings; - // Remove all entries in this QSettings object + // Remove all entries from our QSettings object settings.clear(); // default setting for OptionsModel::StartAtStartup - disabled if (GUIUtil::GetStartOnSystemStartup()) GUIUtil::SetStartOnSystemStartup(false); - // Re-Init to get default values - Init(); - // Ensure Upgrade() is not running again by setting the bImportFinished flag settings.setValue("bImportFinished", true); } -bool OptionsModel::Upgrade() +void OptionsModel::Upgrade() { QSettings settings; + // Already upgraded if (settings.contains("bImportFinished")) - return false; // Already upgraded + return; settings.setValue("bImportFinished", true); @@ -145,18 +181,16 @@ bool OptionsModel::Upgrade() walletdb.EraseSetting("addrProxy"); } } - ApplyProxySettings(); + Init(); - - return true; } - int OptionsModel::rowCount(const QModelIndex & parent) const { return OptionIDRowCount; } +// read QSettings values and return them QVariant OptionsModel::data(const QModelIndex & index, int role) const { if(role == Qt::EditRole) @@ -165,52 +199,55 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const switch(index.row()) { case StartAtStartup: - return QVariant(GUIUtil::GetStartOnSystemStartup()); + return GUIUtil::GetStartOnSystemStartup(); case MinimizeToTray: - return QVariant(fMinimizeToTray); + return fMinimizeToTray; case MapPortUPnP: #ifdef USE_UPNP - return settings.value("fUseUPnP", GetBoolArg("-upnp", true)); + return settings.value("fUseUPnP"); #else - return QVariant(false); + return false; #endif case MinimizeOnClose: - return QVariant(fMinimizeOnClose); - case ProxyUse: { - proxyType proxy; - return QVariant(GetProxy(NET_IPV4, proxy)); - } + return fMinimizeOnClose; + + // default proxy + case ProxyUse: + return settings.value("fUseProxy", false); case ProxyIP: { - proxyType proxy; - if (GetProxy(NET_IPV4, proxy)) - return QVariant(QString::fromStdString(proxy.first.ToStringIP())); - else - return QVariant(QString::fromStdString("127.0.0.1")); + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(0); } case ProxyPort: { - proxyType proxy; - if (GetProxy(NET_IPV4, proxy)) - return QVariant(proxy.first.GetPort()); - else - return QVariant(9050); - } - case ProxySocksVersion: { - proxyType proxy; - if (GetProxy(NET_IPV4, proxy)) - return QVariant(proxy.second); - else - return QVariant(5); + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(1); } + case ProxySocksVersion: + return settings.value("nSocksVersion", 5); + 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: - return QVariant(nDisplayUnit); + return nDisplayUnit; case DisplayAddresses: - return QVariant(bDisplayAddresses); + return bDisplayAddresses; case Language: - return settings.value("language", ""); + return settings.value("language"); case CoinControlFeatures: - return QVariant(fCoinControlFeatures); + return fCoinControlFeatures; + case DatabaseCache: + return settings.value("nDatabaseCache"); + case ThreadsScriptVerif: + return settings.value("nThreadsScriptVerif"); default: return QVariant(); } @@ -218,6 +255,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return QVariant(); } +// write QSettings values bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) { bool successful = true; /* set to false on parse error */ @@ -233,7 +271,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in fMinimizeToTray = value.toBool(); settings.setValue("fMinimizeToTray", fMinimizeToTray); break; - case MapPortUPnP: + case MapPortUPnP: // core option - can be changed on-the-fly settings.setValue("fUseUPnP", value.toBool()); MapPort(value.toBool()); break; @@ -241,44 +279,50 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in fMinimizeOnClose = value.toBool(); settings.setValue("fMinimizeOnClose", fMinimizeOnClose); break; + + // default proxy case ProxyUse: - settings.setValue("fUseProxy", value.toBool()); - successful = ApplyProxySettings(); + if (settings.value("fUseProxy") != value) { + settings.setValue("fUseProxy", value.toBool()); + setRestartRequired(true); + } break; case ProxyIP: { - proxyType proxy; - proxy.first = CService("127.0.0.1", 9050); - GetProxy(NET_IPV4, proxy); - - CNetAddr addr(value.toString().toStdString()); - proxy.first.SetIP(addr); - settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); - successful = ApplyProxySettings(); + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed IP + if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) { + // construct new value from new IP and current port + QString strNewValue = value.toString() + ":" + strlIpPort.at(1); + settings.setValue("addrProxy", strNewValue); + setRestartRequired(true); + } } break; case ProxyPort: { - proxyType proxy; - proxy.first = CService("127.0.0.1", 9050); - GetProxy(NET_IPV4, proxy); - - proxy.first.SetPort(value.toInt()); - settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); - successful = ApplyProxySettings(); + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed port + if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) { + // construct new value from current IP and new port + QString strNewValue = strlIpPort.at(0) + ":" + value.toString(); + settings.setValue("addrProxy", strNewValue); + setRestartRequired(true); + } } break; case ProxySocksVersion: { - proxyType proxy; - proxy.second = 5; - GetProxy(NET_IPV4, proxy); - - proxy.second = value.toInt(); - settings.setValue("nSocksVersion", proxy.second); - successful = ApplyProxySettings(); + if (settings.value("nSocksVersion") != value) { + settings.setValue("nSocksVersion", value.toInt()); + setRestartRequired(true); + } } 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(); - settings.setValue("nTransactionFee", (qint64) nTransactionFee); + settings.setValue("nTransactionFee", (qint64)nTransactionFee); emit transactionFeeChanged(nTransactionFee); break; case DisplayUnit: @@ -291,13 +335,28 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in settings.setValue("bDisplayAddresses", bDisplayAddresses); break; case Language: - settings.setValue("language", value); + if (settings.value("language") != value) { + settings.setValue("language", value); + setRestartRequired(true); + } break; case CoinControlFeatures: fCoinControlFeatures = value.toBool(); settings.setValue("fCoinControlFeatures", fCoinControlFeatures); emit coinControlFeaturesChanged(fCoinControlFeatures); break; + case DatabaseCache: + if (settings.value("nDatabaseCache") != value) { + settings.setValue("nDatabaseCache", value); + setRestartRequired(true); + } + break; + case ThreadsScriptVerif: + if (settings.value("nThreadsScriptVerif") != value) { + settings.setValue("nThreadsScriptVerif", value); + setRestartRequired(true); + } + break; default: break; } @@ -317,3 +376,15 @@ bool OptionsModel::getProxySettings(QString& proxyIP, quint16 &proxyPort) const proxyPort = addrProxy.GetPort(); 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(); +} diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index a50153c76..d05cb4674 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -34,6 +34,8 @@ public: DisplayAddresses, // bool Language, // QString CoinControlFeatures, // bool + ThreadsScriptVerif, // int + DatabaseCache, // int OptionIDRowCount, }; @@ -41,7 +43,7 @@ public: void Reset(); /* Migrate settings from wallet.dat after app initialization */ - bool Upgrade(); /* returns true if settings upgraded */ + void Upgrade(); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; @@ -52,17 +54,24 @@ public: bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } bool getDisplayAddresses() { return bDisplayAddresses; } - QString getLanguage() { return language; } bool getProxySettings(QString& proxyIP, quint16 &proxyPort) const; bool getCoinControlFeatures() { return fCoinControlFeatures; } + const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } + + /* Restart flag helper */ + void setRestartRequired(bool fRequired); + bool isRestartRequired(); private: - int nDisplayUnit; - bool bDisplayAddresses; + /* Qt-only settings */ bool fMinimizeToTray; bool fMinimizeOnClose; QString language; + int nDisplayUnit; + bool bDisplayAddresses; bool fCoinControlFeatures; + /* settings that were overriden by command-line */ + QString strOverriddenByCommandLine; signals: void displayUnitChanged(int unit);