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