summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qspinbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qspinbox.cpp')
-rw-r--r--src/widgets/widgets/qspinbox.cpp173
1 files changed, 77 insertions, 96 deletions
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 7624b1ed3c..73946d54a9 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <private/qabstractspinbox_p.h>
#include <qspinbox.h>
@@ -51,6 +15,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
//#define QSPINBOX_QSBDEBUG
#ifdef QSPINBOX_QSBDEBUG
# define QSBDEBUG qDebug
@@ -128,9 +94,10 @@ public:
manually. The spin box supports integer values but can be extended to
use different strings with validate(), textFromValue() and valueFromText().
- Every time the value changes QSpinBox emits two valueChanged() signals,
- one providing an int and the other a QString. The QString overload
- provides the value with both prefix() and suffix().
+ Every time the value changes QSpinBox emits valueChanged() and
+ textChanged() signals, the former providing a int and the latter
+ a QString. The textChanged() signal provides the value with both
+ prefix() and suffix().
The current value can be fetched with value() and set with setValue().
Clicking the up/down buttons or using the keyboard accelerator's
@@ -165,12 +132,9 @@ public:
for a custom spin box that allows the user to enter icon sizes
(e.g., "32 x 32"):
- \snippet widgets/icons/iconsizespinbox.cpp 1
+ \snippet code/src_gui_widgets_qspinbox.cpp 8
\codeline
- \snippet widgets/icons/iconsizespinbox.cpp 2
-
- See the \l{widgets/icons}{Icons} example for the full source
- code.
+ \snippet code/src_gui_widgets_qspinbox.cpp 9
\sa QDoubleSpinBox, QDateTimeEdit, QSlider, {Spin Boxes Example}
*/
@@ -183,11 +147,11 @@ public:
*/
/*!
- \fn void QSpinBox::valueChanged(const QString &text)
+ \fn void QSpinBox::textChanged(const QString &text)
+ \since 5.14
- \overload
-
- The new value is passed in \a text with prefix() and suffix().
+ This signal is emitted whenever the spin box's text is changed.
+ The new text is passed in \a text with prefix() and suffix().
*/
/*!
@@ -372,7 +336,7 @@ void QSpinBox::setMinimum(int minimum)
{
Q_D(QSpinBox);
const QVariant m(minimum);
- d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));
+ d->setRange(m, (QSpinBoxPrivate::variantCompare(d->maximum, m) > 0 ? d->maximum : m));
}
/*!
@@ -400,7 +364,7 @@ void QSpinBox::setMaximum(int maximum)
{
Q_D(QSpinBox);
const QVariant m(maximum);
- d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
+ d->setRange((QSpinBoxPrivate::variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
}
/*!
@@ -517,7 +481,7 @@ QString QSpinBox::textFromValue(int value) const
QString str;
if (d->displayIntegerBase != 10) {
- const QLatin1String prefix = value < 0 ? QLatin1String("-") : QLatin1String();
+ const auto prefix = value < 0 ? "-"_L1 : ""_L1;
str = prefix + QString::number(qAbs(value), d->displayIntegerBase);
} else {
str = locale().toString(value);
@@ -594,9 +558,9 @@ void QSpinBox::fixup(QString &input) const
values but can be extended to use different strings with
validate(), textFromValue() and valueFromText().
- Every time the value changes QDoubleSpinBox emits two
- valueChanged() signals, one taking providing a double and the other
- a QString. The QString overload provides the value with both
+ Every time the value changes QDoubleSpinBox emits valueChanged() and
+ textChanged() signals, the former providing a double and the latter
+ a QString. The textChanged() signal provides the value with both
prefix() and suffix(). The current value can be fetched with
value() and set with setValue().
@@ -644,11 +608,11 @@ void QSpinBox::fixup(QString &input) const
*/
/*!
- \fn void QDoubleSpinBox::valueChanged(const QString &text);
-
- \overload
+ \fn void QDoubleSpinBox::textChanged(const QString &text)
+ \since 5.14
- The new value is passed in \a text with prefix() and suffix().
+ This signal is emitted whenever the spin box's text is changed.
+ The new text is passed in \a text with prefix() and suffix().
*/
/*!
@@ -728,6 +692,10 @@ void QDoubleSpinBox::setPrefix(const QString &prefix)
d->prefix = prefix;
d->updateEdit();
+
+ d->cachedSizeHint = QSize();
+ d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix
+ updateGeometry();
}
/*!
@@ -837,7 +805,7 @@ void QDoubleSpinBox::setMinimum(double minimum)
Q_D(QDoubleSpinBox);
d->actualMin = minimum;
const QVariant m(d->round(minimum));
- d->setRange(m, (d->variantCompare(d->maximum, m) > 0 ? d->maximum : m));
+ d->setRange(m, (QDoubleSpinBoxPrivate::variantCompare(d->maximum, m) > 0 ? d->maximum : m));
}
/*!
@@ -868,7 +836,7 @@ void QDoubleSpinBox::setMaximum(double maximum)
Q_D(QDoubleSpinBox);
d->actualMax = maximum;
const QVariant m(d->round(maximum));
- d->setRange((d->variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
+ d->setRange((QDoubleSpinBoxPrivate::variantCompare(d->minimum, m) < 0 ? d->minimum : m), m);
}
/*!
@@ -972,9 +940,8 @@ void QDoubleSpinBox::setDecimals(int decimals)
This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a string
containing \a value printed using QWidget::locale().toString(\a value,
- QLatin1Char('f'), decimals()) and will remove the thousand
- separator unless setGroupSeparatorShown() is set. Reimplementations may
- return anything.
+ \c u'f', decimals()) and will remove the thousand separator unless
+ setGroupSeparatorShown() is set. Reimplementations may return anything.
Note: QDoubleSpinBox does not call this function for
specialValueText() and that neither prefix() nor suffix() should
@@ -1054,7 +1021,7 @@ QSpinBoxPrivate::QSpinBoxPrivate()
value = minimum;
displayIntegerBase = 10;
singleStep = QVariant((int)1);
- type = QVariant::Int;
+ type = QMetaType::Int;
}
/*!
@@ -1068,7 +1035,7 @@ void QSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
if (ep != NeverEmit) {
pendingEmit = false;
if (ep == AlwaysEmit || value != old) {
- emit q->valueChanged(edit->displayText());
+ emit q->textChanged(edit->displayText());
emit q->valueChanged(value.toInt());
}
}
@@ -1122,11 +1089,11 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
int num = min;
if (max != min && (copy.isEmpty()
- || (min < 0 && copy == QLatin1String("-"))
- || (max >= 0 && copy == QLatin1String("+")))) {
+ || (min < 0 && copy == "-"_L1)
+ || (max >= 0 && copy == "+"_L1))) {
state = QValidator::Intermediate;
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
- } else if (copy.startsWith(QLatin1Char('-')) && min >= 0) {
+ } else if (copy.startsWith(u'-') && min >= 0) {
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;
@@ -1135,11 +1102,11 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
} else {
num = locale.toInt(copy, &ok);
if (!ok && (max >= 1000 || min <= -1000)) {
- const QChar sep = locale.groupSeparator();
- const QChar doubleSep[2] = {sep, sep};
- if (copy.contains(sep) && !copy.contains(QString(doubleSep, 2))) {
+ const QString sep(locale.groupSeparator());
+ const QString doubleSep = sep + sep;
+ if (copy.contains(sep) && !copy.contains(doubleSep)) {
QString copy2 = copy;
- copy2.remove(locale.groupSeparator());
+ copy2.remove(sep);
num = locale.toInt(copy2, &ok);
}
}
@@ -1205,7 +1172,7 @@ QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate()
value = minimum;
singleStep = QVariant(1.0);
decimals = 2;
- type = QVariant::Double;
+ type = QMetaType::Double;
}
/*!
@@ -1219,7 +1186,7 @@ void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
if (ep != NeverEmit) {
pendingEmit = false;
if (ep == AlwaysEmit || value != old) {
- emit q->valueChanged(edit->displayText());
+ emit q->textChanged(edit->displayText());
emit q->valueChanged(value.toDouble());
}
}
@@ -1275,21 +1242,26 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
const bool plus = max >= 0;
const bool minus = min <= 0;
+ const QString group(locale.groupSeparator());
+ const uint groupUcs = (group.isEmpty() ? 0 :
+ (group.size() > 1 && group.at(0).isHighSurrogate()
+ ? QChar::surrogateToUcs4(group.at(0), group.at(1))
+ : group.at(0).unicode()));
switch (len) {
case 0:
state = max != min ? QValidator::Intermediate : QValidator::Invalid;
goto end;
case 1:
if (copy.at(0) == locale.decimalPoint()
- || (plus && copy.at(0) == QLatin1Char('+'))
- || (minus && copy.at(0) == QLatin1Char('-'))) {
+ || (plus && copy.at(0) == u'+')
+ || (minus && copy.at(0) == u'-')) {
state = QValidator::Intermediate;
goto end;
}
break;
case 2:
if (copy.at(1) == locale.decimalPoint()
- && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) {
+ && ((plus && copy.at(0) == u'+') || (minus && copy.at(0) == u'-'))) {
state = QValidator::Intermediate;
goto end;
}
@@ -1297,7 +1269,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
default: break;
}
- if (copy.at(0) == locale.groupSeparator()) {
+ if (groupUcs && copy.startsWith(group)) {
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
state = QValidator::Invalid;
goto end;
@@ -1313,22 +1285,25 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid;
goto end;
}
- for (int i=dec + 1; i<copy.size(); ++i) {
- if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) {
+ for (int i = dec + 1; i < copy.size(); ++i) {
+ if (copy.at(i).isSpace()
+ || (groupUcs && QStringView{copy}.sliced(i).startsWith(group))) {
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
state = QValidator::Invalid;
goto end;
}
}
} else {
- const QChar last = copy.at(len - 1);
- const QChar secondLast = copy.at(len - 2);
- if ((last == locale.groupSeparator() || last.isSpace())
- && (secondLast == locale.groupSeparator() || secondLast.isSpace())) {
+ const QChar last = copy.back();
+ const bool groupEnd = groupUcs && copy.endsWith(group);
+ const QStringView head(copy.constData(), groupEnd ? len - group.size() : len - 1);
+ const QChar secondLast = head.back();
+ if ((groupEnd || last.isSpace())
+ && ((groupUcs && head.endsWith(group)) || secondLast.isSpace())) {
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
goto end;
- } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) {
+ } else if (last.isSpace() && (!QChar::isSpace(groupUcs) || secondLast.isSpace())) {
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
goto end;
@@ -1342,26 +1317,32 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok;
if (!ok) {
- if (locale.groupSeparator().isPrint()) {
- if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) {
+ if (QChar::isPrint(groupUcs)) {
+ if (max < 1000 && min > -1000 && groupUcs && copy.contains(group)) {
state = QValidator::Invalid;
QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
goto end;
}
const int len = copy.size();
- for (int i=0; i<len- 1; ++i) {
- if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) {
- QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
- state = QValidator::Invalid;
- goto end;
+ for (int i = 0; i < len - 1;) {
+ if (groupUcs && QStringView{copy}.sliced(i).startsWith(group)) {
+ if (QStringView(copy).mid(i + group.size()).startsWith(group)) {
+ QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
+ state = QValidator::Invalid;
+ goto end;
+ }
+ i += group.size();
+ } else {
+ i++;
}
}
QString copy2 = copy;
- copy2.remove(locale.groupSeparator());
+ if (groupUcs)
+ copy2.remove(group);
num = locale.toDouble(copy2, &ok);
- QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok;
+ QSBDEBUG() << group << num << copy2 << ok;
if (!ok) {
state = QValidator::Invalid;