File indexing completed on 2024-04-21 14:55:57
0001 /********************************************************************** 0002 ** 0003 ** 0004 ** KIntValidator: 0005 ** Copyright (C) 1999 Glen Parker <glenebob@nwlink.com> 0006 ** KDoubleValidator: 0007 ** Copyright (c) 2002 Marc Mutz <mutz@kde.org> 0008 ** 0009 ** This library is free software; you can redistribute it and/or 0010 ** modify it under the terms of the GNU Library General Public 0011 ** License as published by the Free Software Foundation; either 0012 ** version 2 of the License, or (at your option) any later version. 0013 ** 0014 ** This library is distributed in the hope that it will be useful, 0015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 ** Library General Public License for more details. 0018 ** 0019 ** You should have received a copy of the GNU Library General Public 0020 ** License along with this library; if not, write to the Free 0021 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0022 ** 0023 *****************************************************************************/ 0024 0025 #include "knumvalidator.h" 0026 0027 #include <QWidget> 0028 #include <QCharRef> 0029 0030 #include <klocale.h> 0031 #include <kdebug.h> 0032 0033 /////////////////////////////////////////////////////////////// 0034 // Implementation of KIntValidator 0035 // 0036 class Q_DECL_HIDDEN KIntValidator::KIntValidatorPrivate 0037 { 0038 public: 0039 KIntValidatorPrivate() 0040 : _base(0), _min(0), _max(0) 0041 {} 0042 int _base; 0043 int _min; 0044 int _max; 0045 }; 0046 0047 KIntValidator::KIntValidator(QWidget *parent, int base) 0048 : QValidator(parent), d(new KIntValidatorPrivate) 0049 { 0050 setBase(base); 0051 } 0052 0053 KIntValidator::KIntValidator(int bottom, int top, QWidget *parent, int base) 0054 : QValidator(parent), d(new KIntValidatorPrivate) 0055 { 0056 setBase(base); 0057 setRange(bottom, top); 0058 } 0059 0060 KIntValidator::~KIntValidator() 0061 { 0062 delete d; 0063 } 0064 0065 QValidator::State KIntValidator::validate(QString &str, int &) const 0066 { 0067 bool ok; 0068 int val = 0; 0069 QString newStr; 0070 0071 newStr = str.trimmed(); 0072 if (d->_base > 10) { 0073 newStr = newStr.toUpper(); 0074 } 0075 0076 if (newStr == QLatin1String("-")) {// a special case 0077 if ((d->_min || d->_max) && d->_min >= 0) { 0078 ok = false; 0079 } else { 0080 return QValidator::Acceptable; 0081 } 0082 } else if (!newStr.isEmpty()) { 0083 val = newStr.toInt(&ok, d->_base); 0084 } else { 0085 val = 0; 0086 ok = true; 0087 } 0088 0089 if (! ok) { 0090 return QValidator::Invalid; 0091 } 0092 0093 if ((! d->_min && ! d->_max) || (val >= d->_min && val <= d->_max)) { 0094 return QValidator::Acceptable; 0095 } 0096 0097 if (d->_max && d->_min >= 0 && val < 0) { 0098 return QValidator::Invalid; 0099 } 0100 0101 return QValidator::Intermediate; 0102 } 0103 0104 void KIntValidator::fixup(QString &str) const 0105 { 0106 int dummy; 0107 int val; 0108 QValidator::State state; 0109 0110 state = validate(str, dummy); 0111 0112 if (state == QValidator::Invalid || state == QValidator::Acceptable) { 0113 return; 0114 } 0115 0116 if (! d->_min && ! d->_max) { 0117 return; 0118 } 0119 0120 val = str.toInt(nullptr, d->_base); 0121 0122 if (val < d->_min) { 0123 val = d->_min; 0124 } 0125 if (val > d->_max) { 0126 val = d->_max; 0127 } 0128 0129 str.setNum(val, d->_base); 0130 } 0131 0132 void KIntValidator::setRange(int bottom, int top) 0133 { 0134 d->_min = bottom; 0135 d->_max = top; 0136 0137 if (d->_max < d->_min) { 0138 d->_max = d->_min; 0139 } 0140 } 0141 0142 void KIntValidator::setBase(int base) 0143 { 0144 d->_base = base; 0145 if (d->_base < 2) { 0146 d->_base = 2; 0147 } 0148 if (d->_base > 36) { 0149 d->_base = 36; 0150 } 0151 } 0152 0153 int KIntValidator::bottom() const 0154 { 0155 return d->_min; 0156 } 0157 0158 int KIntValidator::top() const 0159 { 0160 return d->_max; 0161 } 0162 0163 int KIntValidator::base() const 0164 { 0165 return d->_base; 0166 } 0167 0168 /////////////////////////////////////////////////////////////// 0169 // Implementation of KDoubleValidator 0170 // 0171 0172 class Q_DECL_HIDDEN KDoubleValidator::KDoubleValidatorPrivate 0173 { 0174 public: 0175 KDoubleValidatorPrivate(bool accept = true) : acceptLocalizedNumbers(accept) {} 0176 0177 bool acceptLocalizedNumbers; 0178 }; 0179 0180 KDoubleValidator::KDoubleValidator(QObject *parent) 0181 : QDoubleValidator(parent), d(new KDoubleValidatorPrivate()) 0182 { 0183 } 0184 0185 KDoubleValidator::KDoubleValidator(double bottom, double top, int decimals, 0186 QObject *parent) 0187 : QDoubleValidator(bottom, top, decimals, parent), d(new KDoubleValidatorPrivate()) 0188 { 0189 } 0190 0191 KDoubleValidator::~KDoubleValidator() 0192 { 0193 delete d; 0194 } 0195 0196 bool KDoubleValidator::acceptLocalizedNumbers() const 0197 { 0198 return d->acceptLocalizedNumbers; 0199 } 0200 0201 void KDoubleValidator::setAcceptLocalizedNumbers(bool accept) 0202 { 0203 d->acceptLocalizedNumbers = accept; 0204 } 0205 0206 QValidator::State KDoubleValidator::validate(QString &input, int &p) const 0207 { 0208 QString s = input; 0209 if (acceptLocalizedNumbers()) { 0210 KLocale *l = KLocale::global(); 0211 // ok, we have to re-format the number to have: 0212 // 1. decimalSymbol == '.' 0213 // 2. negativeSign == '-' 0214 // 3. positiveSign == <empty> 0215 // 4. thousandsSeparator() == <empty> (we don't check that there 0216 // are exactly three decimals between each separator): 0217 QString d = l->decimalSymbol(), 0218 n = l->negativeSign(), 0219 p = l->positiveSign(), 0220 t = l->thousandsSeparator(); 0221 // first, delete p's and t's: 0222 if (!p.isEmpty()) 0223 for (int idx = s.indexOf(p); idx >= 0; idx = s.indexOf(p, idx)) { 0224 s.remove(idx, p.length()); 0225 } 0226 0227 if (!t.isEmpty()) 0228 for (int idx = s.indexOf(t); idx >= 0; idx = s.indexOf(t, idx)) { 0229 s.remove(idx, t.length()); 0230 } 0231 0232 // then, replace the d's and n's 0233 if ((!n.isEmpty() && n.indexOf('.') != -1) || 0234 (!d.isEmpty() && d.indexOf('-') != -1)) { 0235 // make sure we don't replace something twice: 0236 kWarning() << "KDoubleValidator: decimal symbol contains '-' or " 0237 "negative sign contains '.' -> improve algorithm" << endl; 0238 return Invalid; 0239 } 0240 0241 if (!d.isEmpty() && d != ".") 0242 for (int idx = s.indexOf(d); idx >= 0; idx = s.indexOf(d, idx + 1)) { 0243 s.replace(idx, d.length(), '.'); 0244 } 0245 0246 if (!n.isEmpty() && n != "-") 0247 for (int idx = s.indexOf(n); idx >= 0; idx = s.indexOf(n, idx + 1)) { 0248 s.replace(idx, n.length(), '-'); 0249 } 0250 } 0251 0252 return base::validate(s, p); 0253 } 0254 0255 #include "moc_knumvalidator.cpp"