QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 : sunilraj.kiran@kcubeconsulting.com
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 #include <QSettings>
27 
28 #include "qgslogger.h"
29 #include "qgslonglongvalidator.h"
30 #include "qgsfield.h"
31 
32 QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, QString defaultValue, QString dateFormat )
33  : QValidator( parent )
34  , mField( field )
35  , mDefaultValue( defaultValue )
36  , mDateFormat( dateFormat )
37 {
38  switch ( mField.type() )
39  {
40  case QVariant::Int:
41  {
42  if ( mField.length() > 0 )
43  {
44  QString re = QString( "-?\\d{0,%1}" ).arg( mField.length() );
45  mValidator = new QRegExpValidator( QRegExp( re ), parent );
46  }
47  else
48  {
49  mValidator = new QIntValidator( parent );
50  }
51  }
52  break;
53 
54  case QVariant::Double:
55  {
56  if ( mField.length() > 0 && mField.precision() > 0 )
57  {
58  QString re = QString( "-?\\d{0,%1}(\\.\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
59  mValidator = new QRegExpValidator( QRegExp( re ), parent );
60  }
61  else if ( mField.length() > 0 && mField.precision() == 0 )
62  {
63  QString re = QString( "-?\\d{0,%1}" ).arg( mField.length() );
64  mValidator = new QRegExpValidator( QRegExp( re ), parent );
65  }
66  else if ( mField.precision() > 0 )
67  {
68  QString re = QString( "-?\\d*(\\.\\d{0,%1})?" ).arg( mField.precision() );
69  mValidator = new QRegExpValidator( QRegExp( re ), parent );
70  }
71  else
72  {
73  mValidator = new QDoubleValidator( parent );
74  }
75  }
76  break;
77 
78  case QVariant::LongLong :
79  mValidator = new QgsLongLongValidator( parent );
80  break;
81 
82  default:
83  mValidator = 0;
84  }
85 
86  QSettings settings;
87  mNullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
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  QValidator::State result = mValidator->validate( s, i );
116  return result;
117  }
118  else if ( mField.type() == QVariant::String )
119  {
120  // allow to enter the NULL representation, which might be
121  // longer than the actual field
122  if ( mNullValue.size() > 0 && s.size() > 0 && s.size() < mNullValue.size() && s == mNullValue.left( s.size() ) )
123  return Intermediate;
124 
125  if ( mDefaultValue.size() > 0 && s.size() > 0 && s.size() < mDefaultValue.size() && s == mDefaultValue.left( s.size() ) )
126  return Intermediate;
127 
128  if ( s == mNullValue )
129  return Acceptable;
130 
131  if ( mField.length() > 0 && s.size() > mField.length() )
132  return Invalid;
133  }
134  else if ( mField.type() == QVariant::Date )
135  {
136  return QDate::fromString( s, mDateFormat ).isValid() ? Acceptable : Intermediate;
137  }
138  else
139  {
140  QgsDebugMsg( QString( "unsupported type %1 for validation" ).arg( mField.type() ) );
141  return Invalid;
142  }
143 
144  return Acceptable;
145 }
146 
148 {
149  if ( mValidator )
150  {
151  mValidator->fixup( s );
152  }
153  else if ( mField.type() == QVariant::String && mField.length() > 0 && s.size() > mField.length() && s != mDefaultValue )
154  {
155  // if the value is longer, this must be a partial NULL representation
156  s = mNullValue;
157  }
158  else if ( mField.type() == QVariant::Date )
159  {
160  // invalid dates will also translate to NULL
161  s = "";
162  }
163 }
virtual State validate(QString &, int &) const override
virtual void fixup(QString &input) const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
int size() const
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:90
QDate fromString(const QString &string, Qt::DateFormat format)
bool isEmpty() const
bool isValid() const
virtual void fixup(QString &) const override
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:40
virtual State validate(QString &input, int &pos) const =0
QVariant value(const QString &key, const QVariant &defaultValue) const
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:85
QString left(int n) const
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
QgsFieldValidator(QObject *parent, const QgsField &field, QString defaultValue, QString dateFormat="yyyy-MM-dd")
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:75