KDEUI
knumvalidator.cpp
Go to the documentation of this file.
00001 /********************************************************************** 00002 ** 00003 ** 00004 ** KIntValidator, KFloatValidator: 00005 ** Copyright (C) 1999 Glen Parker <glenebob@nwlink.com> 00006 ** KDoubleValidator: 00007 ** Copyright (c) 2002 Marc Mutz <mutz@kde.org> 00008 ** 00009 ** This library is free software; you can redistribute it and/or 00010 ** modify it under the terms of the GNU Library General Public 00011 ** License as published by the Free Software Foundation; either 00012 ** version 2 of the License, or (at your option) any later version. 00013 ** 00014 ** This library is distributed in the hope that it will be useful, 00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 ** Library General Public License for more details. 00018 ** 00019 ** You should have received a copy of the GNU Library General Public 00020 ** License along with this library; if not, write to the Free 00021 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 ** 00023 *****************************************************************************/ 00024 00025 #include "knumvalidator.h" 00026 00027 #include <QtGui/QWidget> 00028 #include <QtCore/QCharRef> 00029 00030 #include <klocale.h> 00031 #include <kglobal.h> 00032 #include <kdebug.h> 00033 00035 // Implementation of KIntValidator 00036 // 00037 class KIntValidator::KIntValidatorPrivate 00038 { 00039 public: 00040 KIntValidatorPrivate() 00041 : _base(0), _min(0), _max(0) 00042 {} 00043 int _base; 00044 int _min; 00045 int _max; 00046 }; 00047 00048 KIntValidator::KIntValidator ( QWidget * parent, int base ) 00049 : QValidator(parent), d(new KIntValidatorPrivate) 00050 { 00051 setBase(base); 00052 } 00053 00054 KIntValidator::KIntValidator ( int bottom, int top, QWidget * parent, int base ) 00055 : QValidator(parent), d(new KIntValidatorPrivate) 00056 { 00057 setBase(base); 00058 setRange(bottom, top); 00059 } 00060 00061 KIntValidator::~KIntValidator () 00062 { 00063 delete d; 00064 } 00065 00066 QValidator::State KIntValidator::validate ( QString &str, int & ) const 00067 { 00068 bool ok; 00069 int val = 0; 00070 QString newStr; 00071 00072 newStr = str.trimmed(); 00073 if (d->_base > 10) 00074 newStr = newStr.toUpper(); 00075 00076 if (newStr == QLatin1String("-")) {// a special case 00077 if ((d->_min || d->_max) && d->_min >= 0) 00078 ok = false; 00079 else 00080 return QValidator::Acceptable; 00081 } 00082 else if (!newStr.isEmpty()) 00083 val = newStr.toInt(&ok, d->_base); 00084 else { 00085 val = 0; 00086 ok = true; 00087 } 00088 00089 if (! ok) 00090 return QValidator::Invalid; 00091 00092 if ((! d->_min && ! d->_max) || (val >= d->_min && val <= d->_max)) 00093 return QValidator::Acceptable; 00094 00095 if (d->_max && d->_min >= 0 && val < 0) 00096 return QValidator::Invalid; 00097 00098 return QValidator::Intermediate; 00099 } 00100 00101 void KIntValidator::fixup ( QString &str ) const 00102 { 00103 int dummy; 00104 int val; 00105 QValidator::State state; 00106 00107 state = validate(str, dummy); 00108 00109 if (state == QValidator::Invalid || state == QValidator::Acceptable) 00110 return; 00111 00112 if (! d->_min && ! d->_max) 00113 return; 00114 00115 val = str.toInt(0, d->_base); 00116 00117 if (val < d->_min) val = d->_min; 00118 if (val > d->_max) val = d->_max; 00119 00120 str.setNum(val, d->_base); 00121 } 00122 00123 void KIntValidator::setRange ( int bottom, int top ) 00124 { 00125 d->_min = bottom; 00126 d->_max = top; 00127 00128 if (d->_max < d->_min) 00129 d->_max = d->_min; 00130 } 00131 00132 void KIntValidator::setBase ( int base ) 00133 { 00134 d->_base = base; 00135 if (d->_base < 2) d->_base = 2; 00136 if (d->_base > 36) d->_base = 36; 00137 } 00138 00139 int KIntValidator::bottom () const 00140 { 00141 return d->_min; 00142 } 00143 00144 int KIntValidator::top () const 00145 { 00146 return d->_max; 00147 } 00148 00149 int KIntValidator::base () const 00150 { 00151 return d->_base; 00152 } 00153 00154 00156 // Implementation of KFloatValidator 00157 // 00158 00159 class KFloatValidator::KFloatValidatorPrivate 00160 { 00161 public: 00162 KFloatValidatorPrivate() 00163 : acceptLocalizedNumbers(false), _min(0), _max(0) 00164 {} 00165 bool acceptLocalizedNumbers; 00166 double _min; 00167 double _max; 00168 }; 00169 00170 00171 KFloatValidator::KFloatValidator ( QWidget * parent ) 00172 : QValidator(parent), d(new KFloatValidatorPrivate) 00173 { 00174 d->acceptLocalizedNumbers=false; 00175 } 00176 00177 KFloatValidator::KFloatValidator ( double bottom, double top, QWidget * parent ) 00178 : QValidator(parent), d(new KFloatValidatorPrivate) 00179 { 00180 d->acceptLocalizedNumbers=false; 00181 setRange(bottom, top); 00182 } 00183 00184 KFloatValidator::KFloatValidator ( double bottom, double top, bool localeAware, QWidget * parent ) 00185 : QValidator(parent), d(new KFloatValidatorPrivate) 00186 { 00187 d->acceptLocalizedNumbers = localeAware; 00188 setRange(bottom, top); 00189 } 00190 00191 KFloatValidator::~KFloatValidator () 00192 { 00193 delete d; 00194 } 00195 00196 void KFloatValidator::setAcceptLocalizedNumbers(bool _b) 00197 { 00198 d->acceptLocalizedNumbers=_b; 00199 } 00200 00201 bool KFloatValidator::acceptLocalizedNumbers() const 00202 { 00203 return d->acceptLocalizedNumbers; 00204 } 00205 00206 QValidator::State KFloatValidator::validate ( QString &str, int & ) const 00207 { 00208 bool ok; 00209 double val = 0; 00210 QString newStr; 00211 newStr = str.trimmed(); 00212 00213 if (newStr == QLatin1String("-")) {// a special case 00214 if ((d->_min || d->_max) && d->_min >= 0) 00215 ok = false; 00216 else 00217 return QValidator::Acceptable; 00218 } 00219 else if (newStr == QLatin1String(".") || (d->acceptLocalizedNumbers && newStr==KGlobal::locale()->decimalSymbol())) // another special case 00220 return QValidator::Acceptable; 00221 else if (!newStr.isEmpty()) 00222 { 00223 val = newStr.toDouble(&ok); 00224 if(!ok && d->acceptLocalizedNumbers) 00225 val= KGlobal::locale()->readNumber(newStr,&ok); 00226 } 00227 else { 00228 val = 0; 00229 ok = true; 00230 } 00231 00232 if (! ok) 00233 return QValidator::Invalid; 00234 00235 if (( !d->_min && !d->_max) || (val >= d->_min && val <= d->_max)) 00236 return QValidator::Acceptable; 00237 00238 if (d->_max && d->_min >= 0 && val < 0) 00239 return QValidator::Invalid; 00240 00241 if ( (d->_min || d->_max) && (val < d->_min || val > d->_max)) 00242 return QValidator::Invalid; 00243 00244 return QValidator::Intermediate; 00245 } 00246 00247 void KFloatValidator::fixup ( QString &str ) const 00248 { 00249 int dummy; 00250 double val; 00251 QValidator::State state; 00252 00253 state = validate(str, dummy); 00254 00255 if (state == QValidator::Invalid || state == QValidator::Acceptable) 00256 return; 00257 00258 if (! d->_min && ! d->_max) 00259 return; 00260 00261 val = str.toDouble(); 00262 00263 if (val < d->_min) val = d->_min; 00264 if (val > d->_max) val = d->_max; 00265 00266 str.setNum(val); 00267 } 00268 00269 void KFloatValidator::setRange ( double bottom, double top ) 00270 { 00271 d->_min = bottom; 00272 d->_max = top; 00273 00274 if (d->_max < d->_min) 00275 d->_max = d->_min; 00276 } 00277 00278 double KFloatValidator::bottom () const 00279 { 00280 return d->_min; 00281 } 00282 00283 double KFloatValidator::top () const 00284 { 00285 return d->_max; 00286 } 00287 00288 00289 00290 00292 // Implementation of KDoubleValidator 00293 // 00294 00295 class KDoubleValidator::KDoubleValidatorPrivate { 00296 public: 00297 KDoubleValidatorPrivate( bool accept=true ) : acceptLocalizedNumbers( accept ) {} 00298 00299 bool acceptLocalizedNumbers; 00300 }; 00301 00302 KDoubleValidator::KDoubleValidator( QObject * parent ) 00303 : QDoubleValidator( parent ), d( new KDoubleValidatorPrivate() ) 00304 { 00305 } 00306 00307 KDoubleValidator::KDoubleValidator( double bottom, double top, int decimals, 00308 QObject * parent ) 00309 : QDoubleValidator( bottom, top, decimals, parent ), d( new KDoubleValidatorPrivate() ) 00310 { 00311 } 00312 00313 KDoubleValidator::~KDoubleValidator() 00314 { 00315 delete d; 00316 } 00317 00318 bool KDoubleValidator::acceptLocalizedNumbers() const { 00319 return d->acceptLocalizedNumbers; 00320 } 00321 00322 void KDoubleValidator::setAcceptLocalizedNumbers( bool accept ) { 00323 d->acceptLocalizedNumbers = accept; 00324 } 00325 00326 QValidator::State KDoubleValidator::validate( QString & input, int & p ) const { 00327 QString s = input; 00328 if ( acceptLocalizedNumbers() ) { 00329 KLocale * l = KGlobal::locale(); 00330 // ok, we have to re-format the number to have: 00331 // 1. decimalSymbol == '.' 00332 // 2. negativeSign == '-' 00333 // 3. positiveSign == <empty> 00334 // 4. thousandsSeparator() == <empty> (we don't check that there 00335 // are exactly three decimals between each separator): 00336 QString d = l->decimalSymbol(), 00337 n = l->negativeSign(), 00338 p = l->positiveSign(), 00339 t = l->thousandsSeparator(); 00340 // first, delete p's and t's: 00341 if ( !p.isEmpty() ) 00342 for ( int idx = s.indexOf( p ) ; idx >= 0 ; idx = s.indexOf( p, idx ) ) 00343 s.remove( idx, p.length() ); 00344 00345 00346 if ( !t.isEmpty() ) 00347 for ( int idx = s.indexOf( t ) ; idx >= 0 ; idx = s.indexOf( t, idx ) ) 00348 s.remove( idx, t.length() ); 00349 00350 // then, replace the d's and n's 00351 if ( ( !n.isEmpty() && n.indexOf('.') != -1 ) || 00352 ( !d.isEmpty() && d.indexOf('-') != -1 ) ) { 00353 // make sure we don't replace something twice: 00354 kWarning() << "KDoubleValidator: decimal symbol contains '-' or " 00355 "negative sign contains '.' -> improve algorithm" << endl; 00356 return Invalid; 00357 } 00358 00359 if ( !d.isEmpty() && d != "." ) 00360 for ( int idx = s.indexOf( d ) ; idx >= 0 ; idx = s.indexOf( d, idx + 1 ) ) 00361 s.replace( idx, d.length(), '.'); 00362 00363 if ( !n.isEmpty() && n != "-" ) 00364 for ( int idx = s.indexOf( n ) ; idx >= 0 ; idx = s.indexOf( n, idx + 1 ) ) 00365 s.replace( idx, n.length(), '-' ); 00366 } 00367 00368 return base::validate( s, p ); 00369 } 00370 00371 #include "knumvalidator.moc"
KDE 4.6 API Reference