Skip to content

Commit

Permalink
Make QgsVectorLayerEditBuffer methods const correct
Browse files Browse the repository at this point in the history
Also add some optimisations to avoid iterations over all
contents of the buffers
  • Loading branch information
nyalldawson committed Jul 14, 2016
1 parent 6c6f3c1 commit fe4fa41
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 48 deletions.
9 changes: 9 additions & 0 deletions doc/api_break.dox
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ pointers makes for more robust, safer code. Use an invalid (default constructed)
in code which previously passed a null pointer to QgsVectorFileWriter.</li>
</ul>

\subsection qgis_api_break_3_0_QgsVectorLayerEditBuffer QgsVectorLayerEditBuffer

<ul>
<li>The addedFeatures(), changedAttributeValues(), deletedAttributeIds(), addedAttributes(), changedGeometries()
and deletedFeatureIds() functions now return values, not references. This has no effect on PyQGIS code, but c++
plugins calling these methods will need to be updated.</li>
</ul>



\section qgis_api_break_2_4 QGIS 2.4

Expand Down
44 changes: 31 additions & 13 deletions python/core/qgsvectorlayereditbuffer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,42 @@ class QgsVectorLayerEditBuffer : QObject
/** Stop editing and discard the edits */
virtual void rollBack();

/** Returns a map of new features which are not committed. */
QgsFeatureMap addedFeatures() const;

/** Returns true if the specified feature ID has been added but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureIsAdded( QgsFeatureId id ) const;

/** Returns a map of features with changed attributes values which are not committed */
QgsChangedAttributesMap changedAttributeValues() const;

/** New features which are not commited. */
const QgsFeatureMap& addedFeatures();
/** Returns true if the specified feature ID has had an attribute changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureHasAttributeChanges( QgsFeatureId id ) const;

/** Changed attributes values which are not commited */
const QgsChangedAttributesMap& changedAttributeValues();
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted. */
QgsAttributeList deletedAttributeIds() const;

/** Deleted attributes fields which are not commited. The list is kept sorted. */
const QgsAttributeList& deletedAttributeIds();
/** Returns a list of added attributes fields which are not committed */
QList<QgsField> addedAttributes() const;

/** Added attributes fields which are not commited */
const QList<QgsField>& addedAttributes();
/** Returns a map of features with changed geometries which are not committed. */
QgsGeometryMap changedGeometries() const;

/** Returns true if the specified feature ID has had its geometry changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureHasGeometryChange( QgsFeatureId id ) const;

/** Changed geometries which are not commited. */
const QgsGeometryMap& changedGeometries();
/** Returns a list of deleted feature IDs which are not committed. */
QgsFeatureIds deletedFeatureIds() const;

const QgsFeatureIds deletedFeatureIds();
//QString dumpEditBuffer();

protected slots:
Expand Down Expand Up @@ -131,10 +149,10 @@ class QgsVectorLayerEditBuffer : QObject

void updateFields( QgsFields& fields );

/** Update feature with uncommited geometry updates */
/** Update feature with uncommitted geometry updates */
void updateFeatureGeometry( QgsFeature &f );

/** Update feature with uncommited attribute updates */
/** Update feature with uncommitted attribute updates */
void updateChangedAttributes( QgsFeature &f );

/** Update added and changed features after addition of an attribute */
Expand Down
60 changes: 40 additions & 20 deletions src/core/qgsvectorlayereditbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,42 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
/** Stop editing and discard the edits */
virtual void rollBack();

/** Returns a map of new features which are not committed. */
QgsFeatureMap addedFeatures() const { return mAddedFeatures; }

/** Returns true if the specified feature ID has been added but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureIsAdded( QgsFeatureId id ) const { return mAddedFeatures.contains( id ); }

/** Returns a map of features with changed attributes values which are not committed */
QgsChangedAttributesMap changedAttributeValues() const { return mChangedAttributeValues; }

/** Returns true if the specified feature ID has had an attribute changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureHasAttributeChanges( QgsFeatureId id ) const { return mChangedAttributeValues.contains( id ); }

/** New features which are not commited. */
inline const QgsFeatureMap& addedFeatures() { return mAddedFeatures; }
/** Returns a list of deleted attributes fields which are not committed. The list is kept sorted. */
QgsAttributeList deletedAttributeIds() const { return mDeletedAttributeIds; }

/** Changed attributes values which are not commited */
inline const QgsChangedAttributesMap& changedAttributeValues() { return mChangedAttributeValues; }
/** Returns a list of added attributes fields which are not committed */
QList<QgsField> addedAttributes() const { return mAddedAttributes; }

/** Deleted attributes fields which are not commited. The list is kept sorted. */
inline const QgsAttributeList& deletedAttributeIds() { return mDeletedAttributeIds; }
/** Returns a map of features with changed geometries which are not committed. */
QgsGeometryMap changedGeometries() const { return mChangedGeometries; }

/** Added attributes fields which are not commited */
inline const QList<QgsField>& addedAttributes() { return mAddedAttributes; }
/** Returns true if the specified feature ID has had its geometry changed but not committed.
* @param id feature ID
* @note added in QGIS 3.0
*/
bool featureHasGeometryChange( QgsFeatureId id ) const { return mChangedGeometries.contains( id ); }

/** Changed geometries which are not commited. */
inline const QgsGeometryMap& changedGeometries() { return mChangedGeometries; }
/** Returns a list of deleted feature IDs which are not committed. */
QgsFeatureIds deletedFeatureIds() const { return mDeletedFeatureIds; }

inline const QgsFeatureIds deletedFeatureIds() { return mDeletedFeatureIds; }
//QString dumpEditBuffer();

protected slots:
Expand Down Expand Up @@ -161,10 +179,10 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject

