2013-11-04 16:20:43 +01:00
|
|
|
// Copyright (c) 2011-2013 The Bitcoin developers
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2013-05-28 01:55:01 +02:00
|
|
|
#if defined(HAVE_CONFIG_H)
|
2014-06-23 20:04:24 +02:00
|
|
|
#include "config/bitcoin-config.h"
|
2013-05-28 01:55:01 +02:00
|
|
|
#endif
|
|
|
|
|
2011-05-12 14:49:42 +02:00
|
|
|
#include "optionsdialog.h"
|
2012-06-08 15:21:55 +02:00
|
|
|
#include "ui_optionsdialog.h"
|
|
|
|
|
2011-07-29 14:36:35 +02:00
|
|
|
#include "bitcoinunits.h"
|
2013-12-03 09:10:10 +01:00
|
|
|
#include "guiutil.h"
|
2012-06-08 15:21:55 +02:00
|
|
|
#include "monitoreddatamapper.h"
|
|
|
|
#include "optionsmodel.h"
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2014-07-03 20:25:32 +02:00
|
|
|
#include "main.h" // for MAX_SCRIPTCHECK_THREADS
|
2014-07-25 17:43:41 +02:00
|
|
|
#include "netbase.h"
|
|
|
|
#include "txdb.h" // for -dbcache defaults
|
2014-07-03 20:25:32 +02:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
#include "wallet.h" // for CWallet::minTxFee
|
|
|
|
#endif
|
2013-04-13 07:13:08 +02:00
|
|
|
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 16:11:09 +02:00
|
|
|
#include <boost/thread.hpp>
|
2012-06-08 15:21:55 +02:00
|
|
|
#include <QDir>
|
|
|
|
#include <QIntValidator>
|
2012-06-25 22:36:16 +02:00
|
|
|
#include <QLocale>
|
2012-05-08 23:03:41 +02:00
|
|
|
#include <QMessageBox>
|
2013-12-03 09:10:10 +01:00
|
|
|
#include <QTimer>
|
2011-06-01 14:40:06 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
OptionsDialog::OptionsDialog(QWidget *parent) :
|
|
|
|
QDialog(parent),
|
|
|
|
ui(new Ui::OptionsDialog),
|
|
|
|
model(0),
|
|
|
|
mapper(0),
|
|
|
|
fProxyIpValid(true)
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
ui->setupUi(this);
|
2013-12-03 09:10:10 +01:00
|
|
|
GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
|
|
|
|
|
|
|
|
/* Main elements init */
|
2014-02-16 22:00:12 +01:00
|
|
|
ui->databaseCache->setMinimum(nMinDbCache);
|
|
|
|
ui->databaseCache->setMaximum(nMaxDbCache);
|
2014-02-18 12:48:16 +01:00
|
|
|
ui->threadsScriptVerif->setMinimum(-(int)boost::thread::hardware_concurrency());
|
|
|
|
ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
|
2012-05-07 21:49:22 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Network elements init */
|
|
|
|
#ifndef USE_UPNP
|
|
|
|
ui->mapPortUpnp->setEnabled(false);
|
2011-10-07 13:21:45 +02:00
|
|
|
#endif
|
2011-07-25 21:35:45 +02:00
|
|
|
|
2012-07-09 11:14:38 +02:00
|
|
|
ui->proxyIp->setEnabled(false);
|
|
|
|
ui->proxyPort->setEnabled(false);
|
|
|
|
ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
|
|
|
|
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
ui->proxyIp->installEventFilter(this);
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Window elements init */
|
2012-09-21 19:06:53 +02:00
|
|
|
#ifdef Q_OS_MAC
|
2013-05-03 15:18:28 +02:00
|
|
|
/* remove Window tab on Mac */
|
|
|
|
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
|
2012-05-10 15:33:01 +02:00
|
|
|
#endif
|
2011-07-25 21:35:45 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Display elements init */
|
|
|
|
QDir translations(":translations");
|
|
|
|
ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
|
|
|
|
foreach(const QString &langStr, translations.entryList())
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2012-06-25 22:36:16 +02:00
|
|
|
QLocale locale(langStr);
|
|
|
|
|
|
|
|
/** check if the locale name consists of 2 parts (language_country) */
|
|
|
|
if(langStr.contains("_"))
|
|
|
|
{
|
2012-07-13 07:43:41 +02:00
|
|
|
#if QT_VERSION >= 0x040800
|
|
|
|
/** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */
|
|
|
|
ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
|
|
|
#else
|
2012-06-25 22:36:16 +02:00
|
|
|
/** display language strings as "language - country (locale name)", e.g. "German - Germany (de)" */
|
|
|
|
ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" - ") + QLocale::countryToString(locale.country()) + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
2012-07-13 07:43:41 +02:00
|
|
|
#endif
|
2012-06-25 22:36:16 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-07-13 07:43:41 +02:00
|
|
|
#if QT_VERSION >= 0x040800
|
|
|
|
/** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */
|
|
|
|
ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
|
|
|
#else
|
2012-06-25 22:36:16 +02:00
|
|
|
/** display language strings as "language (locale name)", e.g. "German (de)" */
|
|
|
|
ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
2012-07-13 07:43:41 +02:00
|
|
|
#endif
|
2012-06-25 22:36:16 +02:00
|
|
|
}
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
2014-04-24 22:21:45 +02:00
|
|
|
#if QT_VERSION >= 0x040700
|
|
|
|
ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");
|
|
|
|
#endif
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
ui->unit->setModel(new BitcoinUnits(this));
|
2014-07-03 20:25:32 +02:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
ui->transactionFee->setSingleStep(CWallet::minTxFee.GetFeePerK());
|
|
|
|
#endif
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2011-06-01 09:33:48 +02:00
|
|
|
/* Widget-to-option mapper */
|
2011-06-01 14:40:06 +02:00
|
|
|
mapper = new MonitoredDataMapper(this);
|
2011-05-31 22:24:53 +02:00
|
|
|
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
|
|
|
mapper->setOrientation(Qt::Vertical);
|
2012-06-08 15:21:55 +02:00
|
|
|
|
2012-07-09 11:14:38 +02:00
|
|
|
/* setup/change UI elements when proxy IP is invalid/valid */
|
2013-12-03 09:10:10 +01:00
|
|
|
connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int)));
|
2012-06-08 15:21:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
OptionsDialog::~OptionsDialog()
|
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
|
2012-06-08 15:21:55 +02:00
|
|
|
delete ui;
|
2011-05-31 22:24:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OptionsDialog::setModel(OptionsModel *model)
|
|
|
|
{
|
|
|
|
this->model = model;
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
if(model)
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
/* 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);
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
|
|
|
|
|
|
|
mapper->setModel(model);
|
|
|
|
setMapper();
|
|
|
|
mapper->toFirst();
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
2011-05-12 14:44:52 +02:00
|
|
|
|
2012-07-09 11:14:38 +02:00
|
|
|
/* update the display unit, to not use the default ("BTC") */
|
2012-06-08 15:21:55 +02:00
|
|
|
updateDisplayUnit();
|
2012-07-09 11:14:38 +02:00
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
/* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
|
2012-08-02 09:02:05 +02:00
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
/* Main */
|
|
|
|
connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
|
|
|
|
connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
|
2014-04-07 19:26:30 +02:00
|
|
|
/* Wallet */
|
|
|
|
connect(ui->spendZeroConfChange, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
|
2013-12-03 09:10:10 +01:00
|
|
|
/* Network */
|
2014-05-29 13:02:22 +02:00
|
|
|
connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
|
2013-12-03 09:10:10 +01:00
|
|
|
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
|
|
|
|
/* Display */
|
|
|
|
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
|
2014-04-24 22:21:45 +02:00
|
|
|
connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));
|
2011-05-12 14:44:52 +02:00
|
|
|
}
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
void OptionsDialog::setMapper()
|
2011-05-12 14:44:52 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Main */
|
|
|
|
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
|
2013-12-03 09:10:10 +01:00
|
|
|
mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
|
|
|
|
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
|
2011-06-01 09:33:48 +02:00
|
|
|
|
2014-02-15 10:38:06 +01:00
|
|
|
/* Wallet */
|
|
|
|
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
|
|
|
|
mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
|
2014-03-17 14:04:56 +01:00
|
|
|
mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);
|
2014-02-15 10:38:06 +01:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Network */
|
|
|
|
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
|
2014-05-29 13:02:22 +02:00
|
|
|
mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
|
2012-07-09 11:14:38 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
|
|
|
|
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
|
|
|
|
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
|
2011-06-01 09:33:48 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Window */
|
2012-10-07 18:50:03 +02:00
|
|
|
#ifndef Q_OS_MAC
|
2012-06-08 15:21:55 +02:00
|
|
|
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
|
|
|
|
mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
|
|
|
|
#endif
|
2011-06-01 09:33:48 +02:00
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
/* Display */
|
|
|
|
mapper->addMapping(ui->lang, OptionsModel::Language);
|
|
|
|
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
|
2014-04-24 22:21:45 +02:00
|
|
|
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
|
2011-06-01 09:33:48 +02:00
|
|
|
}
|
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::enableOkButton()
|
2011-06-01 09:33:48 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
/* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
|
2012-06-08 15:21:55 +02:00
|
|
|
if(fProxyIpValid)
|
2013-12-03 09:10:10 +01:00
|
|
|
setOkButtonState(true);
|
2011-06-01 09:33:48 +02:00
|
|
|
}
|
2011-06-01 14:40:06 +02:00
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::disableOkButton()
|
2011-06-01 14:40:06 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
setOkButtonState(false);
|
2011-06-01 14:40:06 +02:00
|
|
|
}
|
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::setOkButtonState(bool fState)
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
ui->okButton->setEnabled(fState);
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
|
|
|
|
2012-08-18 15:54:39 +02:00
|
|
|
void OptionsDialog::on_resetButton_clicked()
|
|
|
|
{
|
|
|
|
if(model)
|
|
|
|
{
|
|
|
|
// confirmation dialog
|
|
|
|
QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
|
2013-12-03 09:10:10 +01:00
|
|
|
tr("Client restart required to activate changes.") + "<br><br>" + tr("Client will be shutdown, do you want to proceed?"),
|
2012-08-18 15:54:39 +02:00
|
|
|
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
|
|
|
|
|
|
|
|
if(btnRetVal == QMessageBox::Cancel)
|
|
|
|
return;
|
|
|
|
|
2013-12-20 18:47:49 +01:00
|
|
|
/* reset all options and close GUI */
|
2012-08-18 15:54:39 +02:00
|
|
|
model->Reset();
|
2013-12-03 09:10:10 +01:00
|
|
|
QApplication::quit();
|
2012-08-18 15:54:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
void OptionsDialog::on_okButton_clicked()
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
mapper->submit();
|
|
|
|
accept();
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
void OptionsDialog::on_cancelButton_clicked()
|
2011-06-01 14:40:06 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
reject();
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::showRestartWarning(bool fPersistent)
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
|
2012-05-07 21:49:22 +02:00
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
if(fPersistent)
|
|
|
|
{
|
|
|
|
ui->statusLabel->setText(tr("Client restart required to activate changes."));
|
|
|
|
}
|
|
|
|
else
|
2012-05-08 23:03:41 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
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()));
|
2012-05-08 23:03:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::clearStatusLabel()
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
ui->statusLabel->clear();
|
2012-05-07 21:49:22 +02:00
|
|
|
}
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
void OptionsDialog::updateDisplayUnit()
|
2012-05-07 21:49:22 +02:00
|
|
|
{
|
2012-06-08 15:21:55 +02:00
|
|
|
if(model)
|
|
|
|
{
|
2012-07-09 11:14:38 +02:00
|
|
|
/* Update transactionFee with the current unit */
|
2012-06-08 15:21:55 +02:00
|
|
|
ui->transactionFee->setDisplayUnit(model->getDisplayUnit());
|
|
|
|
}
|
2011-06-01 14:40:06 +02:00
|
|
|
}
|
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort)
|
2012-07-09 11:14:38 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
Q_UNUSED(nProxyPort);
|
2012-07-09 11:14:38 +02:00
|
|
|
|
2013-12-03 09:10:10 +01:00
|
|
|
const std::string strAddrProxy = pUiProxyIp->text().toStdString();
|
|
|
|
CService addrProxy;
|
|
|
|
|
|
|
|
/* Check for a valid IPv4 / IPv6 address */
|
|
|
|
if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy)))
|
2012-07-09 11:14:38 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
disableOkButton();
|
|
|
|
pUiProxyIp->setValid(false);
|
|
|
|
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
|
|
|
|
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
|
2012-07-09 11:14:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
enableOkButton();
|
|
|
|
ui->statusLabel->clear();
|
2012-07-09 11:14:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-08 15:21:55 +02:00
|
|
|
bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
|
2011-06-01 14:40:06 +02:00
|
|
|
{
|
2012-07-09 11:14:38 +02:00
|
|
|
if(event->type() == QEvent::FocusOut)
|
2012-06-08 15:21:55 +02:00
|
|
|
{
|
2012-07-09 11:14:38 +02:00
|
|
|
if(object == ui->proxyIp)
|
2012-06-08 15:21:55 +02:00
|
|
|
{
|
2013-12-03 09:10:10 +01:00
|
|
|
emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt());
|
2012-06-08 15:21:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return QDialog::eventFilter(object, event);
|
2011-07-25 21:35:45 +02:00
|
|
|
}
|