QGIS API Documentation  2.99.0-Master (0a63d1f)
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 
22 #include <QSettings>
23 #include <QDataStream>
24 #include <QtCore/qmath.h>
25 #include <QIcon>
26 
27 /***************************************************************************
28  * This class is considered CRITICAL and any change MUST be accompanied with
29  * full unit tests in testqgsfield.cpp.
30  * See details in QEP #17
31  ****************************************************************************/
32 
33 #if 0
34 QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
35  QString comment )
36  : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
37  , mComment( comment )
38 {
39  // This function used to lower case the field name since some stores
40  // use upper case (e.g., shapefiles), but that caused problems with
41  // attribute actions getting confused between uppercase and
42  // lowercase versions of the attribute names, so just leave the
43  // names how they are now.
44 }
45 #endif
46 QgsField::QgsField( const QString& name, QVariant::Type type,
47  const QString& typeName, int len, int prec, const QString& comment,
48  QVariant::Type subType )
49 {
50  d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
51 }
52 
54  : d( other.d )
55 {
56 
57 }
58 
59 /***************************************************************************
60  * This class is considered CRITICAL and any change MUST be accompanied with
61  * full unit tests in testqgsfield.cpp.
62  * See details in QEP #17
63  ****************************************************************************/
64 
66 {
67  d = other.d;
68  return *this;
69 }
70 
71 bool QgsField::operator==( const QgsField& other ) const
72 {
73  return *( other.d ) == *d;
74 }
75 
76 bool QgsField::operator!=( const QgsField& other ) const
77 {
78  return !( *this == other );
79 }
80 
81 QString QgsField::name() const
82 {
83  return d->name;
84 }
85 
86 QString QgsField::displayName() const
87 {
88  if ( !d->alias.isEmpty() )
89  return d->alias;
90  else
91  return d->name;
92 }
93 
94 QVariant::Type QgsField::type() const
95 {
96  return d->type;
97 }
98 
99 QVariant::Type QgsField::subType() const
100 {
101  return d->subType;
102 }
103 
104 QString QgsField::typeName() const
105 {
106  return d->typeName;
107 }
108 
109 int QgsField::length() const
110 {
111  return d->length;
112 }
113 
114 int QgsField::precision() const
115 {
116  return d->precision;
117 }
118 
119 QString QgsField::comment() const
120 {
121  return d->comment;
122 }
123 
124 bool QgsField::isNumeric() const
125 {
126  return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
127 }
128 
129 /***************************************************************************
130  * This class is considered CRITICAL and any change MUST be accompanied with
131  * full unit tests in testqgsfield.cpp.
132  * See details in QEP #17
133  ****************************************************************************/
134 
135 void QgsField::setName( const QString& name )
136 {
137  d->name = name;
138 }
139 
140 void QgsField::setType( QVariant::Type type )
141 {
142  d->type = type;
143 }
144 
145 void QgsField::setSubType( QVariant::Type subType )
146 {
147  d->subType = subType;
148 }
149 
150 void QgsField::setTypeName( const QString& typeName )
151 {
152  d->typeName = typeName;
153 }
154 
155 void QgsField::setLength( int len )
156 {
157  d->length = len;
158 }
160 {
161  d->precision = precision;
162 }
163 
164 void QgsField::setComment( const QString& comment )
165 {
166  d->comment = comment;
167 }
168 
169 QString QgsField::defaultValueExpression() const
170 {
171  return d->defaultValueExpression;
172 }
173 
174 void QgsField::setDefaultValueExpression( const QString& expression )
175 {
176  d->defaultValueExpression = expression;
177 }
178 
180 {
181  d->constraints = constraints;
182 }
183 
185 {
186  return d->constraints;
187 }
188 
189 QString QgsField::alias() const
190 {
191  return d->alias;
192 }
193 
194 void QgsField::setAlias( const QString& alias )
195 {
196  d->alias = alias;
197 }
198 
199 /***************************************************************************
200  * This class is considered CRITICAL and any change MUST be accompanied with
201  * full unit tests in testqgsfield.cpp.
202  * See details in QEP #17
203  ****************************************************************************/
204 
205 QString QgsField::displayString( const QVariant& v ) const
206 {
207  if ( v.isNull() )
208  {
209  QSettings settings;
211  }
212 
213  if ( d->type == QVariant::Double && d->precision > 0 )
214  return QString::number( v.toDouble(), 'f', d->precision );
215 
216  return v.toString();
217 }
218 
219 /***************************************************************************
220  * This class is considered CRITICAL and any change MUST be accompanied with
221  * full unit tests in testqgsfield.cpp.
222  * See details in QEP #17
223  ****************************************************************************/
224 
225 bool QgsField::convertCompatible( QVariant& v ) const
226 {
227  if ( v.isNull() )
228  {
229  v.convert( d->type );
230  return true;
231  }
232 
233  if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
234  {
235  v = QVariant( d->type );
236  return false;
237  }
238 
239  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
240  //work around this by first converting to double, and then checking whether the double is convertible to int
241  if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
242  {
243  bool ok = false;
244  double dbl = v.toDouble( &ok );
245  if ( !ok )
246  {
247  //couldn't convert to number
248  v = QVariant( d->type );
249  return false;
250  }
251 
252  double round = qgsRound( dbl );
253  if ( round > INT_MAX || round < -INT_MAX )
254  {
255  //double too large to fit in int
256  v = QVariant( d->type );
257  return false;
258  }
259  v = QVariant( qRound( dbl ) );
260  return true;
261  }
262 
263  if ( !v.convert( d->type ) )
264  {
265  v = QVariant( d->type );
266  return false;
267  }
268 
269  if ( d->type == QVariant::Double && d->precision > 0 )
270  {
271  double s = qPow( 10, d->precision );
272  double d = v.toDouble() * s;
273  v = QVariant(( d < 0 ? ceil( d - 0.5 ) : floor( d + 0.5 ) ) / s );
274  return true;
275  }
276 
277  if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
278  {
279  v = v.toString().left( d->length );
280  return false;
281  }
282 
283  return true;
284 }
285 
287 {
288  d->editorWidgetSetup = v;
289 }
290 
292 {
293  return d->editorWidgetSetup;
294 }
295 
296 /***************************************************************************
297  * This class is considered CRITICAL and any change MUST be accompanied with
298  * full unit tests in testqgsfield.cpp.
299  * See details in QEP #17
300  ****************************************************************************/
301 
302 QDataStream& operator<<( QDataStream& out, const QgsField& field )
303 {
304  out << field.name();
305  out << static_cast< quint32 >( field.type() );
306  out << field.typeName();
307  out << field.length();
308  out << field.precision();
309  out << field.comment();
310  out << field.alias();
311  out << field.defaultValueExpression();
312  out << field.constraints().constraints();
313  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
314  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
315  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
316  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
317  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
318  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
319  out << field.constraints().constraintExpression();
320  out << field.constraints().constraintDescription();
321  out << static_cast< quint32 >( field.subType() );
322  return out;
323 }
324 
325 QDataStream& operator>>( QDataStream& in, QgsField& field )
326 {
327  quint32 type, subType, length, precision, constraints, originNotNull, originUnique, originExpression, strengthNotNull, strengthUnique, strengthExpression;
328  QString name, typeName, comment, alias, defaultValueExpression, constraintExpression, constraintDescription;
329  in >> name >> type >> typeName >> length >> precision >> comment >> alias
330  >> defaultValueExpression >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
331  constraintExpression >> constraintDescription >> subType;
332  field.setName( name );
333  field.setType( static_cast< QVariant::Type >( type ) );
334  field.setTypeName( typeName );
335  field.setLength( static_cast< int >( length ) );
336  field.setPrecision( static_cast< int >( precision ) );
337  field.setComment( comment );
338  field.setAlias( alias );
339  field.setDefaultValueExpression( defaultValueExpression );
340  QgsFieldConstraints fieldConstraints;
341  if ( constraints & QgsFieldConstraints::ConstraintNotNull )
342  {
343  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
344  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthNotNull ) );
345  }
346  else
347  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintNotNull );
348  if ( constraints & QgsFieldConstraints::ConstraintUnique )
349  {
350  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
351  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthUnique ) );
352  }
353  else
354  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintUnique );
355  if ( constraints & QgsFieldConstraints::ConstraintExpression )
356  {
357  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
358  fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthExpression ) );
359  }
360  else
361  fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintExpression );
362  fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
363  field.setConstraints( fieldConstraints );
364  field.setSubType( static_cast< QVariant::Type >( subType ) );
365  return in;
366 }
bool isNumeric() const
Returns if this field is numeric.
QgsField & operator=(const QgsField &other)
Assignment operator.
Definition: qgsfield.cpp:65
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:46
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:53
int precision
Definition: qgsfield.h:51
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:54
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:159
QString comment
Definition: qgsfield.h:52
QDataStream & operator>>(QDataStream &in, QgsField &field)
Reads a field from stream in into field. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:325
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:225
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:135
QgsEditorWidgetSetup editorWidgetSetup() const
Get the editor widget setup for the field.
Definition: qgsfield.cpp:291
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:50
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:155
double qgsRound(double x)
A round function which returns a double to guard against overflows.
Definition: qgis.h:226
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:104
QString defaultValueExpression
Definition: qgsfield.h:55
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:86
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:150
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:76
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:205
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:45
void setDefaultValueExpression(const QString &expression)
Sets an expression to use when calculating the default value for the field.
Definition: qgsfield.cpp:174
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:145
QgsFieldConstraints constraints
Definition: qgsfield.h:56
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:140
bool operator==(const QgsField &other) const
Definition: qgsfield.cpp:71
QString defaultValueExpression() const
Returns the expression used when calculating the default value for the field.
void setAlias(const QString &alias)
Sets the alias for the field (the friendly displayed name of the field ).
Definition: qgsfield.cpp:194
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:99
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.
Definition: qgsfield.cpp:94
void setConstraints(const QgsFieldConstraints &constraints)
Sets constraints which are present for the field.
Definition: qgsfield.cpp:179
void setComment(const QString &comment)
Set the field comment.
Definition: qgsfield.cpp:164
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:302
void removeConstraint(Constraint constraint)
Removes a constraint from the field.
Field must have a unique value.
void setEditorWidgetSetup(const QgsEditorWidgetSetup &v)
Set the editor widget setup for the field.
Definition: qgsfield.cpp:286