QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
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#include "moc_qgsfieldvalidator.cpp"
22
23#include <QValidator>
24#include <QRegularExpression>
25#include <QRegularExpressionValidator>
26#include <QDate>
27#include <QVariant>
28
29#include "qgssettings.h"
30#include "qgslogger.h"
32#include "qgsfields.h"
33#include "qgsapplication.h"
34
35QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, const QString &defaultValue, const QString &dateFormat )
36 : QValidator( parent )
37 , mField( field )
38 , mDefaultValue( defaultValue )
39 , mDateFormat( dateFormat )
40{
41 switch ( mField.type() )
42 {
43 case QMetaType::Type::Int:
44 {
45 if ( mField.length() > 0 )
46 {
47 const QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
48 mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
49 }
50 else
51 {
52 mValidator = new QIntValidator( parent );
53 }
54 }
55 break;
56
57 case QMetaType::Type::Double:
58 {
59 if ( mField.length() > 0 && mField.precision() > 0 )
60 {
61 QString re;
62 // Also accept locale's decimalPoint if it's not a dot
63 if ( QLocale().decimalPoint() != '.' )
64 {
65 re = QStringLiteral( "-?\\d{0,%1}([\\.%2]\\d{0,%3})?" ).arg( mField.length() - mField.precision() ).arg( QLocale().decimalPoint() ).arg( mField.precision() );
66 }
67 else
68 {
69 re = QStringLiteral( "-?\\d{0,%1}([\\.,]\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
70 }
71 mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
72 }
73 else if ( mField.length() > 0 && mField.precision() == 0 )
74 {
75 const QString re = QStringLiteral( "-?\\d{0,%1}" ).arg( mField.length() );
76 mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
77 }
78 else if ( mField.precision() > 0 )
79 {
80 QString re;
81 // Also accept locale's decimalPoint if it's not a dot
82 if ( QLocale().decimalPoint() != '.' )
83 {
84 re = QStringLiteral( "-?\\d*([\\.%1]\\d{0,%2})?" ).arg( QLocale().decimalPoint(), mField.precision() );
85 }
86 else
87 {
88 re = QStringLiteral( "-?\\d*([\\.]\\d{0,%1})?" ).arg( mField.precision() );
89 }
90 mValidator = new QRegularExpressionValidator( QRegularExpression( re ), parent );
91 }
92 else
93 {
94 mValidator = new QDoubleValidator( parent );
95 }
96 }
97 break;
98
99 case QMetaType::Type::LongLong:
100 mValidator = new QgsLongLongValidator( parent );
101 break;
102
103 default:
104 mValidator = nullptr;
105 }
106
108}
109
111{
112 delete mValidator;
113}
114
115QValidator::State QgsFieldValidator::validate( QString &s, int &i ) const
116{
117 // empty values are considered NULL for numbers and dates and are acceptable
118 if ( s.isEmpty() && ( mField.type() == QMetaType::Type::Double || mField.type() == QMetaType::Type::Int || mField.type() == QMetaType::Type::LongLong || mField.type() == QMetaType::Type::QDate ) )
119 {
120 return Acceptable;
121 }
122
123 if ( s == mDefaultValue )
124 return Acceptable;
125
126 // delegate to the child validator if any
127 if ( mValidator )
128 {
129 const QValidator::State result = mValidator->validate( s, i );
130 return result;
131 }
132 else if ( mField.type() == QMetaType::Type::QString )
133 {
134 if ( s == mNullValue )
135 return Acceptable;
136
137 // allow entering the NULL representation, which might be longer than the actual field
138 if ( mField.length() > 0 && s.size() > mField.length() )
139 {
140 if ( !mNullValue.isEmpty() && !s.isEmpty() && s.size() < mNullValue.size() && s == mNullValue.left( s.size() ) )
141 return Intermediate;
142
143 if ( !mDefaultValue.isEmpty() && !s.isEmpty() && s.size() < mDefaultValue.size() && s == mDefaultValue.left( s.size() ) )
144 return Intermediate;
145
146 return Invalid;
147 }
148 }
149 else if ( mField.type() == QMetaType::Type::QDate )
150 {
151 return QDate::fromString( s, mDateFormat ).isValid() ? Acceptable : Intermediate;
152 }
153 else if ( mField.type() == QMetaType::Type::QVariantMap )
154 {
155 return Acceptable;
156 }
157 else if ( mField.type() == QMetaType::Type::User && mField.typeName().compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
158 {
159 return Acceptable;
160 }
161 else
162 {
164 QStringLiteral( "unsupported type %1 (%2) for validation" )
165 .arg( mField.type() )
166 .arg( mField.typeName() )
167 );
168 return Invalid;
169 }
170
171 return Acceptable;
172}
173
174void QgsFieldValidator::fixup( QString &s ) const
175{
176 if ( mValidator )
177 {
178 mValidator->fixup( s );
179 }
180 else if ( mField.type() == QMetaType::Type::QString && mField.length() > 0 && s.size() > mField.length() && s != mDefaultValue )
181 {
182 // if the value is longer, this must be a partial NULL representation
183 s = mNullValue;
184 }
185 else if ( mField.type() == QMetaType::Type::QDate )
186 {
187 // invalid dates will also translate to NULL
188 s = QString();
189 }
190}
static QString nullRepresentation()
Returns the string 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
QMetaType::Type type
Definition qgsfield.h:60
QString typeName() const
Gets the field type.
Definition qgsfield.cpp:161
int precision
Definition qgsfield.h:59
int length
Definition qgsfield.h:58
#define QgsDebugError(str)
Definition qgslogger.h:38