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