QGIS API Documentation  2.8.6-Wien
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 
19 #include <QSettings>
20 #include <QtCore/qmath.h>
21 #include "qgis.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  : mName( name ), mType( type ), mTypeName( typeName )
39  , mLength( len ), mPrecision( prec ), mComment( comment )
40 {
41 }
42 
43 
45 {
46 }
47 
48 bool QgsField::operator==( const QgsField& other ) const
49 {
50  return (( mName == other.mName ) && ( mType == other.mType )
51  && ( mLength == other.mLength ) && ( mPrecision == other.mPrecision ) );
52 }
53 
54 bool QgsField::operator!=( const QgsField& other ) const
55 {
56  return !( *this == other );
57 }
58 
59 
60 const QString & QgsField::name() const
61 {
62  return mName;
63 }
64 
65 QVariant::Type QgsField::type() const
66 {
67  return mType;
68 }
69 
70 const QString & QgsField::typeName() const
71 {
72  return mTypeName;
73 }
74 
75 int QgsField::length() const
76 {
77  return mLength;
78 }
79 
81 {
82  return mPrecision;
83 }
84 
85 const QString & QgsField::comment() const
86 {
87  return mComment;
88 }
89 
90 void QgsField::setName( const QString & nam )
91 {
92  mName = nam;
93 }
94 
95 void QgsField::setType( QVariant::Type type )
96 {
97  mType = type;
98 }
99 
100 void QgsField::setTypeName( const QString & typeName )
101 {
102  mTypeName = typeName;
103 }
104 
105 void QgsField::setLength( int len )
106 {
107  mLength = len;
108 }
109 void QgsField::setPrecision( int prec )
110 {
111  mPrecision = prec;
112 }
113 
114 void QgsField::setComment( const QString & comment )
115 {
116  mComment = comment;
117 }
118 
119 QString QgsField::displayString( const QVariant& v ) const
120 {
121  if ( v.isNull() )
122  {
123  QSettings settings;
124  return settings.value( "qgis/nullValue", "NULL" ).toString();
125  }
126 
127  if ( mType == QVariant::Double && mPrecision > 0 )
128  return QString::number( v.toDouble(), 'f', mPrecision );
129 
130  return v.toString();
131 }
132 
133 bool QgsField::convertCompatible( QVariant& v ) const
134 {
135  if ( v.isNull() )
136  {
137  v.convert( mType );
138  return true;
139  }
140 
141  if ( mType == QVariant::Int && v.toInt() != v.toLongLong() )
142  {
143  v = QVariant( mType );
144  return false;
145  }
146 
147  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
148  //work around this by first converting to double, and then checking whether the double is convertible to int
149  if ( mType == QVariant::Int && v.canConvert( QVariant::Double ) )
150  {
151  bool ok = false;
152  double dbl = v.toDouble( &ok );
153  if ( !ok )
154  {
155  //couldn't convert to number
156  v = QVariant( mType );
157  return false;
158  }
159 
160  double round = qgsRound( dbl );
161  if ( round > INT_MAX || round < -INT_MAX )
162  {
163  //double too large to fit in int
164  v = QVariant( mType );
165  return false;
166  }
167  v = QVariant( qRound( dbl ) );
168  return true;
169  }
170 
171  if ( !v.convert( mType ) )
172  {
173  v = QVariant( mType );
174  return false;
175  }
176 
177  if ( mType == QVariant::Double && mPrecision > 0 )
178  {
179  double s = qPow( 10, mPrecision );
180  double d = v.toDouble() * s;
181  v = QVariant(( d < 0 ? ceil( d - 0.5 ) : floor( d + 0.5 ) ) / s );
182  return true;
183  }
184 
185  if ( mType == QVariant::String && mLength > 0 && v.toString().length() > mLength )
186  {
187  v = v.toString().left( mLength );
188  return false;
189  }
190 
191  return true;
192 }
193 
195 
197 {
198  mFields.clear();
199  mNameToIndex.clear();
200 }
201 
202 bool QgsFields::append( const QgsField& field, FieldOrigin origin, int originIndex )
203 {
204  if ( mNameToIndex.contains( field.name() ) )
205  return false;
206 
207  if ( originIndex == -1 && origin == OriginProvider )
208  originIndex = mFields.count();
209  mFields.append( Field( field, origin, originIndex ) );
210 
211  mNameToIndex.insert( field.name(), mFields.count() - 1 );
212  return true;
213 }
214 
215 bool QgsFields::appendExpressionField( const QgsField& field, int originIndex )
216 {
217  if ( mNameToIndex.contains( field.name() ) )
218  return false;
219 
220  mFields.append( Field( field, OriginExpression, originIndex ) );
221 
222  mNameToIndex.insert( field.name(), mFields.count() - 1 );
223  return true;
224 }
225 
226 void QgsFields::remove( int fieldIdx )
227 {
228  if ( !exists( fieldIdx ) )
229  return;
230 
231  mFields.remove( fieldIdx );
232  mNameToIndex.clear();
233  for ( int idx = 0; idx < count(); ++idx )
234  {
235  mNameToIndex.insert( mFields[idx].field.name(), idx );
236  }
237 }
238 
239 void QgsFields::extend( const QgsFields& other )
240 {
241  for ( int i = 0; i < other.count(); ++i )
242  {
243  append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
244  }
245 }
246 
248 {
249  if ( !exists( fieldIdx ) )
250  return OriginUnknown;
251 
252  return mFields[fieldIdx].origin;
253 }
254 
255 QList<QgsField> QgsFields::toList() const
256 {
257  QList<QgsField> lst;
258  for ( int i = 0; i < mFields.count(); ++i )
259  lst.append( mFields[i].field );
260  return lst;
261 }
262 
263 int QgsFields::fieldNameIndex( const QString& fieldName ) const
264 {
265  for ( int idx = 0; idx < count(); ++idx )
266  {
267  if ( mFields[idx].field.name() == fieldName )
268  return idx;
269  }
270 
271  for ( int idx = 0; idx < count(); ++idx )
272  {
273  if ( QString::compare( mFields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
274  return idx;
275  }
276 
277  return -1;
278 }
279 
281 {
282  QgsAttributeList lst;
283  for ( int i = 0; i < mFields.count(); ++i )
284  lst.append( i );
285  return lst;
286 }
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfield.cpp:255
void setPrecision(int prec)
Set the field precision.
Definition: qgsfield.cpp:109
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:60
bool operator==(const QgsField &other) const
Definition: qgsfield.cpp:48
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
~QgsField()
Destructor.
Definition: qgsfield.cpp:44
void setTypeName(const QString &typ)
Set the field type.
Definition: qgsfield.cpp:100
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:119
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:263
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:80
Container of fields for a vector layer.
Definition: qgsfield.h:172
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:215
void extend(const QgsFields &other)
Extend with fields from another QgsFields container.
Definition: qgsfield.cpp:239
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.h:227
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:105
double qgsRound(double x)
Definition: qgis.h:357
void clear()
Remove all fields.
Definition: qgsfield.cpp:196
bool operator!=(const QgsField &other) const
Definition: qgsfield.cpp:54
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.h:236
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:202
int count() const
Return number of items.
Definition: qgsfield.h:214
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:33
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:226
void setName(const QString &nam)
Set the field name.
Definition: qgsfield.cpp:90
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:95
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:133
const QString & typeName() const
Gets the field type.
Definition: qgsfield.cpp:70
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:75
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:247
const QString & comment() const
Returns the field comment.
Definition: qgsfield.cpp:85
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:280
void setComment(const QString &comment)
Set the field comment.
Definition: qgsfield.cpp:114
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:65