QGIS API Documentation  3.0.2-Girona (307d082)
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 <QRegExpValidator>
24 #include <QDate>
25 #include <QVariant>
26 
27 #include "qgssettings.h"
28 #include "qgslogger.h"
29 #include "qgslonglongvalidator.h"
30 #include "qgsfields.h"
31 #include "qgsapplication.h"
32 
33 QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, const QString &defaultValue, const QString &dateFormat )
34  : QValidator( parent )
35  , mField( field )
36  , mDefaultValue( defaultValue )
37  , mDateFormat( dateFormat )
38 {
39  switch ( mField.type() )
40  {
41  case QVariant::Int:
42  {
43  if ( mField.length() > 0 )
44  {
45  QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
46  mValidator = new QRegExpValidator( QRegExp( re ), parent );
47  }
48  else
49  {
50  mValidator = new QIntValidator( parent );
51  }
52  }
53  break;
54 
55  case QVariant::Double:
56  {
57  if ( mField.length() > 0 && mField.precision() > 0 )
58  {
59  QString re = QStringLiteral( "-?\\d{0,%1}(\\.\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
60  mValidator = new QRegExpValidator( QRegExp( re ), parent );
61  }
62  else if ( mField.length() > 0 && mField.precision() == 0 )
63  {
64  QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
65  mValidator = new QRegExpValidator( QRegExp( re ), parent );
66  }
67  else if ( mField.precision() > 0 )
68  {
69  QString re = QStringLiteral( "-?\\d*(\\.\\d{0,%1})?" ).arg( mField.precision() );
70  mValidator = new QRegExpValidator( QRegExp( re ), parent );
71  }
72  else
73  {
74  mValidator = new QDoubleValidator( parent );
75  }
76  }
77  break;
78 
79  case QVariant::LongLong :
80  mValidator = new QgsLongLongValidator( parent );
81  break;
82 
83  default:
84  mValidator = nullptr;
85  }
86 
88 }
89 
91 {
92  delete mValidator;
93 }
94 
95 QValidator::State QgsFieldValidator::validate( QString &s, int &i ) const
96 {
97  // empty values are considered NULL for numbers and dates and are acceptable
98  if ( s.isEmpty() &&
99  ( mField.type() == QVariant::Double
100  || mField.type() == QVariant::Int
101  || mField.type() == QVariant::LongLong
102  || mField.type() == QVariant::Date
103  )
104  )
105  {
106  return Acceptable;
107  }
108 
109  if ( s == mDefaultValue )
110  return Acceptable;
111 
112  // delegate to the child validator if any
113  if ( mValidator )
114  {
115  // force to use the '.' as a decimal point or in case we are using QDoubleValidator
116  // we can get a valid number with a comma depending on current locale
117  // ... but this will fail subsequently when converted from string to double and
118  // becomes a NULL!
119  if ( mField.type() == QVariant::Double )
120  s = s.replace( ',', '.' );
121  QValidator::State result = mValidator->validate( s, i );
122  return result;
123  }
124  else if ( mField.type() == QVariant::String )
125  {
126  // allow entering the NULL representation, which might be
127  // longer than the actual field
128  if ( !mNullValue.isEmpty() && !s.isEmpty() && s.size() < mNullValue.size() && s == mNullValue.left( s.size() ) )
129  return Intermediate;
130 
131  if ( !mDefaultValue.isEmpty() && !s.isEmpty() && s.size() < mDefaultValue.size() && s == mDefaultValue.left( s.size() ) )
132  return Intermediate;
133 
134  if ( s == mNullValue )
135  return Acceptable;
136 
137  if ( mField.length() > 0 && s.size() > mField.length() )
138  return Invalid;
139  }
140  else if ( mField.type() == QVariant::Date )
141  {
142  return QDate::fromString( s, mDateFormat ).isValid() ? Acceptable : Intermediate;
143  }
144  else
145  {
146  QgsDebugMsg( QString( "unsupported type %1 for validation" ).arg( mField.type() ) );
147  return Invalid;
148  }
149 
150  return Acceptable;
151 }
152 
153 void QgsFieldValidator::fixup( QString &s ) const
154 {
155  if ( mValidator )
156  {
157  mValidator->fixup( s );
158  }
159  else if ( mField.type() == QVariant::String && mField.length() > 0 && s.size() > mField.length() && s != mDefaultValue )
160  {
161  // if the value is longer, this must be a partial NULL representation
162  s = mNullValue;
163  }
164  else if ( mField.type() == QVariant::Date )
165  {
166  // invalid dates will also translate to NULL
167  s = QLatin1String( "" );
168  }
169 }
int precision
Definition: qgsfield.h:54
State validate(QString &s, int &i) const override
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsFieldValidator(QObject *parent, const QgsField &field, const QString &defaultValue, const QString &dateFormat="yyyy-MM-dd")
int length
Definition: qgsfield.h:53
~QgsFieldValidator() override
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
void fixup(QString &s) const override
QVariant::Type type
Definition: qgsfield.h:55