Set the base used to display the spin box value

Provide a new displayIntegerBase property which control the base used
by the spin box to display the value in its internal line edit.

Change-Id: Ibadc37107db8770d757b64350946bf19142e8f6c
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
Kevin Ottens 2013-04-25 17:36:17 +02:00 committed by The Qt Project
parent 44c47af950
commit 48e3cc30ed
4 changed files with 127 additions and 8 deletions

View File

@ -94,6 +94,14 @@ void Window::createSpinBoxes()
priceSpinBox->setValue(99);
//! [4] //! [5]
QLabel *hexLabel = new QLabel(tr("Enter a value between "
"%1 and %2:").arg('-' + QString::number(31, 16)).arg(QString::number(31, 16)));
QSpinBox *hexSpinBox = new QSpinBox;
hexSpinBox->setRange(-31, 31);
hexSpinBox->setSingleStep(1);
hexSpinBox->setValue(0);
hexSpinBox->setDisplayIntegerBase(16);
QVBoxLayout *spinBoxLayout = new QVBoxLayout;
spinBoxLayout->addWidget(integerLabel);
spinBoxLayout->addWidget(integerSpinBox);
@ -101,6 +109,8 @@ void Window::createSpinBoxes()
spinBoxLayout->addWidget(zoomSpinBox);
spinBoxLayout->addWidget(priceLabel);
spinBoxLayout->addWidget(priceSpinBox);
spinBoxLayout->addWidget(hexLabel);
spinBoxLayout->addWidget(hexSpinBox);
spinBoxesGroup->setLayout(spinBoxLayout);
}
//! [5]

View File

@ -78,6 +78,8 @@ public:
q->setInputMethodHints(Qt::ImhDigitsOnly);
setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
}
int displayIntegerBase;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@ -424,6 +426,38 @@ void QSpinBox::setRange(int minimum, int maximum)
d->setRange(QVariant(minimum), QVariant(maximum));
}
/*!
\property QSpinBox::displayIntegerBase
\brief the base used to display the value of the spin box
The default displayIntegerBase value is 10.
\sa textFromValue(), valueFromText()
\since 5.2
*/
int QSpinBox::displayIntegerBase() const
{
Q_D(const QSpinBox);
return d->displayIntegerBase;
}
void QSpinBox::setDisplayIntegerBase(int base)
{
Q_D(QSpinBox);
// Falls back to base 10 on invalid bases (like QString)
if (base < 2 || base > 36) {
qWarning("QSpinBox::setDisplayIntegerBase: Invalid base (%d)", base);
base = 10;
}
if (base != d->displayIntegerBase) {
d->displayIntegerBase = base;
d->updateEdit();
}
}
/*!
This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a
@ -444,9 +478,18 @@ void QSpinBox::setRange(int minimum, int maximum)
QString QSpinBox::textFromValue(int value) const
{
QString str = locale().toString(value);
if (qAbs(value) >= 1000 || value == INT_MIN) {
str.remove(locale().groupSeparator());
Q_D(const QSpinBox);
QString str;
if (d->displayIntegerBase != 10) {
str = QString::number(qAbs(value), d->displayIntegerBase);
if (value < 0)
str.prepend('-');
} else {
str = locale().toString(value);
if (qAbs(value) >= 1000 || value == INT_MIN) {
str.remove(locale().groupSeparator());
}
}
return str;
@ -926,6 +969,7 @@ QSpinBoxPrivate::QSpinBoxPrivate()
minimum = QVariant((int)0);
maximum = QVariant((int)99);
value = minimum;
displayIntegerBase = 10;
singleStep = QVariant((int)1);
type = QVariant::Int;
}
@ -1003,11 +1047,15 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
} else {
bool ok = false;
num = locale.toInt(copy, &ok);
if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
QString copy2 = copy;
copy2.remove(locale.groupSeparator());
num = locale.toInt(copy2, &ok);
if (displayIntegerBase != 10) {
num = copy.toInt(&ok, displayIntegerBase);
} else {
num = locale.toInt(copy, &ok);
if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
QString copy2 = copy;
copy2.remove(locale.groupSeparator());
num = locale.toInt(copy2, &ok);
}
}
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
if (!ok) {

View File

@ -61,6 +61,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
public:
explicit QSpinBox(QWidget *parent = 0);
@ -87,6 +88,8 @@ public:
void setRange(int min, int max);
int displayIntegerBase() const;
void setDisplayIntegerBase(int base);
protected:
bool event(QEvent *event);

View File

@ -98,6 +98,9 @@ private slots:
void setValue_data();
void setValue();
void setDisplayIntegerBase_data();
void setDisplayIntegerBase();
void setPrefixSuffix_data();
void setPrefixSuffix();
@ -274,6 +277,61 @@ void tst_QSpinBox::setValue()
QCOMPARE(spin.value(), expected);
}
void tst_QSpinBox::setDisplayIntegerBase_data()
{
QTest::addColumn<int>("value");
QTest::addColumn<int>("base");
QTest::addColumn<QString>("string");
QTest::newRow("base 10") << 42 << 10 << "42";
QTest::newRow("base 2") << 42 << 2 << "101010";
QTest::newRow("base 8") << 42 << 8 << "52";
QTest::newRow("base 16") << 42 << 16 << "2a";
QTest::newRow("base 0") << 42 << 0 << "42";
QTest::newRow("base -4") << 42 << -4 << "42";
QTest::newRow("base 40") << 42 << 40 << "42";
QTest::newRow("negative base 10") << -42 << 10 << "-42";
QTest::newRow("negative base 2") << -42 << 2 << "-101010";
QTest::newRow("negative base 8") << -42 << 8 << "-52";
QTest::newRow("negative base 16") << -42 << 16 << "-2a";
QTest::newRow("negative base 0") << -42 << 0 << "-42";
QTest::newRow("negative base -4") << -42 << -4 << "-42";
QTest::newRow("negative base 40") << -42 << 40 << "-42";
QTest::newRow("0 base 10") << 0 << 10 << "0";
QTest::newRow("0 base 2") << 0 << 2 << "0";
QTest::newRow("0 base 8") << 0 << 8 << "0";
QTest::newRow("0 base 16") << 0 << 16 << "0";
QTest::newRow("0 base 0") << 0 << 0 << "0";
QTest::newRow("0 base -4") << 0 << -4 << "0";
QTest::newRow("0 base 40") << 0 << 40 << "0";
}
void tst_QSpinBox::setDisplayIntegerBase()
{
QFETCH(int, value);
QFETCH(int, base);
QFETCH(QString, string);
SpinBox spin;
spin.setRange(INT_MIN, INT_MAX);
spin.setValue(value);
QCOMPARE(spin.lineEdit()->text(), QString::number(value));
spin.setDisplayIntegerBase(base);
QCOMPARE(spin.lineEdit()->text(), string);
spin.setValue(0);
QCOMPARE(spin.value(), 0);
QCOMPARE(spin.lineEdit()->text(), QString::number(0, base));
spin.lineEdit()->clear();
QTest::keyClicks(spin.lineEdit(), string);
QCOMPARE(spin.value(), value);
}
void tst_QSpinBox::setPrefixSuffix_data()
{
QTest::addColumn<QString>("prefix");