QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsfields.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfields.cpp - QgsFields
3 
4  ---------------------
5  begin : 22.9.2016
6  copyright : (C) 2016 by Matthias Kuhn
7  email : [email protected]
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 "qgsfields_p.h"
19 #include "qgsapplication.h"
20 #include <QIcon>
21 
22 /***************************************************************************
23  * This class is considered CRITICAL and any change MUST be accompanied with
24  * full unit tests in testqgsfields.cpp.
25  * See details in QEP #17
26  ****************************************************************************/
27 
29 {
30  d = new QgsFieldsPrivate();
31 }
32 
33 QgsFields::QgsFields( const QgsFields &other ) //NOLINT
34  : d( other.d )
35 {
36 }
37 
38 QgsFields &QgsFields::operator =( const QgsFields &other ) //NOLINT
39 {
40  d = other.d;
41  return *this;
42 }
43 
45 {}
46 
48 {
49  d->fields.clear();
50  d->nameToIndex.clear();
51 }
52 
53 /***************************************************************************
54  * This class is considered CRITICAL and any change MUST be accompanied with
55  * full unit tests in testqgsfields.cpp.
56  * See details in QEP #17
57  ****************************************************************************/
58 
59 bool QgsFields::append( const QgsField &field, FieldOrigin origin, int originIndex )
60 {
61  if ( d->nameToIndex.contains( field.name() ) )
62  return false;
63 
64  if ( originIndex == -1 && origin == OriginProvider )
65  originIndex = d->fields.count();
66  d->fields.append( Field( field, origin, originIndex ) );
67 
68  d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
69  return true;
70 }
71 
72 bool QgsFields::appendExpressionField( const QgsField &field, int originIndex )
73 {
74  if ( d->nameToIndex.contains( field.name() ) )
75  return false;
76 
77  d->fields.append( Field( field, OriginExpression, originIndex ) );
78 
79  d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
80  return true;
81 }
82 
83 void QgsFields::remove( int fieldIdx )
84 {
85  if ( !exists( fieldIdx ) )
86  return;
87 
88  d->fields.remove( fieldIdx );
89  d->nameToIndex.clear();
90  for ( int idx = 0; idx < count(); ++idx )
91  {
92  d->nameToIndex.insert( d->fields.at( idx ).field.name(), idx );
93  }
94 }
95 
96 void QgsFields::extend( const QgsFields &other )
97 {
98  for ( int i = 0; i < other.count(); ++i )
99  {
100  append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
101  }
102 }
103 
104 /***************************************************************************
105  * This class is considered CRITICAL and any change MUST be accompanied with
106  * full unit tests in testqgsfields.cpp.
107  * See details in QEP #17
108  ****************************************************************************/
109 
110 bool QgsFields::isEmpty() const
111 {
112  return d->fields.isEmpty();
113 }
114 
115 int QgsFields::count() const
116 {
117  return d->fields.count();
118 }
119 
120 int QgsFields::size() const
121 {
122  return d->fields.count();
123 }
124 
125 QStringList QgsFields::names() const
126 {
127  QStringList lst;
128  for ( int i = 0; i < d->fields.count(); ++i )
129  {
130  lst.append( d->fields[i].field.name() );
131  }
132  return lst;
133 }
134 
135 bool QgsFields::exists( int i ) const
136 {
137  return i >= 0 && i < d->fields.count();
138 }
139 
141 {
142  return d->fields[i].field;
143 }
144 
145 QgsField QgsFields::at( int i ) const
146 {
147  return d->fields[i].field;
148 }
149 
150 QgsField QgsFields::field( int fieldIdx ) const
151 {
152  return d->fields[fieldIdx].field;
153 }
154 
155 QgsField QgsFields::field( const QString &name ) const
156 {
157  return d->fields[ indexFromName( name )].field;
158 }
159 
160 /***************************************************************************
161  * This class is considered CRITICAL and any change MUST be accompanied with
162  * full unit tests in testqgsfields.cpp.
163  * See details in QEP #17
164  ****************************************************************************/
165 
167 {
168  return d->fields[i].field;
169 }
170 
172 {
173  if ( !exists( fieldIdx ) )
174  return OriginUnknown;
175 
176  return d->fields[fieldIdx].origin;
177 }
178 
179 int QgsFields::fieldOriginIndex( int fieldIdx ) const
180 {
181  return d->fields[fieldIdx].originIndex;
182 }
183 
184 int QgsFields::indexFromName( const QString &fieldName ) const
185 {
186  return d->nameToIndex.value( fieldName, -1 );
187 }
188 
189 int QgsFields::indexOf( const QString &fieldName ) const
190 {
191  return d->nameToIndex.value( fieldName, -1 );
192 }
193 
194 QList<QgsField> QgsFields::toList() const
195 {
196  QList<QgsField> lst;
197  for ( int i = 0; i < d->fields.count(); ++i )
198  lst.append( d->fields[i].field );
199  return lst;
200 }
201 
202 bool QgsFields::operator==( const QgsFields &other ) const
203 {
204  return d->fields == other.d->fields;
205 }
206 
207 QgsFields::const_iterator QgsFields::constBegin() const noexcept
208 {
209  if ( d->fields.isEmpty() )
210  return const_iterator();
211 
212  return const_iterator( &d->fields.first() );
213 }
214 
215 QgsFields::const_iterator QgsFields::constEnd() const noexcept
216 {
217  if ( d->fields.isEmpty() )
218  return const_iterator();
219 
220  return const_iterator( &d->fields.last() + 1 );
221 }
222 
223 QgsFields::const_iterator QgsFields::begin() const noexcept
224 {
225  if ( d->fields.isEmpty() )
226  return const_iterator();
227 
228  return const_iterator( &d->fields.first() );
229 }
230 
231 QgsFields::const_iterator QgsFields::end() const noexcept
232 {
233  if ( d->fields.isEmpty() )
234  return const_iterator();
235 
236  return const_iterator( &d->fields.last() + 1 );
237 }
238 
239 QgsFields::iterator QgsFields::begin()
240 {
241  if ( d->fields.isEmpty() )
242  return iterator();
243 
244  d.detach();
245  return iterator( &d->fields.first() );
246 }
247 
248 QgsFields::iterator QgsFields::end()
249 {
250  if ( d->fields.isEmpty() )
251  return iterator();
252 
253  d.detach();
254  return iterator( &d->fields.last() + 1 );
255 }
256 
257 QIcon QgsFields::iconForField( int fieldIdx ) const
258 {
259  switch ( d->fields.at( fieldIdx ).field.type() )
260  {
261  case QVariant::Int:
262  case QVariant::UInt:
263  case QVariant::LongLong:
264  case QVariant::ULongLong:
265  {
266  return QgsApplication::getThemeIcon( "/mIconFieldInteger.svg" );
267  }
268  case QVariant::Double:
269  {
270  return QgsApplication::getThemeIcon( "/mIconFieldFloat.svg" );
271  }
272  case QVariant::String:
273  {
274  return QgsApplication::getThemeIcon( "/mIconFieldText.svg" );
275  }
276  case QVariant::Date:
277  {
278  return QgsApplication::getThemeIcon( "/mIconFieldDate.svg" );
279  }
280  case QVariant::DateTime:
281  {
282  return QgsApplication::getThemeIcon( "/mIconFieldDateTime.svg" );
283  }
284  case QVariant::Time:
285  {
286  return QgsApplication::getThemeIcon( "/mIconFieldTime.svg" );
287  }
288  default:
289  return QIcon();
290  }
291 }
292 
293 /***************************************************************************
294  * This class is considered CRITICAL and any change MUST be accompanied with
295  * full unit tests in testqgsfields.cpp.
296  * See details in QEP #17
297  ****************************************************************************/
298 
299 int QgsFields::lookupField( const QString &fieldName ) const
300 {
301  if ( fieldName.isEmpty() ) //shortcut
302  return -1;
303 
304  for ( int idx = 0; idx < count(); ++idx )
305  {
306  if ( d->fields[idx].field.name() == fieldName )
307  return idx;
308  }
309 
310  for ( int idx = 0; idx < count(); ++idx )
311  {
312  if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
313  return idx;
314  }
315 
316  for ( int idx = 0; idx < count(); ++idx )
317  {
318  QString alias = d->fields[idx].field.alias();
319  if ( !alias.isEmpty() && QString::compare( alias, fieldName, Qt::CaseInsensitive ) == 0 )
320  return idx;
321  }
322 
323  return -1;
324 }
325 
327 {
328  QgsAttributeList lst;
329  for ( int i = 0; i < d->fields.count(); ++i )
330  lst.append( i );
331  return lst;
332 }
333 
334 /***************************************************************************
335  * This class is considered CRITICAL and any change MUST be accompanied with
336  * full unit tests in testqgsfields.cpp.
337  * See details in QEP #17
338  ****************************************************************************/
339 
340 QDataStream &operator<<( QDataStream &out, const QgsFields &fields )
341 {
342  out << static_cast< quint32 >( fields.size() );
343  for ( int i = 0; i < fields.size(); i++ )
344  {
345  out << fields.field( i );
346  }
347  return out;
348 }
349 
350 QDataStream &operator>>( QDataStream &in, QgsFields &fields )
351 {
352  fields.clear();
353  quint32 size;
354  in >> size;
355  for ( quint32 i = 0; i < size; i++ )
356  {
357  QgsField field;
358  in >> field;
359  fields.append( field );
360  }
361  return in;
362 }
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:299
int size() const
Returns number of items.
Definition: qgsfields.cpp:120
FieldOrigin fieldOrigin(int fieldIdx) const
Gets field&#39;s origin (value from an enumeration)
Definition: qgsfields.cpp:171
QString name
Definition: qgsfield.h:57
struct QgsFields::Field Field
QgsFields()
Constructor for an empty field container.
Definition: qgsfields.cpp:28
QgsFields & operator=(const QgsFields &other)
Assignment operator.
Definition: qgsfields.cpp:38
const_iterator constEnd() const noexcept
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qgsfields.cpp:215
QIcon iconForField(int fieldIdx) const
Returns an icon corresponding to a field index, based on the field&#39;s type and source.
Definition: qgsfields.cpp:257
bool exists(int i) const
Returns if a field index is valid.
Definition: qgsfields.cpp:135
Container of fields for a vector layer.
Definition: qgsfields.h:42
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
bool appendExpressionField(const QgsField &field, int originIndex)
Append an expression field. The field must have unique name, otherwise it is rejected (returns false)...
Definition: qgsfields.cpp:72
QStringList names() const
Returns a list with field names.
Definition: qgsfields.cpp:125
void extend(const QgsFields &other)
Extend with fields from another QgsFields container.
Definition: qgsfields.cpp:96
Field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfields.h:49
bool operator==(const QgsFields &other) const
Definition: qgsfields.cpp:202
QDataStream & operator<<(QDataStream &out, const QgsFields &fields)
Writes the fields to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfields.cpp:340
const_iterator end() const noexcept
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qgsfields.cpp:231
int count() const
Returns number of items.
Definition: qgsfields.cpp:115
It has not been specified where the field comes from.
Definition: qgsfields.h:48
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:145
int fieldOriginIndex(int fieldIdx) const
Gets field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfields.cpp:179
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:184
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfields.cpp:326
void clear()
Remove all fields.
Definition: qgsfields.cpp:47
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: qgsfields.cpp:59
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfields.cpp:83
const_iterator begin() const noexcept
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qgsfields.cpp:223
virtual ~QgsFields()
Definition: qgsfields.cpp:44
QDataStream & operator>>(QDataStream &in, QgsFields &fields)
Reads fields from stream in into fields. QGIS version compatibility is not guaranteed.
Definition: qgsfields.cpp:350
const_iterator constBegin() const noexcept
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qgsfields.cpp:207
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:189
QgsField operator[](int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:166
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfields.cpp:194
bool isEmpty() const
Check whether the container is empty.
Definition: qgsfields.cpp:110
QList< int > QgsAttributeList
Definition: qgsfield.h:27
Field is calculated from an expression.
Definition: qgsfields.h:52
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:150