QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 <limits>
21#include <QRegularExpressionValidator>
22#include <QRegularExpression>
23#include <QLocale>
24#include "qgis_gui.h"
25
26#include "qgsdoublevalidator.h"
27
28const QString PERMISSIVE_DOUBLE = R"([+\-%3]?[\d]{0,1000}([\.%1][\d]{0,1000})?([eE%4][+\-%3]?[\d]{0,%2})?)";
29
31 : QRegularExpressionValidator( parent )
32 , mMinimum( std::numeric_limits<qreal>::lowest() )
33 , mMaximum( std::numeric_limits<qreal>::max() )
34{
35 // The regular expression accept double with point as decimal point but also the locale decimal point
36 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
37 .arg( 1000 )
38 .arg( QLocale().negativeSign() )
39 .arg( QLocale().exponential() ) );
40 setRegularExpression( reg );
41}
42
43QgsDoubleValidator::QgsDoubleValidator( const QRegularExpression &expression, double bottom, double top, QObject *parent )
44 : QRegularExpressionValidator( parent )
45 , mMinimum( bottom )
46 , mMaximum( top )
47{
48 setRegularExpression( expression );
49}
50
51QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, QObject *parent )
52 : QRegularExpressionValidator( parent )
53 , mMinimum( bottom )
54 , mMaximum( top )
55{
56 // The regular expression accept double with point as decimal point but also the locale decimal point
57 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
58 .arg( 1000 )
59 .arg( QLocale().negativeSign() )
60 .arg( QLocale().exponential() ) );
61 setRegularExpression( reg );
62}
63
64QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, int decimal, QObject *parent )
65 : QRegularExpressionValidator( parent )
66 , mMinimum( bottom )
67 , mMaximum( top )
68{
69 // The regular expression accept double with point as decimal point but also the locale decimal point
70 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
71 .arg( QString::number( decimal ) )
72 .arg( QLocale().negativeSign() )
73 .arg( QLocale().exponential() ) );
74 setRegularExpression( reg );
75}
76
77QgsDoubleValidator::QgsDoubleValidator( int decimal, QObject *parent )
78 : QRegularExpressionValidator( parent )
79 , mMinimum( std::numeric_limits<qreal>::lowest() )
80 , mMaximum( std::numeric_limits<qreal>::max() )
81{
82 // The regular expression accept double with point as decimal point but also the locale decimal point
83 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
84 .arg( QString::number( decimal ) )
85 .arg( QLocale().negativeSign() )
86 .arg( QLocale().exponential() ) );
87 setRegularExpression( reg );
88}
89
91{
92 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() )
93 .arg( QString::number( maxDecimals ) )
94 .arg( QLocale().negativeSign() )
95 .arg( QLocale().exponential() ) );
96 setRegularExpression( reg );
97}
98
99QValidator::State QgsDoubleValidator::validate( QString &input, int & ) const
100{
101 if ( input.isEmpty() )
102 return Intermediate;
103
104
105 bool ok = false;
106 const double entered = QgsDoubleValidator::toDouble( input, &ok );
107 if ( ! ok )
108 {
109 if ( regularExpression().match( input ).captured( 0 ) == input )
110 return Intermediate;
111 else
112 return Invalid;
113 }
114
115 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
116 return Acceptable;
117 else
118 return Intermediate;
119}
120
121QValidator::State QgsDoubleValidator::validate( QString &input ) const
122{
123 if ( input.isEmpty() )
124 return Intermediate;
125
126
127 bool ok = false;
128 const double entered = QgsDoubleValidator::toDouble( input, &ok );
129 if ( ! ok )
130 {
131 if ( regularExpression().match( input ).captured( 0 ) == input )
132 return Intermediate;
133 else
134 return Invalid;
135 }
136
137 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
138 return Acceptable;
139 else
140 return Intermediate;
141}
142
143double QgsDoubleValidator::toDouble( const QString &input )
144{
145 bool ok = false;
146 return toDouble( input, &ok );
147}
148
149double QgsDoubleValidator::toDouble( const QString &input, bool *ok )
150{
151 double value = QLocale().toDouble( input, ok );
152
153 if ( ! *ok )
154 {
155 value = QLocale( QLocale::C ).toDouble( input, ok );
156 }
157 // Still non ok? Try without locale's group separator
158 if ( ! *ok && !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
159 {
160 value = QLocale().toDouble( QString( input ).replace( QLocale().groupSeparator(), QString() ), ok );
161 }
162 return value ;
163}
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
QgsDoubleValidator(QObject *parent)
Constructor for QgsDoubleValidator.
QValidator::State validate(QString &input, int &) const override
void setMaxDecimals(int maxDecimals)
Sets the number of decimals accepted by the validator to maxDecimals.
const QString PERMISSIVE_DOUBLE