QGIS API Documentation  2.14.0-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 }
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)
const char * name() const
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.