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