kdeui: simplify KDoubleValidator

the validation now depends entire on the locale, top and bottom values
(i.e. on how QDoubleValidator validates)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-03-14 19:59:38 +02:00
parent 57832e3e37
commit 84ea11af90
2 changed files with 19 additions and 65 deletions

View file

@ -176,11 +176,20 @@ int KIntValidator::base() const
// Implementation of KDoubleValidator // Implementation of KDoubleValidator
// //
static void kAcceptLocalizedNumbers(KDoubleValidator *validator, const bool accept)
{
if (accept) {
validator->setLocale(KGlobal::locale()->toLocale());
} else {
validator->setLocale(QLocale::c());
}
}
class KDoubleValidator::KDoubleValidatorPrivate class KDoubleValidator::KDoubleValidatorPrivate
{ {
public: public:
KDoubleValidatorPrivate(bool accept = true) KDoubleValidatorPrivate()
: acceptLocalizedNumbers(accept) : acceptLocalizedNumbers(true)
{ {
} }
@ -191,12 +200,14 @@ KDoubleValidator::KDoubleValidator(QObject *parent)
: QDoubleValidator(parent), : QDoubleValidator(parent),
d(new KDoubleValidatorPrivate()) d(new KDoubleValidatorPrivate())
{ {
kAcceptLocalizedNumbers(this, true);
} }
KDoubleValidator::KDoubleValidator(double bottom, double top, int decimals, QObject *parent) KDoubleValidator::KDoubleValidator(double bottom, double top, int decimals, QObject *parent)
: QDoubleValidator(bottom, top, decimals, parent), : QDoubleValidator(bottom, top, decimals, parent),
d(new KDoubleValidatorPrivate()) d(new KDoubleValidatorPrivate())
{ {
kAcceptLocalizedNumbers(this, true);
} }
KDoubleValidator::~KDoubleValidator() KDoubleValidator::~KDoubleValidator()
@ -212,60 +223,7 @@ bool KDoubleValidator::acceptLocalizedNumbers() const
void KDoubleValidator::setAcceptLocalizedNumbers(bool accept) void KDoubleValidator::setAcceptLocalizedNumbers(bool accept)
{ {
d->acceptLocalizedNumbers = accept; d->acceptLocalizedNumbers = accept;
} kAcceptLocalizedNumbers(this, accept);
QValidator::State KDoubleValidator::validate(QString &input, int &p) const
{
QString s = input;
if (acceptLocalizedNumbers()) {
KLocale* l = KGlobal::locale();
const QLocale ll = l->toLocale();
// ok, we have to re-format the number to have:
// 1. decimalPoint == '.'
// 2. negativeSign == '-'
// 3. positiveSign == <empty>
// 4. groupSeparator() == <empty> (we don't check that there
// are exactly three decimals between each separator):
QString d = ll.decimalPoint();
QString n = ll.negativeSign();
QString p = ll.positiveSign();
QString t = ll.groupSeparator();
// first, delete p's and t's:
if (!p.isEmpty()) {
for (int idx = s.indexOf(p); idx >= 0; idx = s.indexOf(p, idx)) {
s.remove(idx, p.length());
}
}
if (!t.isEmpty()) {
for (int idx = s.indexOf(t); idx >= 0; idx = s.indexOf(t, idx)) {
s.remove(idx, t.length());
}
}
// then, replace the d's and n's
if ((!n.isEmpty() && n.indexOf('.') != -1) || (!d.isEmpty() && d.indexOf('-') != -1)) {
// make sure we don't replace something twice:
kWarning() << "KDoubleValidator: decimal symbol contains '-' or "
"negative sign contains '.' -> improve algorithm";
return QValidator::Invalid;
}
if (!d.isEmpty() && d != ".") {
for (int idx = s.indexOf(d); idx >= 0; idx = s.indexOf(d, idx + 1)) {
s.replace(idx, d.length(), '.');
}
}
if (!n.isEmpty() && n != "-") {
for (int idx = s.indexOf(n); idx >= 0; idx = s.indexOf(n, idx + 1)) {
s.replace(idx, n.length(), '-');
}
}
}
return base::validate(s, p);
} }
#include "moc_knumvalidator.cpp" #include "moc_knumvalidator.cpp"

View file

@ -92,10 +92,10 @@ class KDEUI_EXPORT KIntValidator : public QValidator {
/** /**
@short A locale-aware QDoubleValidator @short A locale-aware QDoubleValidator
KDoubleValidator extends QDoubleValidator to be KDoubleValidator extends QDoubleValidator to be locale-aware. That
locale-aware. That means that - subject to not being disabled - means that - subject to not being disabled - the system locale
the system locale decimal point, thousand separator, positive decimal point, thousand separator, positive and negative sign are
and negative sign are used for validation. used for validation.
@author Marc Mutz <mutz@kde.org> @author Marc Mutz <mutz@kde.org>
@see KIntValidator @see KIntValidator
@ -113,21 +113,17 @@ public:
top] and a precision of @p decimals decimals after the decimal top] and a precision of @p decimals decimals after the decimal
point. */ point. */
KDoubleValidator( double bottom, double top, int decimals, KDoubleValidator( double bottom, double top, int decimals,
QObject * parent ); QObject * parent );
/** Destructs the validator. /** Destructs the validator.
*/ */
virtual ~KDoubleValidator(); virtual ~KDoubleValidator();
/** Overloaded for internal reasons. The API is not affected. */
virtual QValidator::State validate( QString & input, int & pos ) const;
/** @return whether localized numbers are accepted (default: true) */ /** @return whether localized numbers are accepted (default: true) */
bool acceptLocalizedNumbers() const; bool acceptLocalizedNumbers() const;
/** Sets whether to accept localized numbers (default: true) */ /** Sets whether to accept localized numbers (default: true) */
void setAcceptLocalizedNumbers( bool accept ); void setAcceptLocalizedNumbers( bool accept );
private: private:
typedef QDoubleValidator base;
class KDoubleValidatorPrivate; class KDoubleValidatorPrivate;
KDoubleValidatorPrivate * const d; KDoubleValidatorPrivate * const d;
}; };