QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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() ).arg( 1000 ).arg( QLocale().negativeSign() ).arg( QLocale().exponential() ) );
41 setRegularExpression( reg );
42}
43
44QgsDoubleValidator::QgsDoubleValidator( const QRegularExpression &expression, double bottom, double top, QObject *parent )
45 : QRegularExpressionValidator( parent )
46 , mMinimum( bottom )
47 , mMaximum( top )
48{
49 setRegularExpression( expression );
50}
51
52QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, QObject *parent )
53 : QRegularExpressionValidator( parent )
54 , mMinimum( bottom )
55 , mMaximum( top )
56{
57 // The regular expression accept double with point as decimal point but also the locale decimal point
58 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() ).arg( 1000 ).arg( QLocale().negativeSign() ).arg( QLocale().exponential() ) );
59 setRegularExpression( reg );
60}
61
62QgsDoubleValidator::QgsDoubleValidator( double bottom, double top, int decimal, QObject *parent )
63 : QRegularExpressionValidator( parent )
64 , mMinimum( bottom )
65 , mMaximum( top )
66{
67 // The regular expression accept double with point as decimal point but also the locale decimal point
68 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() ).arg( QString::number( decimal ) ).arg( QLocale().negativeSign() ).arg( QLocale().exponential() ) );
69 setRegularExpression( reg );
70}
71
72QgsDoubleValidator::QgsDoubleValidator( int decimal, QObject *parent )
73 : QRegularExpressionValidator( parent )
74 , mMinimum( std::numeric_limits<qreal>::lowest() )
75 , mMaximum( std::numeric_limits<qreal>::max() )
76{
77 // The regular expression accept double with point as decimal point but also the locale decimal point
78 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() ).arg( QString::number( decimal ) ).arg( QLocale().negativeSign() ).arg( QLocale().exponential() ) );
79 setRegularExpression( reg );
80}
81
83{
84 const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( QLocale().decimalPoint() ).arg( QString::number( maxDecimals ) ).arg( QLocale().negativeSign() ).arg( QLocale().exponential() ) );
85 setRegularExpression( reg );
86}
87
88QValidator::State QgsDoubleValidator::validate( QString &input, int & ) const
89{
90 if ( input.isEmpty() )
91 return Intermediate;
92
93
94 bool ok = false;
95 const double entered = QgsDoubleValidator::toDouble( input, &ok );
96 if ( !ok )
97 {
98 if ( regularExpression().match( input ).captured( 0 ) == input )
99 return Intermediate;
100 else
101 return Invalid;
102 }
103
104 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
105 return Acceptable;
106 else
107 return Intermediate;
108}
109
110QValidator::State QgsDoubleValidator::validate( QString &input ) const
111{
112 if ( input.isEmpty() )
113 return Intermediate;
114
115
116 bool ok = false;
117 const double entered = QgsDoubleValidator::toDouble( input, &ok );
118 if ( !ok )
119 {
120 if ( regularExpression().match( input ).captured( 0 ) == input )
121 return Intermediate;
122 else
123 return Invalid;
124 }
125
126 if ( entered >= mMinimum && entered <= mMaximum && regularExpression().match( input ).captured( 0 ) == input )
127 return Acceptable;
128 else
129 return Intermediate;
130}
131
132double QgsDoubleValidator::toDouble( const QString &input )
133{
134 bool ok = false;
135 return toDouble( input, &ok );
136}
137
138double QgsDoubleValidator::toDouble( const QString &input, bool *ok )
139{
140 double value = QLocale().toDouble( input, ok );
141
142 if ( !*ok )
143 {
144 value = QLocale( QLocale::C ).toDouble( input, ok );
145 }
146 // Still non ok? Try without locale's group separator
147 if ( !*ok && !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
148 {
149 value = QLocale().toDouble( QString( input ).replace( QLocale().groupSeparator(), QString() ), ok );
150 }
151 return value;
152}
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