source: trunk/src/widgets/qvalidator.cpp@ 108

Last change on this file since 108 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 18.8 KB
Line 
1/****************************************************************************
2** $Id: qvalidator.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of validator classes
5**
6** Created : 970610
7**
8** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qvalidator.h"
39#ifndef QT_NO_VALIDATOR
40
41#include <limits.h>
42#include <math.h>
43
44/*!
45 \class QValidator
46 \brief The QValidator class provides validation of input text.
47
48 \ingroup misc
49 \mainclass
50
51 The class itself is abstract. Two subclasses, \l QIntValidator and
52 \l QDoubleValidator, provide basic numeric-range checking, and \l
53 QRegExpValidator provides general checking using a custom regular
54 expression.
55
56 If the built-in validators aren't sufficient, you can subclass
57 QValidator. The class has two virtual functions: validate() and
58 fixup().
59
60 \l validate() must be implemented by every subclass. It returns
61 \c Invalid, \c Intermediate or \c Acceptable depending on whether
62 its argument is valid (for the subclass's definition of valid).
63
64 These three states require some explanation. An \c Invalid string
65 is \e clearly invalid. \c Intermediate is less obvious: the
66 concept of validity is slippery when the string is incomplete
67 (still being edited). QValidator defines \c Intermediate as the
68 property of a string that is neither clearly invalid nor
69 acceptable as a final result. \c Acceptable means that the string
70 is acceptable as a final result. One might say that any string
71 that is a plausible intermediate state during entry of an \c
72 Acceptable string is \c Intermediate.
73
74 Here are some examples:
75
76 \list
77
78 \i For a line edit that accepts integers from 0 to 999 inclusive,
79 42 and 666 are \c Acceptable, the empty string and 1114 are \c
80 Intermediate and asdf is \c Invalid.
81
82 \i For an editable combobox that accepts URLs, any well-formed URL
83 is \c Acceptable, "http://www.trolltech.com/," is \c Intermediate
84 (it might be a cut-and-paste that accidentally took in a comma at
85 the end), the empty string is valid (the user might select and
86 delete all of the text in preparation of entering a new URL) and
87 "http:///./" is \c Invalid.
88
89 \i For a spin box that accepts lengths, "11cm" and "1in" are \c
90 Acceptable, "11" and the empty string are \c Intermediate and
91 "http://www.trolltech.com" and "hour" are \c Invalid.
92
93 \endlist
94
95 \l fixup() is provided for validators that can repair some user
96 errors. The default implementation does nothing. QLineEdit, for
97 example, will call fixup() if the user presses Enter (or Return)
98 and the content is not currently valid. This allows the fixup()
99 function the opportunity of performing some magic to make an \c
100 Invalid string \c Acceptable.
101
102 QValidator is typically used with QLineEdit, QSpinBox and
103 QComboBox.
104*/
105
106
107/*!
108 \enum QValidator::State
109
110 This enum type defines the states in which a validated string can
111 exist.
112
113 \value Invalid the string is \e clearly invalid.
114
115 \value Intermediate the string is a plausible intermediate value
116 during editing.
117
118 \value Acceptable the string is acceptable as a final result,
119 i.e. it is valid.
120*/
121
122
123/*!
124 Sets up the validator. The \a parent and \a name parameters are
125 passed on to the QObject constructor.
126*/
127
128QValidator::QValidator( QObject * parent, const char *name )
129 : QObject( parent, name )
130{
131}
132
133
134/*!
135 Destroys the validator, freeing any storage and other resources
136 used.
137*/
138
139QValidator::~QValidator()
140{
141}
142
143
144/*!
145 \fn QValidator::State QValidator::validate( QString& input, int& pos ) const
146
147 This pure virtual function returns \c Invalid if \a input is
148 invalid according to this validator's rules, \c Intermediate if it
149 is likely that a little more editing will make the input
150 acceptable (e.g. the user types '4' into a widget which accepts
151 integers between 10 and 99) and \c Acceptable if the input is
152 valid.
153
154 The function can change \a input and \a pos (the cursor position)
155 if it wants to.
156*/
157
158
159/*!
160 \fn void QValidator::fixup( QString & input ) const
161
162 This function attempts to change \a input to be valid according to
163 this validator's rules. It need not result in a valid string:
164 callers of this function must re-test afterwards; the default does
165 nothing.
166
167 Reimplementations of this function can change \a input even if
168 they do not produce a valid string. For example, an ISBN validator
169 might want to delete every character except digits and "-", even
170 if the result is still not a valid ISBN; a surname validator might
171 want to remove whitespace from the start and end of the string,
172 even if the resulting string is not in the list of accepted
173 surnames.
174*/
175
176void QValidator::fixup( QString & ) const
177{
178}
179
180
181/*!
182 \class QIntValidator
183 \brief The QIntValidator class provides a validator which ensures
184 that a string contains a valid integer within a specified range.
185
186 \ingroup misc
187
188 Example of use:
189
190 \code
191 QValidator* validator = new QIntValidator( 100, 999, this );
192 QLineEdit* edit = new QLineEdit( this );
193
194 // the edit lineedit will only accept integers between 100 and 999
195 edit->setValidator( validator );
196 \endcode
197
198 Below we present some examples of validators. In practice they would
199 normally be associated with a widget as in the example above.
200
201 \code
202 QString str;
203 int pos = 0;
204 QIntValidator v( 100, 999, this );
205
206 str = "1";
207 v.validate( str, pos ); // returns Intermediate
208 str = "12";
209 v.validate( str, pos ); // returns Intermediate
210
211 str = "123";
212 v.validate( str, pos ); // returns Acceptable
213 str = "678";
214 v.validate( str, pos ); // returns Acceptable
215
216 str = "1234";
217 v.validate( str, pos ); // returns Invalid
218 str = "-123";
219 v.validate( str, pos ); // returns Invalid
220 str = "abc";
221 v.validate( str, pos ); // returns Invalid
222 str = "12cm";
223 v.validate( str, pos ); // returns Invalid
224 \endcode
225
226 The minimum and maximum values are set in one call with setRange()
227 or individually with setBottom() and setTop().
228
229 \sa QDoubleValidator QRegExpValidator
230*/
231
232
233/*!
234 Constructs a validator called \a name with parent \a parent, that
235 accepts all integers.
236*/
237
238QIntValidator::QIntValidator( QObject * parent, const char *name )
239 : QValidator( parent, name )
240{
241 b = INT_MIN;
242 t = INT_MAX;
243}
244
245
246/*!
247 Constructs a validator called \a name with parent \a parent, that
248 accepts integers from \a minimum to \a maximum inclusive.
249*/
250
251QIntValidator::QIntValidator( int minimum, int maximum,
252 QObject * parent, const char* name )
253 : QValidator( parent, name )
254{
255 b = minimum;
256 t = maximum;
257}
258
259
260/*!
261 Destroys the validator, freeing any resources allocated.
262*/
263
264QIntValidator::~QIntValidator()
265{
266 // nothing
267}
268
269
270/*!
271 Returns \c Acceptable if the \a input is an integer within the
272 valid range, \c Intermediate if the \a input is an integer outside
273 the valid range and \c Invalid if the \a input is not an integer.
274
275 Note: If the valid range consists of just positive integers (e.g. 0 - 100)
276 and \a input is a negative integer then Invalid is returned.
277
278 \code
279 int pos = 0;
280 s = "35";
281 v.validate( s, pos ); // returns Acceptable
282
283 s = "105";
284 v.validate( s, pos ); // returns Intermediate
285
286 s = "abc";
287 v.validate( s, pos ); // returns Invalid
288
289 \endcode
290*/
291
292QValidator::State QIntValidator::validate( QString & input, int & ) const
293{
294 QString stripped = input.stripWhiteSpace();
295 if ( stripped.isEmpty() || (b < 0 && stripped == "-") )
296 return Intermediate;
297 bool ok;
298 long entered = input.toLong( &ok );
299 if ( !ok || (entered < 0 && b >= 0) ) {
300 return Invalid;
301 } else if ( entered >= b && entered <= t ) {
302 return Acceptable;
303 } else {
304 if ( entered >= 0 )
305 return ( entered > t ) ? Invalid : Intermediate;
306 else
307 return ( entered < b ) ? Invalid : Intermediate;
308 }
309}
310
311
312/*!
313 Sets the range of the validator to only accept integers between \a
314 bottom and \a top inclusive.
315*/
316
317void QIntValidator::setRange( int bottom, int top )
318{
319 b = bottom;
320 t = top;
321}
322
323
324/*!
325 \property QIntValidator::bottom
326 \brief the validator's lowest acceptable value
327
328 \sa setRange()
329*/
330void QIntValidator::setBottom( int bottom )
331{
332 setRange( bottom, top() );
333}
334
335/*!
336 \property QIntValidator::top
337 \brief the validator's highest acceptable value
338
339 \sa setRange()
340*/
341void QIntValidator::setTop( int top )
342{
343 setRange( bottom(), top );
344}
345
346
347#ifndef QT_NO_REGEXP
348
349/*!
350 \class QDoubleValidator
351
352 \brief The QDoubleValidator class provides range checking of
353 floating-point numbers.
354
355 \ingroup misc
356
357 QDoubleValidator provides an upper bound, a lower bound and a
358 limit on the number of digits after the decimal point. It does not
359 provide a fixup() function.
360
361 You can set the acceptable range in one call with setRange(), or
362 with setBottom() and setTop(). Set the number of decimal places
363 with setDecimals(). The validate() function returns the validation
364 state.
365
366 \sa QIntValidator QRegExpValidator
367*/
368
369/*!
370 Constructs a validator object with parent \a parent, called \a
371 name, which accepts any double.
372*/
373
374QDoubleValidator::QDoubleValidator( QObject * parent, const char *name )
375 : QValidator( parent, name )
376{
377 b = -HUGE_VAL;
378 t = HUGE_VAL;
379 d = 1000;
380}
381
382
383/*!
384 Constructs a validator object with parent \a parent, called \a
385 name. This validator will accept doubles from \a bottom to \a top
386 inclusive, with up to \a decimals digits after the decimal point.
387*/
388
389QDoubleValidator::QDoubleValidator( double bottom, double top, int decimals,
390 QObject * parent, const char* name )
391 : QValidator( parent, name )
392{
393 b = bottom;
394 t = top;
395 d = decimals;
396}
397
398
399/*!
400 Destroys the validator, freeing any resources used.
401*/
402
403QDoubleValidator::~QDoubleValidator()
404{
405}
406
407
408/*!
409 Returns \c Acceptable if the string \a input contains a double
410 that is within the valid range and is in the correct format.
411
412 Returns \c Intermediate if \a input contains a double that is
413 outside the range or is in the wrong format, e.g. with too many
414 digits after the decimal point or is empty.
415
416 Returns \c Invalid if the \a input is not a double.
417
418 Note: If the valid range consists of just positive doubles (e.g. 0.0 - 100.0)
419 and \a input is a negative double then Invalid is returned.
420*/
421
422QValidator::State QDoubleValidator::validate( QString & input, int & ) const
423{
424 QRegExp empty( QString::fromLatin1(" *-?\\.? *") );
425 if ( b >= 0 &&
426 input.stripWhiteSpace().startsWith(QString::fromLatin1("-")) )
427 return Invalid;
428 if ( empty.exactMatch(input) )
429 return Intermediate;
430 bool ok = TRUE;
431 double entered = input.toDouble( &ok );
432 int nume = input.contains( 'e', FALSE );
433 if ( !ok ) {
434 // explicit exponent regexp
435 QRegExp expexpexp( QString::fromLatin1("[Ee][+-]?\\d*$") );
436 int eeePos = expexpexp.search( input );
437 if ( eeePos > 0 && nume == 1 ) {
438 QString mantissa = input.left( eeePos );
439 entered = mantissa.toDouble( &ok );
440 if ( !ok )
441 return Invalid;
442 } else if ( eeePos == 0 ) {
443 return Intermediate;
444 } else {
445 return Invalid;
446 }
447 }
448
449 int i = input.find( '.' );
450 if ( i >= 0 && nume == 0 ) {
451 // has decimal point (but no E), now count digits after that
452 i++;
453 int j = i;
454 while( input[j].isDigit() )
455 j++;
456 if ( j - i > d )
457 return Intermediate;
458 }
459
460 if ( entered < b || entered > t )
461 return Intermediate;
462 else
463 return Acceptable;
464}
465
466
467/*!
468 Sets the validator to accept doubles from \a minimum to \a maximum
469 inclusive, with at most \a decimals digits after the decimal
470 point.
471*/
472
473void QDoubleValidator::setRange( double minimum, double maximum, int decimals )
474{
475 b = minimum;
476 t = maximum;
477 d = decimals;
478}
479
480/*!
481 \property QDoubleValidator::bottom
482 \brief the validator's minimum acceptable value
483
484 \sa setRange()
485*/
486
487void QDoubleValidator::setBottom( double bottom )
488{
489 setRange( bottom, top(), decimals() );
490}
491
492
493/*!
494 \property QDoubleValidator::top
495 \brief the validator's maximum acceptable value
496
497 \sa setRange()
498*/
499
500void QDoubleValidator::setTop( double top )
501{
502 setRange( bottom(), top, decimals() );
503}
504
505/*!
506 \property QDoubleValidator::decimals
507 \brief the validator's maximum number of digits after the decimal point
508
509 \sa setRange()
510*/
511
512void QDoubleValidator::setDecimals( int decimals )
513{
514 setRange( bottom(), top(), decimals );
515}
516
517
518/*!
519 \class QRegExpValidator
520 \brief The QRegExpValidator class is used to check a string
521 against a regular expression.
522
523 \ingroup misc
524
525 QRegExpValidator contains a regular expression, "regexp", used to
526 determine whether an input string is \c Acceptable, \c
527 Intermediate or \c Invalid.
528
529 The regexp is treated as if it begins with the start of string
530 assertion, <b>^</b>, and ends with the end of string assertion
531 <b>$</b> so the match is against the entire input string, or from
532 the given position if a start position greater than zero is given.
533
534 For a brief introduction to Qt's regexp engine see \l QRegExp.
535
536 Example of use:
537 \code
538 // regexp: optional '-' followed by between 1 and 3 digits
539 QRegExp rx( "-?\\d{1,3}" );
540 QValidator* validator = new QRegExpValidator( rx, this );
541
542 QLineEdit* edit = new QLineEdit( this );
543 edit->setValidator( validator );
544 \endcode
545
546 Below we present some examples of validators. In practice they would
547 normally be associated with a widget as in the example above.
548
549 \code
550 // integers 1 to 9999
551 QRegExp rx( "[1-9]\\d{0,3}" );
552 // the validator treats the regexp as "^[1-9]\\d{0,3}$"
553 QRegExpValidator v( rx, 0 );
554 QString s;
555 int pos = 0;
556
557 s = "0"; v.validate( s, pos ); // returns Invalid
558 s = "12345"; v.validate( s, pos ); // returns Invalid
559 s = "1"; v.validate( s, pos ); // returns Acceptable
560
561 rx.setPattern( "\\S+" ); // one or more non-whitespace characters
562 v.setRegExp( rx );
563 s = "myfile.txt"; v.validate( s, pos ); // Returns Acceptable
564 s = "my file.txt"; v.validate( s, pos ); // Returns Invalid
565
566 // A, B or C followed by exactly five digits followed by W, X, Y or Z
567 rx.setPattern( "[A-C]\\d{5}[W-Z]" );
568 v.setRegExp( rx );
569 s = "a12345Z"; v.validate( s, pos ); // Returns Invalid
570 s = "A12345Z"; v.validate( s, pos ); // Returns Acceptable
571 s = "B12"; v.validate( s, pos ); // Returns Intermediate
572
573 // match most 'readme' files
574 rx.setPattern( "read\\S?me(\.(txt|asc|1st))?" );
575 rx.setCaseSensitive( FALSE );
576 v.setRegExp( rx );
577 s = "readme"; v.validate( s, pos ); // Returns Acceptable
578 s = "README.1ST"; v.validate( s, pos ); // Returns Acceptable
579 s = "read me.txt"; v.validate( s, pos ); // Returns Invalid
580 s = "readm"; v.validate( s, pos ); // Returns Intermediate
581 \endcode
582
583 \sa QRegExp QIntValidator QDoubleValidator
584*/
585
586/*!
587 Constructs a validator that accepts any string (including an empty
588 one) as valid. The object's parent is \a parent and its name is \a
589 name.
590*/
591
592QRegExpValidator::QRegExpValidator( QObject *parent, const char *name )
593 : QValidator( parent, name ), r( QString::fromLatin1(".*") )
594{
595}
596
597/*!
598 Constructs a validator which accepts all strings that match the
599 regular expression \a rx. The object's parent is \a parent and its
600 name is \a name.
601
602 The match is made against the entire string, e.g. if the regexp is
603 <b>[A-Fa-f0-9]+</b> it will be treated as <b>^[A-Fa-f0-9]+$</b>.
604*/
605
606QRegExpValidator::QRegExpValidator( const QRegExp& rx, QObject *parent,
607 const char *name )
608 : QValidator( parent, name ), r( rx )
609{
610}
611
612/*!
613 Destroys the validator, freeing any resources allocated.
614*/
615
616QRegExpValidator::~QRegExpValidator()
617{
618}
619
620/*!
621 Returns \c Acceptable if \a input is matched by the regular
622 expression for this validator, \c Intermediate if it has matched
623 partially (i.e. could be a valid match if additional valid
624 characters are added), and \c Invalid if \a input is not matched.
625
626 The \a pos parameter is set to the length of the \a input parameter.
627
628 For example, if the regular expression is <b>\\w\\d\\d</b> (that
629 is, word-character, digit, digit) then "A57" is \c Acceptable,
630 "E5" is \c Intermediate and "+9" is \c Invalid.
631
632 \sa QRegExp::match() QRegExp::search()
633*/
634
635QValidator::State QRegExpValidator::validate( QString& input, int& pos ) const
636{
637 if ( r.exactMatch(input) ) {
638 return Acceptable;
639 } else {
640 if ( ((QRegExp&) r).matchedLength() == (int) input.length() ) {
641 return Intermediate;
642 } else {
643 pos = input.length();
644 return Invalid;
645 }
646 }
647}
648
649/*!
650 Sets the regular expression used for validation to \a rx.
651
652 \sa regExp()
653*/
654
655void QRegExpValidator::setRegExp( const QRegExp& rx )
656{
657 r = rx;
658}
659
660/*!
661 \fn const QRegExp& QRegExpValidator::regExp() const
662
663 Returns the regular expression used for validation.
664
665 \sa setRegExp()
666*/
667
668#endif
669
670#endif
Note: See TracBrowser for help on using the repository browser.