mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
parent
77163ba0ec
commit
c1fac42518
@ -1502,6 +1502,50 @@ Returns true if the feature's attribute was successfully changed.
|
||||
.. seealso:: :py:func:`changeGeometry`
|
||||
|
||||
.. seealso:: :py:func:`updateFeature`
|
||||
%End
|
||||
|
||||
bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skeipDefaultValues = false );
|
||||
%Docstring
|
||||
Changes attributes' values for a feature (but does not immediately
|
||||
commit the changes).
|
||||
The ``fid`` argument specifies the ID of the feature to be changed.
|
||||
|
||||
The new values to be assigned to the fields are given by ``newValues``.
|
||||
|
||||
If a valid QVariant is specified for a field in ``oldValues``, it will be
|
||||
used as the field value in the case of an undo operation corresponding
|
||||
to this attribute value change. If an invalid QVariant is used (the
|
||||
default behavior), then the feature's current value will be
|
||||
automatically retrieved and used. Note that this involves a feature
|
||||
request to the underlying data provider, so it is more efficient to
|
||||
explicitly pass an oldValue if it is already available.
|
||||
|
||||
If ``skipDefaultValue`` is set to true, default field values will not
|
||||
be updated. This can be used to override default field value
|
||||
expressions.
|
||||
|
||||
Returns true if feature's attributes was successfully changed.
|
||||
|
||||
.. note::
|
||||
|
||||
Calls to changeAttributeValues() are only valid for layers in
|
||||
which edits have been enabled by a call to startEditing(). Changes made
|
||||
to features using this method are not committed to the underlying data
|
||||
provider until a commitChanges() call is made. Any uncommitted changes
|
||||
can be discarded by calling rollBack().
|
||||
|
||||
.. seealso:: :py:func:`startEditing`
|
||||
|
||||
.. seealso:: :py:func:`commitChanges`
|
||||
|
||||
.. seealso:: :py:func:`changeGeometry`
|
||||
|
||||
.. seealso:: :py:func:`updateFeature`
|
||||
|
||||
.. seealso:: :py:func:`changeAttributeValue`
|
||||
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
bool addAttribute( const QgsField &field );
|
||||
|
@ -58,6 +58,15 @@ Change feature's geometry
|
||||
virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
||||
%Docstring
|
||||
Changed an attribute value (but does not commit it)
|
||||
%End
|
||||
|
||||
virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues );
|
||||
%Docstring
|
||||
Changes values of attributes (but does not commit it).
|
||||
|
||||
:return: true if attributes are well updated, false otherwise
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
virtual bool addAttribute( const QgsField &field );
|
||||
|
@ -30,6 +30,17 @@ class QgsVectorLayerEditPassthrough : QgsVectorLayerEditBuffer
|
||||
|
||||
virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
||||
|
||||
|
||||
virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues );
|
||||
|
||||
%Docstring
|
||||
Changes values of attributes (but does not commit it).
|
||||
|
||||
:return: true if attributes are well updated, false otherwise
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
virtual bool addAttribute( const QgsField &field );
|
||||
|
||||
virtual bool deleteAttribute( int attr );
|
||||
|
@ -185,6 +185,23 @@ created if its fields are not empty.
|
||||
:return: false if an error happened, true otherwise
|
||||
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
|
||||
%Docstring
|
||||
Changes attributes' values in joined layers. The feature id given in
|
||||
parameter is the one added in target layer. If the corresponding joined
|
||||
feature does not exist in a joined layer, then it's automatically
|
||||
created if its fields are not empty.
|
||||
|
||||
:param fid: The feature id
|
||||
:param newValues: The new values for attributes
|
||||
:param oldValues: The old values for attributes
|
||||
|
||||
:return: false if an error happened, true otherwise
|
||||
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
|
@ -202,6 +202,37 @@ Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttribute
|
||||
};
|
||||
|
||||
|
||||
class QgsVectorLayerUndoPassthroughCommandChangeAttributes: QgsVectorLayerUndoPassthroughCommand
|
||||
{
|
||||
%Docstring
|
||||
Undo command for changing attributes' values from a vector layer in transaction group.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsvectorlayerundopassthroughcommand.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsVectorLayerUndoPassthroughCommandChangeAttributes( QgsVectorLayerEditBuffer *buffer /Transfer/, QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
|
||||
%Docstring
|
||||
Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttributes
|
||||
|
||||
:param buffer: associated edit buffer
|
||||
:param fid: feature ID of feature
|
||||
:param newValues: New values for attributes
|
||||
:param oldValues: Old values for attributes
|
||||
%End
|
||||
|
||||
virtual void undo();
|
||||
|
||||
virtual void redo();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QgsVectorLayerUndoPassthroughCommandAddAttribute : QgsVectorLayerUndoPassthroughCommand
|
||||
{
|
||||
%Docstring
|
||||
|
@ -2387,6 +2387,64 @@ bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QV
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues, bool skipDefaultValues )
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
QgsAttributeMap newValuesJoin;
|
||||
QgsAttributeMap oldValuesJoin;
|
||||
|
||||
QgsAttributeMap newValuesNotJoin;
|
||||
QgsAttributeMap oldValuesNotJoin;
|
||||
|
||||
for ( auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
|
||||
{
|
||||
const int field = it.key();
|
||||
const QVariant newValue = it.value();
|
||||
QVariant oldValue;
|
||||
|
||||
if ( oldValues.contains( field ) )
|
||||
oldValue = oldValues[field];
|
||||
|
||||
switch ( fields().fieldOrigin( field ) )
|
||||
{
|
||||
case QgsFields::OriginJoin:
|
||||
newValuesJoin[field] = newValue;
|
||||
oldValuesJoin[field] = oldValue;
|
||||
break;
|
||||
|
||||
case QgsFields::OriginProvider:
|
||||
case QgsFields::OriginEdit:
|
||||
case QgsFields::OriginExpression:
|
||||
{
|
||||
newValuesNotJoin[field] = newValue;
|
||||
oldValuesNotJoin[field] = oldValue;
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsFields::OriginUnknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! newValuesJoin.isEmpty() && mJoinBuffer )
|
||||
{
|
||||
result = mJoinBuffer->changeAttributeValues( fid, newValuesJoin, oldValuesJoin );
|
||||
}
|
||||
|
||||
if ( ! newValuesNotJoin.isEmpty() && mEditBuffer && mDataProvider )
|
||||
{
|
||||
result &= mEditBuffer->changeAttributeValues( fid, newValues, oldValues );
|
||||
}
|
||||
|
||||
if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
|
||||
{
|
||||
updateDefaultValues( fid );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::addAttribute( const QgsField &field )
|
||||
{
|
||||
if ( !mEditBuffer || !mDataProvider )
|
||||
|
@ -1395,6 +1395,43 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
*/
|
||||
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false );
|
||||
|
||||
/**
|
||||
* Changes attributes' values for a feature (but does not immediately
|
||||
* commit the changes).
|
||||
* The \a fid argument specifies the ID of the feature to be changed.
|
||||
*
|
||||
* The new values to be assigned to the fields are given by \a newValues.
|
||||
*
|
||||
* If a valid QVariant is specified for a field in \a oldValues, it will be
|
||||
* used as the field value in the case of an undo operation corresponding
|
||||
* to this attribute value change. If an invalid QVariant is used (the
|
||||
* default behavior), then the feature's current value will be
|
||||
* automatically retrieved and used. Note that this involves a feature
|
||||
* request to the underlying data provider, so it is more efficient to
|
||||
* explicitly pass an oldValue if it is already available.
|
||||
*
|
||||
* If \a skipDefaultValue is set to true, default field values will not
|
||||
* be updated. This can be used to override default field value
|
||||
* expressions.
|
||||
*
|
||||
* Returns true if feature's attributes was successfully changed.
|
||||
*
|
||||
* \note Calls to changeAttributeValues() are only valid for layers in
|
||||
* which edits have been enabled by a call to startEditing(). Changes made
|
||||
* to features using this method are not committed to the underlying data
|
||||
* provider until a commitChanges() call is made. Any uncommitted changes
|
||||
* can be discarded by calling rollBack().
|
||||
*
|
||||
* \see startEditing()
|
||||
* \see commitChanges()
|
||||
* \see changeGeometry()
|
||||
* \see updateFeature()
|
||||
* \see changeAttributeValue()
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skeipDefaultValues = false );
|
||||
|
||||
/**
|
||||
* Add an attribute field (but does not commit it)
|
||||
* returns true if the field was added
|
||||
@ -2376,6 +2413,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
//! stores information about uncommitted changes to layer
|
||||
QgsVectorLayerEditBuffer *mEditBuffer = nullptr;
|
||||
friend class QgsVectorLayerEditBuffer;
|
||||
friend class QgsVectorLayerEditPassthrough;
|
||||
|
||||
//stores information about joined layers
|
||||
QgsVectorLayerJoinBuffer *mJoinBuffer = nullptr;
|
||||
|
@ -208,6 +208,23 @@ bool QgsVectorLayerEditBuffer::changeGeometry( QgsFeatureId fid, const QgsGeomet
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerEditBuffer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues )
|
||||
{
|
||||
bool success = true;
|
||||
for ( auto it = newValues.constBegin() ; it != newValues.constEnd(); ++it )
|
||||
{
|
||||
const int field = it.key();
|
||||
const QVariant newValue = it.value();
|
||||
QVariant oldValue;
|
||||
|
||||
if ( oldValues.contains( field ) )
|
||||
oldValue = oldValues[field];
|
||||
|
||||
success &= changeAttributeValue( fid, field, newValue, oldValue );
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
|
||||
{
|
||||
|
@ -65,6 +65,13 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
|
||||
//! Changed an attribute value (but does not commit it)
|
||||
virtual bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
||||
|
||||
/**
|
||||
* Changes values of attributes (but does not commit it).
|
||||
* \returns true if attributes are well updated, false otherwise
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues );
|
||||
|
||||
/**
|
||||
* Add an attribute field (but does not commit it)
|
||||
returns true if the field was added */
|
||||
@ -265,6 +272,7 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
|
||||
friend class QgsVectorLayerUndoPassthroughCommandDeleteFeatures;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandChangeGeometry;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandChangeAttribute;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandChangeAttributes;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandAddAttribute;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandDeleteAttribute;
|
||||
friend class QgsVectorLayerUndoPassthroughCommandRenameAttribute;
|
||||
|
@ -86,6 +86,11 @@ bool QgsVectorLayerEditPassthrough::changeAttributeValue( QgsFeatureId fid, int
|
||||
return modify( new QgsVectorLayerUndoPassthroughCommandChangeAttribute( this, fid, field, newValue ) );
|
||||
}
|
||||
|
||||
bool QgsVectorLayerEditPassthrough::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues )
|
||||
{
|
||||
return modify( new QgsVectorLayerUndoPassthroughCommandChangeAttributes( this, fid, newValues, oldValues ) );
|
||||
}
|
||||
|
||||
bool QgsVectorLayerEditPassthrough::addAttribute( const QgsField &field )
|
||||
{
|
||||
return modify( new QgsVectorLayerUndoPassthroughCommandAddAttribute( this, field ) );
|
||||
|
@ -38,6 +38,14 @@ class CORE_EXPORT QgsVectorLayerEditPassthrough : public QgsVectorLayerEditBuffe
|
||||
bool deleteFeatures( const QgsFeatureIds &fids ) override;
|
||||
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geom ) override;
|
||||
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() ) override;
|
||||
|
||||
/**
|
||||
* Changes values of attributes (but does not commit it).
|
||||
* \returns true if attributes are well updated, false otherwise
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues ) override;
|
||||
|
||||
bool addAttribute( const QgsField &field ) override;
|
||||
bool deleteAttribute( int attr ) override;
|
||||
bool renameAttribute( int attr, const QString &newName ) override;
|
||||
|
@ -637,6 +637,25 @@ bool QgsVectorLayerJoinBuffer::changeAttributeValue( QgsFeatureId fid, int field
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerJoinBuffer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
for ( auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
|
||||
{
|
||||
const int field = it.key();
|
||||
const QVariant newValue = it.value();
|
||||
QVariant oldValue;
|
||||
|
||||
if ( oldValues.contains( field ) )
|
||||
oldValue = oldValues[field];
|
||||
|
||||
success &= changeAttributeValue( fid, field, newValue, oldValue );
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerJoinBuffer::deleteFeature( QgsFeatureId fid ) const
|
||||
{
|
||||
return deleteFeatures( QgsFeatureIds() << fid );
|
||||
|
@ -171,6 +171,22 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer : public QObject, public QgsFeatureSi
|
||||
*/
|
||||
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
|
||||
|
||||
/**
|
||||
* Changes attributes' values in joined layers. The feature id given in
|
||||
* parameter is the one added in target layer. If the corresponding joined
|
||||
* feature does not exist in a joined layer, then it's automatically
|
||||
* created if its fields are not empty.
|
||||
*
|
||||
* \param fid The feature id
|
||||
* \param newValues The new values for attributes
|
||||
* \param oldValues The old values for attributes
|
||||
*
|
||||
* \returns false if an error happened, true otherwise
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
|
||||
|
||||
/**
|
||||
* Deletes a feature from joined layers. The feature id given in
|
||||
* parameter is the one coming from the target layer.
|
||||
|
@ -403,3 +403,35 @@ void QgsVectorLayerUndoPassthroughCommandUpdate::redo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsVectorLayerUndoPassthroughCommandChangeAttributes::QgsVectorLayerUndoPassthroughCommandChangeAttributes( QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues )
|
||||
: QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
|
||||
, mFid( fid )
|
||||
, mNewValues( newValues )
|
||||
, mOldValues( oldValues )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsVectorLayerUndoPassthroughCommandChangeAttributes::undo()
|
||||
{
|
||||
if ( rollBackToSavePoint() )
|
||||
{
|
||||
for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
|
||||
{
|
||||
emit mBuffer->attributeValueChanged( mFid, it.key(), it.value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerUndoPassthroughCommandChangeAttributes::redo()
|
||||
{
|
||||
QgsChangedAttributesMap attribMap;
|
||||
attribMap.insert( mFid, mNewValues );
|
||||
if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) )
|
||||
{
|
||||
for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
|
||||
{
|
||||
emit mBuffer->attributeValueChanged( mFid, it.key(), it.value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,6 +203,35 @@ class CORE_EXPORT QgsVectorLayerUndoPassthroughCommandChangeAttribute: public Qg
|
||||
const QVariant mOldValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsVectorLayerUndoPassthroughCommandChangeAttributes
|
||||
* \brief Undo command for changing attributes' values from a vector layer in transaction group.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
|
||||
class CORE_EXPORT QgsVectorLayerUndoPassthroughCommandChangeAttributes: public QgsVectorLayerUndoPassthroughCommand
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttributes
|
||||
* \param buffer associated edit buffer
|
||||
* \param fid feature ID of feature
|
||||
* \param newValues New values for attributes
|
||||
* \param oldValues Old values for attributes
|
||||
*/
|
||||
QgsVectorLayerUndoPassthroughCommandChangeAttributes( QgsVectorLayerEditBuffer *buffer SIP_TRANSFER, QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap() );
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
QgsFeatureId mFid;
|
||||
const QgsAttributeMap mNewValues;
|
||||
const QgsAttributeMap mOldValues;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsVectorLayerUndoPassthroughCommandAddAttribute
|
||||
|
@ -330,6 +330,9 @@ bool QgsAttributeForm::saveEdits()
|
||||
{
|
||||
mLayer->beginEditCommand( mEditCommandMessage );
|
||||
|
||||
QgsAttributeMap newValues;
|
||||
QgsAttributeMap oldValues;
|
||||
|
||||
int n = 0;
|
||||
for ( int i = 0; i < dst.count(); ++i )
|
||||
{
|
||||
@ -346,10 +349,14 @@ bool QgsAttributeForm::saveEdits()
|
||||
QgsDebugMsg( QString( "src:'%1' (type:%2, isNull:%3, isValid:%4)" )
|
||||
.arg( src.at( i ).toString(), src.at( i ).typeName() ).arg( src.at( i ).isNull() ).arg( src.at( i ).isValid() ) );
|
||||
|
||||
success &= mLayer->changeAttributeValue( mFeature.id(), i, dst.at( i ), src.at( i ) );
|
||||
newValues[i] = dst.at( i );
|
||||
oldValues[i] = src.at( i );
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
success = mLayer->changeAttributeValues( mFeature.id(), newValues, oldValues );
|
||||
|
||||
if ( success && n > 0 )
|
||||
{
|
||||
mLayer->endEditCommand();
|
||||
|
Loading…
x
Reference in New Issue
Block a user