QGIS API Documentation
qgsvectorlayereditbuffer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayereditbuffer.cpp
3  ---------------------
4  begin : Dezember 2012
5  copyright : (C) 2012 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
16 
17 #include "qgsgeometry.h"
18 #include "qgslogger.h"
20 #include "qgsvectordataprovider.h"
21 #include "qgsvectorlayer.h"
22 
23 
25 template <class Key, class T> void mapToReversedLists( const QMap< Key, T >& map, QList<Key>& ks, QList<T>& vs )
26 {
27  ks.reserve( map.size() );
28  vs.reserve( map.size() );
29  typename QMap<Key, T>::const_iterator i = map.constEnd();
30  while ( i-- != map.constBegin() )
31  {
32  ks.append( i.key() );
33  vs.append( i.value() );
34  }
35 }
36 
37 
39  : L( layer )
40 {
41  connect( L->undoStack(), SIGNAL( indexChanged( int ) ), this, SLOT( undoIndexChanged( int ) ) ); // TODO[MD]: queued?
42 }
43 
45 {
46 }
47 
48 
50 {
51  return !L->undoStack()->isClean();
52 }
53 
54 
56 {
57  QgsDebugMsg( QString( "undo index changed %1" ).arg( index ) );
58  Q_UNUSED( index );
59  emit layerModified();
60 }
61 
62 
64 {
65  // delete attributes from the higher indices to lower indices
66  for ( int i = mDeletedAttributeIds.count() - 1; i >= 0; --i )
67  {
68  fields.remove( mDeletedAttributeIds[i] );
69  }
70  // add new fields
71  for ( int i = 0; i < mAddedAttributes.count(); ++i )
72  {
74  }
75 }
76 
77 
79 {
80  if ( mChangedGeometries.contains( f.id() ) )
82 }
83 
84 
86 {
87  QgsAttributes attrs = f.attributes();
88 
89  // remove all attributes that will disappear - from higher indices to lower
90  for ( int idx = mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
91  {
92  attrs.remove( mDeletedAttributeIds[idx] );
93  }
94 
95  // adjust size to accommodate added attributes
96  attrs.resize( attrs.count() + mAddedAttributes.count() );
97 
98  // update changed attributes
99  if ( mChangedAttributeValues.contains( f.id() ) )
100  {
101  const QgsAttributeMap &map = mChangedAttributeValues[f.id()];
102  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
103  attrs[it.key()] = it.value();
104  }
105 
106  f.setAttributes( attrs );
107 }
108 
109 
110 
111 
113 {
115  {
116  return false;
117  }
118  if ( L->mUpdatedFields.count() != f.attributes().count() )
119  return false;
120 
121  // TODO: check correct geometry type
122 
123  L->undoStack()->push( new QgsVectorLayerUndoCommandAddFeature( this, f ) );
124  return true;
125 }
126 
127 
129 {
131  return false;
132 
133  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
134  {
135  addFeature( *iter );
136  }
137 
138  L->updateExtents();
139  return true;
140 }
141 
142 
143 
145 {
147  return false;
148 
149  if ( FID_IS_NEW( fid ) )
150  {
151  if ( !mAddedFeatures.contains( fid ) )
152  return false;
153  }
154  else // existing feature
155  {
156  if ( mDeletedFeatureIds.contains( fid ) )
157  return false;
158  }
159 
160  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteFeature( this, fid ) );
161  return true;
162 }
163 
165 {
167  return false;
168 
169  Q_FOREACH ( QgsFeatureId fid, fids )
170  deleteFeature( fid );
171 
172  return true;
173 }
174 
175 
177 {
178  if ( !L->hasGeometryType() )
179  {
180  return false;
181  }
182 
183  if ( FID_IS_NEW( fid ) )
184  {
185  if ( !mAddedFeatures.contains( fid ) )
186  return false;
187  }
189  return false;
190 
191  // TODO: check compatible geometry
192 
193  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, geom ) );
194  return true;
195 }
196 
197 
198 bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
199 {
200  if ( FID_IS_NEW( fid ) )
201  {
202  if ( !mAddedFeatures.contains( fid ) )
203  return false;
204  }
206  {
207  return false;
208  }
209 
210  if ( field < 0 || field >= L->fields().count() ||
211  L->fields().fieldOrigin( field ) == QgsFields::OriginJoin ||
213  return false;
214 
215  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, newValue, oldValue ) );
216  return true;
217 }
218 
219 
221 {
223  return false;
224 
225  if ( field.name().isEmpty() )
226  return false;
227 
228  Q_FOREACH ( const QgsField& updatedField, L->fields() )
229  {
230  if ( updatedField.name() == field.name() )
231  return false;
232  }
233 
234  if ( !L->dataProvider()->supportedType( field ) )
235  return false;
236 
237  L->undoStack()->push( new QgsVectorLayerUndoCommandAddAttribute( this, field ) );
238  return true;
239 }
240 
241 
243 {
245  return false;
246 
247  if ( index < 0 || index >= L->fields().count() )
248  return false;
249 
250  // find out source of the field
251  QgsFields::FieldOrigin origin = L->fields().fieldOrigin( index );
252  int originIndex = L->fields().fieldOriginIndex( index );
253 
254  if ( origin == QgsFields::OriginProvider && mDeletedAttributeIds.contains( originIndex ) )
255  return false;
256 
257  if ( origin == QgsFields::OriginJoin )
258  return false;
259 
260  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteAttribute( this, index ) );
261  return true;
262 }
263 
264 
266 {
267  QgsVectorDataProvider* provider = L->dataProvider();
268  commitErrors.clear();
269 
270  int cap = provider->capabilities();
271  bool success = true;
272 
273  // geometry updates attribute updates
274  // yes no => changeGeometryValues
275  // no yes => changeAttributeValues
276  // yes yes => changeFeatures
277 
278  //
279  // update geometries
280  //
282  {
283  if ( provider->changeGeometryValues( mChangedGeometries ) )
284  {
285  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
286 
289  }
290  else
291  {
292  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
293  success = false;
294  }
295  }
296 
297  QgsFields oldFields = L->fields();
298 
299  //
300  // delete attributes
301  //
302  bool attributesChanged = false;
303  if ( !mDeletedAttributeIds.isEmpty() )
304  {
306  {
307  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
308 
310 
312  attributesChanged = true;
313  }
314  else
315  {
316  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
317 #if 0
318  QString list = "ERROR: Pending attribute deletes:";
319  Q_FOREACH ( int idx, mDeletedAttributeIds )
320  {
321  list.append( ' ' + L->pendingFields().at( idx ).name() );
322  }
323  commitErrors << list;
324 #endif
325  success = false;
326  }
327  }
328 
329  //
330  // add attributes
331  //
332  if ( !mAddedAttributes.isEmpty() )
333  {
335  {
336  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
337 
339 
341  attributesChanged = true;
342  }
343  else
344  {
345  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
346 #if 0
347  QString list = "ERROR: Pending adds:";
348  Q_FOREACH ( QgsField f, mAddedAttributes )
349  {
350  list.append( ' ' + f.name() );
351  }
352  commitErrors << list;
353 #endif
354  success = false;
355  }
356  }
357 
358  //
359  // check that addition/removal went as expected
360  //
361  bool attributeChangesOk = true;
362  if ( attributesChanged )
363  {
364  L->updateFields();
365  QgsFields newFields = L->fields();
366 
367  if ( oldFields.count() != newFields.count() )
368  {
369  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
370  attributeChangesOk = false; // don't try attribute updates - they'll fail.
371  }
372 
373  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
374  {
375  const QgsField& oldField = oldFields.at( i );
376  const QgsField& newField = newFields.at( i );
377  if ( attributeChangesOk && oldField != newField )
378  {
379  commitErrors
380  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
381  << tr( "Provider: %1" ).arg( L->providerType() )
382  << tr( "Storage: %1" ).arg( L->storageType() )
383  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
384  .arg( tr( "expected field" ),
385  oldField.name(),
386  QVariant::typeToName( oldField.type() ),
387  oldField.typeName() )
388  .arg( oldField.length() )
389  .arg( oldField.precision() )
390  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
391  .arg( tr( "retrieved field" ),
392  newField.name(),
393  QVariant::typeToName( newField.type() ),
394  newField.typeName() )
395  .arg( newField.length() )
396  .arg( newField.precision() );
397  attributeChangesOk = false; // don't try attribute updates - they'll fail.
398  }
399  }
400  }
401 
402  if ( attributeChangesOk )
403  {
405  {
407 
409  {
410  commitErrors << tr( "SUCCESS: %1 attribute value(s) and %2 geometries changed." ).arg( mChangedAttributeValues.size(), mChangedGeometries.size() );
413 
416  }
417  else
418  {
419  success = false;
420  }
421  }
422  else
423  {
424  //
425  // change attributes
426  //
428  {
430  {
431  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
432 
435  }
436  else
437  {
438  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
439 #if 0
440  QString list = "ERROR: pending changes:";
441  Q_FOREACH ( QgsFeatureId id, mChangedAttributeValues.keys() )
442  {
443  list.append( "\n " + FID_TO_STRING( id ) + '[' );
444  Q_FOREACH ( int idx, mChangedAttributeValues[ id ].keys() )
445  {
446  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( idx ).name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
447  }
448  list.append( " ]" );
449  }
450  commitErrors << list;
451 #endif
452  success = false;
453  }
454  }
455  }
456 
457  //
458  // delete features
459  //
460  if ( success && !mDeletedFeatureIds.isEmpty() )
461  {
463  {
464  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
465  // TODO[MD]: we should not need this here
466  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
467  {
470  }
471 
473 
475  }
476  else
477  {
478  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
479 #if 0
480  QString list = "ERROR: pending deletes:";
481  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
482  {
483  list.append( ' ' + FID_TO_STRING( id ) );
484  }
485  commitErrors << list;
486 #endif
487  success = false;
488  }
489  }
490 
491  //
492  // add features
493  //
494  if ( success && !mAddedFeatures.isEmpty() )
495  {
497  {
499  QgsFeatureList featuresToAdd;
500  // get the list of added features in reversed order
501  // this will preserve the order how they have been added e.g. (-1, -2, -3) while in the map they are ordered (-3, -2, -1)
502  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
503 
504  if ( provider->addFeatures( featuresToAdd ) )
505  {
506  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
507 
508  emit committedFeaturesAdded( L->id(), featuresToAdd );
509 
510  // notify everyone that the features with temporary ids were updated with permanent ids
511  for ( int i = 0; i < featuresToAdd.count(); ++i )
512  {
513  if ( featuresToAdd[i].id() != ids[i] )
514  {
515  //update selection
516  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
517  {
518  L->mSelectedFeatureIds.remove( ids[i] );
519  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
520  }
521  emit featureDeleted( ids[i] );
522  emit featureAdded( featuresToAdd[i].id() );
523  }
524  }
525 
527  }
528  else
529  {
530  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
531 #if 0
532  QString list = "ERROR: pending adds:";
533  Q_FOREACH ( QgsFeature f, mAddedFeatures )
534  {
535  list.append( ' ' + FID_TO_STRING( f.id() ) + '[' );
536  for ( int i = 0; i < L->pendingFields().size(); i++ )
537  {
538  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( i ).name() ).arg( f.attributes()[i].toString() ) );
539  }
540  list.append( " ]" );
541  }
542  commitErrors << list;
543 #endif
544  success = false;
545  }
546  }
547  else
548  {
549  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
550  success = false;
551  }
552  }
553  }
554  else
555  {
556  success = false;
557  }
558 
559  if ( !success && provider->hasErrors() )
560  {
561  commitErrors << tr( "\n Provider errors:" );
562  Q_FOREACH ( QString e, provider->errors() )
563  {
564  commitErrors << " " + e.replace( '\n', "\n " );
565  }
566  provider->clearErrors();
567  }
568 
569  return success;
570 }
571 
572 
574 {
575  if ( !isModified() )
576  return;
577 
578  // limit canvas redraws to one by jumping to beginning of stack
579  // see QgsUndoWidget::indexChanged
580  L->undoStack()->setIndex( 0 );
581 
582  Q_ASSERT( mAddedAttributes.isEmpty() );
583  Q_ASSERT( mDeletedAttributeIds.isEmpty() );
584  Q_ASSERT( mChangedAttributeValues.isEmpty() );
585  Q_ASSERT( mChangedGeometries.isEmpty() );
586  Q_ASSERT( mAddedFeatures.isEmpty() );
587 }
588 
589 #if 0
590 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
591 {
592  QString msg;
593  if ( !mChangedGeometries.isEmpty() )
594  {
595  msg += "CHANGED GEOMETRIES:\n";
596  for ( QgsGeometryMap::const_iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it )
597  {
598  // QgsFeatureId, QgsGeometry
599  msg += QString( "- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
600  }
601  }
602  return msg;
603 }
604 #endif
605 
607 {
608  // go through the changed attributes map and adapt indices
609  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
610  for ( ; it != mChangedAttributeValues.end(); ++it )
611  {
612  updateAttributeMapIndex( it.value(), index, + 1 );
613  }
614 
615  // go through added features and adapt attributes
616  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
617  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
618  {
619  QgsAttributes attrs = featureIt->attributes();
620  attrs.insert( index, QVariant() );
621  featureIt->setAttributes( attrs );
622  }
623 }
624 
626 {
627  // go through the changed attributes map and adapt indices
628  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
629  for ( ; it != mChangedAttributeValues.end(); ++it )
630  {
631  QgsAttributeMap& attrMap = it.value();
632  // remove the attribute
633  if ( attrMap.contains( index ) )
634  attrMap.remove( index );
635 
636  // update attribute indices
637  updateAttributeMapIndex( attrMap, index, -1 );
638  }
639 
640  // go through added features and adapt attributes
641  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
642  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
643  {
644  QgsAttributes attrs = featureIt->attributes();
645  attrs.remove( index );
646  featureIt->setAttributes( attrs );
647  }
648 }
649 
650 
651 
653 {
654  QgsAttributeMap updatedMap;
655  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
656  {
657  int attrIndex = it.key();
658  updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
659  }
660  map = updatedMap;
661 }
662 
663 
664 
666 {
667  L->updateFields();
668 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
void clear()
static unsigned index
QString & append(QChar ch)
void handleAttributeDeleted(int index)
Update added and changed features after removal of an attribute.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:195
virtual bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
bool contains(const Key &key) const
void committedAttributesDeleted(const QString &layerId, const QgsAttributeList &deletedAttributes)
Signals emitted after committing changes.
void mapToReversedLists(const QMap< Key, T > &map, QList< Key > &ks, QList< T > &vs)
populate two lists (ks, vs) from map - in reverse order
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes.
virtual bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
virtual bool addFeature(QgsFeature &f)
Adds a feature.
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:196
void committedAttributesAdded(const QString &layerId, const QList< QgsField > &addedAttributes)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsFields fields() const
Returns the list of fields of this layer.
int size() const
void reserve(int alloc)
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features.
const_iterator constBegin() const
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:104
void insert(int i, const T &value)
#define FID_TO_STRING(fid)
Definition: qgsfeature.h:89
friend class QgsVectorLayerUndoCommandChangeGeometry
Container of fields for a vector layer.
Definition: qgsfield.h:187
virtual void rollBack()
Stop editing and discard the edits.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:115
QStringList errors()
Get recorded errors.
friend class QgsVectorLayerUndoCommandAddAttribute
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not commited.
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommited geometry updates.
QSet< T > toSet() const
Allows deletion of attributes (fields)
field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfield.h:194
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
void clear()
virtual bool addFeatures(QgsFeatureList &flist)
Adds a list of features.
QString tr(const char *sourceText, const char *disambiguation, int n)
friend class QgsVectorLayerUndoCommandDeleteAttribute
int size() const
virtual void updateExtents()
Update the extents for the layer.
T value(int i) const
QList< Key > keys() const
void featureAdded(QgsFeatureId fid)
QgsFields pendingFields() const
Returns the list of fields of this layer.
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
int count(const T &value) const
void append(const T &value)
void setIndex(int idx)
bool supportedType(const QgsField &field) const
check if provider supports type of field
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:94
void resize(int size)
const Key & key() const
Allows addition of new attributes (fields)
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
bool hasErrors()
Provider has errors to report.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
bool isEmpty() const
virtual bool changeFeatures(const QgsChangedAttributesMap &attr_map, const QgsGeometryMap &geometry_map)
Changes attribute values and geometries of existing features.
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:419
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
void handleAttributeAdded(int index)
Update added and changed features after addition of an attribute.
Allows modifications of geometries.
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:309
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
const T & value() const
virtual bool deleteFeatures(const QgsFeatureIds &fid)
Deletes a set of features from the layer (but does not commit it)
void clearErrors()
Clear recorded errors.
int count() const
Return number of items.
Definition: qgsfield.cpp:365
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
iterator end()
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:333
iterator begin()
virtual bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
virtual bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
friend class QgsVectorLayerUndoCommandDeleteFeature
iterator end()
bool contains(const T &value) const
Supports joint updates for attributes and geometry Providers supporting this should still define Chan...
bool contains(const T &value) const
const char * typeToName(Type typ)
const Key key(const T &value) const
QString providerType() const
Return the provider type for this layer.
QString & replace(int position, int n, QChar after)
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
bool isClean() const
QList< QgsField > mAddedAttributes
Added attributes fields which are not commited.
bool remove(const T &value)
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:99
int count(const T &value) const
int size() const
Return number of items.
Definition: qgsfield.cpp:370
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:411
virtual bool deleteAttributes(const QgsAttributeIds &attributes)
Deletes existing attributes.
bool isEmpty() const
virtual bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
qint64 QgsFeatureId
Definition: qgsfeature.h:31
virtual bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
Changed an attribute value (but does not commit it)
#define FID_IS_NEW(fid)
Definition: qgsfeature.h:87
iterator insert(const Key &key, const T &value)
bool isEmpty() const
QUndoStack * undoStack()
Return pointer to layer&#39;s undo stack.
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
QgsVectorDataProvider * dataProvider()
Returns the data provider.
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
void clear()
This is the base class for vector data providers.
QgsFeatureMap mAddedFeatures
New features which are not commited.
A vector of attributes.
Definition: qgsfeature.h:115
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void updateFields(QgsFields &fields)
void layerModified()
This signal is emitted when modifications has been done on layer.
Represents a vector layer which manages a vector based data sets.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
field is calculated from an expression
Definition: qgsfield.h:197
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not commited.
iterator begin()
Allows modification of attribute values.
void updateAttributeMapIndex(QgsAttributeMap &attrs, int index, int offset) const
Updates an index in an attribute map to a new value (for updates of changed attributes) ...
virtual bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature&#39;s geometry.
int size() const
void featureDeleted(QgsFeatureId fid)
void push(QUndoCommand *cmd)
friend class QgsVectorLayerUndoCommandChangeAttribute
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:89
const T value(const Key &key) const
int remove(const Key &key)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.