Skip to content

Commit

Permalink
Fix renaming a virtual field leads to crash (fix #15669)
Browse files Browse the repository at this point in the history
(cherry-picked from 3a76708)
  • Loading branch information
nyalldawson committed Oct 12, 2016
1 parent d0b3430 commit ba99c7c
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
10 changes: 10 additions & 0 deletions python/core/qgsexpressionfieldbuffer.sip
Expand Up @@ -27,6 +27,16 @@ class QgsExpressionFieldBuffer
*/
void removeExpression( int index );

/**
* Renames an expression field at a given index
*
* @param index The index of the expression to change
* @param name New name for field
*
* @note added in 3.0
*/
void renameExpression( int index, const QString& name );

/**
* Changes the expression at a given index
*
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsexpressionfieldbuffer.cpp
Expand Up @@ -33,6 +33,11 @@ void QgsExpressionFieldBuffer::removeExpression( int index )
mExpressions.removeAt( index );
}

void QgsExpressionFieldBuffer::renameExpression( int index, const QString& name )
{
mExpressions[index].field.setName( name );
}

void QgsExpressionFieldBuffer::updateExpression( int index, const QString& exp )
{
mExpressions[index].expression = exp;
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsexpressionfieldbuffer.h
Expand Up @@ -67,6 +67,16 @@ class CORE_EXPORT QgsExpressionFieldBuffer
*/
void removeExpression( int index );

/**
* Renames an expression field at a given index
*
* @param index The index of the expression to change
* @param name New name for field
*
* @note added in 3.0
*/
void renameExpression( int index, const QString& name );

/**
* Changes the expression at a given index
*
Expand Down
35 changes: 32 additions & 3 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2378,12 +2378,41 @@ void QgsVectorLayer::remAttributeAlias( int attIndex )
}
}

bool QgsVectorLayer::renameAttribute( int attIndex, const QString& newName )
bool QgsVectorLayer::renameAttribute( int index, const QString& newName )
{
if ( !mEditBuffer || !mDataProvider )
if ( index < 0 || index >= fields().count() )
return false;

return mEditBuffer->renameAttribute( attIndex, newName );
switch ( mUpdatedFields.fieldOrigin( index ) )
{
case QgsFields::OriginExpression:
{
if ( mExpressionFieldBuffer )
{
int oi = mUpdatedFields.fieldOriginIndex( index );
mExpressionFieldBuffer->renameExpression( oi, newName );
updateFields();
return true;
}
else
{
return false;
}
}

case QgsFields::OriginProvider:
case QgsFields::OriginEdit:

if ( !mEditBuffer || !mDataProvider )
return false;

return mEditBuffer->renameAttribute( index, newName );

case QgsFields::OriginJoin:
case QgsFields::OriginUnknown:
return false;

}
}

void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString )
Expand Down
10 changes: 10 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Expand Up @@ -1028,6 +1028,16 @@ def checkFieldNames(names):
#layer.undoStack().redo()
#checkFieldNames(['fldint'])

def test_RenameExpressionField(self):
layer = createLayerWithOnePoint()
exp_field_idx = layer.addExpressionField('1+1', QgsField('math_is_hard', QVariant.Int))

#rename and check
self.assertTrue(layer.renameAttribute(exp_field_idx, 'renamed'))
self.assertEqual(layer.fields()[exp_field_idx].name(), 'renamed')
f = next(layer.getFeatures())
self.assertEqual(f.fields()[exp_field_idx].name(), 'renamed')

def test_fields(self):
layer = createLayerWithOnePoint()

Expand Down

0 comments on commit ba99c7c

Please sign in to comment.