QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsdoublevalidator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdoublevalidator.cpp - description
3 -------------------
4 begin : June 2020
5 copyright : (C) 2020 by Sebastien Peillet
7
8 adapted version of Qgslonglongvalidator + QgsFieldValidator
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include "qgsdoublevalidator.h"
21
22#include <limits>
23
24#include "qgis_gui.h"
25
26#include <QLocale>
27#include <QRegularExpression>
28#include <QRegularExpressionValidator>
29
30#include "moc_qgsdoublevalidator.cpp"
31
32const QString PERMISSIVE_DOUBLE = R"([+\-%3]?[\d]{0,1000}([\.%1][\d]{0,1000})?([eE%4][+\-%3]?[\d]{0,%2})?)";
33
35 : QRegularExpressionValidator( parent )
36 , mMinimum( std::numeric_limits<qreal>::lowest() )
37 , mMaximum( std::numeric_limits<qreal>::max() )
38{
39 // The regular expression accept double with point as decimal point but also the locale decimal point
40 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
41 .arg( 1000 )
42 .arg( QLocale().negativeSign() )
43 .arg( QLocale().exponential() ) );
44 setRegularExpression( reg );
45}
46
47QgsDoubleValidator::QgsDoubleValidator( const QRegularExpression &expression, double bottom, double top, QObject *parent )
48 : QRegularExpressionValidator( parent )
49 , mMinimum( bottom )
50 , mMaximum( top )
51{
52 setRegularExpression( expression );
53}
54
55QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, QObject *parent )
56 : QRegularExpressionValidator( parent )
57 , mMinimum( bottom )
58 , mMaximum( top )
59{
60 // The regular expression accept double with point as decimal point but also the locale decimal point
61 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
62 .arg( 1000 )
63 .arg( QLocale().negativeSign() )
64 .arg( QLocale().exponential() ) );
65 setRegularExpression( reg );
66}
67
68QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, int decimal, QObject *parent )
69 : QRegularExpressionValidator( parent )
70 , mMinimum( bottom )
71 , mMaximum( top )
72{
73 // The regular expression accept double with point as decimal point but also the locale decimal point
74 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
75 .arg( QString::number( decimal ) )
76 .arg( QLocale().negativeSign() )
77 .arg( QLocale().exponential() ) );
78 setRegularExpression( reg );
79}
80
81QgsDoubleValidator::QgsDoubleValidator( int decimal, QObject *parent )
82 : QRegularExpressionValidator( parent )
83 , mMinimum( std::numeric_limits<qreal>::lowest() )
84 , mMaximum( std::numeric_limits<qreal>::max() )
85{
86 // The regular expression accept double with point as decimal point but also the locale decimal point
87 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
88 .arg( QString::number( decimal ) )
89 .arg( QLocale().negativeSign() )
90 .arg( QLocale().exponential() ) );
91 setRegularExpression( reg );
92}
93
95{
96 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
97 .arg( QString::number( maxDecimals ) )
98 .arg( QLocale().negativeSign() )
99 .arg( QLocale().exponential() ) );
100 setRegularExpression( reg );
101}
102
103QValidator::State QgsDoubleValidator::validate( QString &input, int & ) const
104{
105 if ( input.isEmpty() )
106 return Intermediate;
107
108
109 bool ok = false;
110 const double entered = QgsDoubleValidator::toDouble( input, &ok );
111 if ( !ok )
112 {
113 if ( regularExpression().match( input ).captured( 0 ) == input )
114 return Intermediate;
115 else
116 return Invalid;
117 }
118
119 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
120 return Acceptable;
121 else
122 return Intermediate;
123}
124
125QValidator::State QgsDoubleValidator::validate( QString &input ) const
126{
127 if ( input.isEmpty() )
128 return Intermediate;
129
130
131 bool ok = false;
132 const double entered = QgsDoubleValidator::toDouble( input, &ok );
133 if ( !ok )
134 {
135 if ( regularExpression().match( input ).captured( 0 ) == input )
136 return Intermediate;
137 else
138 return Invalid;
139 }
140
141 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
142 return Acceptable;
143 else
144 return Intermediate;
145}
146
147double QgsDoubleValidator::toDouble( const QString &input )
148{
149 bool ok = false;
150 return toDouble( input, &ok );
151}
152
153double QgsDoubleValidator::toDouble( const QString &input, bool *ok )
154{
155 double value = QLocale().toDouble( input, ok );
156
157 if ( !*ok )
158 {
159 value = QLocale( QLocale::C ).toDouble( input, ok );
160 }
161 // Still non ok? Try without locale's group separator
162 if ( !*ok && !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
163 {
164 value = QLocale().toDouble( QString( input ).replace( QLocale().groupSeparator(), QString() ), ok );
165 }
166 return value;
167}
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
QgsDoubleValidator(QObject *parent)
Constructor for QgsDoubleValidator.
double top() const
Returns top range limit.
QValidator::State validate(QString &input, int &) const override
void setMaxDecimals(int maxDecimals)
Sets the number of decimals accepted by the validator to maxDecimals.
double bottom() const
Returns top range limit.
const QString PERMISSIVE_DOUBLE