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

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