QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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"
19 #include <qgsmessagelog.h>
21 #include "qgsvectordataprovider.h"
22 #include "qgsvectorlayer.h"
23 
24 
26 template <class Key, class T> void mapToReversedLists( const QMap< Key, T >& map, QList<Key>& ks, QList<T>& vs )
27 {
28  ks.reserve( map.size() );
29  vs.reserve( map.size() );
30  typename QMap<Key, T>::const_iterator i = map.constEnd();
31  while ( i-- != map.constBegin() )
32  {
33  ks.append( i.key() );
34  vs.append( i.value() );
35  }
36 }
37 
38 
40  : L( layer )
41 {
42  connect( L->undoStack(), SIGNAL( indexChanged( int ) ), this, SLOT( undoIndexChanged( int ) ) ); // TODO[MD]: queued?
43 }
44 
46 {
47 }
48 
49 
51 {
52  return !L->undoStack()->isClean();
53 }
54 
55 
57 {
58  QgsDebugMsg( QString( "undo index changed %1" ).arg( index ) );
59  Q_UNUSED( index );
60  emit layerModified();
61 }
62 
63 
65 {
66  // delete attributes from the higher indices to lower indices
67  for ( int i = mDeletedAttributeIds.count() - 1; i >= 0; --i )
68  {
69  fields.remove( mDeletedAttributeIds.at( i ) );
70  }
71  // add new fields
72  for ( int i = 0; i < mAddedAttributes.count(); ++i )
73  {
75  }
76  // rename fields
77  QgsFieldNameMap::const_iterator renameIt = mRenamedAttributes.constBegin();
78  for ( ; renameIt != mRenamedAttributes.constEnd(); ++renameIt )
79  {
80  fields[ renameIt.key()].setName( renameIt.value() );
81  }
82 }
83 
84 
86 {
87  if ( mChangedGeometries.contains( f.id() ) )
89 }
90 
91 
93 {
94  QgsAttributes attrs = f.attributes();
95 
96  // remove all attributes that will disappear - from higher indices to lower
97  for ( int idx = mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
98  {
99  attrs.remove( mDeletedAttributeIds[idx] );
100  }
101 
102  // adjust size to accommodate added attributes
103  attrs.resize( attrs.count() + mAddedAttributes.count() );
104 
105  // update changed attributes
106  if ( mChangedAttributeValues.contains( f.id() ) )
107  {
108  const QgsAttributeMap &map = mChangedAttributeValues[f.id()];
109  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
110  attrs[it.key()] = it.value();
111  }
112 
113  f.setAttributes( attrs );
114 }
115 
117 {
118  QgsVectorDataProvider* provider = L->dataProvider();
119 
120  if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
121  {
122  return false;
123  }
124  if ( L->mUpdatedFields.count() != f.attributes().count() )
125  return false;
126 
127  // if not then try to convert to a compatible geometry type
128  if ( !adaptGeometry( f.geometry() ) )
129  return false;
130 
131  L->undoStack()->push( new QgsVectorLayerUndoCommandAddFeature( this, f ) );
132  return true;
133 }
134 
136 {
138  return false;
139 
140  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
141  {
142  if ( !addFeature( *iter ) )
143  return false;
144  }
145 
146  L->updateExtents();
147  return true;
148 }
149 
150 
151 
153 {
155  return false;
156 
157  if ( FID_IS_NEW( fid ) )
158  {
159  if ( !mAddedFeatures.contains( fid ) )
160  return false;
161  }
162  else // existing feature
163  {
164  if ( mDeletedFeatureIds.contains( fid ) )
165  return false;
166  }
167 
168  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteFeature( this, fid ) );
169  return true;
170 }
171 
173 {
175  return false;
176 
177  Q_FOREACH ( QgsFeatureId fid, fids )
178  deleteFeature( fid );
179 
180  return true;
181 }
182 
184 {
185  /* this routine was introduced to fi the following issue:
186  * https://issues.qgis.org/issues/15741
187  * and later used in changeGeometry and addFeature to
188  * fix also the following issue
189  * https://issues.qgis.org/issues/16948
190  * https://issues.qgis.org/issues/15741
191  */
192  QgsVectorDataProvider* provider = L->dataProvider();
193  if ( geometry && geometry->geometry() &&
194  !geometry->isEmpty() &&
195  geometry->wkbType() != provider->geometryType() )
196  {
197  // check if provider do strict geometry control
198  // otherwise leave to the commit to rise provider errors
199  if ( provider->doesStrictFeatureTypeCheck() )
200  {
201  QgsGeometry* newGeom = provider->convertToProviderType( geometry );
202  if ( !newGeom )
203  return false;
204  geometry = newGeom;
205  }
206  }
207  return true;
208 }
209 
211 {
212  if ( !L->hasGeometryType() )
213  {
214  return false;
215  }
216 
217  if ( FID_IS_NEW( fid ) )
218  {
219  if ( !mAddedFeatures.contains( fid ) )
220  return false;
221  }
223  return false;
224 
225  // if not then try to convert to a compatible geometry type
226  if ( !adaptGeometry( geom ) )
227  {
228  return false;
229  }
230 
231  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, geom ) );
232  return true;
233 }
234 
235 
236 bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
237 {
238  if ( FID_IS_NEW( fid ) )
239  {
240  if ( !mAddedFeatures.contains( fid ) )
241  return false;
242  }
244  {
245  return false;
246  }
247 
248  if ( field < 0 || field >= L->fields().count() ||
249  L->fields().fieldOrigin( field ) == QgsFields::OriginJoin ||
251  return false;
252 
253  L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, newValue, oldValue ) );
254  return true;
255 }
256 
257 
259 {
261  return false;
262 
263  if ( field.name().isEmpty() )
264  return false;
265 
266  Q_FOREACH ( const QgsField& updatedField, L->fields() )
267  {
268  if ( updatedField.name() == field.name() )
269  return false;
270  }
271 
272  if ( !L->dataProvider()->supportedType( field ) )
273  return false;
274 
275  L->undoStack()->push( new QgsVectorLayerUndoCommandAddAttribute( this, field ) );
276  return true;
277 }
278 
279 
281 {
283  return false;
284 
285  if ( index < 0 || index >= L->fields().count() )
286  return false;
287 
288  // find out source of the field
289  QgsFields::FieldOrigin origin = L->fields().fieldOrigin( index );
290  int originIndex = L->fields().fieldOriginIndex( index );
291 
292  if ( origin == QgsFields::OriginProvider && mDeletedAttributeIds.contains( originIndex ) )
293  return false;
294 
295  if ( origin == QgsFields::OriginJoin )
296  return false;
297 
298  L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteAttribute( this, index ) );
299  return true;
300 }
301 
303 {
305  return false;
306 
307  if ( newName.isEmpty() )
308  return false;
309 
310  if ( index < 0 || index >= L->fields().count() )
311  return false;
312 
313  Q_FOREACH ( const QgsField& updatedField, L->fields() )
314  {
315  if ( updatedField.name() == newName )
316  return false;
317  }
318 
319  L->undoStack()->push( new QgsVectorLayerUndoCommandRenameAttribute( this, index, newName ) );
320  return true;
321 }
322 
323 
325 {
326  QgsVectorDataProvider* provider = L->dataProvider();
327  commitErrors.clear();
328 
329  int cap = provider->capabilities();
330  bool success = true;
331 
332  // geometry updates attribute updates
333  // yes no => changeGeometryValues
334  // no yes => changeAttributeValues
335  // yes yes => changeFeatures
336 
337  //
338  // update geometries
339  //
341  {
342  if ( provider->changeGeometryValues( mChangedGeometries ) )
343  {
344  commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
345 
348  }
349  else
350  {
351  commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
352  success = false;
353  }
354  }
355 
356  QgsFields oldFields = L->fields();
357 
358  //
359  // delete attributes
360  //
361  bool attributesChanged = false;
362  if ( !mDeletedAttributeIds.isEmpty() )
363  {
365  {
366  commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
367 
369 
371  attributesChanged = true;
372  }
373  else
374  {
375  commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
376 #if 0
377  QString list = "ERROR: Pending attribute deletes:";
378  Q_FOREACH ( int idx, mDeletedAttributeIds )
379  {
380  list.append( ' ' + L->pendingFields().at( idx ).name() );
381  }
382  commitErrors << list;
383 #endif
384  success = false;
385  }
386  }
387 
388  //
389  // add attributes
390  //
391  if ( !mAddedAttributes.isEmpty() )
392  {
394  {
395  commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );
396 
398 
400  attributesChanged = true;
401  }
402  else
403  {
404  commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
405 #if 0
406  QString list = "ERROR: Pending adds:";
407  Q_FOREACH ( QgsField f, mAddedAttributes )
408  {
409  list.append( ' ' + f.name() );
410  }
411  commitErrors << list;
412 #endif
413  success = false;
414  }
415  }
416 
417  // rename attributes
418  if ( !mRenamedAttributes.isEmpty() )
419  {
421  {
422  commitErrors << tr( "SUCCESS: %n attribute(s) renamed.", "renamed attributes count", mRenamedAttributes.size() );
423 
425 
427  attributesChanged = true;
428  }
429  else
430  {
431  commitErrors << tr( "ERROR: %n attribute(s) not renamed", "not renamed attributes count", mRenamedAttributes.size() );
432  success = false;
433  }
434  }
435 
436  //
437  // check that addition/removal went as expected
438  //
439  bool attributeChangesOk = true;
440  if ( attributesChanged )
441  {
442  L->updateFields();
443  QgsFields newFields = L->fields();
444 
445  if ( oldFields.count() != newFields.count() )
446  {
447  commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
448  attributeChangesOk = false; // don't try attribute updates - they'll fail.
449  }
450 
451  for ( int i = 0; i < qMin( oldFields.count(), newFields.count() ); ++i )
452  {
453  const QgsField& oldField = oldFields.at( i );
454  const QgsField& newField = newFields.at( i );
455  if ( attributeChangesOk && oldField != newField )
456  {
457  commitErrors
458  << tr( "ERROR: field with index %1 is not the same!" ).arg( i )
459  << tr( "Provider: %1" ).arg( L->providerType() )
460  << tr( "Storage: %1" ).arg( L->storageType() )
461  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
462  .arg( tr( "expected field" ),
463  oldField.name(),
464  QVariant::typeToName( oldField.type() ),
465  oldField.typeName() )
466  .arg( oldField.length() )
467  .arg( oldField.precision() )
468  << QString( "%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
469  .arg( tr( "retrieved field" ),
470  newField.name(),
471  QVariant::typeToName( newField.type() ),
472  newField.typeName() )
473  .arg( newField.length() )
474  .arg( newField.precision() );
475  attributeChangesOk = false; // don't try attribute updates - they'll fail.
476  }
477  }
478  }
479 
480  if ( attributeChangesOk )
481  {
483  {
485 
487  {
488  commitErrors << tr( "SUCCESS: %1 attribute value(s) and %2 geometries changed." ).arg( mChangedAttributeValues.size(), mChangedGeometries.size() );
491 
494  }
495  else
496  {
497  success = false;
498  }
499  }
500  else
501  {
502  //
503  // change attributes
504  //
506  {
508  {
509  commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
510 
513  }
514  else
515  {
516  commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
517 #if 0
518  QString list = "ERROR: pending changes:";
519  Q_FOREACH ( QgsFeatureId id, mChangedAttributeValues.keys() )
520  {
521  list.append( "\n " + FID_TO_STRING( id ) + '[' );
522  Q_FOREACH ( int idx, mChangedAttributeValues[ id ].keys() )
523  {
524  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( idx ).name() ).arg( mChangedAttributeValues[id][idx].toString() ) );
525  }
526  list.append( " ]" );
527  }
528  commitErrors << list;
529 #endif
530  success = false;
531  }
532  }
533  }
534 
535  //
536  // delete features
537  //
538  if ( success && !mDeletedFeatureIds.isEmpty() )
539  {
541  {
542  commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
543  // TODO[MD]: we should not need this here
544  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
545  {
548  }
549 
551 
553  }
554  else
555  {
556  commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
557 #if 0
558  QString list = "ERROR: pending deletes:";
559  Q_FOREACH ( QgsFeatureId id, mDeletedFeatureIds )
560  {
561  list.append( ' ' + FID_TO_STRING( id ) );
562  }
563  commitErrors << list;
564 #endif
565  success = false;
566  }
567  }
568 
569  //
570  // add features
571  //
572  if ( success && !mAddedFeatures.isEmpty() )
573  {
575  {
577  QgsFeatureList featuresToAdd;
578  // get the list of added features in reversed order
579  // 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)
580  mapToReversedLists( mAddedFeatures, ids, featuresToAdd );
581 
582  if ( provider->addFeatures( featuresToAdd ) )
583  {
584  commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );
585 
586  emit committedFeaturesAdded( L->id(), featuresToAdd );
587 
588  // notify everyone that the features with temporary ids were updated with permanent ids
589  for ( int i = 0; i < featuresToAdd.count(); ++i )
590  {
591  if ( featuresToAdd[i].id() != ids[i] )
592  {
593  //update selection
594  if ( L->mSelectedFeatureIds.contains( ids[i] ) )
595  {
596  L->mSelectedFeatureIds.remove( ids[i] );
597  L->mSelectedFeatureIds.insert( featuresToAdd[i].id() );
598  }
599  emit featureDeleted( ids[i] );
600  emit featureAdded( featuresToAdd[i].id() );
601  }
602  }
603 
605  }
606  else
607  {
608  commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
609 #if 0
610  QString list = "ERROR: pending adds:";
611  Q_FOREACH ( QgsFeature f, mAddedFeatures )
612  {
613  list.append( ' ' + FID_TO_STRING( f.id() ) + '[' );
614  for ( int i = 0; i < L->pendingFields().size(); i++ )
615  {
616  list.append( QString( " %1:%2" ).arg( L->pendingFields().at( i ).name() ).arg( f.attributes()[i].toString() ) );
617  }
618  list.append( " ]" );
619  }
620  commitErrors << list;
621 #endif
622  success = false;
623  }
624  }
625  else
626  {
627  commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
628  success = false;
629  }
630  }
631  }
632  else
633  {
634  success = false;
635  }
636 
637  if ( !success && provider->hasErrors() )
638  {
639  commitErrors << tr( "\n Provider errors:" );
640  Q_FOREACH ( QString e, provider->errors() )
641  {
642  commitErrors << " " + e.replace( '\n', "\n " );
643  }
644  provider->clearErrors();
645  }
646 
647  return success;
648 }
649 
650 
652 {
653  if ( !isModified() )
654  return;
655 
656  // limit canvas redraws to one by jumping to beginning of stack
657  // see QgsUndoWidget::indexChanged
658  L->undoStack()->setIndex( 0 );
659 
660  Q_ASSERT( mAddedAttributes.isEmpty() );
661  Q_ASSERT( mDeletedAttributeIds.isEmpty() );
662  Q_ASSERT( mChangedAttributeValues.isEmpty() );
663  Q_ASSERT( mChangedGeometries.isEmpty() );
664  Q_ASSERT( mAddedFeatures.isEmpty() );
665 }
666 
667 #if 0
668 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
669 {
670  QString msg;
671  if ( !mChangedGeometries.isEmpty() )
672  {
673  msg += "CHANGED GEOMETRIES:\n";
674  for ( QgsGeometryMap::const_iterator it = mChangedGeometries.begin(); it != mChangedGeometries.end(); ++it )
675  {
676  // QgsFeatureId, QgsGeometry
677  msg += QString( "- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
678  }
679  }
680  return msg;
681 }
682 #endif
683 
685 {
686  // go through the changed attributes map and adapt indices
687  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
688  for ( ; it != mChangedAttributeValues.end(); ++it )
689  {
690  updateAttributeMapIndex( it.value(), index, + 1 );
691  }
692 
693  // go through added features and adapt attributes
694  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
695  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
696  {
697  QgsAttributes attrs = featureIt->attributes();
698  attrs.insert( index, QVariant() );
699  featureIt->setAttributes( attrs );
700  }
701 
702  // go through renamed attributes and adapt
703  QList< int > sortedRenamedIndices = mRenamedAttributes.keys();
704  //sort keys
705  qSort( sortedRenamedIndices.begin(), sortedRenamedIndices.end(), qGreater< int >() );
706  Q_FOREACH ( int renameIndex, sortedRenamedIndices )
707  {
708  if ( renameIndex >= index )
709  {
710  mRenamedAttributes[ renameIndex + 1 ] = mRenamedAttributes.value( renameIndex );
711  }
712  }
713  //remove last
714  mRenamedAttributes.remove( index );
715 }
716 
718 {
719  // go through the changed attributes map and adapt indices
720  QgsChangedAttributesMap::iterator it = mChangedAttributeValues.begin();
721  for ( ; it != mChangedAttributeValues.end(); ++it )
722  {
723  QgsAttributeMap& attrMap = it.value();
724  // remove the attribute
725  if ( attrMap.contains( index ) )
726  attrMap.remove( index );
727 
728  // update attribute indices
729  updateAttributeMapIndex( attrMap, index, -1 );
730  }
731 
732  // go through added features and adapt attributes
733  QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
734  for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
735  {
736  QgsAttributes attrs = featureIt->attributes();
737  attrs.remove( index );
738  featureIt->setAttributes( attrs );
739  }
740 
741  // go through rename attributes and adapt
742  QList< int > sortedRenamedIndices = mRenamedAttributes.keys();
743  //sort keys
744  qSort( sortedRenamedIndices.begin(), sortedRenamedIndices.end() );
745  int last = -1;
746  mRenamedAttributes.remove( index );
747  Q_FOREACH ( int renameIndex, sortedRenamedIndices )
748  {
749  if ( renameIndex > index )
750  {
751  mRenamedAttributes.insert( renameIndex - 1, mRenamedAttributes.value( renameIndex ) );
752  last = renameIndex;
753  }
754  }
755  //remove last
756  if ( last > -1 )
757  mRenamedAttributes.remove( last );
758 }
759 
760 
761 
763 {
764  QgsAttributeMap updatedMap;
765  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
766  {
767  int attrIndex = it.key();
768  updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
769  }
770  map = updatedMap;
771 }
772 
773 
774 
776 {
777  L->updateFields();
778 }
779 
781 {
782  bool success = true;
783  QgsAttributeMap::const_iterator it;
784  for ( it = newValues.constBegin() ; it != newValues.constEnd(); ++it )
785  {
786  const int field = it.key();
787  const QVariant newValue = it.value();
788  QVariant oldValue;
789 
790  if ( oldValues.contains( field ) )
791  oldValue = oldValues[field];
792 
793  success &= changeAttributeValue( fid, field, newValue, oldValue );
794  }
795 
796  return success;
797 }
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:260
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual bool renameAttribute(int attr, const QString &newName)
Renames an attribute field (but does not commit it)
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
virtual bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
int size() const
Return number of items.
Definition: qgsfield.cpp:407
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:448
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
QString name
Definition: qgsfield.h:52
int precision
Definition: qgsfield.h:50
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes.
virtual bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
virtual bool addFeature(QgsFeature &f)
Adds a feature.
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:261
void committedAttributesAdded(const QString &layerId, const QList< QgsField > &addedAttributes)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
bool adaptGeometry(QgsGeometry *geometry)
Apply geometry modification basing on provider geometry type.
int size() const
void reserve(int alloc)
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features.
const_iterator constBegin() const
const T & at(int i) const
virtual bool renameAttributes(const QgsFieldNameMap &renamedAttributes)
Renames existing attributes.
void insert(int i, const T &value)
#define FID_TO_STRING(fid)
Definition: qgsfeature.h:89
friend class QgsVectorLayerUndoCommandChangeGeometry
T value() const
Container of fields for a vector layer.
Definition: qgsfield.h:252
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:259
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.
int count() const
Return number of items.
Definition: qgsfield.cpp:402
QString tr(const char *sourceText, const char *disambiguation, int n)
friend class QgsVectorLayerUndoCommandDeleteAttribute
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:422
int size() const
virtual void updateExtents()
Update the extents for the layer.
bool supportedType(const QgsField &field) const
check if provider supports type of field
T value(int i) const
QgsFields fields() const
Returns the list of fields of this layer.
int length
Definition: qgsfield.h:49
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:456
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QList< Key > keys() const
virtual bool doesStrictFeatureTypeCheck() const
Returns true if the provider is strict about the type of inserted features (e.g.
void featureAdded(QgsFeatureId fid)
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
int count(const T &value) const
void append(const T &value)
void setIndex(int idx)
QString id() const
Get this layer&#39;s unique ID, this ID is used to access this layer from map layer registry.
void resize(int size)
const Key & key() const
Allows addition of new attributes (fields)
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:102
bool hasErrors()
Provider has errors to report.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
bool isEmpty() const
virtual bool changeFeatures(const QgsChangedAttributesMap &attr_map, const QgsGeometryMap &geometry_map)
Changes attribute values and geometries of existing features.
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
void handleAttributeAdded(int index)
Update added and changed features after addition of an attribute.
bool isEmpty() const
Returns true if the geometry is empty (ie, contains no underlying geometry accessible via geometry)...
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:346
const T & value() const
virtual bool deleteFeatures(const QgsFeatureIds &fid)
Deletes a set of features from the layer (but does not commit it)
void clearErrors()
Clear recorded errors.
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
iterator end()
virtual QGis::WkbType geometryType() const =0
Get feature type.
virtual bool changeAttributeValues(QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues)
Changes values of attributes (but does not commit it).
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
void updateAttributeMapIndex(QgsAttributeMap &attrs, int index, int offset) const
Updates an index in an attribute map to a new value (for updates of changed attributes) ...
void remove(int fieldIdx)
Remove a field with the given index.
Definition: qgsfield.cpp:370
iterator begin()
virtual bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
virtual bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
friend class QgsVectorLayerUndoCommandDeleteFeature
iterator end()
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
bool contains(const T &value) const
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
Supports joint updates for attributes and geometry Providers supporting this should still define Chan...
bool contains(const T &value) const
const char * typeToName(Type typ)
const Key key(const T &value) const
QString & replace(int position, int n, QChar after)
bool isClean() const
QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
QList< QgsField > mAddedAttributes
Added attributes fields which are not commited.
bool remove(const T &value)
QgsGeometry * convertToProviderType(const QgsGeometry *geom) const
Converts the geometry to the provider type if possible / necessary this is the list of possible modif...
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
void committedAttributesRenamed(const QString &layerId, const QgsFieldNameMap &renamedAttributes)
Emitted after committing an attribute rename.
int count(const T &value) const
virtual bool deleteAttributes(const QgsAttributeIds &attributes)
Deletes existing attributes.
bool isEmpty() const
virtual bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
qint64 QgsFeatureId
Definition: qgsfeature.h:31
QgsFields pendingFields() const
Returns the list of fields of this layer.
virtual bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
Changed an attribute value (but does not commit it)
#define FID_IS_NEW(fid)
Definition: qgsfeature.h:87
iterator insert(const Key &key, const T &value)
bool isEmpty() const
QUndoStack * undoStack()
Return pointer to layer&#39;s undo stack.
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
QgsVectorDataProvider * dataProvider()
Returns the data provider.
QString providerType() const
Return the provider type for this layer.
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
void clear()
This is the base class for vector data providers.
QgsFeatureMap mAddedFeatures
New features which are not commited.
A vector of attributes.
Definition: qgsfeature.h:115
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void updateFields(QgsFields &fields)
void layerModified()
This signal is emitted when modifications has been done on layer.
Represents a vector layer which manages a vector based data sets.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:97
field is calculated from an expression
Definition: qgsfield.h:262
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not commited.
iterator begin()
Allows modification of attribute values.
virtual bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature&#39;s geometry.
int size() const
void featureDeleted(QgsFeatureId fid)
void push(QUndoCommand *cmd)
Supports renaming attributes (fields).
friend class QgsVectorLayerUndoCommandChangeAttribute
const T value(const Key &key) const
int remove(const Key &key)