QGIS API Documentation  2.12.0-Lyon
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 
164 
166 {
167  if ( !L->hasGeometryType() )
168  {
169  return false;
170  }
171 
172  if ( FID_IS_NEW( fid ) )
173  {
174  if ( !mAddedFeatures.contains( fid ) )
175  return false;
176  }
178  return false;
179 
180  // TODO: check compatible geometry
181 
182  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, geom ) );
183  return true;
184 }
185 
186 
187 bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
188 {
189  if ( FID_IS_NEW( fid ) )
190  {
191  if ( !mAddedFeatures.contains( fid ) )
192  return false;
193  }
195  {
196  return false;
197  }
198 
199  if ( field < 0 || field >= L->fields().count() ||
200  L->fields().fieldOrigin( field ) == QgsFields::OriginJoin ||
202  return false;
203 
204  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, newValue, oldValue ) );
205  return true;
206 }
207 
208 
210 {
212  return false;
213 
214  if ( field.name().isEmpty() )
215  return false;
216 
217  const QgsFields& updatedFields = L->fields();
218  for ( int idx = 0; idx < updatedFields.count(); ++idx )
219  {
220  if ( updatedFields[idx].name() == field.name() )
221  return false;
222  }
223 
224  if ( !L->dataProvider()->supportedType( field ) )
225  return false;
226 
227  L->undoStack()->push( new QgsVectorLayerUndoCommandAddAttribute( this, field ) );
228  return true;
229 }
230 
231 
233 {
235  return false;
236 
237  if ( index < 0 || index >= L->fields().count() )
238  return false;
239 
240  // find out source of the field
241  QgsFields::FieldOrigin origin = L->fields().fieldOrigin( index );
242  int originIndex = L->fields().fieldOriginIndex( index );
243 
244  if ( origin == QgsFields::OriginProvider && mDeletedAttributeIds.contains( originIndex ) )
245  return false;
246 
247  if ( origin == QgsFields::OriginJoin )
248  return false;
249 
250  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteAttribute( this, index ) );
251  return true;
252 }
253 
254 
256 {
257  QgsVectorDataProvider* provider = L->dataProvider();
258  commitErrors.clear();
259 
260  int cap = provider->capabilities();
261  bool success = true;
262 
263  //
264  // update geometries
265  //
266  if ( !mChangedGeometries.isEmpty() )
267  {
269  {
270  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
271 
273 
275  }
276  else
277  {
278  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
279  success = false;
280  }
281  }
282 
283  QgsFields oldFields = L->fields();
284 
285  //
286  // delete attributes
287  //
288  bool attributesChanged = false;
289  if ( !mDeletedAttributeIds.isEmpty() )
290  {
292  {
293  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
294 
296 
298  attributesChanged = true;
299  }
300  else
301  {
302  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
303 #if 0
304  QString list = "ERROR: Pending attribute deletes:";
305  Q_FOREACH ( int idx, mDeletedAttributeIds )
306  {
307  list.append( " " + L->pendingFields().at( idx ).name() );
308  }
309  commitErrors << list;
310 #endif
311  success = false;
312  }
313  }
314 
315  //
316  // add attributes
317  //
318  if ( !mAddedAttributes.isEmpty() )
319  {
321  {
322  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
323 
325 
327  attributesChanged = true;
328  }
329  else
330  {
331  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
332 #if 0
333  QString list = "ERROR: Pending adds:";
334  Q_FOREACH ( QgsField f, mAddedAttributes )
335  {
336  list.append( " " + f.name() );
337  }
338  commitErrors << list;
339 #endif
340  success = false;
341  }
342  }
343 
344  //
345  // check that addition/removal went as expected
346  //
347  bool attributeChangesOk = true;
348  if ( attributesChanged )
349  {
350  L->updateFields();
351  QgsFields newFields = L->fields();
352 
353  if ( oldFields.count() != newFields.count() )
354  {
355  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
356  attributeChangesOk = false; // don't try attribute updates - they'll fail.
357  }
358 
359  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
360  {
361  const QgsField& oldField = oldFields.at( i );
362  const QgsField& newField = newFields.at( i );
363  if ( attributeChangesOk && oldField != newField )
364  {
365  commitErrors
366  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
367  << tr( "Provider: %1" ).arg( L->providerType() )
368  << tr( "Storage: %1" ).arg( L->storageType() )
369  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
370  .arg( tr( "expected field" ),
371  oldField.name(),
372  QVariant::typeToName( oldField.type() ),
373  oldField.typeName() )
374  .arg( oldField.length() )
375  .arg( oldField.precision() )
376  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
377  .arg( tr( "retrieved field" ),
378  newField.name(),
379  QVariant::typeToName( newField.type() ),
380  newField.typeName() )
381  .arg( newField.length() )
382  .arg( newField.precision() );
383  attributeChangesOk = false; // don't try attribute updates - they'll fail.
384  }
385  }
386  }
387 
388  if ( attributeChangesOk )
389  {
390  //
391  // change attributes
392  //
394  {
396  {
397  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
398 
400 
402  }
403  else
404  {
405  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
406 #if 0
407  QString list = "ERROR: pending changes:";
408  Q_FOREACH ( QgsFeatureId id, mChangedAttributeValues.keys() )
409  {
410  list.append( "\n " + FID_TO_STRING( id ) + "[" );
411  Q_FOREACH ( int idx, mChangedAttributeValues[ id ].keys() )
412  {
413  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( idx ).name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
414  }
415  list.append( " ]" );
416  }
417  commitErrors << list;
418 #endif
419  success = false;
420  }
421  }
422 
423  //
424  // delete features
425  //
426  if ( success && !mDeletedFeatureIds.isEmpty() )
427  {
429  {
430  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
431  // TODO[MD]: we should not need this here
433  {
435  mChangedGeometries.remove( *it );
436  }
437 
439 
441  }
442  else
443  {
444  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
445 #if 0
446  QString list = "ERROR: pending deletes:";
447  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
448  {
449  list.append( " " + FID_TO_STRING( id ) );
450  }
451  commitErrors << list;
452 #endif
453  success = false;
454  }
455  }
456 
457  //
458  // add features
459  //
460  if ( success && !mAddedFeatures.isEmpty() )
461  {
463  {
465  QgsFeatureList featuresToAdd;
466  // get the list of added features in reversed order
467  // 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)
468  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
469 
470  if ( provider->addFeatures( featuresToAdd ) )
471  {
472  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
473 
474  emit committedFeaturesAdded( L->id(), featuresToAdd );
475 
476  // notify everyone that the features with temporary ids were updated with permanent ids
477  for ( int i = 0; i < featuresToAdd.count(); ++i )
478  {
479  if ( featuresToAdd[i].id() != ids[i] )
480  {
481  //update selection
482  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
483  {
484  L->mSelectedFeatureIds.remove( ids[i] );
485  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
486  }
487  emit featureDeleted( ids[i] );
488  emit featureAdded( featuresToAdd[i].id() );
489  }
490  }
491 
493  }
494  else
495  {
496  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
497 #if 0
498  QString list = "ERROR: pending adds:";
499  Q_FOREACH ( QgsFeature f, mAddedFeatures )
500  {
501  list.append( " " + FID_TO_STRING( f.id() ) + "[" );
502  for ( int i = 0; i < L->pendingFields().size(); i++ )
503  {
504  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( i ).name() ).arg( f.attributes()[i].toString() ) );
505  }
506  list.append( " ]" );
507  }
508  commitErrors << list;
509 #endif
510  success = false;
511  }
512  }
513  else
514  {
515  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
516  success = false;
517  }
518  }
519  }
520  else
521  {
522  success = false;
523  }
524 
525  if ( !success && provider->hasErrors() )
526  {
527  commitErrors << tr( "\n Provider errors:" );
528  Q_FOREACH ( QString e, provider->errors() )
529  {
530  commitErrors << " " + e.replace( "\n", "\n " );
531  }
532  provider->clearErrors();
533  }
534 
535  return success;
536 }
537 
538 
540 {
541  if ( !isModified() )
542  return;
543 
544  // limit canvas redraws to one by jumping to beginning of stack
545  // see QgsUndoWidget::indexChanged
546  L->undoStack()->setIndex( 0 );
547 
548  Q_ASSERT( mAddedAttributes.isEmpty() );
549  Q_ASSERT( mDeletedAttributeIds.isEmpty() );
550  Q_ASSERT( mChangedAttributeValues.isEmpty() );
551  Q_ASSERT( mChangedGeometries.isEmpty() );
552  Q_ASSERT( mAddedFeatures.isEmpty() );
553 }
554 
555 #if 0
556 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
557 {
558  QString msg;
559  if ( !mChangedGeometries.isEmpty() )
560  {
561  msg += "CHANGED GEOMETRIES:\n";
562  for ( QgsGeometryMap::const_iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it )
563  {
564  // QgsFeatureId, QgsGeometry
565  msg += QString( "- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
566  }
567  }
568  return msg;
569 }
570 #endif
571 
573 {
574  // go through the changed attributes map and adapt indices
575  Q_FOREACH ( QgsFeatureId fid, mChangedAttributeValues.keys() )
576  {
578  }
579 
580  // go through added features and adapt attributes
581  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
582  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
583  {
584  QgsAttributes attrs = featureIt->attributes();
585  attrs.insert( index, QVariant() );
586  featureIt->setAttributes( attrs );
587  }
588 }
589 
591 {
592  // go through the changed attributes map and adapt indices
593  Q_FOREACH ( QgsFeatureId fid, mChangedAttributeValues.keys() )
594  {
596  // remove the attribute
597  if ( attrMap.contains( index ) )
598  attrMap.remove( index );
599 
600  // update attribute indices
601  updateAttributeMapIndex( attrMap, index, -1 );
602  }
603 
604  // go through added features and adapt attributes
605  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
606  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
607  {
608  QgsAttributes attrs = featureIt->attributes();
609  attrs.remove( index );
610  featureIt->setAttributes( attrs );
611  }
612 }
613 
614 
615 
617 {
618  QgsAttributeMap updatedMap;
619  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
620  {
621  int attrIndex = it.key();
622  updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
623  }
624  map = updatedMap;
625 }
626 
627 
628 
630 {
631  L->updateFields();
632 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:53
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:72
void clear()
Allows modification of attribute values.
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:185
Allows modifications of geometries.
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:186
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:92
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:177
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's attributes.
Definition: qgsfeature.cpp:97
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
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:184
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:176
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)
const char * name() const
QgsFields pendingFields() const
Returns the list of fields of this layer.
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:106
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
void resize(int size)
const Key & key() const
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:92
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
bool hasErrors()
Provider has errors to report.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
bool isEmpty() const
Allows deletion of attributes (fields)
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:359
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
void handleAttributeAdded(int index)
Update added and changed features after addition of an attribute.
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:261
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
const T & value() const
void clearErrors()
Clear recorded errors.
int count() const
Return number of items.
Definition: qgsfield.cpp:311
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:40
iterator end()
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:331
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:285
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()
iterator begin()
virtual bool changeGeometryValues(QgsGeometryMap &geometry_map)
Changes geometries of existing features.
bool contains(const T &value) const
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)
const QString & typeName() const
Gets the field type.
Definition: qgsfield.cpp:82
iterator end()
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:87
int count(const T &value) const
int size() const
Return number of items.
Definition: qgsfield.cpp:316
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:351
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)
Allows addition of new attributes (fields)
bool isEmpty() const
QUndoStack * undoStack()
Return pointer to layer'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:109
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:187
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not commited.
iterator begin()
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'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:77
int remove(const Key &key)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.