mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
Apply default values on update
This commit is contained in:
parent
7b36287ff3
commit
f2d512a73a
@ -72,11 +72,17 @@ class QgsDefaultValue
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns if this default value is should be applied.
|
Returns if this default value should be applied.
|
||||||
:return: false if the expression is a null string.
|
:return: false if the expression is a null string.
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
%Docstring
|
||||||
|
Checks if a default value is set. Alias for isValid().
|
||||||
|
:return: false if the expression is a null string.
|
||||||
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -925,7 +925,7 @@ Return the provider type for this layer
|
|||||||
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
|
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
|
||||||
|
|
||||||
|
|
||||||
bool updateFeature( QgsFeature &f );
|
bool updateFeature( const QgsFeature &f );
|
||||||
%Docstring
|
%Docstring
|
||||||
Updates an existing feature. This method needs to query the datasource
|
Updates an existing feature. This method needs to query the datasource
|
||||||
on every call. Consider using changeAttributeValue() or
|
on every call. Consider using changeAttributeValue() or
|
||||||
@ -1172,13 +1172,13 @@ Returns list of attributes making up the primary key
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
%End
|
%End
|
||||||
|
|
||||||
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom );
|
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom, bool skipDefaultValue = false );
|
||||||
%Docstring
|
%Docstring
|
||||||
Change feature's geometry
|
Change feature's geometry
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
%End
|
%End
|
||||||
|
|
||||||
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false );
|
||||||
%Docstring
|
%Docstring
|
||||||
Changes an attribute value (but does not commit it)
|
Changes an attribute value (but does not commit it)
|
||||||
|
|
||||||
|
@ -50,5 +50,10 @@ void QgsDefaultValue::setApplyOnUpdate( bool applyOnUpdate )
|
|||||||
|
|
||||||
bool QgsDefaultValue::isValid() const
|
bool QgsDefaultValue::isValid() const
|
||||||
{
|
{
|
||||||
return mExpression.isEmpty();
|
return !mExpression.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDefaultValue::operator bool() const
|
||||||
|
{
|
||||||
|
return !mExpression.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,17 @@ class CORE_EXPORT QgsDefaultValue
|
|||||||
void setApplyOnUpdate( bool applyOnUpdate );
|
void setApplyOnUpdate( bool applyOnUpdate );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if this default value is should be applied.
|
* Returns if this default value should be applied.
|
||||||
* \returns false if the expression is a null string.
|
* \returns false if the expression is a null string.
|
||||||
*/
|
*/
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a default value is set. Alias for isValid().
|
||||||
|
* \returns false if the expression is a null string.
|
||||||
|
*/
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString mExpression;
|
QString mExpression;
|
||||||
bool mApplyOnUpdate = false;
|
bool mApplyOnUpdate = false;
|
||||||
|
@ -766,6 +766,25 @@ void QgsVectorLayer::setExtent( const QgsRectangle &r )
|
|||||||
mValidExtent = true;
|
mValidExtent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsVectorLayer::updateDefaultValues( QgsFeatureId fid, QgsFeature feature )
|
||||||
|
{
|
||||||
|
if ( !mDefaultValueOnUpdateFields.isEmpty() )
|
||||||
|
{
|
||||||
|
if ( !feature.isValid() )
|
||||||
|
feature = getFeature( fid );
|
||||||
|
|
||||||
|
const QgsFields fields = mFields;
|
||||||
|
int size = fields.size();
|
||||||
|
for ( int idx : qgsAsConst( mDefaultValueOnUpdateFields ) )
|
||||||
|
{
|
||||||
|
if ( idx < 0 || idx >= size )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
defaultValue( idx, feature );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QgsRectangle QgsVectorLayer::extent() const
|
QgsRectangle QgsVectorLayer::extent() const
|
||||||
{
|
{
|
||||||
QgsRectangle rect;
|
QgsRectangle rect;
|
||||||
@ -941,47 +960,52 @@ bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags )
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QgsVectorLayer::updateFeature( QgsFeature &f )
|
bool QgsVectorLayer::updateFeature( const QgsFeature &updatedFeature )
|
||||||
{
|
{
|
||||||
QgsFeatureRequest req;
|
bool hasChanged = false;
|
||||||
req.setFilterFid( f.id() );
|
bool hasError = false;
|
||||||
if ( !f.hasGeometry() )
|
|
||||||
req.setFlags( QgsFeatureRequest::NoGeometry );
|
|
||||||
if ( f.attributes().isEmpty() )
|
|
||||||
req.setSubsetOfAttributes( QgsAttributeList() );
|
|
||||||
|
|
||||||
QgsFeature current;
|
QgsFeature currentFeature = getFeature( updatedFeature.id() );
|
||||||
if ( !getFeatures( req ).nextFeature( current ) )
|
if ( currentFeature.isValid() )
|
||||||
{
|
{
|
||||||
QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
|
QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( updatedFeature.id() ) );
|
||||||
return false;
|
|
||||||
|
if ( updatedFeature.hasGeometry() && currentFeature.hasGeometry() && !updatedFeature.geometry().isGeosEqual( currentFeature.geometry() ) )
|
||||||
|
{
|
||||||
|
if ( changeGeometry( updatedFeature.id(), updatedFeature.geometry(), true ) )
|
||||||
|
{
|
||||||
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if ( f.hasGeometry() && current.hasGeometry() && !f.geometry().isGeosEqual( current.geometry() ) )
|
|
||||||
{
|
{
|
||||||
if ( !changeGeometry( f.id(), f.geometry() ) )
|
QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( updatedFeature.id() ) );
|
||||||
{
|
|
||||||
QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsAttributes fa = f.attributes();
|
QgsAttributes fa = updatedFeature.attributes();
|
||||||
QgsAttributes ca = current.attributes();
|
QgsAttributes ca = currentFeature.attributes();
|
||||||
|
|
||||||
for ( int attr = 0; attr < fa.count(); ++attr )
|
for ( int attr = 0; attr < fa.count(); ++attr )
|
||||||
{
|
{
|
||||||
if ( fa.at( attr ) != ca.at( attr ) )
|
if ( fa.at( attr ) != ca.at( attr ) )
|
||||||
{
|
{
|
||||||
if ( !changeAttributeValue( f.id(), attr, fa.at( attr ), ca.at( attr ) ) )
|
if ( changeAttributeValue( updatedFeature.id(), attr, fa.at( attr ), ca.at( attr ), true ) )
|
||||||
{
|
{
|
||||||
QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
|
hasChanged = true;
|
||||||
return false;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( updatedFeature.id() ) );
|
||||||
|
hasError = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if ( hasChanged && !mDefaultValueOnUpdateFields.isEmpty() )
|
||||||
|
updateDefaultValues( updatedFeature.id(), updatedFeature );
|
||||||
|
|
||||||
|
return !hasError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2260,7 +2284,7 @@ bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &error
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, const QgsGeometry &geom )
|
bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, const QgsGeometry &geom, bool skipDefaultValue )
|
||||||
{
|
{
|
||||||
if ( !mEditBuffer || !mDataProvider )
|
if ( !mEditBuffer || !mDataProvider )
|
||||||
{
|
{
|
||||||
@ -2272,33 +2296,40 @@ bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, const QgsGeometry &geom )
|
|||||||
bool result = mEditBuffer->changeGeometry( fid, geom );
|
bool result = mEditBuffer->changeGeometry( fid, geom );
|
||||||
|
|
||||||
if ( result )
|
if ( result )
|
||||||
|
{
|
||||||
updateExtents();
|
updateExtents();
|
||||||
|
if ( !skipDefaultValue && !mDefaultValueOnUpdateFields.isEmpty() )
|
||||||
|
updateDefaultValues( fid );
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
|
bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue, bool skipDefaultValues )
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
switch ( fields().fieldOrigin( field ) )
|
switch ( fields().fieldOrigin( field ) )
|
||||||
{
|
{
|
||||||
case QgsFields::OriginJoin:
|
case QgsFields::OriginJoin:
|
||||||
return mJoinBuffer->changeAttributeValue( fid, field, newValue, oldValue );
|
result = mJoinBuffer->changeAttributeValue( fid, field, newValue, oldValue );
|
||||||
|
|
||||||
case QgsFields::OriginProvider:
|
case QgsFields::OriginProvider:
|
||||||
case QgsFields::OriginEdit:
|
case QgsFields::OriginEdit:
|
||||||
case QgsFields::OriginExpression:
|
case QgsFields::OriginExpression:
|
||||||
{
|
{
|
||||||
if ( !mEditBuffer || !mDataProvider )
|
if ( mEditBuffer && mDataProvider )
|
||||||
return false;
|
result = mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
|
||||||
else
|
|
||||||
return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case QgsFields::OriginUnknown:
|
case QgsFields::OriginUnknown:
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
|
||||||
|
updateDefaultValues( fid );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QgsVectorLayer::addAttribute( const QgsField &field )
|
bool QgsVectorLayer::addAttribute( const QgsField &field )
|
||||||
@ -2920,6 +2951,9 @@ void QgsVectorLayer::updateFields()
|
|||||||
|
|
||||||
mFields[ index ].setAlias( aliasIt.value() );
|
mFields[ index ].setAlias( aliasIt.value() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update default values
|
||||||
|
mDefaultValueOnUpdateFields.clear();
|
||||||
QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
|
QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
|
||||||
for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
|
for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
|
||||||
{
|
{
|
||||||
@ -2928,6 +2962,8 @@ void QgsVectorLayer::updateFields()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
mFields[ index ].setDefaultValue( defaultIt.value() );
|
mFields[ index ].setDefaultValue( defaultIt.value() );
|
||||||
|
if ( defaultIt.value().applyOnUpdate() )
|
||||||
|
mDefaultValueOnUpdateFields.insert( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
|
QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
|
||||||
|
@ -913,7 +913,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
|||||||
\param f Feature to update
|
\param f Feature to update
|
||||||
\returns True in case of success and False in case of error
|
\returns True in case of success and False in case of error
|
||||||
*/
|
*/
|
||||||
bool updateFeature( QgsFeature &f );
|
bool updateFeature( const QgsFeature &f );
|
||||||
|
|
||||||
/** Insert a new vertex before the given vertex number,
|
/** Insert a new vertex before the given vertex number,
|
||||||
* in the given ring, item (first number is index 0), and feature
|
* in the given ring, item (first number is index 0), and feature
|
||||||
@ -1142,7 +1142,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
|||||||
bool setReadOnly( bool readonly = true );
|
bool setReadOnly( bool readonly = true );
|
||||||
|
|
||||||
//! Change feature's geometry
|
//! Change feature's geometry
|
||||||
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom );
|
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom, bool skipDefaultValue = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes an attribute value (but does not commit it)
|
* Changes an attribute value (but does not commit it)
|
||||||
@ -1154,7 +1154,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
|||||||
*
|
*
|
||||||
* \returns true in case of success
|
* \returns true in case of success
|
||||||
*/
|
*/
|
||||||
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false );
|
||||||
|
|
||||||
/** Add an attribute field (but does not commit it)
|
/** Add an attribute field (but does not commit it)
|
||||||
* returns true if the field was added
|
* returns true if the field was added
|
||||||
@ -1958,6 +1958,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
|||||||
|
|
||||||
private: // Private methods
|
private: // Private methods
|
||||||
|
|
||||||
|
void updateDefaultValues( QgsFeatureId fid, QgsFeature feature = QgsFeature() );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the provider is in read-only mode
|
* Returns true if the provider is in read-only mode
|
||||||
*/
|
*/
|
||||||
@ -2014,6 +2016,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
|||||||
//! Map which stores default value expressions for fields
|
//! Map which stores default value expressions for fields
|
||||||
QMap<QString, QgsDefaultValue> mDefaultExpressionMap;
|
QMap<QString, QgsDefaultValue> mDefaultExpressionMap;
|
||||||
|
|
||||||
|
//! An internal structure to keep track of fields that have a defaultValueOnUpdate
|
||||||
|
QSet<int> mDefaultValueOnUpdateFields;
|
||||||
|
|
||||||
//! Map which stores constraints for fields
|
//! Map which stores constraints for fields
|
||||||
QMap< QString, QgsFieldConstraints::Constraints > mFieldConstraints;
|
QMap< QString, QgsFieldConstraints::Constraints > mFieldConstraints;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user