QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsfieldvalidator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfieldvalidator.cpp - description
3  -------------------
4  begin : March 2011
5  copyright : (C) 2011 by SunilRajKiran-kCube
6  email : [email protected]
7 
8  adapted version of QValidator for QgsField
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 "qgsfieldvalidator.h"
21 
22 #include <QValidator>
23 #include <QRegularExpression>
24 #include <QRegularExpressionValidator>
25 #include <QDate>
26 #include <QVariant>
27 
28 #include "qgssettings.h"
29 #include "qgslogger.h"
30 #include "qgslonglongvalidator.h"
31 #include "qgsfields.h"
32 #include "qgsapplication.h"
33 
34 QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, const QString &defaultValue, const QString &dateFormat )
35  : QValidator( parent )
36  , mField( field )
37  , mDefaultValue( defaultValue )
38  , mDateFormat( dateFormat )
39 {
40  switch ( mField.type() )
41  {
42  case QVariant::Int:
43  {
44  if ( mField.length() > 0 )
45  {
46  const QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
47  mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
48  }
49  else
50  {
51  mValidator = new QIntValidator( parent );
52  }
53  }
54  break;
55 
56  case QVariant::Double:
57  {
58  if ( mField.length() > 0 && mField.precision() > 0 )
59  {
60  QString re;
61  // Also accept locale's decimalPoint if it's not a dot
62  if ( QLocale().decimalPoint() != '.' )
63  {
64  re = QStringLiteral( "-?\\d{0,%1}([\\.%2]\\d{0,%3})?" ).arg( mField.length() - mField.precision() ).arg( QLocale().decimalPoint() ).arg( mField.precision() );
65  }
66  else
67  {
68  re = QStringLiteral( "-?\\d{0,%1}([\\.,]\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
69  }
70  mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
71  }
72  else if ( mField.length() > 0 && mField.precision() == 0 )
73  {
74  const QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
75  mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
76  }
77  else if ( mField.precision() > 0 )
78  {
79  QString re;
80  // Also accept locale's decimalPoint if it's not a dot
81  if ( QLocale().decimalPoint() != '.' )
82  {
83  re = QStringLiteral( "-?\\d*([\\.%1]\\d{0,%2})?" ).arg( QLocale().decimalPoint(), mField.precision() );
84  }
85  else
86  {
87  re = QStringLiteral( "-?\\d*([\\.]\\d{0,%1})?" ).arg( mField.precision() );
88  }
89  mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
90  }
91  else
92  {
93  mValidator = new QDoubleValidator( parent );
94  }
95  }
96  break;
97 
98  case QVariant::LongLong :
99  mValidator = new QgsLongLongValidator( parent );
100  break;
101 
102  default:
103  mValidator = nullptr;
104  }
105 
106  mNullValue = QgsApplication::nullRepresentation();
107 }
108 
110 {
111  delete mValidator;
112 }
113 
114 QValidator::State QgsFieldValidator::validate( QString &s, int &i ) const
115 {
116  // empty values are considered NULL for numbers and dates and are acceptable
117  if ( s.isEmpty() &&
118  ( mField.type() == QVariant::Double
119  || mField.type() == QVariant::Int
120  || mField.type() == QVariant::LongLong
121  || mField.type() == QVariant::Date
122  )
123  )
124  {
125  return Acceptable;
126  }
127 
128  if ( s == mDefaultValue )
129  return Acceptable;
130 
131  // delegate to the child validator if any
132  if ( mValidator )
133  {
134  const QValidator::State result = mValidator->validate( s, i );
135  return result;
136  }
137  else if ( mField.type() == QVariant::String )
138  {
139  if ( s == mNullValue )
140  return Acceptable;
141 
142  // allow entering the NULL representation, which might be longer than the actual field
143  if ( mField.length() > 0 && s.size() > mField.length() )
144  {
145  if ( !mNullValue.isEmpty() && !s.isEmpty() && s.size() < mNullValue.size() && s == mNullValue.left( s.size() ) )
146  return Intermediate;
147 
148  if ( !mDefaultValue.isEmpty() && !s.isEmpty() && s.size() < mDefaultValue.size() && s == mDefaultValue.left( s.size() ) )
149  return Intermediate;
150 
151  return Invalid;
152  }
153  }
154  else if ( mField.type() == QVariant::Date )
155  {
156  return QDate::fromString( s, mDateFormat ).isValid() ? Acceptable : Intermediate;
157  }
158  else if ( mField.type() == QVariant::Map )
159  {
160  return Acceptable;
161  }
162  else
163  {
164  QgsDebugMsg( QStringLiteral( "unsupported type %1 for validation" ).arg( mField.type() ) );
165  return Invalid;
166  }
167 
168  return Acceptable;
169 }
170 
171 void QgsFieldValidator::fixup( QString &s ) const
172 {
173  if ( mValidator )
174  {
175  mValidator->fixup( s );
176  }
177  else if ( mField.type() == QVariant::String && mField.length() > 0 && s.size() > mField.length() && s != mDefaultValue )
178  {
179  // if the value is longer, this must be a partial NULL representation
180  s = mNullValue;
181  }
182  else if ( mField.type() == QVariant::Date )
183  {
184  // invalid dates will also translate to NULL
185  s = QString();
186  }
187 }
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
State validate(QString &s, int &i) const override
QgsFieldValidator(QObject *parent, const QgsField &field, const QString &defaultValue, const QString &dateFormat="yyyy-MM-dd")
void fixup(QString &s) const override
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
int precision
Definition: qgsfield.h:57
int length
Definition: qgsfield.h:56
QVariant::Type type
Definition: qgsfield.h:58
const QgsField & field
Definition: qgsfield.h:463
#define QgsDebugMsg(str)
Definition: qgslogger.h:38