1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <qdebug.h>
6
7#include "qvalidator.h"
8#ifndef QT_NO_VALIDATOR
9#include "private/qobject_p.h"
10#include "private/qlocale_p.h"
11#include "private/qnumeric_p.h"
12#include "private/qstringiterator_p.h"
13
14#include <limits.h>
15#include <cmath>
16
17QT_BEGIN_NAMESPACE
18
19/*!
20 \class QValidator
21 \brief The QValidator class provides validation of input text.
22 \inmodule QtGui
23
24 The class itself is abstract. Two subclasses, \l QIntValidator and
25 \l QDoubleValidator, provide basic numeric-range checking, and \l
26 QRegularExpressionValidator provides general checking using a custom regular
27 expression.
28
29 If the built-in validators aren't sufficient, you can subclass
30 QValidator. The class has two virtual functions: validate() and
31 fixup().
32
33 \l validate() must be implemented by every subclass. It returns
34 \l Invalid, \l Intermediate or \l Acceptable depending on whether
35 its argument is valid (for the subclass's definition of valid).
36
37 These three states require some explanation. An \l Invalid string
38 is \e clearly invalid. \l Intermediate is less obvious: the
39 concept of validity is difficult to apply when the string is
40 incomplete (still being edited). QValidator defines \l Intermediate
41 as the property of a string that is neither clearly invalid nor
42 acceptable as a final result. \l Acceptable means that the string
43 is acceptable as a final result. One might say that any string
44 that is a plausible intermediate state during entry of an \l
45 Acceptable string is \l Intermediate.
46
47 Here are some examples:
48
49 \list
50
51 \li For a line edit that accepts integers from 10 to 1000 inclusive,
52 42 and 123 are \l Acceptable, the empty string, 5, or 1234 are \l
53 Intermediate, and "asdf" and 10114 is \l Invalid.
54
55 \li For an editable combobox that accepts URLs, any well-formed URL
56 is \l Acceptable, "http://example.com/," is \l Intermediate
57 (it might be a cut and paste action that accidentally took in a
58 comma at the end), the empty string is \l Intermediate (the user
59 might select and delete all of the text in preparation for entering
60 a new URL) and "http:///./" is \l Invalid.
61
62 \li For a spin box that accepts lengths, "11cm" and "1in" are \l
63 Acceptable, "11" and the empty string are \l Intermediate, and
64 "http://example.com" and "hour" are \l Invalid.
65
66 \endlist
67
68 \l fixup() is provided for validators that can repair some user
69 errors. The default implementation does nothing. QLineEdit, for
70 example, will call fixup() if the user presses Enter (or Return)
71 and the content is not currently valid. This allows the fixup()
72 function the opportunity of performing some magic to make an \l
73 Invalid string \l Acceptable.
74
75 A validator has a locale, set with setLocale(). It is typically used
76 to parse localized data. For example, QIntValidator and QDoubleValidator
77 use it to parse localized representations of integers and doubles.
78
79 QValidator is typically used with QLineEdit, QSpinBox and
80 QComboBox.
81
82 \sa QIntValidator, QDoubleValidator, QRegularExpressionValidator, {Line Edits Example}
83*/
84
85
86/*!
87 \enum QValidator::State
88
89 This enum type defines the states in which a validated string can
90 exist.
91
92 \value Invalid The string is \e clearly invalid.
93 \value Intermediate The string is a plausible intermediate value.
94 \value Acceptable The string is acceptable as a final result;
95 i.e. it is valid.
96*/
97
98/*!
99 \fn void QValidator::changed()
100
101 This signal is emitted when any property that may affect the validity of
102 a string has changed.
103*/
104
105/*!
106 \fn void QIntValidator::topChanged(int top)
107
108 This signal is emitted after the top property changed.
109
110 \sa QIntValidator::top(), QIntValidator::setTop(), QIntValidator::bottom(), QIntValidator::setBottom()
111 \internal
112*/
113
114/*!
115 \fn void QIntValidator::bottomChanged(int bottom)
116
117 This signal is emitted after the bottom property changed.
118
119 \sa QIntValidator::top(), QIntValidator::setTop(), QIntValidator::bottom(), QIntValidator::setBottom()
120 \internal
121*/
122
123/*!
124 \fn void QDoubleValidator::topChanged(double top)
125
126 This signal is emitted after the top property changed.
127
128 \sa QDoubleValidator::top(), QDoubleValidator::setTop(), QDoubleValidator::bottom(), QDoubleValidator::setBottom()
129 \internal
130*/
131
132/*!
133 \fn void QDoubleValidator::bottomChanged(double bottom)
134
135 This signal is emitted after the bottom property changed.
136
137 \sa QDoubleValidator::top(), QDoubleValidator::setTop(), QDoubleValidator::bottom(), QDoubleValidator::setBottom()
138 \internal
139*/
140
141/*!
142 \fn void QDoubleValidator::decimalsChanged(int decimals)
143
144 This signal is emitted after the decimals property changed.
145
146 \internal
147*/
148
149/*!
150 \fn void QDoubleValidator::notationChanged(QDoubleValidator::Notation notation)
151
152 This signal is emitted after the notation property changed.
153
154 QDoubleValidator::Notation is not a registered metatype, so for queued connections,
155 you will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
156
157 \internal
158*/
159
160class QValidatorPrivate : public QObjectPrivate{
161 Q_DECLARE_PUBLIC(QValidator)
162public:
163 QValidatorPrivate() : QObjectPrivate()
164 {
165 }
166
167 QLocale locale;
168};
169
170
171/*!
172 Sets up the validator. The \a parent parameter is
173 passed on to the QObject constructor.
174*/
175
176QValidator::QValidator(QObject * parent)
177 : QValidator(*new QValidatorPrivate, parent)
178{
179}
180
181/*!
182 Destroys the validator, freeing any storage and other resources
183 used.
184*/
185
186QValidator::~QValidator()
187{
188}
189
190/*!
191 Returns the locale for the validator. The locale is by default initialized to the same as QLocale().
192
193 \sa setLocale()
194 \sa QLocale::QLocale()
195*/
196QLocale QValidator::locale() const
197{
198 Q_D(const QValidator);
199 return d->locale;
200}
201
202/*!
203 Sets the \a locale that will be used for the validator. Unless
204 setLocale has been called, the validator will use the default
205 locale set with QLocale::setDefault(). If a default locale has not
206 been set, it is the operating system's locale.
207
208 \sa locale(), QLocale::setDefault()
209*/
210void QValidator::setLocale(const QLocale &locale)
211{
212 Q_D(QValidator);
213 if (d->locale != locale) {
214 d->locale = locale;
215 emit changed();
216 }
217}
218
219/*!
220 \fn QValidator::State QValidator::validate(QString &input, int &pos) const
221
222 This virtual function returns \l Invalid if \a input is invalid
223 according to this validator's rules, \l Intermediate if it
224 is likely that a little more editing will make the input
225 acceptable (e.g. the user types "4" into a widget which accepts
226 integers between 10 and 99), and \l Acceptable if the input is
227 valid.
228
229 The function can change both \a input and \a pos (the cursor position)
230 if required.
231*/
232
233
234/*!
235 \fn void QValidator::fixup(QString & input) const
236
237 This function attempts to change \a input to be valid according to
238 this validator's rules. It need not result in a valid string:
239 callers of this function must re-test afterwards; the default does
240 nothing.
241
242 Reimplementations of this function can change \a input even if
243 they do not produce a valid string. For example, an ISBN validator
244 might want to delete every character except digits and "-", even
245 if the result is still not a valid ISBN; a surname validator might
246 want to remove whitespace from the start and end of the string,
247 even if the resulting string is not in the list of accepted
248 surnames.
249*/
250
251void QValidator::fixup(QString &) const
252{
253}
254
255
256/*!
257 \class QIntValidator
258 \brief The QIntValidator class provides a validator that ensures
259 a string contains a valid integer within a specified range.
260 \inmodule QtGui
261
262 Example of use:
263
264 \snippet code/src_gui_util_qvalidator.cpp 0
265
266 Below we present some examples of validators. In practice they would
267 normally be associated with a widget as in the example above.
268
269 \snippet code/src_gui_util_qvalidator.cpp 1
270
271 Notice that the value \c 999 returns Intermediate. Values
272 consisting of a number of digits equal to or less than the max
273 value are considered intermediate. This is intended because the
274 digit that prevents a number from being in range is not necessarily the
275 last digit typed. This also means that an intermediate number can
276 have leading zeros.
277
278 The minimum and maximum values are set in one call with setRange(),
279 or individually with setBottom() and setTop().
280
281 QIntValidator uses its locale() to interpret the number. For example,
282 in Arabic locales, QIntValidator will accept Arabic digits.
283
284 \note The QLocale::NumberOptions set on the locale() also affect the
285 way the number is interpreted. For example, since QLocale::RejectGroupSeparator
286 is not set by default, the validator will accept group separators. It is thus
287 recommended to use QLocale::toInt() to obtain the numeric value.
288
289 \sa QDoubleValidator, QRegularExpressionValidator, QLocale::toInt(), {Line Edits Example}
290*/
291
292/*!
293 Constructs a validator with a \a parent object that
294 accepts all integers.
295*/
296
297QIntValidator::QIntValidator(QObject * parent)
298 : QIntValidator(INT_MIN, INT_MAX, parent)
299{
300}
301
302
303/*!
304 Constructs a validator with a \a parent, that accepts integers
305 from \a minimum to \a maximum inclusive.
306*/
307
308QIntValidator::QIntValidator(int minimum, int maximum,
309 QObject * parent)
310 : QValidator(parent)
311{
312 b = minimum;
313 t = maximum;
314}
315
316
317/*!
318 Destroys the validator.
319*/
320
321QIntValidator::~QIntValidator()
322{
323 // nothing
324}
325
326
327/*!
328 \fn QValidator::State QIntValidator::validate(QString &input, int &pos) const
329
330 Returns \l Acceptable if the \a input is an integer within the
331 valid range. If \a input has at most as many digits as the top of the range,
332 or is a prefix of an integer in the valid range, returns \l Intermediate.
333 Otherwise, returns \l Invalid.
334
335 If the valid range consists of just positive integers (e.g., 32 to 100) and
336 \a input is a negative integer, then Invalid is returned. (On the other
337 hand, if the range consists of negative integers (e.g., -100 to -32) and \a
338 input is a positive integer without leading plus sign, then Intermediate is
339 returned, because the user might be just about to type the minus (especially
340 for right-to-left languages).
341
342 Similarly, if the valid range is between 46 and 53, then 41 and 59 will be
343 evaluated as \l Intermediate, as otherwise the user wouldn't be able to
344 change a value from 49 to 51.
345
346 \snippet code/src_gui_util_qvalidator.cpp 2
347
348 By default, the \a pos parameter is not used by this validator.
349*/
350
351static int numDigits(qlonglong n)
352{
353 if (n == 0)
354 return 1;
355 return (int)std::log10(x: double(n)) + 1;
356}
357
358static qlonglong pow10(int exp)
359{
360 qlonglong result = 1;
361 for (int i = 0; i < exp; ++i)
362 result *= 10;
363 return result;
364}
365
366template <typename T> static inline
367std::optional<QValidator::State> initialResultCheck(T min, T max,
368 const QLocaleData::ParsingResult &result)
369{
370
371 using ParsingResult = QLocaleData::ParsingResult;
372 if (result.state == ParsingResult::Invalid)
373 return QValidator::Invalid;
374
375 const CharBuff &buff = result.buff;
376 if (buff.isEmpty())
377 return QValidator::Intermediate;
378
379 char ch = buff[0];
380 const bool signConflicts = (min >= 0 && ch == '-') || (max < 0 && ch == '+');
381 if (signConflicts)
382 return QValidator::Invalid;
383
384 if (result.state == ParsingResult::Intermediate)
385 return QValidator::Intermediate;
386
387 return std::nullopt;
388}
389
390QValidator::State QIntValidator::validate(QString & input, int&) const
391{
392 QLocaleData::ParsingResult result =
393 locale().d->m_data->validateChars(str: input, numMode: QLocaleData::IntegerMode, decDigits: -1,
394 number_options: locale().numberOptions());
395
396 std::optional<State> opt = initialResultCheck(min: b, max: t, result);
397 if (opt)
398 return *opt;
399
400 const CharBuff &buff = result.buff;
401 QSimpleParsedNumber r = QLocaleData::bytearrayToLongLong(num: buff, base: 10);
402 if (!r.ok())
403 return Invalid;
404
405 qint64 entered = r.result;
406 if (entered >= b && entered <= t) {
407 bool ok = false;
408 locale().toInt(s: input, ok: &ok);
409 return ok ? Acceptable : Intermediate;
410 }
411
412 if (entered >= 0) {
413 // the -entered < b condition is necessary to allow people to type
414 // the minus last (e.g. for right-to-left languages)
415 // The buffLength > tLength condition validates values consisting
416 // of a number of digits equal to or less than the max value as intermediate.
417
418 int buffLength = buff.size();
419 if (buff[0] == '+')
420 buffLength--;
421 const int tLength = t != 0 ? static_cast<int>(std::log10(x: qAbs(t))) + 1 : 1;
422
423 return (entered > t && -entered < b && buffLength > tLength) ? Invalid : Intermediate;
424 } else {
425 return (entered < b) ? Invalid : Intermediate;
426 }
427}
428
429/*! \reimp */
430void QIntValidator::fixup(QString &input) const
431{
432 auto [parseState, buff] =
433 locale().d->m_data->validateChars(str: input, numMode: QLocaleData::IntegerMode, decDigits: -1,
434 number_options: locale().numberOptions());
435 if (parseState == QLocaleData::ParsingResult::Invalid)
436 return;
437
438 QSimpleParsedNumber r = QLocaleData::bytearrayToLongLong(num: buff, base: 10);
439 if (r.ok())
440 input = locale().toString(i: r.result);
441}
442
443/*!
444 Sets the range of the validator to only accept integers between \a
445 bottom and \a top inclusive.
446*/
447
448void QIntValidator::setRange(int bottom, int top)
449{
450 bool rangeChanged = false;
451 if (b != bottom) {
452 b = bottom;
453 rangeChanged = true;
454 emit bottomChanged(bottom: b);
455 }
456
457 if (t != top) {
458 t = top;
459 rangeChanged = true;
460 emit topChanged(top: t);
461 }
462
463 if (rangeChanged)
464 emit changed();
465}
466
467
468/*!
469 \property QIntValidator::bottom
470 \brief the validator's lowest acceptable value
471
472 By default, this property's value is derived from the lowest signed
473 integer available (-2147483648).
474
475 \sa setRange()
476*/
477void QIntValidator::setBottom(int bottom)
478{
479 setRange(bottom, top: top());
480}
481
482/*!
483 \property QIntValidator::top
484 \brief the validator's highest acceptable value
485
486 By default, this property's value is derived from the highest signed
487 integer available (2147483647).
488
489 \sa setRange()
490*/
491void QIntValidator::setTop(int top)
492{
493 setRange(bottom: bottom(), top);
494}
495
496/*!
497 \internal
498*/
499QValidator::QValidator(QObjectPrivate &d, QObject *parent)
500 : QObject(d, parent)
501{
502}
503
504/*!
505 \internal
506*/
507QValidator::QValidator(QValidatorPrivate &d, QObject *parent)
508 : QObject(d, parent)
509{
510}
511
512class QDoubleValidatorPrivate : public QValidatorPrivate
513{
514 Q_DECLARE_PUBLIC(QDoubleValidator)
515public:
516 QDoubleValidatorPrivate()
517 : QValidatorPrivate()
518 , notation(QDoubleValidator::ScientificNotation)
519 {
520 }
521
522 QDoubleValidator::Notation notation;
523
524 QValidator::State validateWithLocale(QString & input, QLocaleData::NumberMode numMode, const QLocale &locale) const;
525 void fixupWithLocale(QString &input, QLocaleData::NumberMode numMode,
526 const QLocale &locale) const;
527};
528
529
530/*!
531 \class QDoubleValidator
532
533 \brief The QDoubleValidator class provides range checking of
534 floating-point numbers.
535 \inmodule QtGui
536
537 QDoubleValidator provides an upper bound, a lower bound, and a
538 limit on the number of digits after the decimal point.
539
540 You can set the acceptable range in one call with setRange(), or
541 with setBottom() and setTop(). Set the number of decimal places
542 with setDecimals(). The validate() function returns the validation
543 state.
544
545 QDoubleValidator uses its locale() to interpret the number. For example,
546 in the German locale, "1,234" will be accepted as the fractional number
547 1.234. In Arabic locales, QDoubleValidator will accept Arabic digits.
548
549 \note The QLocale::NumberOptions set on the locale() also affect the way the
550 number is interpreted. For example, since QLocale::RejectGroupSeparator is
551 not set by default (except on the \c "C" locale), the validator will accept
552 group separators. If the string passes validation, pass it to
553 locale().toDouble() to obtain its numeric value.
554
555 \sa QIntValidator, QRegularExpressionValidator, QLocale::toDouble(), {Line Edits Example}
556*/
557
558 /*!
559 \enum QDoubleValidator::Notation
560 \since 4.3
561 This enum defines the allowed notations for entering a double.
562
563 \value StandardNotation The string is written in the standard format, a
564 whole number part optionally followed by a separator
565 and fractional part, for example \c{"0.015"}.
566
567 \value ScientificNotation The string is written in scientific form, which
568 optionally appends an exponent part to the
569 standard format, for example \c{"1.5E-2"}.
570
571 The whole number part may, as usual, include a sign. This, along with the
572 separators for fractional part, exponent and any digit-grouping, depend on
573 locale. QDoubleValidator doesn't check the placement (which would also
574 depend on locale) of any digit-grouping separators it finds, but it will
575 reject input that contains them if \l QLocale::RejectGroupSeparator is set
576 in \c locale().numberOptions().
577
578 \sa QLocale::numberOptions(), QLocale::decimalPoint(),
579 QLocale::exponential(), QLocale::negativeSign()
580*/
581
582/*!
583 Constructs a validator object with a \a parent object
584 that accepts any double.
585*/
586
587QDoubleValidator::QDoubleValidator(QObject *parent)
588 : QDoubleValidator(-HUGE_VAL, HUGE_VAL, -1, parent)
589{
590}
591
592
593/*!
594 Constructs a validator object with a \a parent object. This
595 validator will accept doubles from \a bottom to \a top inclusive,
596 with up to \a decimals digits after the decimal point.
597*/
598
599QDoubleValidator::QDoubleValidator(double bottom, double top, int decimals,
600 QObject * parent)
601 : QValidator(*new QDoubleValidatorPrivate , parent)
602{
603 b = bottom;
604 t = top;
605 dec = decimals;
606}
607
608
609/*!
610 Destroys the validator.
611*/
612
613QDoubleValidator::~QDoubleValidator()
614{
615}
616
617
618/*!
619 \fn QValidator::State QDoubleValidator::validate(QString &input, int &pos) const
620
621 Returns \l Acceptable if the string \a input is in the correct format and
622 contains a double within the valid range.
623
624 Returns \l Intermediate if \a input is in the wrong format or contains a
625 double outside the range.
626
627 Returns \l Invalid if the \a input doesn't represent a double or has too
628 many digits after the decimal point.
629
630 Note: If the valid range consists of just positive doubles (e.g. 0.0 to 100.0)
631 and \a input is a negative double then \l Invalid is returned. If notation()
632 is set to StandardNotation, and the input contains more digits before the
633 decimal point than a double in the valid range may have, \l Invalid is returned.
634 If notation() is ScientificNotation, and the input is not in the valid range,
635 \l Intermediate is returned. The value may yet become valid by changing the exponent.
636
637 By default, the \a pos parameter is not used by this validator.
638*/
639
640#ifndef LLONG_MAX
641# define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)
642#endif
643
644QValidator::State QDoubleValidator::validate(QString & input, int &) const
645{
646 Q_D(const QDoubleValidator);
647
648 QLocaleData::NumberMode numMode = QLocaleData::DoubleStandardMode;
649 switch (d->notation) {
650 case StandardNotation:
651 numMode = QLocaleData::DoubleStandardMode;
652 break;
653 case ScientificNotation:
654 numMode = QLocaleData::DoubleScientificMode;
655 break;
656 }
657
658 return d->validateWithLocale(input, numMode, locale: locale());
659}
660
661QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocaleData::NumberMode numMode, const QLocale &locale) const
662{
663 Q_Q(const QDoubleValidator);
664 QLocaleData::ParsingResult result =
665 locale.d->m_data->validateChars(str: input, numMode, decDigits: q->dec, number_options: locale.numberOptions());
666
667 std::optional<QValidator::State> opt = initialResultCheck(min: q->b, max: q->t, result);
668 if (opt)
669 return *opt;
670
671 bool ok = false;
672 double i = locale.toDouble(s: input, ok: &ok); // returns 0.0 if !ok
673 Q_ASSERT(!qIsNaN(i)); // Would be caught by validateChars()
674 if (!ok)
675 return QValidator::Intermediate;
676
677 if (i >= q->b && i <= q->t)
678 return QValidator::Acceptable;
679
680 if (notation == QDoubleValidator::StandardNotation) {
681 double max = qMax(a: qAbs(t: q->b), b: qAbs(t: q->t));
682 qlonglong v;
683 // Need a whole number to pass to convertDoubleTo() or it fails. Use
684 // floor, as max is positive so this has the same number of digits
685 // before the decimal point, where qCeil() might take us up to a power
686 // of ten, adding a digit.
687 if (convertDoubleTo(v: qFloor(v: max), value: &v)) {
688 qlonglong n = pow10(exp: numDigits(n: v));
689 // In order to get the highest possible number in the intermediate
690 // range we need to get 10 to the power of the number of digits
691 // after the decimal's and subtract that from the top number.
692 //
693 // For example, where q->dec == 2 and with a range of 0.0 - 9.0
694 // then the minimum possible number is 0.00 and the maximum
695 // possible is 9.99. Therefore 9.999 and 10.0 should be seen as
696 // invalid.
697 if (qAbs(t: i) > (n - std::pow(x: 10, y: -q->dec)))
698 return QValidator::Invalid;
699 }
700 }
701
702 return QValidator::Intermediate;
703}
704
705/*!
706 \since 6.3
707 \overload
708
709 Attempts to fix the \a input string to an \l Acceptable representation of a
710 double.
711
712 The format of the number is determined by \l notation(), \l decimals(),
713 \l locale() and the latter's \l {QLocale::}{numberOptions()}.
714
715 To comply with \l notation(), when \l ScientificNotation is used, the fixed
716 value will be represented in its normalized form, which means that any
717 non-zero value will have one non-zero digit before the decimal point.
718
719 \snippet code/src_gui_util_qvalidator.cpp 7
720
721 To comply with \l decimals(), when it is \c {-1} the number of digits used
722 will be determined by \l QLocale::FloatingPointShortest. Otherwise, the
723 fractional part of the number is truncated (with rounding, as appropriate)
724 if its length exceeds \l decimals(). When \l notation() is
725 \l ScientificNotation this is done after the number has been put into its
726 normalized form.
727
728 \snippet code/src_gui_util_qvalidator.cpp 8
729
730 \note If \l decimals() is set to, and the string provides, more than
731 \c {std::numeric_limits<double>::digits10}, digits beyond that many in the
732 fractional part may be changed. The resulting string shall encode the same
733 floating-point number, when parsed to a \c double.
734*/
735void QDoubleValidator::fixup(QString &input) const
736{
737 Q_D(const QDoubleValidator);
738 const auto numberMode = d->notation == StandardNotation ? QLocaleData::DoubleStandardMode
739 : QLocaleData::DoubleScientificMode;
740
741 d->fixupWithLocale(input, numMode: numberMode, locale: locale());
742}
743
744void QDoubleValidatorPrivate::fixupWithLocale(QString &input, QLocaleData::NumberMode numMode,
745 const QLocale &locale) const
746{
747 Q_Q(const QDoubleValidator);
748 // Passing -1 as the number of decimals, because fixup() exists to improve
749 // an Intermediate value, if it can.
750 auto [parseState, buff] =
751 locale.d->m_data->validateChars(str: input, numMode, decDigits: -1, number_options: locale.numberOptions());
752 if (parseState == QLocaleData::ParsingResult::Invalid)
753 return;
754
755 // buff contains data in C locale.
756 bool ok = false;
757 const double entered = QByteArrayView(buff).toDouble(ok: &ok);
758 if (ok) {
759 // Here we need to adjust the output format accordingly
760 char mode;
761 if (numMode == QLocaleData::DoubleStandardMode) {
762 mode = 'f';
763 } else {
764 // Scientific mode can be either 'e' or 'E'
765 const QString exp = locale.exponential();
766 bool preferUpper = false;
767 QStringIterator scan(exp);
768 while (!preferUpper && scan.hasNext()) {
769 const char32_t ch = scan.next();
770 if (QChar::isUpper(ucs4: ch))
771 preferUpper = true;
772 }
773 if (preferUpper)
774 mode = input.contains(s: exp.toLower()) ? 'e' : 'E';
775 else // If case-free, we don't care which we use; otherwise, prefer lower.
776 mode = input.contains(s: exp.toUpper()) ? 'E' : 'e';
777 }
778 int precision;
779 if (q->dec < 0) {
780 precision = QLocale::FloatingPointShortest;
781 } else {
782 if (mode == 'f') {
783 const auto decimalPointIndex = buff.indexOf(t: '.');
784 precision = decimalPointIndex >= 0 ? buff.size() - decimalPointIndex - 1 : 0;
785 } else {
786 auto eIndex = buff.indexOf(t: 'e');
787 // No need to check for 'E' because we can get only 'e' after a
788 // call to validateChars()
789 if (eIndex < 0)
790 eIndex = buff.size();
791 precision = eIndex - (buff.contains(t: '.') ? 1 : 0)
792 - (buff[0] == '-' || buff[0] == '+' ? 1 : 0);
793 }
794 // Use q->dec to limit the number of decimals, because we want the
795 // fixup() result to pass validate().
796 precision = qMin(a: precision, b: q->dec);
797 }
798 input = locale.toString(f: entered, format: mode, precision);
799 }
800}
801
802/*!
803 Sets the validator to accept doubles from \a minimum to \a maximum
804 inclusive, with at most \a decimals digits after the decimal
805 point.
806
807 \note Setting the number of decimals to -1 effectively sets it to unlimited.
808 This is also the value used by a default-constructed validator.
809*/
810
811void QDoubleValidator::setRange(double minimum, double maximum, int decimals)
812{
813 bool rangeChanged = false;
814 if (b != minimum) {
815 b = minimum;
816 rangeChanged = true;
817 emit bottomChanged(bottom: b);
818 }
819
820 if (t != maximum) {
821 t = maximum;
822 rangeChanged = true;
823 emit topChanged(top: t);
824 }
825
826 if (dec != decimals) {
827 dec = decimals;
828 rangeChanged = true;
829 emit decimalsChanged(decimals: dec);
830 }
831 if (rangeChanged)
832 emit changed();
833}
834
835/*!
836 \overload
837
838 Sets the validator to accept doubles from \a minimum to \a maximum
839 inclusive without changing the number of digits after the decimal point.
840*/
841void QDoubleValidator::setRange(double minimum, double maximum)
842{
843 setRange(minimum, maximum, decimals: decimals());
844}
845
846/*!
847 \property QDoubleValidator::bottom
848 \brief the validator's minimum acceptable value
849
850 By default, this property contains a value of -infinity.
851
852 \sa setRange()
853*/
854
855void QDoubleValidator::setBottom(double bottom)
856{
857 setRange(minimum: bottom, maximum: top(), decimals: decimals());
858}
859
860
861/*!
862 \property QDoubleValidator::top
863 \brief the validator's maximum acceptable value
864
865 By default, this property contains a value of infinity.
866
867 \sa setRange()
868*/
869
870void QDoubleValidator::setTop(double top)
871{
872 setRange(minimum: bottom(), maximum: top, decimals: decimals());
873}
874
875/*!
876 \property QDoubleValidator::decimals
877 \brief the validator's maximum number of digits after the decimal point
878
879 By default, this property contains a value of -1, which means any number
880 of digits is accepted.
881
882 \sa setRange()
883*/
884
885void QDoubleValidator::setDecimals(int decimals)
886{
887 setRange(minimum: bottom(), maximum: top(), decimals);
888}
889
890/*!
891 \property QDoubleValidator::notation
892 \since 4.3
893 \brief the notation of how a string can describe a number
894
895 By default, this property is set to ScientificNotation.
896
897 \sa Notation
898*/
899
900void QDoubleValidator::setNotation(Notation newNotation)
901{
902 Q_D(QDoubleValidator);
903 if (d->notation != newNotation) {
904 d->notation = newNotation;
905 emit notationChanged(notation: d->notation);
906 emit changed();
907 }
908}
909
910QDoubleValidator::Notation QDoubleValidator::notation() const
911{
912 Q_D(const QDoubleValidator);
913 return d->notation;
914}
915
916#if QT_CONFIG(regularexpression)
917
918/*!
919 \class QRegularExpressionValidator
920 \inmodule QtGui
921 \brief The QRegularExpressionValidator class is used to check a string
922 against a regular expression.
923
924 \since 5.1
925
926 QRegularExpressionValidator uses a regular expression (regexp) to
927 determine whether an input string is \l Acceptable, \l
928 Intermediate, or \l Invalid. The regexp can either be supplied
929 when the QRegularExpressionValidator is constructed, or at a later time.
930
931 If the regexp partially matches against the string, the result is
932 considered \l Intermediate. For example, "" and "A" are \l Intermediate for
933 the regexp \b{[A-Z][0-9]} (whereas "_" would be \l Invalid).
934
935 QRegularExpressionValidator automatically wraps the regular expression in
936 the \c{\\A} and \c{\\z} anchors; in other words, it always attempts to do
937 an exact match.
938
939 Example of use:
940 \snippet code/src_gui_util_qvalidator.cpp 5
941
942 Below we present some examples of validators. In practice they would
943 normally be associated with a widget as in the example above.
944
945 \snippet code/src_gui_util_qvalidator.cpp 6
946
947 \sa QRegularExpression, QIntValidator, QDoubleValidator
948*/
949
950class QRegularExpressionValidatorPrivate : public QValidatorPrivate
951{
952 Q_DECLARE_PUBLIC(QRegularExpressionValidator)
953
954public:
955 QRegularExpression origRe; // the one set by the user
956 QRegularExpression usedRe; // the one actually used
957 void setRegularExpression(const QRegularExpression &re);
958};
959
960/*!
961 Constructs a validator with a \a parent object that accepts
962 any string (including an empty one) as valid.
963*/
964
965QRegularExpressionValidator::QRegularExpressionValidator(QObject *parent)
966 : QValidator(*new QRegularExpressionValidatorPrivate, parent)
967{
968 // origRe in the private will be an empty QRegularExpression,
969 // and therefore this validator will match any string.
970}
971
972/*!
973 Constructs a validator with a \a parent object that
974 accepts all strings that match the regular expression \a re.
975*/
976
977QRegularExpressionValidator::QRegularExpressionValidator(const QRegularExpression &re, QObject *parent)
978 : QRegularExpressionValidator(parent)
979{
980 Q_D(QRegularExpressionValidator);
981 d->setRegularExpression(re);
982}
983
984
985/*!
986 Destroys the validator.
987*/
988
989QRegularExpressionValidator::~QRegularExpressionValidator()
990{
991}
992
993/*!
994 Returns \l Acceptable if \a input is matched by the regular expression for
995 this validator, \l Intermediate if it has matched partially (i.e. could be
996 a valid match if additional valid characters are added), and \l Invalid if
997 \a input is not matched.
998
999 In case the \a input is not matched, the \a pos parameter is set to
1000 the length of the \a input parameter; otherwise, it is not modified.
1001
1002 For example, if the regular expression is \b{\\w\\d\\d} (word-character,
1003 digit, digit) then "A57" is \l Acceptable, "E5" is \l Intermediate, and
1004 "+9" is \l Invalid.
1005
1006 \sa QRegularExpression::match()
1007*/
1008
1009QValidator::State QRegularExpressionValidator::validate(QString &input, int &pos) const
1010{
1011 Q_D(const QRegularExpressionValidator);
1012
1013 // We want a validator with an empty QRegularExpression to match anything;
1014 // since we're going to do an exact match (by using d->usedRe), first check if the rx is empty
1015 // (and, if so, accept the input).
1016 if (d->origRe.pattern().isEmpty())
1017 return Acceptable;
1018
1019 const QRegularExpressionMatch m = d->usedRe.match(subject: input, offset: 0, matchType: QRegularExpression::PartialPreferCompleteMatch);
1020 if (m.hasMatch()) {
1021 return Acceptable;
1022 } else if (input.isEmpty() || m.hasPartialMatch()) {
1023 return Intermediate;
1024 } else {
1025 pos = input.size();
1026 return Invalid;
1027 }
1028}
1029
1030/*!
1031 \property QRegularExpressionValidator::regularExpression
1032 \brief the regular expression used for validation
1033
1034 By default, this property contains a regular expression with an empty
1035 pattern (which therefore matches any string).
1036*/
1037
1038QRegularExpression QRegularExpressionValidator::regularExpression() const
1039{
1040 Q_D(const QRegularExpressionValidator);
1041 return d->origRe;
1042}
1043
1044void QRegularExpressionValidator::setRegularExpression(const QRegularExpression &re)
1045{
1046 Q_D(QRegularExpressionValidator);
1047 d->setRegularExpression(re);
1048}
1049
1050/*!
1051 \internal
1052
1053 Sets \a re as the regular expression. It wraps the regexp that's actually used
1054 between \\A and \\z, therefore forcing an exact match.
1055*/
1056void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpression &re)
1057{
1058 Q_Q(QRegularExpressionValidator);
1059
1060 if (origRe != re) {
1061 usedRe = origRe = re; // copies also the pattern options
1062 usedRe.setPattern(QRegularExpression::anchoredPattern(expression: re.pattern()));
1063 emit q->regularExpressionChanged(re);
1064 emit q->changed();
1065 }
1066}
1067
1068#endif // QT_CONFIG(regularexpression)
1069
1070QT_END_NAMESPACE
1071
1072#include "moc_qvalidator.cpp"
1073
1074#endif // QT_NO_VALIDATOR
1075

source code of qtbase/src/gui/util/qvalidator.cpp