QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
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"
31#include "qgsfields.h"
32#include "qgsapplication.h"
33
34QgsFieldValidator::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
107}
108
110{
111 delete mValidator;
112}
113
114QValidator::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 if ( mField.type() == QVariant::UserType && mField.typeName().compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
163 {
164 return Acceptable;
165 }
166 else
167 {
169 QStringLiteral( "unsupported type %1 (%2) for validation" )
170 .arg( mField.type() )
171 .arg( mField.typeName() )
172 );
173 return Invalid;
174 }
175
176 return Acceptable;
177}
178
179void QgsFieldValidator::fixup( QString &s ) const
180{
181 if ( mValidator )
182 {
183 mValidator->fixup( s );
184 }
185 else if ( mField.type() == QVariant::String && mField.length() > 0 && s.size() > mField.length() && s != mDefaultValue )
186 {
187 // if the value is longer, this must be a partial NULL representation
188 s = mNullValue;
189 }
190 else if ( mField.type() == QVariant::Date )
191 {
192 // invalid dates will also translate to NULL
193 s = QString();
194 }
195}
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:53
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:150
int precision
Definition: qgsfield.h:59
int length
Definition: qgsfield.h:58
QVariant::Type type
Definition: qgsfield.h:60
#define QgsDebugError(str)
Definition: qgslogger.h:38