25 template <
class Key,
class T>
void mapToReversedLists(
const QMap< Key, T > &map, QList<Key> &ks, QList<T> &vs )
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() )
33 vs.append( i.value() );
52 QgsDebugMsgLevel( QStringLiteral(
"undo index changed %1" ).arg( index ), 4 );
70 fields.
rename( renameIt.key(), renameIt.value() );
105 for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
106 attrs[it.key()] = it.value();
137 for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
152 QgsDebugMsg( QStringLiteral(
"Cannot delete features (missing DeleteFeature capability)" ) );
160 QgsDebugMsg( QStringLiteral(
"Cannot delete features (in the list of added features)" ) );
168 QgsDebugMsg( QStringLiteral(
"Cannot delete features (in the list of deleted features)" ) );
181 QgsDebugMsg( QStringLiteral(
"Cannot delete features (missing DeleteFeatures capability)" ) );
186 const auto constFids = fids;
218 for (
auto it = newValues.constBegin() ; it != newValues.constEnd(); ++it )
220 const int field = it.key();
221 const QVariant newValue = it.value();
224 if ( oldValues.contains( field ) )
225 oldValue = oldValues[field];
260 if ( field.
name().isEmpty() )
264 for (
const QgsField &updatedField : fields )
266 if ( updatedField.name() == field.
name() )
305 if ( newName.isEmpty() )
312 for (
const QgsField &updatedField : fields )
314 if ( updatedField.name() == newName )
326 commitErrors.clear();
348 if ( ( ! f.hasGeometry() ) ||
349 ( f.geometry().wkbType() == provider->
wkbType() ) )
354 commitErrors << tr(
"ERROR: %n feature(s) not added - geometry type is not compatible with the current layer.",
"not added features count",
mAddedFeatures.size() );
363 commitErrors << tr(
"ERROR: %n feature(s) not added - provider doesn't support adding features.",
"not added features count",
mAddedFeatures.size() );
375 commitErrors << tr(
"SUCCESS: %n geometries were changed.",
"changed geometries count",
mChangedGeometries.size() );
382 commitErrors << tr(
"ERROR: %n geometries not changed.",
"not changed geometries count",
mChangedGeometries.size() );
392 bool attributesChanged =
false;
397 commitErrors << tr(
"SUCCESS: %n attribute(s) deleted.",
"deleted attributes count",
mDeletedAttributeIds.size() );
402 attributesChanged =
true;
406 commitErrors << tr(
"ERROR: %n attribute(s) not deleted.",
"not deleted attributes count",
mDeletedAttributeIds.size() );
408 QString list =
"ERROR: Pending attribute deletes:";
410 for (
int idx : constMDeletedAttributeIds )
414 commitErrors << list;
425 commitErrors << tr(
"SUCCESS: %n attribute(s) renamed.",
"renamed attributes count",
mRenamedAttributes.size() );
430 attributesChanged =
true;
434 commitErrors << tr(
"ERROR: %n attribute(s) not renamed",
"not renamed attributes count",
mRenamedAttributes.size() );
446 commitErrors << tr(
"SUCCESS: %n attribute(s) added.",
"added attributes count",
mAddedAttributes.size() );
451 attributesChanged =
true;
455 commitErrors << tr(
"ERROR: %n new attribute(s) not added",
"not added attributes count",
mAddedAttributes.size() );
457 QString list =
"ERROR: Pending adds:";
459 for (
QgsField f : constMAddedAttributes )
461 list.append(
' ' + f.name() );
463 commitErrors << list;
472 bool attributeChangesOk =
true;
473 if ( attributesChanged )
480 commitErrors << tr(
"ERROR: the count of fields is incorrect after addition/removal of fields!" );
481 attributeChangesOk =
false;
484 for (
int i = 0; i < std::min( oldFields.
count(), newFields.
count() ); ++i )
488 if ( attributeChangesOk && oldField != newField )
491 << tr(
"ERROR: field with index %1 is not the same!" ).arg( i )
494 << QStringLiteral(
"%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
495 .arg( tr(
"expected field" ),
497 QVariant::typeToName( oldField.
type() ),
501 << QStringLiteral(
"%1: name=%2 type=%3 typeName=%4 len=%5 precision=%6" )
502 .arg( tr(
"retrieved field" ),
504 QVariant::typeToName( newField.
type() ),
508 attributeChangesOk =
false;
513 if ( attributeChangesOk )
542 commitErrors << tr(
"SUCCESS: %n attribute value(s) changed.",
"changed attribute values count",
mChangedAttributeValues.size() );
549 commitErrors << tr(
"ERROR: %n attribute value change(s) not applied.",
"not changed attribute values count",
mChangedAttributeValues.size() );
551 QString list =
"ERROR: pending changes:";
557 for (
int idx : constKeys )
563 commitErrors << list;
577 commitErrors << tr(
"SUCCESS: %n feature(s) deleted.",
"deleted features count",
mDeletedFeatureIds.size() );
592 commitErrors << tr(
"ERROR: %n feature(s) not deleted.",
"not deleted features count",
mDeletedFeatureIds.size() );
594 QString list =
"ERROR: pending deletes:";
600 commitErrors << list;
613 QList<QgsFeatureId> ids;
621 for (
int i = 0; i < featuresToAdd.count(); ++i )
628 commitErrors << tr(
"SUCCESS: %n feature(s) added.",
"added features count", featuresToAdd.size() );
633 for (
int i = 0; i < featuresToAdd.count(); ++i )
635 if ( featuresToAdd[i].
id() != ids[i] )
638 if (
L->mSelectedFeatureIds.contains( ids[i] ) )
640 L->mSelectedFeatureIds.remove( ids[i] );
641 L->mSelectedFeatureIds.insert( featuresToAdd[i].
id() );
652 commitErrors << tr(
"ERROR: %n feature(s) not added.",
"not added features count",
mAddedFeatures.size() );
654 QString list =
"ERROR: pending adds:";
661 list.append( QString(
" %1:%2" ).arg(
L->
fields().
at( i ).
name() ).arg( f.attributes()[i].toString() ) );
665 commitErrors << list;
672 commitErrors << tr(
"ERROR: %n feature(s) not added - provider doesn't support adding features.",
"not added features count",
mAddedFeatures.size() );
684 commitErrors << tr(
"\n Provider errors:" );
685 const auto constErrors = provider->
errors();
686 for ( QString e : constErrors )
688 commitErrors <<
" " + e.replace(
'\n', QLatin1String(
"\n " ) );
714 QString QgsVectorLayerEditBuffer::dumpEditBuffer()
719 msg +=
"CHANGED GEOMETRIES:\n";
723 msg += QString(
"- FID %1: %2" ).arg( it.key() ).arg( it.value().to );
744 attrs.insert( index, QVariant() );
745 featureIt->setAttributes( attrs );
751 std::sort( sortedRenamedIndices.begin(), sortedRenamedIndices.end(), std::greater< int >() );
752 const auto constSortedRenamedIndices = sortedRenamedIndices;
753 for (
int renameIndex : constSortedRenamedIndices )
755 if ( renameIndex >= index )
772 if ( attrMap.contains( index ) )
773 attrMap.remove( index );
784 attrs.remove( index );
785 featureIt->setAttributes( attrs );
791 std::sort( sortedRenamedIndices.begin(), sortedRenamedIndices.end() );
794 const auto constSortedRenamedIndices = sortedRenamedIndices;
795 for (
int renameIndex : constSortedRenamedIndices )
797 if ( renameIndex > index )
813 for ( QgsAttributeMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
815 int attrIndex = it.key();
816 updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider...
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommitted attribute updates.
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...
QSet< QgsFeatureId > QgsFeatureIds
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.
int size() const
Returns number of items.
FieldOrigin fieldOrigin(int fieldIdx) const
Gets field's origin (value from an enumeration)
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
QgsWkbTypes::Type wkbType() const override=0
Returns the geometry type which is returned by this layer.
void undoIndexChanged(int index)
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 to the provider.
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...
void committedAttributesAdded(const QString &layerId, const QList< QgsField > &addedAttributes)
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
QList< QgsFeature > QgsFeatureList
QString providerType() const
Returns the provider type (provider key) for this layer.
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features from the provider.
virtual bool renameAttributes(const QgsFieldNameMap &renamedAttributes)
Renames existing attributes.
friend class QgsVectorLayerUndoCommandChangeGeometry
Container of fields for a vector layer.
virtual void rollBack()
Stop editing and discard the edits.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
friend class QgsVectorLayerUndoCommandAddAttribute
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not committed.
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommitted geometry updates.
Allows deletion of attributes (fields)
Field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsFieldNameMap mRenamedAttributes
Renamed attributes which are not committed.
bool rename(int fieldIdx, const QString &name)
Renames a name of field.
friend class QgsVectorLayerUndoCommandRenameAttribute
int count() const
Returns number of items.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
friend class QgsVectorLayerUndoCommandDeleteAttribute
bool supportedType(const QgsField &field) const
check if provider supports type of field
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
int fieldOriginIndex(int fieldIdx) const
Gets field's origin index (its meaning is specific to each type of origin)
virtual bool doesStrictFeatureTypeCheck() const
Returns true if the provider is strict about the type of inserted features (e.g.
void featureAdded(QgsFeatureId fid)
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
virtual void updateExtents(bool force=false)
Update the extents for the layer.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
static void matchAttributesToFields(QgsFeature &feature, const QgsFields &fields)
Matches the attributes in feature to the specified fields.
Allows addition of new attributes (fields)
#define QgsDebugMsgLevel(str, level)
QString typeName() const
Gets the field type.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
friend class QgsVectorLayerUndoCommandAddFeature
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
virtual bool changeFeatures(const QgsChangedAttributesMap &attr_map, const QgsGeometryMap &geometry_map)
Changes attribute values and geometries of existing features.
QMap< int, QVariant > QgsAttributeMap
QgsGeometryMap mChangedGeometries
Changed geometries which are not committed.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QStringList errors() const
Gets recorded errors.
virtual bool changeGeometry(QgsFeatureId fid, const QgsGeometry &geom)
Change feature's geometry.
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)
Appends a field. The field must have unique name, otherwise it is rejected (returns false) ...
virtual bool deleteFeatures(const QgsFeatureIds &fid)
Deletes a set of features from the layer (but does not commit it)
void clearErrors()
Clear recorded errors.
QgsGeometry convertToProviderType(const QgsGeometry &geom) const
Converts the geometry to the provider type if possible / necessary.
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not committed.
Encapsulate a field in an attribute table or data source.
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.
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)
Removes a field with the given index.
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
QgsVectorLayerEditBuffer()=default
Constructor for QgsVectorLayerEditBuffer.
QList< QgsField > mAddedAttributes
Added attributes fields which are not committed.
#define FID_TO_STRING(fid)
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
void committedAttributesRenamed(const QString &layerId, const QgsFieldNameMap &renamedAttributes)
Emitted after committing an attribute rename.
bool hasErrors() const
Provider has errors to report.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
virtual bool deleteAttributes(const QgsAttributeIds &attributes)
Deletes existing attributes from the provider.
virtual bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
virtual bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
Changed an attribute value (but does not commit it)
Allows deletion of features.
QUndoStack * undoStack()
Returns pointer to layer's undo stack.
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
This is the base class for vector data providers.
QgsFeatureMap mAddedFeatures
New features which are not committed.
void updateFields(QgsFields &fields)
void layerModified()
Emitted when modifications has been done on layer.
Represents a vector layer which manages a vector based data sets.
Field is calculated from an expression.
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not committed. The list is kept sorted.
Allows modification of attribute values.
void featureDeleted(QgsFeatureId fid)
Supports joint updates for attributes and geometry Providers supporting this should still define Chan...
friend class QgsVectorLayerUndoCommandChangeAttribute