QGIS API Documentation  3.0.2-Girona (307d082)
qgsfield.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfield.cpp - Describes a field in a layer or table
3  --------------------------------------
4  Date : 01-Jan-2004
5  Copyright : (C) 2004 by Gary E.Sherman
6  email : sherman at mrcc.com
7 
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsfields.h"
18 #include "qgsfield_p.h"
19 #include "qgis.h"
20 #include "qgsapplication.h"
21 #include "qgssettings.h"
22 
23 #include <QDataStream>
24 #include <QIcon>
25 
26 /***************************************************************************
27  * This class is considered CRITICAL and any change MUST be accompanied with
28  * full unit tests in testqgsfield.cpp.
29  * See details in QEP #17
30  ****************************************************************************/
31 
32 #if 0
33 QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
34  QString comment )
35  : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
36  , mComment( comment )
37 {
38  // This function used to lower case the field name since some stores
39  // use upper case (e.g., shapefiles), but that caused problems with
40  // attribute actions getting confused between uppercase and
41  // lowercase versions of the attribute names, so just leave the
42  // names how they are now.
43 }
44 #endif
45 QgsField::QgsField( const QString &name, QVariant::Type type,
46  const QString &typeName, int len, int prec, const QString &comment,
47  QVariant::Type subType )
48 {
49  d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
50 }
51 
52 QgsField::QgsField( const QgsField &other ) //NOLINT
53  : d( other.d )
54 {
55 
56 }
57 
58 /***************************************************************************
59  * This class is considered CRITICAL and any change MUST be accompanied with
60  * full unit tests in testqgsfield.cpp.
61  * See details in QEP #17
62  ****************************************************************************/
63 
64 QgsField &QgsField::operator =( const QgsField &other ) //NOLINT
65 {
66  d = other.d;
67  return *this;
68 }
69 
70 bool QgsField::operator==( const QgsField &other ) const
71 {
72  return *( other.d ) == *d;
73 }
74 
75 bool QgsField::operator!=( const QgsField &other ) const
76 {
77  return !( *this == other );
78 }
79 
80 QString QgsField::name() const
81 {
82  return d->name;
83 }
84 
85 QString QgsField::displayName() const
86 {
87  if ( !d->alias.isEmpty() )
88  return d->alias;
89  else
90  return d->name;
91 }
92 
93 QVariant::Type QgsField::type() const
94 {
95  return d->type;
96 }
97 
98 QVariant::Type QgsField::subType() const
99 {
100  return d->subType;
101 }
102 
103 QString QgsField::typeName() const
104 {
105  return d->typeName;
106 }
107 
108 int QgsField::length() const
109 {
110  return d->length;
111 }
112 
113 int QgsField::precision() const
114 {
115  return d->precision;
116 }
117 
118 QString QgsField::comment() const
119 {
120  return d->comment;
121 }
122 
123 bool QgsField::isNumeric() const
124 {
125  return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
126 }
127 
128 /***************************************************************************
129  * This class is considered CRITICAL and any change MUST be accompanied with
130  * full unit tests in testqgsfield.cpp.
131  * See details in QEP #17
132  ****************************************************************************/
133 
134 void QgsField::setName( const QString &name )
135 {
136  d->name = name;
137 }
138 
139 void QgsField::setType( QVariant::Type type )
140 {
141  d->type = type;
142 }
143 
144 void QgsField::setSubType( QVariant::Type subType )
145 {
146  d->subType = subType;
147 }
148 
149 void QgsField::setTypeName( const QString &typeName )
150 {
151  d->typeName = typeName;
152 }
153 
154 void QgsField::setLength( int len )
155 {
156  d->length = len;
157 }
159 {
160  d->precision = precision;
161 }
162 
163 void QgsField::setComment( const QString &comment )
164 {
165  d->comment = comment;
166 }
167 
169 {
170  return d->defaultValueDefinition;
171 }
172 
174 {
175  d->defaultValueDefinition = defaultValueDefinition;
176 }
177 
179 {
180  d->constraints = constraints;
181 }
182 
184 {
185  return d->constraints;
186 }
187 
188 QString QgsField::alias() const
189 {
190  return d->alias;
191 }
192 
193 void QgsField::setAlias( const QString &alias )
194 {
195  d->alias = alias;
196 }
197 
198 /***************************************************************************
199  * This class is considered CRITICAL and any change MUST be accompanied with
200  * full unit tests in testqgsfield.cpp.
201  * See details in QEP #17
202  ****************************************************************************/
203 
204 QString QgsField::displayString( const QVariant &v ) const
205 {
206  if ( v.isNull() )
207  {
209  }
210 
211  if ( d->type == QVariant::Double && d->precision > 0 )
212  return QString::number( v.toDouble(), 'f', d->precision );
213 
214  return v.toString();
215 }
216 
217 /***************************************************************************
218  * This class is considered CRITICAL and any change MUST be accompanied with
219  * full unit tests in testqgsfield.cpp.
220  * See details in QEP #17
221  ****************************************************************************/
222 
223 bool QgsField::convertCompatible( QVariant &v ) const
224 {
225  if ( v.isNull() )
226  {
227  v.convert( d->type );
228  return true;
229  }
230 
231  if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
232  {
233  v = QVariant( d->type );
234  return false;
235  }
236 
237  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
238  //work around this by first converting to double, and then checking whether the double is convertible to int
239  if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
240  {
241  bool ok = false;
242  double dbl = v.toDouble( &ok );
243  if ( !ok )
244  {
245  //couldn't convert to number
246  v = QVariant( d->type );
247  return false;
248  }
249 
250  double round = std::round( dbl );
251  if ( round > INT_MAX || round < -INT_MAX )
252  {
253  //double too large to fit in int
254  v = QVariant( d->type );
255  return false;
256  }
257  v = QVariant( static_cast< int >( std::round( dbl ) ) );
258  return true;
259  }
260 
261  if ( !v.convert( d->type ) )
262  {
263  v = QVariant( d->type );
264  return false;
265  }
266 
267  if ( d->type == QVariant::Double && d->precision > 0 )
268  {
269  double s = std::pow( 10, d->precision );
270  double d = v.toDouble() * s;
271  v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
272  return true;
273  }
274 
275  if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
276  {
277  v = v.toString().left( d->length );
278  return false;
279  }
280 
281  return true;
282 }
283 
285 {
286  d->editorWidgetSetup = v;
287 }
288 
290 {
291  return d->editorWidgetSetup;
292 }
293 
294 /***************************************************************************
295  * This class is considered CRITICAL and any change MUST be accompanied with
296  * full unit tests in testqgsfield.cpp.
297  * See details in QEP #17
298  ****************************************************************************/
299 
300 QDataStream &operator<<( QDataStream &out, const QgsField &field )
301 {
302  out << field.name();
303  out << static_cast< quint32 >( field.type() );
304  out << field.typeName();
305  out << field.length();
306  out << field.precision();
307  out << field.comment();
308  out << field.alias();
309  out << field.defaultValueDefinition().expression();
310  out << field.defaultValueDefinition().applyOnUpdate();
311  out << field.constraints().constraints();
312  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
313  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
314  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
315  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
316  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
317  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
318  out << field.constraints().constraintExpression();
319  out << field.constraints().constraintDescription();
320  out << static_cast< quint32 >( field.subType() );
321  return out;
322 }
323 
324 QDataStream &operator>>( QDataStream &in, QgsField &field )
325 {
326  quint32 type;
327  quint32 subType;
328  quint32 length;
329  quint32 precision;
330  quint32 constraints;
331  quint32 originNotNull;
332  quint32 originUnique;
333  quint32 originExpression;
334  quint32 strengthNotNull;
335  quint32 strengthUnique;
336  quint32 strengthExpression;
337 
338  bool applyOnUpdate;
339 
340  QString name;
341  QString typeName;
342  QString comment;
343  QString alias;
344  QString defaultValueExpression;
345  QString constraintExpression;
346  QString constraintDescription;
347 
348  in >> name >> type >> typeName >> length >> precision >> comment >> alias
349  >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
350  constraintExpression >> constraintDescription >> subType;
351  field.setName( name );
352  field.setType( static_cast< QVariant::Type >( type ) );
353  field.setTypeName( typeName );
354  field.setLength( static_cast< int >( length ) );
355  field.setPrecision( static_cast< int >( precision ) );
356  field.setComment( comment );
357  field.setAlias( alias );
358  field.setDefaultValueDefinition( QgsDefaultValue( defaultValueExpression, applyOnUpdate ) );
359  QgsFieldConstraints fieldConstraints;
360  if ( constraints & QgsFieldConstraints::ConstraintNotNull )
361  {
362  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
363  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthNotNull ) );
364  }
365  else
366  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintNotNull );
367  if ( constraints & QgsFieldConstraints::ConstraintUnique )
368  {
369  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
370  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthUnique ) );
371  }
372  else
373  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintUnique );
374  if ( constraints & QgsFieldConstraints::ConstraintExpression )
375  {
376  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
377  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthExpression ) );
378  }
379  else
380  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintExpression );
381  fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
382  field.setConstraints( fieldConstraints );
383  field.setSubType( static_cast< QVariant::Type >( subType ) );
384  return in;
385 }
bool isNumeric() const
Returns if this field is numeric.
QgsField & operator=(const QgsField &other)
Assignment operator.
Definition: qgsfield.cpp:64
void setConstraintStrength(Constraint constraint, ConstraintStrength strength)
Sets the strength of a constraint.
QgsField(const QString &name=QString(), QVariant::Type type=QVariant::Invalid, const QString &typeName=QString(), int len=0, int prec=0, const QString &comment=QString(), QVariant::Type subType=QVariant::Invalid)
Constructor.
Definition: qgsfield.cpp:45
QString comment() const
Returns the field comment.
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
QString name
Definition: qgsfield.h:57
int precision
Definition: qgsfield.h:54
QString alias() const
Returns the alias for the field (the friendly displayed name of the field ), or an empty string if th...
QString alias
Definition: qgsfield.h:58
The QgsDefaultValue class provides a container for managing client side default values for fields...
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:158
QString comment
Definition: qgsfield.h:56
QDataStream & operator>>(QDataStream &in, QgsField &field)
Reads a field from stream in into field. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:324
void setDefaultValueDefinition(const QgsDefaultValue &defaultValueDefinition)
Sets an expression to use when calculating the default value for the field.
Definition: qgsfield.cpp:173
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:223
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:134
QgsEditorWidgetSetup editorWidgetSetup() const
Get the editor widget setup for the field.
Definition: qgsfield.cpp:289
int precision() const
Gets the precision of the field.
Stores information about constraints which may be present on a field.
QString name() const
Returns the name of the field.
Field has an expression constraint set. See constraintExpression().
int length
Definition: qgsfield.h:53
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:154
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:103
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:85
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:149
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
bool operator!=(const QgsField &other) const
Definition: qgsfield.cpp:75
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:204
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
void setConstraint(Constraint constraint, ConstraintOrigin origin=ConstraintOriginLayer)
Sets a constraint on the field.
void setSubType(QVariant::Type subType)
If the field is a collection, set its element&#39;s type.
Definition: qgsfield.cpp:144
QgsFieldConstraints constraints
Definition: qgsfield.h:60
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:139
bool operator==(const QgsField &other) const
Definition: qgsfield.cpp:70
void setAlias(const QString &alias)
Sets the alias for the field (the friendly displayed name of the field ).
Definition: qgsfield.cpp:193
void setConstraintExpression(const QString &expression, const QString &description=QString())
Set the constraint expression for the field.
Holder for the widget type and its configuration for a field.
int length() const
Gets the length of the field.
QVariant::Type subType() const
If the field is a collection, gets its element&#39;s type.
Definition: qgsfield.cpp:98
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
const QgsFieldConstraints & constraints() const
Returns constraints which are present for the field.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
void setConstraints(const QgsFieldConstraints &constraints)
Sets constraints which are present for the field.
Definition: qgsfield.cpp:178
void setComment(const QString &comment)
Set the field comment.
Definition: qgsfield.cpp:163
QVariant::Type type
Definition: qgsfield.h:55
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:300
QgsDefaultValue defaultValueDefinition
Definition: qgsfield.h:59
void removeConstraint(Constraint constraint)
Removes a constraint from the field.
QgsDefaultValue defaultValueDefinition() const
Returns the expression used when calculating the default value for the field.
Field must have a unique value.
void setEditorWidgetSetup(const QgsEditorWidgetSetup &v)
Set the editor widget setup for the field.
Definition: qgsfield.cpp:284