QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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->nameToIndex.remove( d->fields[fieldIdx].field.name() );
263  d->fields.remove( fieldIdx );
264 }
265 
266 void QgsFields::extend( const QgsFields& other )
267 {
268  for ( int i = 0; i < other.count(); ++i )
269  {
270  append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
271  }
272 }
273 
274 bool QgsFields::isEmpty() const
275 {
276  return d->fields.isEmpty();
277 }
278 
279 int QgsFields::count() const
280 {
281  return d->fields.count();
282 }
283 
284 int QgsFields::size() const
285 {
286  return d->fields.count();
287 }
288 
289 bool QgsFields::exists( int i ) const
290 {
291  return i >= 0 && i < d->fields.count();
292 }
293 
295 {
296  return d->fields[i].field;
297 }
298 
299 const QgsField &QgsFields::at( int i ) const
300 {
301  return d->fields[i].field;
302 }
303 
304 const QgsField &QgsFields::field( int fieldIdx ) const
305 {
306  return d->fields[fieldIdx].field;
307 }
308 
309 const QgsField &QgsFields::field( const QString &name ) const
310 {
311  return d->fields[ indexFromName( name )].field;
312 }
313 
314 const QgsField &QgsFields::operator[]( int i ) const
315 {
316  return d->fields[i].field;
317 }
318 
320 {
321  if ( !exists( fieldIdx ) )
322  return OriginUnknown;
323 
324  return d->fields[fieldIdx].origin;
325 }
326 
327 int QgsFields::fieldOriginIndex( int fieldIdx ) const
328 {
329  return d->fields[fieldIdx].originIndex;
330 }
331 
332 int QgsFields::indexFromName( const QString &name ) const
333 {
334  return d->nameToIndex.value( name, -1 );
335 }
336 
337 QList<QgsField> QgsFields::toList() const
338 {
339  QList<QgsField> lst;
340  for ( int i = 0; i < d->fields.count(); ++i )
341  lst.append( d->fields[i].field );
342  return lst;
343 }
344 
345 bool QgsFields::operator==( const QgsFields &other ) const
346 {
347  return d->fields == other.d->fields;
348 }
349 
350 int QgsFields::fieldNameIndex( const QString& fieldName ) const
351 {
352  for ( int idx = 0; idx < count(); ++idx )
353  {
354  if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
355  {
356  return idx;
357  }
358  }
359  return -1;
360 }
361 
363 {
364  QgsAttributeList lst;
365  for ( int i = 0; i < d->fields.count(); ++i )
366  lst.append( i );
367  return lst;
368 }
369 
370 QDataStream& operator<<( QDataStream& out, const QgsFields& fields )
371 {
372  out << ( quint32 )fields.size();
373  for ( int i = 0; i < fields.size(); i++ )
374  {
375  out << fields.field( i );
376  }
377  return out;
378 }
379 
380 QDataStream& operator>>( QDataStream& in, QgsFields& fields )
381 {
382  fields.clear();
383  quint32 size;
384  in >> size;
385  for ( quint32 i = 0; i < size; i++ )
386  {
387  QgsField field;
388  in >> field;
389  fields.append( field );
390  }
391  return in;
392 }
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfield.cpp:337
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:314
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:304
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:350
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:266
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:289
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:327
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:279
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:299
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:332
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:284
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:319
const QString & comment() const
Returns the field comment.
Definition: qgsfield.cpp:94
bool isEmpty() const
Check whether the container is empty.
Definition: qgsfield.cpp:274
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:362
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:345
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:74