Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsvectorlayereditbuffer.h 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 : : ***************************************************************************/ 15 : : #ifndef QGSVECTORLAYEREDITBUFFER_H 16 : : #define QGSVECTORLAYEREDITBUFFER_H 17 : : 18 : : #include "qgis_core.h" 19 : : #include <QList> 20 : : #include <QSet> 21 : : 22 : : #include "qgsfeature.h" 23 : : #include "qgsfields.h" 24 : : #include "qgsgeometry.h" 25 : : 26 : : class QgsVectorLayer; 27 : : 28 : : typedef QList<int> QgsAttributeList SIP_SKIP; 29 : : typedef QSet<int> QgsAttributeIds SIP_SKIP; 30 : : typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap; 31 : : 32 : : /** 33 : : * \ingroup core 34 : : * \class QgsVectorLayerEditBuffer 35 : : */ 36 : 2 : class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject 37 : : { 38 : 0 : Q_OBJECT 39 : : public: 40 : : QgsVectorLayerEditBuffer( QgsVectorLayer *layer ); 41 : : 42 : : //! Returns TRUE if the provider has been modified since the last commit 43 : : virtual bool isModified() const; 44 : : 45 : : 46 : : /** 47 : : * Adds a feature 48 : : * \param f feature to add 49 : : * \returns TRUE in case of success and FALSE in case of error 50 : : */ 51 : : virtual bool addFeature( QgsFeature &f ); 52 : : 53 : : //! Insert a copy of the given features into the layer (but does not commit it) 54 : : virtual bool addFeatures( QgsFeatureList &features ); 55 : : 56 : : //! Delete a feature from the layer (but does not commit it) 57 : : virtual bool deleteFeature( QgsFeatureId fid ); 58 : : 59 : : //! Deletes a set of features from the layer (but does not commit it) 60 : : virtual bool deleteFeatures( const QgsFeatureIds &fid ); 61 : : 62 : : //! Change feature's geometry 63 : : virtual bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom ); 64 : : 65 : : //! Changed an attribute value (but does not commit it) 66 : : virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() ); 67 : : 68 : : /** 69 : : * Changes values of attributes (but does not commit it). 70 : : * \returns TRUE if attributes are well updated, FALSE otherwise 71 : : * \since QGIS 3.0 72 : : */ 73 : : virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues ); 74 : : 75 : : /** 76 : : * Add an attribute field (but does not commit it) 77 : : returns true if the field was added 78 : : */ 79 : : virtual bool addAttribute( const QgsField &field ); 80 : : 81 : : //! Delete an attribute field (but does not commit it) 82 : : virtual bool deleteAttribute( int attr ); 83 : : 84 : : /** 85 : : * Renames an attribute field (but does not commit it) 86 : : * \param attr attribute index 87 : : * \param newName new name of field 88 : : * \since QGIS 2.16 89 : : */ 90 : : virtual bool renameAttribute( int attr, const QString &newName ); 91 : : 92 : : /** 93 : : Attempts to commit any changes to disk. Returns the result of the attempt. 94 : : If a commit fails, the in-memory changes are left alone. 95 : : 96 : : This allows editing to continue if the commit failed on e.g. a 97 : : disallowed value in a Postgres database - the user can re-edit and try 98 : : again. 99 : : 100 : : The commits occur in distinct stages, 101 : : (add attributes, add features, change attribute values, change 102 : : geometries, delete features, delete attributes) 103 : : so if a stage fails, it's difficult to roll back cleanly. 104 : : Therefore any error message also includes which stage failed so 105 : : that the user has some chance of repairing the damage cleanly. 106 : : */ 107 : : virtual bool commitChanges( QStringList &commitErrors ); 108 : : 109 : : //! Stop editing and discard the edits 110 : : virtual void rollBack(); 111 : : 112 : : /** 113 : : * Returns a map of new features which are not committed. 114 : : * \see isFeatureAdded() 115 : : */ 116 : 4 : QgsFeatureMap addedFeatures() const { return mAddedFeatures; } 117 : : 118 : : /** 119 : : * Returns TRUE if the specified feature ID has been added but not committed. 120 : : * \param id feature ID 121 : : * \see addedFeatures() 122 : : * \since QGIS 3.0 123 : : */ 124 : : bool isFeatureAdded( QgsFeatureId id ) const { return mAddedFeatures.contains( id ); } 125 : : 126 : : /** 127 : : * Returns a map of features with changed attributes values which are not committed. 128 : : * \see isFeatureAttributesChanged() 129 : : */ 130 : 4 : QgsChangedAttributesMap changedAttributeValues() const { return mChangedAttributeValues; } 131 : : 132 : : /** 133 : : * Returns TRUE if the specified feature ID has had an attribute changed but not committed. 134 : : * \param id feature ID 135 : : * \see changedAttributeValues() 136 : : * \since QGIS 3.0 137 : : */ 138 : : bool isFeatureAttributesChanged( QgsFeatureId id ) const { return mChangedAttributeValues.contains( id ); } 139 : : 140 : : /** 141 : : * Returns a list of deleted attributes fields which are not committed. The list is kept sorted. 142 : : * \see isAttributeDeleted() 143 : : */ 144 : 4 : QgsAttributeList deletedAttributeIds() const { return mDeletedAttributeIds; } 145 : : 146 : : /** 147 : : * Returns TRUE if the specified attribute has been deleted but not committed. 148 : : * \param index attribute index 149 : : * \see deletedAttributeIds() 150 : : * \since QGIS 3.0 151 : : */ 152 : : bool isAttributeDeleted( int index ) const { return mDeletedAttributeIds.contains( index ); } 153 : : 154 : : /** 155 : : * Returns a list of added attributes fields which are not committed. 156 : : */ 157 : 4 : QList<QgsField> addedAttributes() const { return mAddedAttributes; } 158 : : 159 : : /** 160 : : * Returns a map of features with changed geometries which are not committed. 161 : : * \see isFeatureGeometryChanged() 162 : : */ 163 : 4 : QgsGeometryMap changedGeometries() const { return mChangedGeometries; } 164 : : 165 : : /** 166 : : * Returns TRUE if the specified feature ID has had its geometry changed but not committed. 167 : : * \param id feature ID 168 : : * \see changedGeometries() 169 : : * \since QGIS 3.0 170 : : */ 171 : : bool isFeatureGeometryChanged( QgsFeatureId id ) const { return mChangedGeometries.contains( id ); } 172 : : 173 : : /** 174 : : * Returns a list of deleted feature IDs which are not committed. 175 : : * \see isFeatureDeleted() 176 : : */ 177 : 4 : QgsFeatureIds deletedFeatureIds() const { return mDeletedFeatureIds; } 178 : : 179 : : /** 180 : : * Returns TRUE if the specified feature ID has been deleted but not committed. 181 : : * \param id feature ID 182 : : * \see deletedFeatureIds() 183 : : * \since QGIS 3.0 184 : : */ 185 : : bool isFeatureDeleted( QgsFeatureId id ) const { return mDeletedFeatureIds.contains( id ); } 186 : : 187 : : /** 188 : : * Updates \a fields 189 : : * \note Not available in Python bindings 190 : : * \since QGIS 3.18 191 : : */ 192 : : void updateFields( QgsFields &fields ) SIP_SKIP; 193 : : 194 : : //QString dumpEditBuffer(); 195 : : 196 : : protected slots: 197 : : void undoIndexChanged( int index ); 198 : : 199 : : signals: 200 : : //! Emitted when modifications has been done on layer 201 : : void layerModified(); 202 : : 203 : : void featureAdded( QgsFeatureId fid ); 204 : : void featureDeleted( QgsFeatureId fid ); 205 : : 206 : : /** 207 : : * Emitted when a feature's geometry is changed. 208 : : * \param fid feature ID 209 : : * \param geom new feature geometry 210 : : */ 211 : : void geometryChanged( QgsFeatureId fid, const QgsGeometry &geom ); 212 : : 213 : : void attributeValueChanged( QgsFeatureId fid, int idx, const QVariant & ); 214 : : void attributeAdded( int idx ); 215 : : void attributeDeleted( int idx ); 216 : : 217 : : /** 218 : : * Emitted when an attribute has been renamed 219 : : * \param idx attribute index 220 : : * \param newName new attribute name 221 : : * \since QGIS 2.16 222 : : */ 223 : : void attributeRenamed( int idx, const QString &newName ); 224 : : 225 : : //! Signals emitted after committing changes 226 : : void committedAttributesDeleted( const QString &layerId, const QgsAttributeList &deletedAttributes ); 227 : : void committedAttributesAdded( const QString &layerId, const QList<QgsField> &addedAttributes ); 228 : : 229 : : /** 230 : : * Emitted after committing an attribute rename 231 : : * \param layerId ID of layer 232 : : * \param renamedAttributes map of field index to new name 233 : : * \since QGIS 2.16 234 : : */ 235 : : void committedAttributesRenamed( const QString &layerId, const QgsFieldNameMap &renamedAttributes ); 236 : : void committedFeaturesAdded( const QString &layerId, const QgsFeatureList &addedFeatures ); 237 : : void committedFeaturesRemoved( const QString &layerId, const QgsFeatureIds &deletedFeatureIds ); 238 : : void committedAttributeValuesChanges( const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues ); 239 : : void committedGeometriesChanges( const QString &layerId, const QgsGeometryMap &changedGeometries ); 240 : : 241 : : protected: 242 : : 243 : : //! Constructor for QgsVectorLayerEditBuffer 244 : 0 : QgsVectorLayerEditBuffer() = default; 245 : : 246 : : //! Update feature with uncommitted geometry updates 247 : : void updateFeatureGeometry( QgsFeature &f ); 248 : : 249 : : //! Update feature with uncommitted attribute updates 250 : : void updateChangedAttributes( QgsFeature &f ); 251 : : 252 : : //! Update added and changed features after addition of an attribute 253 : : void handleAttributeAdded( int index ); 254 : : 255 : : //! Update added and changed features after removal of an attribute 256 : : void handleAttributeDeleted( int index ); 257 : : 258 : : //! Updates an index in an attribute map to a new value (for updates of changed attributes) 259 : : void updateAttributeMapIndex( QgsAttributeMap &attrs, int index, int offset ) const; 260 : : 261 : : void updateLayerFields(); 262 : : 263 : : protected: 264 : 0 : QgsVectorLayer *L = nullptr; 265 : : 266 : : friend class QgsVectorLayerUndoCommand; 267 : : friend class QgsVectorLayerUndoCommandAddFeature; 268 : : friend class QgsVectorLayerUndoCommandDeleteFeature; 269 : : friend class QgsVectorLayerUndoCommandChangeGeometry; 270 : : friend class QgsVectorLayerUndoCommandChangeAttribute; 271 : : friend class QgsVectorLayerUndoCommandAddAttribute; 272 : : friend class QgsVectorLayerUndoCommandDeleteAttribute; 273 : : friend class QgsVectorLayerUndoCommandRenameAttribute; 274 : : 275 : : friend class QgsVectorLayerUndoPassthroughCommand; 276 : : friend class QgsVectorLayerUndoPassthroughCommandAddFeatures; 277 : : friend class QgsVectorLayerUndoPassthroughCommandDeleteFeatures; 278 : : friend class QgsVectorLayerUndoPassthroughCommandChangeGeometry; 279 : : friend class QgsVectorLayerUndoPassthroughCommandChangeAttribute; 280 : : friend class QgsVectorLayerUndoPassthroughCommandChangeAttributes; 281 : : friend class QgsVectorLayerUndoPassthroughCommandAddAttribute; 282 : : friend class QgsVectorLayerUndoPassthroughCommandDeleteAttribute; 283 : : friend class QgsVectorLayerUndoPassthroughCommandRenameAttribute; 284 : : friend class QgsVectorLayerUndoPassthroughCommandUpdate; 285 : : 286 : : /** 287 : : * Deleted feature IDs which are not committed. Note a feature can be added and then deleted 288 : : again before the change is committed - in that case the added feature would be removed 289 : : from mAddedFeatures only and *not* entered here. 290 : : */ 291 : : QgsFeatureIds mDeletedFeatureIds; 292 : : 293 : : //! New features which are not committed. 294 : : QgsFeatureMap mAddedFeatures; 295 : : 296 : : //! Changed attributes values which are not committed 297 : : QgsChangedAttributesMap mChangedAttributeValues; 298 : : 299 : : //! Deleted attributes fields which are not committed. The list is kept sorted. 300 : : QgsAttributeList mDeletedAttributeIds; 301 : : 302 : : //! Added attributes fields which are not committed 303 : : QList<QgsField> mAddedAttributes; 304 : : 305 : : //! Renamed attributes which are not committed. 306 : : QgsFieldNameMap mRenamedAttributes; 307 : : 308 : : //! Changed geometries which are not committed. 309 : : QgsGeometryMap mChangedGeometries; 310 : : 311 : : friend class QgsGrassProvider; //GRASS provider totally abuses the edit buffer 312 : : }; 313 : : 314 : : #endif // QGSVECTORLAYEREDITBUFFER_H