QGIS API Documentation  2.10.1-Pisa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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->pendingFields().count() ||
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->pendingFields();
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->pendingFields().count() )
238  return false;
239 
240  // find out source of the field
241  QgsFields::FieldOrigin origin = L->pendingFields().fieldOrigin( index );
242  int originIndex = L->pendingFields().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  QgsFields oldFields = L->pendingFields();
264 
265  //
266  // delete attributes
267  //
268  bool attributesChanged = false;
269  if ( !mDeletedAttributeIds.isEmpty() )
270  {
272  {
273  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
274 
276 
278  attributesChanged = true;
279  }
280  else
281  {
282  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
283 #if 0
284  QString list = "ERROR: Pending attribute deletes:";
285  foreach ( int idx, mDeletedAttributeIds )
286  {
287  list.append( " " + L->pendingFields()[idx].name() );
288  }
289  commitErrors << list;
290 #endif
291  success = false;
292  }
293  }
294 
295  //
296  // add attributes
297  //
298  if ( !mAddedAttributes.isEmpty() )
299  {
301  {
302  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
303 
305 
307  attributesChanged = true;
308  }
309  else
310  {
311  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
312 #if 0
313  QString list = "ERROR: Pending adds:";
314  foreach ( QgsField f, mAddedAttributes )
315  {
316  list.append( " " + f.name() );
317  }
318  commitErrors << list;
319 #endif
320  success = false;
321  }
322  }
323 
324  //
325  // check that addition/removal went as expected
326  //
327  bool attributeChangesOk = true;
328  if ( attributesChanged )
329  {
330  L->updateFields();
331  QgsFields newFields = L->pendingFields();
332 
333  if ( oldFields.count() != newFields.count() )
334  {
335  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
336  attributeChangesOk = false; // don't try attribute updates - they'll fail.
337  }
338 
339  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
340  {
341  const QgsField& oldField = oldFields[i];
342  const QgsField& newField = newFields[i];
343  if ( attributeChangesOk && oldField != newField )
344  {
345  commitErrors
346  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
347  << tr( "Provider: %1" ).arg( L->providerType() )
348  << tr( "Storage: %1" ).arg( L->storageType() )
349  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
350  .arg( tr( "expected field" ) )
351  .arg( oldField.name() )
352  .arg( QVariant::typeToName( oldField.type() ) )
353  .arg( oldField.typeName() )
354  .arg( oldField.length() )
355  .arg( oldField.precision() )
356  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
357  .arg( tr( "retrieved field" ) )
358  .arg( newField.name() )
359  .arg( QVariant::typeToName( newField.type() ) )
360  .arg( newField.typeName() )
361  .arg( newField.length() )
362  .arg( newField.precision() );
363  attributeChangesOk = false; // don't try attribute updates - they'll fail.
364  }
365  }
366  }
367 
368  if ( attributeChangesOk )
369  {
370  //
371  // change attributes
372  //
374  {
376  {
377  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
378 
380 
382  }
383  else
384  {
385  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
386 #if 0
387  QString list = "ERROR: pending changes:";
388  foreach ( QgsFeatureId id, mChangedAttributeValues.keys() )
389  {
390  list.append( "\n " + FID_TO_STRING( id ) + "[" );
391  foreach ( int idx, mChangedAttributeValues[ id ].keys() )
392  {
393  list.append( QString( " %1:%2" ).arg( L->pendingFields()[idx].name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
394  }
395  list.append( " ]" );
396  }
397  commitErrors << list;
398 #endif
399  success = false;
400  }
401  }
402 
403  //
404  // delete features
405  //
406  if ( success && !mDeletedFeatureIds.isEmpty() )
407  {
409  {
410  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
411  // TODO[MD]: we should not need this here
413  {
415  mChangedGeometries.remove( *it );
416  }
417 
419 
421  }
422  else
423  {
424  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
425 #if 0
426  QString list = "ERROR: pending deletes:";
427  foreach ( QgsFeatureId id, mDeletedFeatureIds )
428  {
429  list.append( " " + FID_TO_STRING( id ) );
430  }
431  commitErrors << list;
432 #endif
433  success = false;
434  }
435  }
436 
437  //
438  // add features
439  //
440  if ( success && !mAddedFeatures.isEmpty() )
441  {
443  {
445  QgsFeatureList featuresToAdd;
446  // get the list of added features in reversed order
447  // 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)
448  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
449 
450  if ( provider->addFeatures( featuresToAdd ) )
451  {
452  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
453 
454  emit committedFeaturesAdded( L->id(), featuresToAdd );
455 
456  // notify everyone that the features with temporary ids were updated with permanent ids
457  for ( int i = 0; i < featuresToAdd.count(); ++i )
458  {
459  if ( featuresToAdd[i].id() != ids[i] )
460  {
461  //update selection
462  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
463  {
464  L->mSelectedFeatureIds.remove( ids[i] );
465  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
466  }
467  emit featureDeleted( ids[i] );
468  emit featureAdded( featuresToAdd[i].id() );
469  }
470  }
471 
473  }
474  else
475  {
476  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
477 #if 0
478  QString list = "ERROR: pending adds:";
479  foreach ( QgsFeature f, mAddedFeatures )
480  {
481  list.append( " " + FID_TO_STRING( f.id() ) + "[" );
482  for ( int i = 0; i < L->pendingFields().size(); i++ )
483  {
484  list.append( QString( " %1:%2" ).arg( L->pendingFields()[i].name() ).arg( f.attributes()[i].toString() ) );
485  }
486  list.append( " ]" );
487  }
488  commitErrors << list;
489 #endif
490  success = false;
491  }
492  }
493  else
494  {
495  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
496  success = false;
497  }
498  }
499  }
500  else
501  {
502  success = false;
503  }
504 
505  //
506  // update geometries
507  //
508  if ( success && !mChangedGeometries.isEmpty() )
509  {
511  {
512  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
513 
515 
517  }
518  else
519  {
520  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
521  success = false;
522  }
523  }
524 
525  if ( !success && provider->hasErrors() )
526  {
527  commitErrors << tr( "\n Provider errors:" );
528  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  for ( int i = 0; i < mChangedAttributeValues.size(); ++i )
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  for ( int i = 0; i < mChangedAttributeValues.size(); ++i )
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:51
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:69
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:181
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:182
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
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:89
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:173
virtual void rollBack()
Stop editing and discard the edits.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:75
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:95
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's ...
Definition: qgsfield.h:180
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:162
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
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:104
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
allows addition of new attributes (fields)
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:90
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
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:331
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:233
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:99
const T & value() const
void clearErrors()
Clear recorded errors.
int count() const
Return number of items.
Definition: qgsfield.cpp:283
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:38
iterator end()
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:257
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:79
iterator end()
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:84
int count(const T &value) const
int size() const
Return number of items.
Definition: qgsfield.cpp:288
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:323
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's undo stack.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
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:183
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'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:74
int remove(const Key &key)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.