void updateFields( QgsFields& fields );

/** Update feature with uncommited geometry updates */
/** Update feature with uncommitted geometry updates */
void updateFeatureGeometry( QgsFeature &f );

/** Update feature with uncommited attribute updates */
/** Update feature with uncommitted attribute updates */
void updateChangedAttributes( QgsFeature &f );

/** Update added and changed features after addition of an attribute */
Expand All @@ -191,29 +209,31 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
friend class QgsVectorLayerUndoCommandDeleteAttribute;
friend class QgsVectorLayerUndoCommandRenameAttribute;

/** Deleted feature IDs which are not commited. Note a feature can be added and then deleted
/** Deleted feature IDs which are not committed. Note a feature can be added and then deleted
again before the change is committed - in that case the added feature would be removed
from mAddedFeatures only and *not* entered here.
*/
QgsFeatureIds mDeletedFeatureIds;

/** New features which are not commited. */
/** New features which are not committed. */
QgsFeatureMap mAddedFeatures;

/** Changed attributes values which are not commited */
/** Changed attributes values which are not committed */
QgsChangedAttributesMap mChangedAttributeValues;

/** Deleted attributes fields which are not commited. The list is kept sorted. */
/** Deleted attributes fields which are not committed. The list is kept sorted. */
QgsAttributeList mDeletedAttributeIds;

/** Added attributes fields which are not commited */
/** Added attributes fields which are not committed */
QList<QgsField> mAddedAttributes;

/** Renamed attributes which are not commited. */
/** Renamed attributes which are not committed. */
QgsFieldNameMap mRenamedAttributes;

/** Changed geometries which are not commited. */
/** Changed geometries which are not committed. */
QgsGeometryMap mChangedGeometries;

friend class QgsGrassProvider; //GRASS provider totally abuses the edit buffer
};

#endif // QGSVECTORLAYEREDITBUFFER_H
17 changes: 12 additions & 5 deletions src/gui/attributetable/qgsattributetablefiltermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,18 @@ bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModel
QgsVectorLayerEditBuffer* editBuffer = layer()->editBuffer();
if ( editBuffer )
{
const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
const QList<QgsFeatureId> changedGeometries = editBuffer->changedGeometries().keys();
const QgsFeatureId fid = masterModel()->rowToId( sourceRow );
return addedFeatures.contains( fid ) || changedFeatures.contains( fid ) || changedGeometries.contains( fid );
QgsFeatureId fid = masterModel()->rowToId( sourceRow );

if ( editBuffer->featureIsAdded( fid ) )
return true;

if ( editBuffer->featureHasAttributeChanges( fid ) )
return true;

if ( editBuffer->featureHasGeometryChange( fid ) )
return true;

return false;
}
return false;
}
Expand Down
7 changes: 2 additions & 5 deletions src/gui/attributetable/qgsfeaturelistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,11 @@ QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const

if ( editBuffer )
{
const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();

if ( addedFeatures.contains( feat.id() ) )
if ( editBuffer->featureIsAdded( feat.id() ) )
{
featInfo.isNew = true;
}
if ( changedFeatures.contains( feat.id() ) )
if ( editBuffer->featureHasAttributeChanges( feat.id() ) )
{
featInfo.isEdited = true;
}
Expand Down
10 changes: 5 additions & 5 deletions src/providers/grass/qgsgrassprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
}
// geometry
const QgsAbstractGeometryV2 *geometry = 0;
if ( !mEditBuffer->addedFeatures().contains( fid ) )
if ( !mEditBuffer->featureIsAdded( fid ) )
{
#ifdef QGISDEBUG
QgsDebugMsg( "the feature is missing in buffer addedFeatures :" );
Expand Down Expand Up @@ -1248,7 +1248,7 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )

setPoints( mPoints, geometry );

QgsFeatureMap& addedFeatures = const_cast<QgsFeatureMap&>( mEditBuffer->addedFeatures() );
QgsFeatureMap& addedFeatures = mEditBuffer->mAddedFeatures;

// change polygon to linestring
QgsWKBTypes::Type wkbType = QgsWKBTypes::flatType( geometry->wkbType() );
Expand All @@ -1271,7 +1271,7 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
// resetting fid probably is not possible because it is stored in undo commands and used in buffer maps

// It may be that user manualy entered cat value
QgsFeatureMap& addedFeatures = const_cast<QgsFeatureMap&>( mEditBuffer->addedFeatures() );
QgsFeatureMap& addedFeatures = mEditBuffer->mAddedFeatures;
QgsFeature& feature = addedFeatures[fid];
int catIndex = feature.fields()->indexFromName( mLayer->keyColumnName() );
if ( catIndex != -1 )
Expand Down Expand Up @@ -1721,7 +1721,7 @@ void QgsGrassProvider::onAttributeValueChanged( QgsFeatureId fid, int idx, const
{
QgsDebugMsg( "changing attributes in different layer is not allowed" );
// reset the value
QgsChangedAttributesMap &changedAttributes = const_cast<QgsChangedAttributesMap &>( mEditBuffer->changedAttributeValues() );
QgsChangedAttributesMap &changedAttributes = mEditBuffer->mChangedAttributeValues;
if ( idx == mLayer->keyColumn() )
{
// should not happen because cat field is not editable
Expand Down Expand Up @@ -1923,7 +1923,7 @@ void QgsGrassProvider::setAddedFeaturesSymbol()
{
return;
}
QgsFeatureMap& features = const_cast<QgsFeatureMap&>( mEditBuffer->addedFeatures() );
QgsFeatureMap& features = mEditBuffer->mAddedFeatures;
Q_FOREACH ( QgsFeatureId fid, features.keys() )
{
QgsFeature feature = features[fid];
Expand Down

0 comments on commit fe4fa41

Please sign in to comment.