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); priceSpinBox->setValue(99);
//! [4] //! [5] //! [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; QVBoxLayout *spinBoxLayout = new QVBoxLayout;
spinBoxLayout->addWidget(integerLabel); spinBoxLayout->addWidget(integerLabel);
spinBoxLayout->addWidget(integerSpinBox); spinBoxLayout->addWidget(integerSpinBox);
@ -101,6 +109,8 @@ void Window::createSpinBoxes()
spinBoxLayout->addWidget(zoomSpinBox); spinBoxLayout->addWidget(zoomSpinBox);
spinBoxLayout->addWidget(priceLabel); spinBoxLayout->addWidget(priceLabel);
spinBoxLayout->addWidget(priceSpinBox); spinBoxLayout->addWidget(priceSpinBox);
spinBoxLayout->addWidget(hexLabel);
spinBoxLayout->addWidget(hexSpinBox);
spinBoxesGroup->setLayout(spinBoxLayout); spinBoxesGroup->setLayout(spinBoxLayout);
} }
//! [5] //! [5]

View File

@ -78,6 +78,8 @@ public:
q->setInputMethodHints(Qt::ImhDigitsOnly); q->setInputMethodHints(Qt::ImhDigitsOnly);
setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem); setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
} }
int displayIntegerBase;
}; };
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@ -424,6 +426,38 @@ void QSpinBox::setRange(int minimum, int maximum)
d->setRange(QVariant(minimum), QVariant(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 This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a 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 QSpinBox::textFromValue(int value) const
{ {
QString str = locale().toString(value); Q_D(const QSpinBox);
if (qAbs(value) >= 1000 || value == INT_MIN) { QString str;
str.remove(locale().groupSeparator());
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; return str;
@ -926,6 +969,7 @@ QSpinBoxPrivate::QSpinBoxPrivate()
minimum = QVariant((int)0); minimum = QVariant((int)0);
maximum = QVariant((int)99); maximum = QVariant((int)99);
value = minimum; value = minimum;
displayIntegerBase = 10;
singleStep = QVariant((int)1); singleStep = QVariant((int)1);
type = QVariant::Int; 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 state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
} else { } else {
bool ok = false; bool ok = false;
num = locale.toInt(copy, &ok); if (displayIntegerBase != 10) {
if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) { num = copy.toInt(&ok, displayIntegerBase);
QString copy2 = copy; } else {
copy2.remove(locale.groupSeparator()); num = locale.toInt(copy, &ok);
num = locale.toInt(copy2, &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; QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
if (!ok) { 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 maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep) Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true) Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
public: public:
explicit QSpinBox(QWidget *parent = 0); explicit QSpinBox(QWidget *parent = 0);
@ -87,6 +88,8 @@ public:
void setRange(int min, int max); void setRange(int min, int max);
int displayIntegerBase() const;
void setDisplayIntegerBase(int base);
protected: protected:
bool event(QEvent *event); bool event(QEvent *event);

View File

@ -98,6 +98,9 @@ private slots:
void setValue_data(); void setValue_data();
void setValue(); void setValue();
void setDisplayIntegerBase_data();
void setDisplayIntegerBase();
void setPrefixSuffix_data(); void setPrefixSuffix_data();
void setPrefixSuffix(); void setPrefixSuffix();
@ -274,6 +277,61 @@ void tst_QSpinBox::setValue()
QCOMPARE(spin.value(), expected); 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() void tst_QSpinBox::setPrefixSuffix_data()
{ {
QTest::addColumn<QString>("prefix"); QTest::addColumn<QString>("prefix");