QGIS API Documentation  2.12.0-Lyon
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 "qgsfield.h"
18 #include "qgsfield_p.h"
19 #include "qgis.h"
20 
21 #include <QSettings>
22 #include <QDataStream>
23 #include <QtCore/qmath.h>
24 
25 
26 #if 0
27 QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
28  QString comment )
29  : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
30  , mComment( comment )
31 {
32  // This function used to lower case the field name since some stores
33  // use upper case (eg. shapefiles), but that caused problems with
34  // attribute actions getting confused between uppercase and
35  // lowercase versions of the attribute names, so just leave the
36  // names how they are now.
37 }
38 #endif
39 QgsField::QgsField( const QString& name, QVariant::Type type,
40  const QString& typeName, int len, int prec, const QString& comment )
41 {
42  d = new QgsFieldPrivate( name, type, typeName, len, prec, comment );
43 }
44 
46  : d( other.d )
47 {
48 
49 }
50 
52 {
53  d = other.d;
54  return *this;
55 }
56 
57 
59 {
60 }
61 
62 bool QgsField::operator==( const QgsField& other ) const
63 {
64  return *( other.d ) == *d;
65 }
66 
67 bool QgsField::operator!=( const QgsField& other ) const
68 {
69  return !( *this == other );
70 }
71 
72 const QString & QgsField::name() const
73 {
74  return d->name;
75 }
76 
77 QVariant::Type QgsField::type() const
78 {
79  return d->type;
80 }
81 
82 const QString & QgsField::typeName() const
83 {
84  return d->typeName;
85 }
86 
87 int QgsField::length() const
88 {
89  return d->length;
90 }
91 
93 {
94  return d->precision;
95 }
96 
97 const QString & QgsField::comment() const
98 {
99  return d->comment;
100 }
101 
102 void QgsField::setName( const QString& name )
103 {
104  d->name = name;
105 }
106 
107 void QgsField::setType( QVariant::Type type )
108 {
109  d->type = type;
110 }
111 
112 void QgsField::setTypeName( const QString& typeName )
113 {
114  d->typeName = typeName;
115 }
116 
117 void QgsField::setLength( int len )
118 {
119  d->length = len;
120 }
121 void QgsField::setPrecision( int precision )
122 {
123  d->precision = precision;
124 }
125 
126 void QgsField::setComment( const QString& comment )
127 {
128  d->comment = comment;
129 }
130 
132 {
133  if ( v.isNull() )
134  {
135  QSettings settings;
136  return settings.value( "qgis/nullValue", "NULL" ).toString();
137  }
138 
139  if ( d->type == QVariant::Double && d->precision > 0 )
140  return QString::number( v.toDouble(), 'f', d->precision );
141 
142  return v.toString();
143 }
144 
146 {
147  if ( v.isNull() )
148  {
149  v.convert( d->type );
150  return true;
151  }
152 
153  if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
154  {
155  v = QVariant( d->type );
156  return false;
157  }
158 
159  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
160  //work around this by first converting to double, and then checking whether the double is convertible to int
161  if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
162  {
163  bool ok = false;
164  double dbl = v.toDouble( &ok );
165  if ( !ok )
166  {
167  //couldn't convert to number
168  v = QVariant( d->type );
169  return false;
170  }
171 
172  double round = qgsRound( dbl );
173  if ( round > INT_MAX || round < -INT_MAX )
174  {
175  //double too large to fit in int
176  v = QVariant( d->type );
177  return false;
178  }
179  v = QVariant( qRound( dbl ) );
180  return true;
181  }
182 
183  if ( !v.convert( d->type ) )
184  {
185  v = QVariant( d->type );
186  return false;
187  }
188 
189  if ( d->type == QVariant::Double && d->precision > 0 )
190  {
191  double s = qPow( 10, d->precision );
192  double d = v.toDouble() * s;
193  v = QVariant(( d < 0 ? ceil( d - 0.5 ) : floor( d + 0.5 ) ) / s );
194  return true;
195  }
196 
197  if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
198  {
199  v = v.toString().left( d->length );
200  return false;
201  }
202 
203  return true;
204 }
205 
206 
208 {
209  out << field.name();
210  out << ( quint32 )field.type();
211  out << field.typeName();
212  out << field.length();
213  out << field.precision();
214  out << field.comment();
215  return out;
216 }
217 
219 {
220  quint32 type, length, precision;
221  QString name, typeName, comment;
222  in >> name >> type >> typeName >> length >> precision >> comment;
223  field.setName( name );
224  field.setType(( QVariant::Type )type );
225  field.setTypeName( typeName );
226  field.setLength(( int )length );
227  field.setPrecision(( int )precision );
228  field.setComment( comment );
229  return in;
230 }
231 
233 
235 {
236  d = new QgsFieldsPrivate( );
237 }
238 
240  : d( other.d )
241 {
242 }
243 
245 {
246  d = other.d;
247  return *this;
248 }
249 
251 {
252 
253 }
254 
256 {
257  d->fields.clear();
258  d->nameToIndex.clear();
259 }
260 
261 bool QgsFields::append( const QgsField& field, FieldOrigin origin, int originIndex )
262 {
263  if ( d->nameToIndex.contains( field.name() ) )
264  return false;
265 
266  if ( originIndex == -1 && origin == OriginProvider )
267  originIndex = d->fields.count();
268  d->fields.append( Field( field, origin, originIndex ) );
269 
270  d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
271  return true;
272 }
273 
274 bool QgsFields::appendExpressionField( const QgsField& field, int originIndex )
275 {
276  if ( d->nameToIndex.contains( field.name() ) )
277  return false;
278 
279  d->fields.append( Field( field, OriginExpression, originIndex ) );
280 
281  d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
282  return true;
283 }
284 
285 void QgsFields::remove( int fieldIdx )
286 {
287  if ( !exists( fieldIdx ) )
288  return;
289 
290  d->fields.remove( fieldIdx );
291  d->nameToIndex.clear();
292  for ( int idx = 0; idx < count(); ++idx )
293  {
294  d->nameToIndex.insert( d->fields[idx].field.name(), idx );
295  }
296 }
297 
298 void QgsFields::extend( const QgsFields& other )
299 {
300  for ( int i = 0; i < other.count(); ++i )
301  {
302  append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
303  }
304 }
305 
306 bool QgsFields::isEmpty() const
307 {
308  return d->fields.isEmpty();
309 }
310 
311 int QgsFields::count() const
312 {
313  return d->fields.count();
314 }
315 
316 int QgsFields::size() const
317 {
318  return d->fields.count();
319 }
320 
321 bool QgsFields::exists( int i ) const
322 {
323  return i >= 0 && i < d->fields.count();
324 }
325 
327 {
328  return d->fields[i].field;
329 }
330 
331 const QgsField &QgsFields::at( int i ) const
332 {
333  return d->fields[i].field;
334 }
335 
336 const QgsField &QgsFields::field( int fieldIdx ) const
337 {
338  return d->fields[fieldIdx].field;
339 }
340 
341 const QgsField &QgsFields::field( const QString &name ) const
342 {
343  return d->fields[ indexFromName( name )].field;
344 }
345 
346 const QgsField &QgsFields::operator[]( int i ) const
347 {
348  return d->fields[i].field;
349 }
350 
352 {
353  if ( !exists( fieldIdx ) )
354  return OriginUnknown;
355 
356  return d->fields[fieldIdx].origin;
357 }
358 
359 int QgsFields::fieldOriginIndex( int fieldIdx ) const
360 {
361  return d->fields[fieldIdx].originIndex;
362 }
363 
364 int QgsFields::indexFromName( const QString &name ) const
365 {
366  return d->nameToIndex.value( name, -1 );
367 }
368 
370 {
371  QList<QgsField> lst;
372  for ( int i = 0; i < d->fields.count(); ++i )
373  lst.append( d->fields[i].field );
374  return lst;
375 }
376 
377 bool QgsFields::operator==( const QgsFields &other ) const
378 {
379  return d->fields == other.d->fields;
380 }
381 
382 int QgsFields::fieldNameIndex( const QString& fieldName ) const
383 {
384  for ( int idx = 0; idx < count(); ++idx )
385  {
386  if ( d->fields[idx].field.name() == fieldName )
387  return idx;
388  }
389 
390  for ( int idx = 0; idx < count(); ++idx )
391  {
392  if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
393  return idx;
394  }
395 
396  return -1;
397 }
398 
400 {
401  QgsAttributeList lst;
402  for ( int i = 0; i < d->fields.count(); ++i )
403  lst.append( i );
404  return lst;
405 }
406 
408 {
409  out << ( quint32 )fields.size();
410  for ( int i = 0; i < fields.size(); i++ )
411  {
412  out << fields.field( i );
413  }
414  return out;
415 }
416 
418 {
419  fields.clear();
420  quint32 size;
421  in >> size;
422  for ( quint32 i = 0; i < size; i++ )
423  {
424  QgsField field;
425  in >> field;
426  fields.append( field );
427  }
428  return in;
429 }
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfield.cpp:369
bool canConvert(Type t) const
qlonglong toLongLong(bool *ok) const
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:72
const QgsField & operator[](int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:346
QgsField & operator=(const QgsField &other)
Assignment operator.
Definition: qgsfield.cpp:51
bool operator==(const QgsField &other) const
Definition: qgsfield.cpp:62
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:336
struct QgsFields::Field Field
QgsFields()
Constructor for an empty field container.
Definition: qgsfield.cpp:234
virtual ~QgsField()
Destructor.
Definition: qgsfield.cpp:58
QgsFields & operator=(const QgsFields &other)
Assignment operator.
Definition: qgsfield.cpp:244
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:131
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:121
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:382
QgsField(const QString &name=QString(), QVariant::Type type=QVariant::Invalid, const QString &typeName=QString(), int len=0, int prec=0, const QString &comment=QString())
Constructor.
Definition: qgsfield.cpp:39
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:92
QDataStream & operator>>(QDataStream &in, QgsField &field)
Reads a field from stream in into field.
Definition: qgsfield.cpp:218
Container of fields for a vector layer.
Definition: qgsfield.h:177
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:102
bool appendExpressionField(const QgsField &field, int originIndex)
Append an expression field. The field must have unique name, otherwise it is rejected (returns false)...
Definition: qgsfield.cpp:274
void extend(const QgsFields &other)
Extend with fields from another QgsFields container.
Definition: qgsfield.cpp:298
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:184
it has not been specified where the field comes from
Definition: qgsfield.h:183
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:117
double qgsRound(double x)
Definition: qgis.h:295
bool exists(int i) const
Return if a field index is valid.
Definition: qgsfield.cpp:321
QString number(int n, int base)
void append(const T &value)
int toInt(bool *ok) const
bool isNull() const
void clear()
Remove all fields.
Definition: qgsfield.cpp:255
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:112
bool operator!=(const QgsField &other) const
Definition: qgsfield.cpp:67
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:359
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
Definition: qgsfield.cpp:261
int count() const
Return number of items.
Definition: qgsfield.cpp:311
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:40
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:331
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:285
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.cpp:364
virtual ~QgsFields()
Definition: qgsfield.cpp:250
QVariant value(const QString &key, const QVariant &defaultValue) const
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:107
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:145
const QString & typeName() const
Gets the field type.
Definition: qgsfield.cpp:82
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:87
int size() const
Return number of items.
Definition: qgsfield.cpp:316
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:351
int length() const
const QString & comment() const
Returns the field comment.
Definition: qgsfield.cpp:97
QString left(int n) const
double toDouble(bool *ok) const
bool isEmpty() const
Check whether the container is empty.
Definition: qgsfield.cpp:306
int compare(const QString &other) const
field is calculated from an expression
Definition: qgsfield.h:187
bool convert(Type t)
QString toString() const
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:399
void setComment(const QString &comment)
Set the field comment.
Definition: qgsfield.cpp:126
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out.
Definition: qgsfield.cpp:207
bool operator==(const QgsFields &other) const
Definition: qgsfield.cpp:377
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:77