QGIS API Documentation  3.25.0-Master (dec16ba68b)
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 : [email protected]
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 
28 const 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 
40 QgsDoubleValidator::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 
48 QgsDoubleValidator::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 
58 QgsDoubleValidator::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 
68 QgsDoubleValidator::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 
78 void QgsDoubleValidator::setMaxDecimals( int maxDecimals )
79 {
80  const QRegularExpression reg( PERMISSIVE_DOUBLE.arg( locale().decimalPoint() ).arg( QString::number( maxDecimals ) ) );
81  setRegularExpression( reg );
82 }
83 
84 QValidator::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 
106 QValidator::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 
128 double QgsDoubleValidator::toDouble( const QString &input )
129 {
130  bool ok = false;
131  return toDouble( input, &ok );
132 }
133 
134 double 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