Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14864486
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Subscribers
None
View Options
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
index 923b17e66d..25ad0c66af 100644
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -1,184 +1,186 @@
// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinamountfield.h"
#include "bitcoinunits.h"
#include "guiconstants.h"
#include "qvaluecombobox.h"
#include <QApplication>
#include <QDoubleSpinBox>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <qmath.h> // for qPow()
BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
QWidget(parent),
amount(0),
currentUnit(-1)
{
+ nSingleStep = 100000; // satoshis
+
amount = new QDoubleSpinBox(this);
amount->setLocale(QLocale::c());
- amount->setDecimals(8);
amount->installEventFilter(this);
amount->setMaximumWidth(170);
- amount->setSingleStep(0.001);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(amount);
unit = new QValueComboBox(this);
unit->setModel(new BitcoinUnits(this));
layout->addWidget(unit);
layout->addStretch(1);
layout->setContentsMargins(0,0,0,0);
setLayout(layout);
setFocusPolicy(Qt::TabFocus);
setFocusProxy(amount);
// If one if the widgets changes, the combined content changes as well
connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
// Set default based on configuration
unitChanged(unit->currentIndex());
}
void BitcoinAmountField::setText(const QString &text)
{
if (text.isEmpty())
amount->clear();
else
amount->setValue(text.toDouble());
}
void BitcoinAmountField::clear()
{
amount->clear();
unit->setCurrentIndex(0);
}
bool BitcoinAmountField::validate()
{
bool valid = true;
if (amount->value() == 0.0)
valid = false;
else if (!BitcoinUnits::parse(currentUnit, text(), 0))
valid = false;
else if (amount->value() > BitcoinUnits::maxAmount(currentUnit))
valid = false;
setValid(valid);
return valid;
}
void BitcoinAmountField::setValid(bool valid)
{
if (valid)
amount->setStyleSheet("");
else
amount->setStyleSheet(STYLE_INVALID);
}
QString BitcoinAmountField::text() const
{
if (amount->text().isEmpty())
return QString();
else
return amount->text();
}
bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::FocusIn)
{
// Clear invalid flag on focus
setValid(true);
}
else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Comma)
{
// Translate a comma into a period
QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
QApplication::sendEvent(object, &periodKeyEvent);
return true;
}
}
return QWidget::eventFilter(object, event);
}
QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
{
QWidget::setTabOrder(prev, amount);
QWidget::setTabOrder(amount, unit);
return unit;
}
qint64 BitcoinAmountField::value(bool *valid_out) const
{
qint64 val_out = 0;
bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
if (valid_out)
{
*valid_out = valid;
}
return val_out;
}
void BitcoinAmountField::setValue(qint64 value)
{
setText(BitcoinUnits::format(currentUnit, value));
}
void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
amount->setReadOnly(fReadOnly);
unit->setEnabled(!fReadOnly);
}
void BitcoinAmountField::unitChanged(int idx)
{
// Use description tooltip for current unit for the combobox
unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
// Determine new unit ID
int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
// Parse current value and convert to new unit
bool valid = false;
qint64 currentValue = value(&valid);
currentUnit = newUnit;
// Set max length after retrieving the value, to prevent truncation
amount->setDecimals(BitcoinUnits::decimals(currentUnit));
amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
-
- if (currentUnit == BitcoinUnits::uBTC)
- amount->setSingleStep(0.01);
- else
- amount->setSingleStep(0.001);
+ amount->setSingleStep((double)nSingleStep / (double)BitcoinUnits::factor(currentUnit));
if (valid)
{
// If value was valid, re-place it in the widget with the new unit
setValue(currentValue);
}
else
{
// If current value is invalid, just clear field
setText("");
}
setValid(true);
}
void BitcoinAmountField::setDisplayUnit(int newUnit)
{
unit->setValue(newUnit);
}
+
+void BitcoinAmountField::setSingleStep(qint64 step)
+{
+ nSingleStep = step;
+ unitChanged(unit->currentIndex());
+}
diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h
index d54f536b1f..521a9ed561 100644
--- a/src/qt/bitcoinamountfield.h
+++ b/src/qt/bitcoinamountfield.h
@@ -1,68 +1,72 @@
// 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.
#ifndef BITCOINAMOUNTFIELD_H
#define BITCOINAMOUNTFIELD_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QDoubleSpinBox;
class QValueComboBox;
QT_END_NAMESPACE
/** Widget for entering bitcoin amounts.
*/
class BitcoinAmountField: public QWidget
{
Q_OBJECT
Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true)
public:
explicit BitcoinAmountField(QWidget *parent = 0);
qint64 value(bool *valid=0) const;
void setValue(qint64 value);
+ /** Set single step in satoshis **/
+ void setSingleStep(qint64 step);
+
/** Make read-only **/
void setReadOnly(bool fReadOnly);
/** Mark current value as invalid in UI. */
void setValid(bool valid);
/** Perform input validation, mark field as invalid if entered value is not valid. */
bool validate();
/** Change unit used to display amount. */
void setDisplayUnit(int unit);
/** Make field empty and ready for new input. */
void clear();
/** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907),
in these cases we have to set it up manually.
*/
QWidget *setupTabChain(QWidget *prev);
signals:
void textChanged();
protected:
/** Intercept focus-in event and ',' key presses */
bool eventFilter(QObject *object, QEvent *event);
private:
QDoubleSpinBox *amount;
QValueComboBox *unit;
int currentUnit;
+ qint64 nSingleStep;
void setText(const QString &text);
QString text() const;
private slots:
void unitChanged(int idx);
};
#endif // BITCOINAMOUNTFIELD_H
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 317e1db7d3..f4eb7ef07e 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -1,289 +1,291 @@
// 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.
#if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h"
#endif
#include "optionsdialog.h"
#include "ui_optionsdialog.h"
#include "bitcoinunits.h"
#include "guiutil.h"
#include "monitoreddatamapper.h"
#include "optionsmodel.h"
#include "netbase.h"
+#include "main.h"
#include <QDir>
#include <QIntValidator>
#include <QLocale>
#include <QMessageBox>
#include <QTimer>
OptionsDialog::OptionsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::OptionsDialog),
model(0),
mapper(0),
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
ui->mapPortUpnp->setEnabled(false);
#endif
ui->proxyIp->setEnabled(false);
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);
ui->socksVersion->setCurrentIndex(0);
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->socksVersion, SLOT(setEnabled(bool)));
ui->proxyIp->installEventFilter(this);
/* Window elements init */
#ifdef Q_OS_MAC
/* remove Window tab on Mac */
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
#endif
/* Display elements init */
QDir translations(":translations");
ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
foreach(const QString &langStr, translations.entryList())
{
QLocale locale(langStr);
/** check if the locale name consists of 2 parts (language_country) */
if(langStr.contains("_"))
{
#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
/** 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));
#endif
}
else
{
#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
/** display language strings as "language (locale name)", e.g. "German (de)" */
ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr));
#endif
}
}
ui->unit->setModel(new BitcoinUnits(this));
+ ui->transactionFee->setSingleStep(CTransaction::nMinTxFee);
/* Widget-to-option mapper */
mapper = new MonitoredDataMapper(this);
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical);
/* setup/change UI elements when proxy IP is invalid/valid */
connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int)));
}
OptionsDialog::~OptionsDialog()
{
GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
delete ui;
}
void OptionsDialog::setModel(OptionsModel *model)
{
this->model = 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);
setMapper();
mapper->toFirst();
}
/* update the display unit, to not use the default ("BTC") */
updateDisplayUnit();
/* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
/* 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()
{
/* Main */
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
/* Wallet */
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
/* Network */
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
mapper->addMapping(ui->socksVersion, OptionsModel::ProxySocksVersion);
/* Window */
#ifndef Q_OS_MAC
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
#endif
/* Display */
mapper->addMapping(ui->lang, OptionsModel::Language);
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses);
mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);
}
void OptionsDialog::enableOkButton()
{
/* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
if(fProxyIpValid)
setOkButtonState(true);
}
void OptionsDialog::disableOkButton()
{
setOkButtonState(false);
}
void OptionsDialog::setOkButtonState(bool fState)
{
ui->okButton->setEnabled(fState);
}
void OptionsDialog::on_resetButton_clicked()
{
if(model)
{
// confirmation dialog
QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
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);
if(btnRetVal == QMessageBox::Cancel)
return;
/* reset all options and close GUI */
model->Reset();
QApplication::quit();
}
}
void OptionsDialog::on_okButton_clicked()
{
mapper->submit();
accept();
}
void OptionsDialog::on_cancelButton_clicked()
{
reject();
}
void OptionsDialog::showRestartWarning(bool fPersistent)
{
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
if(fPersistent)
{
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::clearStatusLabel()
{
ui->statusLabel->clear();
}
void OptionsDialog::updateDisplayUnit()
{
if(model)
{
/* Update transactionFee with the current unit */
ui->transactionFee->setDisplayUnit(model->getDisplayUnit());
}
}
void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort)
{
Q_UNUSED(nProxyPort);
const std::string strAddrProxy = pUiProxyIp->text().toStdString();
CService addrProxy;
/* Check for a valid IPv4 / IPv6 address */
if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy)))
{
disableOkButton();
pUiProxyIp->setValid(false);
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
}
else
{
enableOkButton();
ui->statusLabel->clear();
}
}
bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
{
if(event->type() == QEvent::FocusOut)
{
if(object == ui->proxyIp)
{
emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt());
}
}
return QDialog::eventFilter(object, event);
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, May 21, 20:01 (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5865834
Default Alt Text
(17 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment