QGIS API Documentation  2.14.11-Essen
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  const QgsFields& updatedFields = L->fields();
229  for ( int idx = 0; idx < updatedFields.count(); ++idx )
230  {
231  if ( updatedFields[idx].name() == field.name() )
232  return false;
233  }
234 
235  if ( !L->dataProvider()->supportedType( field ) )
236  return false;
237 
238  L->undoStack()->push( new QgsVectorLayerUndoCommandAddAttribute( this, field ) );
239  return true;
240 }
241 
242 
244 {
246  return false;
247 
248  if ( index < 0 || index >= L->fields().count() )
249  return false;
250 
251  // find out source of the field
252  QgsFields::FieldOrigin origin = L->fields().fieldOrigin( index );
253  int originIndex = L->fields().fieldOriginIndex( index );
254 
255  if ( origin == QgsFields::OriginProvider && mDeletedAttributeIds.contains( originIndex ) )
256  return false;
257 
258  if ( origin == QgsFields::OriginJoin )
259  return false;
260 
261  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteAttribute( this, index ) );
262  return true;
263 }
264 
265 
267 {
268  QgsVectorDataProvider* provider = L->dataProvider();
269  commitErrors.clear();
270 
271  int cap = provider->capabilities();
272  bool success = true;
273 
274  // geometry updates attribute updates
275  // yes no => changeGeometryValues
276  // no yes => changeAttributeValues
277  // yes yes => changeFeatures
278 
279  //
280  // update geometries
281  //
283  {
284  if ( provider->changeGeometryValues( mChangedGeometries ) )
285  {
286  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
287 
290  }
291  else
292  {
293  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
294  success = false;
295  }
296  }
297 
298  QgsFields oldFields = L->fields();
299 
300  //
301  // delete attributes
302  //
303  bool attributesChanged = false;
304  if ( !mDeletedAttributeIds.isEmpty() )
305  {
307  {
308  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
309 
311 
313  attributesChanged = true;
314  }
315  else
316  {
317  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
318 #if 0
319  QString list = "ERROR: Pending attribute deletes:";
320  Q_FOREACH ( int idx, mDeletedAttributeIds )
321  {
322  list.append( ' ' + L->pendingFields().at( idx ).name() );
323  }
324  commitErrors << list;
325 #endif
326  success = false;
327  }
328  }
329 
330  //
331  // add attributes
332  //
333  if ( !mAddedAttributes.isEmpty() )
334  {
336  {
337  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
338 
340 
342  attributesChanged = true;
343  }
344  else
345  {
346  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
347 #if 0
348  QString list = "ERROR: Pending adds:";
349  Q_FOREACH ( QgsField f, mAddedAttributes )
350  {
351  list.append( ' ' + f.name() );
352  }
353  commitErrors << list;
354 #endif
355  success = false;
356  }
357  }
358 
359  //
360  // check that addition/removal went as expected
361  //
362  bool attributeChangesOk = true;
363  if ( attributesChanged )
364  {
365  L->updateFields();
366  QgsFields newFields = L->fields();
367 
368  if ( oldFields.count() != newFields.count() )
369  {
370  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
371  attributeChangesOk = false; // don't try attribute updates - they'll fail.
372  }
373 
374  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
375  {
376  const QgsField& oldField = oldFields.at( i );
377  const QgsField& newField = newFields.at( i );
378  if ( attributeChangesOk && oldField != newField )
379  {
380  commitErrors
381  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
382  << tr( "Provider: %1" ).arg( L->providerType() )
383  << tr( "Storage: %1" ).arg( L->storageType() )
384  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
385  .arg( tr( "expected field" ),
386  oldField.name(),
387  QVariant::typeToName( oldField.type() ),
388  oldField.typeName() )
389  .arg( oldField.length() )
390  .arg( oldField.precision() )
391  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
392  .arg( tr( "retrieved field" ),
393  newField.name(),
394  QVariant::typeToName( newField.type() ),
395  newField.typeName() )
396  .arg( newField.length() )
397  .arg( newField.precision() );
398  attributeChangesOk = false; // don't try attribute updates - they'll fail.
399  }
400  }
401  }
402 
403  if ( attributeChangesOk )
404  {
406  {
408 
410  {
411  commitErrors << tr( "SUCCESS: %1 attribute value(s) and %2 geometries changed." ).arg( mChangedAttributeValues.size(), mChangedGeometries.size() );
414 
417  }
418  else
419  {
420  success = false;
421  }
422  }
423  else
424  {
425  //
426  // change attributes
427  //
429  {
431  {
432  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
433 
436  }
437  else
438  {
439  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
440 #if 0
441  QString list = "ERROR: pending changes:";
442  Q_FOREACH ( QgsFeatureId id, mChangedAttributeValues.keys() )
443  {
444  list.append( "\n " + FID_TO_STRING( id ) + '[' );
445  Q_FOREACH ( int idx, mChangedAttributeValues[ id ].keys() )
446  {
447  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( idx ).name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
448  }
449  list.append( " ]" );
450  }
451  commitErrors << list;
452 #endif
453  success = false;
454  }
455  }
456  }
457 
458  //
459  // delete features
460  //
461  if ( success && !mDeletedFeatureIds.isEmpty() )
462  {
464  {
465  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
466  // TODO[MD]: we should not need this here
467  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
468  {
471  }
472 
474 
476  }
477  else
478  {
479  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
480 #if 0
481  QString list = "ERROR: pending deletes:";
482  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
483  {
484  list.append( ' ' + FID_TO_STRING( id ) );
485  }
486  commitErrors << list;
487 #endif
488  success = false;
489  }
490  }
491 
492  //
493  // add features
494  //
495  if ( success && !mAddedFeatures.isEmpty() )
496  {
498  {
500  QgsFeatureList featuresToAdd;
501  // get the list of added features in reversed order
502  // 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)
503  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
504 
505  if ( provider->addFeatures( featuresToAdd ) )
506  {
507  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
508 
509  emit committedFeaturesAdded( L->id(), featuresToAdd );
510 
511  // notify everyone that the features with temporary ids were updated with permanent ids
512  for ( int i = 0; i < featuresToAdd.count(); ++i )
513  {
514  if ( featuresToAdd[i].id() != ids[i] )
515  {
516  //update selection
517  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
518  {
519  L->mSelectedFeatureIds.remove( ids[i] );
520  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
521  }
522  emit featureDeleted( ids[i] );
523  emit featureAdded( featuresToAdd[i].id() );
524  }
525  }
526 
528  }
529  else
530  {
531  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
532 #if 0
533  QString list = "ERROR: pending adds:";
534  Q_FOREACH ( QgsFeature f, mAddedFeatures )
535  {
536  list.append( ' ' + FID_TO_STRING( f.id() ) + '[' );
537  for ( int i = 0; i < L->pendingFields().size(); i++ )
538  {
539  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( i ).name() ).arg( f.attributes()[i].toString() ) );
540  }
541  list.append( " ]" );
542  }
543  commitErrors << list;
544 #endif
545  success = false;
546  }
547  }
548  else
549  {
550  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
551  success = false;
552  }
553  }
554  }
555  else
556  {
557  success = false;
558  }
559 
560  if ( !success && provider->hasErrors() )
561  {
562  commitErrors << tr( "\n Provider errors:" );
563  Q_FOREACH ( QString e, provider->errors() )
564  {
565  commitErrors << " " + e.replace( '\n', "\n " );
566  }
567  provider->clearErrors();
568  }
569 
570  return success;
571 }
572 
573 
575 {
576  if ( !isModified() )
577  return;
578 
579  // limit canvas redraws to one by jumping to beginning of stack
580  // see QgsUndoWidget::indexChanged
581  L->undoStack()->setIndex( 0 );
582 
583  Q_ASSERT( mAddedAttributes.isEmpty() );
584  Q_ASSERT( mDeletedAttributeIds.isEmpty() );
585  Q_ASSERT( mChangedAttributeValues.isEmpty() );
586  Q_ASSERT( mChangedGeometries.isEmpty() );
587  Q_ASSERT( mAddedFeatures.isEmpty() );
588 }
589 
590 #if 0
591 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
592 {
593  QString msg;
594  if ( !mChangedGeometries.isEmpty() )
595  {
596  msg += "CHANGED GEOMETRIES:\n";
597  for ( QgsGeometryMap::const_iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it )
598  {
599  // QgsFeatureId, QgsGeometry
600  msg += QString( "- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
601  }
602  }
603  return msg;
604 }
605 #endif
606 
608 {
609  // go through the changed attributes map and adapt indices
610  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
611  for ( ; it != mChangedAttributeValues.end(); ++it )
612  {
613  updateAttributeMapIndex( it.value(), index, + 1 );
614  }
615 
616  // go through added features and adapt attributes
617  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
618  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
619  {
620  QgsAttributes attrs = featureIt->attributes();
621  attrs.insert( index, QVariant() );
622  featureIt->setAttributes( attrs );
623  }
624 }
625 
627 {
628  // go through the changed attributes map and adapt indices
629  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
630  for ( ; it != mChangedAttributeValues.end(); ++it )
631  {
632  QgsAttributeMap& attrMap = it.value();
633  // remove the attribute
634  if ( attrMap.contains( index ) )
635  attrMap.remove( index );
636 
637  // update attribute indices
638  updateAttributeMapIndex( attrMap, index, -1 );
639  }
640 
641  // go through added features and adapt attributes
642  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
643  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
644  {
645  QgsAttributes attrs = featureIt->attributes();
646  attrs.remove( index );
647  featureIt->setAttributes( attrs );
648  }
649 }
650 
651 
652 
654 {
655  QgsAttributeMap updatedMap;
656  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
657  {
658  int attrIndex = it.key();
659  updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
660  }
661  map = updatedMap;
662 }
663 
664 
665 
667 {
668  L->updateFields();
669 }
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
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
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
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)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
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
int size() const
void reserve(int alloc)
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features.
const_iterator constBegin() const
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
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:104
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.
int count() const
Return number of items.
Definition: qgsfield.cpp:365
QString tr(const char *sourceText, const char *disambiguation, int n)
friend class QgsVectorLayerUndoCommandDeleteAttribute
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
int size() const
virtual void updateExtents()
Update the extents for the layer.
bool supportedType(const QgsField &field) const
check if provider supports type of field
T value(int i) const
QgsFields fields() const
Returns the list of fields of this layer.
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:419
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QList< Key > keys() const
void featureAdded(QgsFeatureId fid)
const char * name() const
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)
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
void resize(int size)
const Key & key() const
Allows addition of new attributes (fields)
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:94
bool hasErrors()
Provider has errors to report.
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)
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
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
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.
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.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
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) ...
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()
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
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 & replace(int position, int n, QChar after)
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 count(const T &value) const
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:99
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
QgsFields pendingFields() const
Returns the list of fields of this layer.
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.
QString providerType() const
Return the provider type for this layer.
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.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:89
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.
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
const T value(const Key &key) const
int remove(const Key &key)