QGIS API Documentation  2.17.0-Master (8784312)
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  // rename fields
76  QgsFieldNameMap::const_iterator renameIt = mRenamedAttributes.constBegin();
77  for ( ; renameIt != mRenamedAttributes.constEnd(); ++renameIt )
78  {
79  fields[ renameIt.key()].setName( renameIt.value() );
80  }
81 }
82 
83 
85 {
86  if ( mChangedGeometries.contains( f.id() ) )
88 }
89 
90 
92 {
93  QgsAttributes attrs = f.attributes();
94 
95  // remove all attributes that will disappear - from higher indices to lower
96  for ( int idx = mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
97  {
98  attrs.remove( mDeletedAttributeIds[idx] );
99  }
100 
101  // adjust size to accommodate added attributes
102  attrs.resize( attrs.count() + mAddedAttributes.count() );
103 
104  // update changed attributes
105  if ( mChangedAttributeValues.contains( f.id() ) )
106  {
107  const QgsAttributeMap &map = mChangedAttributeValues[f.id()];
108  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
109  attrs[it.key()] = it.value();
110  }
111 
112  f.setAttributes( attrs );
113 }
114 
115 
116 
117 
119 {
121  {
122  return false;
123  }
124  if ( L->mUpdatedFields.count() != f.attributes().count() )
125  return false;
126 
127  // TODO: check correct geometry type
128 
129  L->undoStack()->push( new QgsVectorLayerUndoCommandAddFeature( this, f ) );
130  return true;
131 }
132 
133 
135 {
137  return false;
138 
139  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
140  {
141  addFeature( *iter );
142  }
143 
144  L->updateExtents();
145  return true;
146 }
147 
148 
149 
151 {
153  return false;
154 
155  if ( FID_IS_NEW( fid ) )
156  {
157  if ( !mAddedFeatures.contains( fid ) )
158  return false;
159  }
160  else // existing feature
161  {
162  if ( mDeletedFeatureIds.contains( fid ) )
163  return false;
164  }
165 
166  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteFeature( this, fid ) );
167  return true;
168 }
169 
171 {
173  return false;
174 
175  Q_FOREACH ( QgsFeatureId fid, fids )
176  deleteFeature( fid );
177 
178  return true;
179 }
180 
181 
183 {
184  if ( !L->hasGeometryType() )
185  {
186  return false;
187  }
188 
189  if ( FID_IS_NEW( fid ) )
190  {
191  if ( !mAddedFeatures.contains( fid ) )
192  return false;
193  }
195  return false;
196 
197  // TODO: check compatible geometry
198 
199  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, geom ) );
200  return true;
201 }
202 
203 
204 bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
205 {
206  if ( FID_IS_NEW( fid ) )
207  {
208  if ( !mAddedFeatures.contains( fid ) )
209  return false;
210  }
212  {
213  return false;
214  }
215 
216  if ( field < 0 || field >= L->fields().count() ||
217  L->fields().fieldOrigin( field ) == QgsFields::OriginJoin ||
219  return false;
220 
221  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, newValue, oldValue ) );
222  return true;
223 }
224 
225 
227 {
229  return false;
230 
231  if ( field.name().isEmpty() )
232  return false;
233 
234  Q_FOREACH ( const QgsField& updatedField, L->fields() )
235  {
236  if ( updatedField.name() == field.name() )
237  return false;
238  }
239 
240  if ( !L->dataProvider()->supportedType( field ) )
241  return false;
242 
243  L->undoStack()->push( new QgsVectorLayerUndoCommandAddAttribute( this, field ) );
244  return true;
245 }
246 
247 
249 {
251  return false;
252 
253  if ( index < 0 || index >= L->fields().count() )
254  return false;
255 
256  // find out source of the field
257  QgsFields::FieldOrigin origin = L->fields().fieldOrigin( index );
258  int originIndex = L->fields().fieldOriginIndex( index );
259 
260  if ( origin == QgsFields::OriginProvider && mDeletedAttributeIds.contains( originIndex ) )
261  return false;
262 
263  if ( origin == QgsFields::OriginJoin )
264  return false;
265 
266  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteAttribute( this, index ) );
267  return true;
268 }
269 
271 {
273  return false;
274 
275  if ( newName.isEmpty() )
276  return false;
277 
278  if ( index < 0 || index >= L->fields().count() )
279  return false;
280 
281  Q_FOREACH ( const QgsField& updatedField, L->fields() )
282  {
283  if ( updatedField.name() == newName )
284  return false;
285  }
286 
287  L->undoStack()->push( new QgsVectorLayerUndoCommandRenameAttribute( this, index, newName ) );
288  return true;
289 }
290 
291 
293 {
294  QgsVectorDataProvider* provider = L->dataProvider();
295  commitErrors.clear();
296 
297  int cap = provider->capabilities();
298  bool success = true;
299 
300  // geometry updates attribute updates
301  // yes no => changeGeometryValues
302  // no yes => changeAttributeValues
303  // yes yes => changeFeatures
304 
305  //
306  // update geometries
307  //
309  {
310  if ( provider->changeGeometryValues( mChangedGeometries ) )
311  {
312  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
313 
316  }
317  else
318  {
319  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
320  success = false;
321  }
322  }
323 
324  QgsFields oldFields = L->fields();
325 
326  //
327  // delete attributes
328  //
329  bool attributesChanged = false;
330  if ( !mDeletedAttributeIds.isEmpty() )
331  {
333  {
334  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
335 
337 
339  attributesChanged = true;
340  }
341  else
342  {
343  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
344 #if 0
345  QString list = "ERROR: Pending attribute deletes:";
346  Q_FOREACH ( int idx, mDeletedAttributeIds )
347  {
348  list.append( ' ' + L->pendingFields().at( idx ).name() );
349  }
350  commitErrors << list;
351 #endif
352  success = false;
353  }
354  }
355 
356  //
357  // add attributes
358  //
359  if ( !mAddedAttributes.isEmpty() )
360  {
362  {
363  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
364 
366 
368  attributesChanged = true;
369  }
370  else
371  {
372  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
373 #if 0
374  QString list = "ERROR: Pending adds:";
375  Q_FOREACH ( QgsField f, mAddedAttributes )
376  {
377  list.append( ' ' + f.name() );
378  }
379  commitErrors << list;
380 #endif
381  success = false;
382  }
383  }
384 
385  // rename attributes
386  if ( !mRenamedAttributes.isEmpty() )
387  {
389  {
390  commitErrors << tr( "SUCCESS: %n attribute(s) renamed.", "renamed attributes count", mRenamedAttributes.size() );
391 
393 
395  attributesChanged = true;
396  }
397  else
398  {
399  commitErrors << tr( "ERROR: %n attribute(s) not renamed", "not renamed attributes count", mRenamedAttributes.size() );
400  success = false;
401  }
402  }
403 
404  //
405  // check that addition/removal went as expected
406  //
407  bool attributeChangesOk = true;
408  if ( attributesChanged )
409  {
410  L->updateFields();
411  QgsFields newFields = L->fields();
412 
413  if ( oldFields.count() != newFields.count() )
414  {
415  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
416  attributeChangesOk = false; // don't try attribute updates - they'll fail.
417  }
418 
419  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
420  {
421  const QgsField& oldField = oldFields.at( i );
422  const QgsField& newField = newFields.at( i );
423  if ( attributeChangesOk && oldField != newField )
424  {
425  commitErrors
426  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
427  << tr( "Provider: %1" ).arg( L->providerType() )
428  << tr( "Storage: %1" ).arg( L->storageType() )
429  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
430  .arg( tr( "expected field" ),
431  oldField.name(),
432  QVariant::typeToName( oldField.type() ),
433  oldField.typeName() )
434  .arg( oldField.length() )
435  .arg( oldField.precision() )
436  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
437  .arg( tr( "retrieved field" ),
438  newField.name(),
439  QVariant::typeToName( newField.type() ),
440  newField.typeName() )
441  .arg( newField.length() )
442  .arg( newField.precision() );
443  attributeChangesOk = false; // don't try attribute updates - they'll fail.
444  }
445  }
446  }
447 
448  if ( attributeChangesOk )
449  {
451  {
453 
455  {
456  commitErrors << tr( "SUCCESS: %1 attribute value(s) and %2 geometries changed." ).arg( mChangedAttributeValues.size(), mChangedGeometries.size() );
459 
462  }
463  else
464  {
465  success = false;
466  }
467  }
468  else
469  {
470  //
471  // change attributes
472  //
474  {
476  {
477  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
478 
481  }
482  else
483  {
484  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
485 #if 0
486  QString list = "ERROR: pending changes:";
487  Q_FOREACH ( QgsFeatureId id, mChangedAttributeValues.keys() )
488  {
489  list.append( "\n " + FID_TO_STRING( id ) + '[' );
490  Q_FOREACH ( int idx, mChangedAttributeValues[ id ].keys() )
491  {
492  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( idx ).name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
493  }
494  list.append( " ]" );
495  }
496  commitErrors << list;
497 #endif
498  success = false;
499  }
500  }
501  }
502 
503  //
504  // delete features
505  //
506  if ( success && !mDeletedFeatureIds.isEmpty() )
507  {
509  {
510  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
511  // TODO[MD]: we should not need this here
512  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
513  {
516  }
517 
519 
521  }
522  else
523  {
524  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
525 #if 0
526  QString list = "ERROR: pending deletes:";
527  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
528  {
529  list.append( ' ' + FID_TO_STRING( id ) );
530  }
531  commitErrors << list;
532 #endif
533  success = false;
534  }
535  }
536 
537  //
538  // add features
539  //
540  if ( success && !mAddedFeatures.isEmpty() )
541  {
543  {
545  QgsFeatureList featuresToAdd;
546  // get the list of added features in reversed order
547  // 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)
548  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
549 
550  if ( provider->addFeatures( featuresToAdd ) )
551  {
552  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
553 
554  emit committedFeaturesAdded( L->id(), featuresToAdd );
555 
556  // notify everyone that the features with temporary ids were updated with permanent ids
557  for ( int i = 0; i < featuresToAdd.count(); ++i )
558  {
559  if ( featuresToAdd[i].id() != ids[i] )
560  {
561  //update selection
562  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
563  {
564  L->mSelectedFeatureIds.remove( ids[i] );
565  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
566  }
567  emit featureDeleted( ids[i] );
568  emit featureAdded( featuresToAdd[i].id() );
569  }
570  }
571 
573  }
574  else
575  {
576  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
577 #if 0
578  QString list = "ERROR: pending adds:";
579  Q_FOREACH ( QgsFeature f, mAddedFeatures )
580  {
581  list.append( ' ' + FID_TO_STRING( f.id() ) + '[' );
582  for ( int i = 0; i < L->pendingFields().size(); i++ )
583  {
584  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( i ).name() ).arg( f.attributes()[i].toString() ) );
585  }
586  list.append( " ]" );
587  }
588  commitErrors << list;
589 #endif
590  success = false;
591  }
592  }
593  else
594  {
595  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
596  success = false;
597  }
598  }
599  }
600  else
601  {
602  success = false;
603  }
604 
605  if ( !success && provider->hasErrors() )
606  {
607  commitErrors << tr( "\n Provider errors:" );
608  Q_FOREACH ( QString e, provider->errors() )
609  {
610  commitErrors << " " + e.replace( '\n', "\n " );
611  }
612  provider->clearErrors();
613  }
614 
615  return success;
616 }
617 
618 
620 {
621  if ( !isModified() )
622  return;
623 
624  // limit canvas redraws to one by jumping to beginning of stack
625  // see QgsUndoWidget::indexChanged
626  L->undoStack()->setIndex( 0 );
627 
628  Q_ASSERT( mAddedAttributes.isEmpty() );
629  Q_ASSERT( mDeletedAttributeIds.isEmpty() );
630  Q_ASSERT( mChangedAttributeValues.isEmpty() );
631  Q_ASSERT( mChangedGeometries.isEmpty() );
632  Q_ASSERT( mAddedFeatures.isEmpty() );
633 }
634 
635 #if 0
636 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
637 {
638  QString msg;
639  if ( !mChangedGeometries.isEmpty() )
640  {
641  msg += "CHANGED GEOMETRIES:\n";
642  for ( QgsGeometryMap::const_iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it )
643  {
644  // QgsFeatureId, QgsGeometry
645  msg += QString( "- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
646  }
647  }
648  return msg;
649 }
650 #endif
651 
653 {
654  // go through the changed attributes map and adapt indices
655  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
656  for ( ; it != mChangedAttributeValues.end(); ++it )
657  {
658  updateAttributeMapIndex( it.value(), index, + 1 );
659  }
660 
661  // go through added features and adapt attributes
662  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
663  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
664  {
665  QgsAttributes attrs = featureIt->attributes();
666  attrs.insert( index, QVariant() );
667  featureIt->setAttributes( attrs );
668  }
669 
670  // go through renamed attributes and adapt
671  QList< int > sortedRenamedIndices = mRenamedAttributes.keys();
672  //sort keys
673  qSort( sortedRenamedIndices.begin(), sortedRenamedIndices.end(), qGreater< int >() );
674  Q_FOREACH ( int renameIndex, sortedRenamedIndices )
675  {
676  if ( renameIndex >= index )
677  {
678  mRenamedAttributes[ renameIndex + 1 ] = mRenamedAttributes.value( renameIndex );
679  }
680  }
681  //remove last
682  mRenamedAttributes.remove( index );
683 }
684 
686 {
687  // go through the changed attributes map and adapt indices
688  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
689  for ( ; it != mChangedAttributeValues.end(); ++it )
690  {
691  QgsAttributeMap& attrMap = it.value();
692  // remove the attribute
693  if ( attrMap.contains( index ) )
694  attrMap.remove( index );
695 
696  // update attribute indices
697  updateAttributeMapIndex( attrMap, index, -1 );
698  }
699 
700  // go through added features and adapt attributes
701  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
702  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
703  {
704  QgsAttributes attrs = featureIt->attributes();
705  attrs.remove( index );
706  featureIt->setAttributes( attrs );
707  }
708 
709  // go through rename attributes and adapt
710  QList< int > sortedRenamedIndices = mRenamedAttributes.keys();
711  //sort keys
712  qSort( sortedRenamedIndices.begin(), sortedRenamedIndices.end() );
713  int last = -1;
714  mRenamedAttributes.remove( index );
715  Q_FOREACH ( int renameIndex, sortedRenamedIndices )
716  {
717  if ( renameIndex > index )
718  {
719  mRenamedAttributes.insert( renameIndex - 1, mRenamedAttributes.value( renameIndex ) );
720  last = renameIndex;
721  }
722  }
723  //remove last
724  if ( last > -1 )
725  mRenamedAttributes.remove( last );
726 }
727 
728 
729 
731 {
732  QgsAttributeMap updatedMap;
733  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
734  {
735  int attrIndex = it.key();
736  updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
737  }
738  map = updatedMap;
739 }
740 
741 
742 
744 {
745  L->updateFields();
746 }
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:201
virtual bool renameAttribute(int attr, const QString &newName)
Renames an attribute field (but does not commit it)
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:202
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
virtual bool renameAttributes(const QgsFieldNameMap &renamedAttributes)
Renames existing attributes.
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:193
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:200
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
QgsFieldNameMap mRenamedAttributes
Renamed attributes which are not commited.
friend class QgsVectorLayerUndoCommandRenameAttribute
void clear()
virtual bool addFeatures(QgsFeatureList &flist)
Adds a list of features.
QString tr(const char *sourceText, const char *disambiguation, int n)
friend class QgsVectorLayerUndoCommandDeleteAttribute
int size() const
virtual void updateExtents()
Update the extents for the layer.
T value(int i) const
QList< Key > keys() const
void featureAdded(QgsFeatureId fid)
QgsFields pendingFields() const
Returns the list of fields of this layer.
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
int count(const T &value) const
void append(const T &value)
void setIndex(int idx)
bool supportedType(const QgsField &field) const
check if provider supports type of field
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:94
void resize(int size)
const Key & key() const
Allows addition of new attributes (fields)
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
bool hasErrors()
Provider has errors to report.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
bool isEmpty() const
virtual bool changeFeatures(const QgsChangedAttributesMap &attr_map, const QgsGeometryMap &geometry_map)
Changes attribute values and geometries of existing features.
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:419
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
void handleAttributeAdded(int index)
Update added and changed features after addition of an attribute.
Allows modifications of geometries.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
Definition: qgsfield.cpp:309
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
const T & value() const
virtual bool deleteFeatures(const QgsFeatureIds &fid)
Deletes a set of features from the layer (but does not commit it)
void clearErrors()
Clear recorded errors.
int count() const
Return number of items.
Definition: qgsfield.cpp:365
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
iterator end()
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:333
iterator begin()
virtual bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
virtual bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
friend class QgsVectorLayerUndoCommandDeleteFeature
iterator end()
bool contains(const T &value) const
Supports joint updates for attributes and geometry Providers supporting this should still define Chan...
bool contains(const T &value) const
const char * typeToName(Type typ)
const Key key(const T &value) const
QString providerType() const
Return the provider type for this layer.
QString & replace(int position, int n, QChar after)
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
bool isClean() const
QList< QgsField > mAddedAttributes
Added attributes fields which are not commited.
bool remove(const T &value)
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
void committedAttributesRenamed(const QString &layerId, const QgsFieldNameMap &renamedAttributes)
Emitted after committing an attribute rename.
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:203
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)
Supports renaming attributes (fields).
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.