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