Skip to content

Commit ebcc694

Browse files
authoredJan 31, 2019
fix #18954 add&rename vector fields (#8982)
fix #18954 add&rename vector fields at the same time
1 parent 44c4e8c commit ebcc694

File tree

8 files changed

+124
-49
lines changed

8 files changed

+124
-49
lines changed
 

‎python/core/auto_generated/qgsfields.sip.in

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,29 @@ Copy constructor
5454

5555
void clear();
5656
%Docstring
57-
Remove all fields
57+
Removes all fields
5858
%End
5959

6060
bool append( const QgsField &field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
6161
%Docstring
62-
Append a field. The field must have unique name, otherwise it is rejected (returns false)
62+
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
63+
%End
64+
65+
bool rename( int fieldIdx, const QString &name );
66+
%Docstring
67+
Renames a name of field. The field must have unique name, otherwise change is rejected (returns false)
68+
69+
.. versionadded:: 3.6
6370
%End
6471

6572
bool appendExpressionField( const QgsField &field, int originIndex );
6673
%Docstring
67-
Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
74+
Appends an expression field. The field must have unique name, otherwise it is rejected (returns false)
6875
%End
6976

7077
void remove( int fieldIdx );
7178
%Docstring
72-
Remove a field with the given index
79+
Removes a field with the given index
7380
%End
7481
%MethodCode
7582
if ( a0 < 0 || a0 >= sipCpp->count() )
@@ -85,12 +92,12 @@ Remove a field with the given index
8592

8693
void extend( const QgsFields &other );
8794
%Docstring
88-
Extend with fields from another QgsFields container
95+
Extends with fields from another QgsFields container
8996
%End
9097

9198
bool isEmpty() const;
9299
%Docstring
93-
Check whether the container is empty
100+
Checks whether the container is empty
94101
%End
95102

96103
int count() const;
@@ -252,7 +259,7 @@ name of the field.
252259

253260
int lookupField( const QString &fieldName ) const;
254261
%Docstring
255-
Look up field's index from the field name.
262+
Looks up field's index from the field name.
256263
This method matches in the following order:
257264

258265
1. The exact field name taking case sensitivity into account

‎src/app/qgssourcefieldsproperties.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,6 @@ void QgsSourceFieldsProperties::attributeAdded( int idx )
145145
setRow( row, idx, fields.at( idx ) );
146146
mFieldsList->setCurrentCell( row, idx );
147147

148-
//in case there are rows following, there is increased the id to the correct ones
149-
for ( int i = idx + 1; i < mIndexedWidgets.count(); i++ )
150-
mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
151-
152-
if ( sorted )
153-
mFieldsList->setSortingEnabled( true );
154-
155148
for ( int i = 0; i < mFieldsList->columnCount(); i++ )
156149
{
157150
switch ( mLayer->fields().fieldOrigin( idx ) )
@@ -170,6 +163,9 @@ void QgsSourceFieldsProperties::attributeAdded( int idx )
170163
break;
171164
}
172165
}
166+
167+
if ( sorted )
168+
mFieldsList->setSortingEnabled( true );
173169
}
174170

175171

@@ -204,7 +200,11 @@ void QgsSourceFieldsProperties::setRow( int row, int idx, const QgsField &field
204200
}
205201
mFieldsList->setItem( row, AttrIdCol, dataItem );
206202

203+
// in case we insert and not append reindex remaining widgets by 1
204+
for ( int i = idx + 1; i < mIndexedWidgets.count(); i++ )
205+
mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
207206
mIndexedWidgets.insert( idx, mFieldsList->item( row, 0 ) );
207+
208208
mFieldsList->setItem( row, AttrNameCol, new QTableWidgetItem( field.name() ) );
209209
mFieldsList->setItem( row, AttrAliasCol, new QTableWidgetItem( field.alias() ) );
210210
mFieldsList->setItem( row, AttrTypeCol, new QTableWidgetItem( QVariant::typeToName( field.type() ) ) );

‎src/core/qgsfields.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ bool QgsFields::append( const QgsField &field, FieldOrigin origin, int originInd
6969
return true;
7070
}
7171

72+
bool QgsFields::rename( int fieldIdx, const QString &name )
73+
{
74+
if ( !exists( fieldIdx ) )
75+
return false;
76+
77+
if ( name.isEmpty() )
78+
return false;
79+
80+
if ( d->nameToIndex.contains( name ) )
81+
return false;
82+
83+
const QString oldName = d->fields[ fieldIdx ].field.name();
84+
d->fields[ fieldIdx ].field.setName( name );
85+
d->nameToIndex.remove( oldName );
86+
d->nameToIndex.insert( name, fieldIdx );
87+
return true;
88+
}
89+
7290
bool QgsFields::appendExpressionField( const QgsField &field, int originIndex )
7391
{
7492
if ( d->nameToIndex.contains( field.name() ) )

‎src/core/qgsfields.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class QgsFieldsPrivate;
3939
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
4040
* \note QgsFields objects are implicitly shared.
4141
*/
42-
class CORE_EXPORT QgsFields
42+
class CORE_EXPORT QgsFields
4343
{
4444
public:
4545

@@ -94,16 +94,22 @@ class CORE_EXPORT QgsFields
9494

9595
virtual ~QgsFields();
9696

97-
//! Remove all fields
97+
//! Removes all fields
9898
void clear();
9999

100-
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
100+
//! Appends a field. The field must have unique name, otherwise it is rejected (returns false)
101101
bool append( const QgsField &field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
102102

103-
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
103+
/**
104+
* Renames a name of field. The field must have unique name, otherwise change is rejected (returns false)
105+
* \since QGIS 3.6
106+
*/
107+
bool rename( int fieldIdx, const QString &name );
108+
109+
//! Appends an expression field. The field must have unique name, otherwise it is rejected (returns false)
104110
bool appendExpressionField( const QgsField &field, int originIndex );
105111

106-
//! Remove a field with the given index
112+
//! Removes a field with the given index
107113
void remove( int fieldIdx );
108114
#ifdef SIP_RUN
109115
% MethodCode
@@ -119,10 +125,10 @@ class CORE_EXPORT QgsFields
119125
% End
120126
#endif
121127

122-
//! Extend with fields from another QgsFields container
128+
//! Extends with fields from another QgsFields container
123129
void extend( const QgsFields &other );
124130

125-
//! Check whether the container is empty
131+
//! Checks whether the container is empty
126132
bool isEmpty() const;
127133

128134
//! Returns number of items
@@ -282,7 +288,7 @@ class CORE_EXPORT QgsFields
282288
int indexOf( const QString &fieldName ) const;
283289

284290
/**
285-
* Look up field's index from the field name.
291+
* Looks up field's index from the field name.
286292
* This method matches in the following order:
287293
*
288294
* 1. The exact field name taking case sensitivity into account

‎src/core/qgsvectorlayereditbuffer.cpp

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,18 @@ void QgsVectorLayerEditBuffer::updateFields( QgsFields &fields )
6262
{
6363
fields.remove( mDeletedAttributeIds.at( i ) );
6464
}
65-
// add new fields
66-
for ( int i = 0; i < mAddedAttributes.count(); ++i )
67-
{
68-
fields.append( mAddedAttributes.at( i ), QgsFields::OriginEdit, i );
69-
}
65+
7066
// rename fields
7167
QgsFieldNameMap::const_iterator renameIt = mRenamedAttributes.constBegin();
7268
for ( ; renameIt != mRenamedAttributes.constEnd(); ++renameIt )
7369
{
74-
fields[ renameIt.key()].setName( renameIt.value() );
70+
fields.rename( renameIt.key(), renameIt.value() );
71+
}
72+
73+
// add new fields
74+
for ( int i = 0; i < mAddedAttributes.count(); ++i )
75+
{
76+
fields.append( mAddedAttributes.at( i ), QgsFields::OriginEdit, i );
7577
}
7678
}
7779

@@ -413,6 +415,25 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList &commitErrors )
413415
}
414416
}
415417

418+
// rename attributes
419+
if ( !mRenamedAttributes.isEmpty() )
420+
{
421+
if ( ( cap & QgsVectorDataProvider::RenameAttributes ) && provider->renameAttributes( mRenamedAttributes ) )
422+
{
423+
commitErrors << tr( "SUCCESS: %n attribute(s) renamed.", "renamed attributes count", mRenamedAttributes.size() );
424+
425+
emit committedAttributesRenamed( L->id(), mRenamedAttributes );
426+
427+
mRenamedAttributes.clear();
428+
attributesChanged = true;
429+
}
430+
else
431+
{
432+
commitErrors << tr( "ERROR: %n attribute(s) not renamed", "not renamed attributes count", mRenamedAttributes.size() );
433+
success = false;
434+
}
435+
}
436+
416437
//
417438
// add attributes
418439
//
@@ -442,25 +463,6 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList &commitErrors )
442463
}
443464
}
444465

445-
// rename attributes
446-
if ( !mRenamedAttributes.isEmpty() )
447-
{
448-
if ( ( cap & QgsVectorDataProvider::RenameAttributes ) && provider->renameAttributes( mRenamedAttributes ) )
449-
{
450-
commitErrors << tr( "SUCCESS: %n attribute(s) renamed.", "renamed attributes count", mRenamedAttributes.size() );
451-
452-
emit committedAttributesRenamed( L->id(), mRenamedAttributes );
453-
454-
mRenamedAttributes.clear();
455-
attributesChanged = true;
456-
}
457-
else
458-
{
459-
commitErrors << tr( "ERROR: %n attribute(s) not renamed", "not renamed attributes count", mRenamedAttributes.size() );
460-
success = false;
461-
}
462-
}
463-
464466
//
465467
// check that addition/removal went as expected
466468
//

‎src/core/qgsvectorlayerundocommand.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,18 +423,38 @@ QgsVectorLayerUndoCommandRenameAttribute::QgsVectorLayerUndoCommandRenameAttribu
423423
, mOldName( layer()->fields().at( fieldIndex ).name() )
424424
, mNewName( newName )
425425
{
426+
const QgsFields &fields = layer()->fields();
427+
QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex );
428+
mOriginIndex = fields.fieldOriginIndex( mFieldIndex );
429+
mProviderField = ( origin == QgsFields::OriginProvider );
426430
}
427431

428432
void QgsVectorLayerUndoCommandRenameAttribute::undo()
429433
{
430-
mBuffer->mRenamedAttributes[ mFieldIndex ] = mOldName;
434+
if ( mProviderField )
435+
{
436+
mBuffer->mRenamedAttributes[ mFieldIndex ] = mOldName;
437+
}
438+
else
439+
{
440+
// newly added attribute
441+
mBuffer->mAddedAttributes[mOriginIndex].setName( mOldName );
442+
}
431443
mBuffer->updateLayerFields();
432444
emit mBuffer->attributeRenamed( mFieldIndex, mOldName );
433445
}
434446

435447
void QgsVectorLayerUndoCommandRenameAttribute::redo()
436448
{
437-
mBuffer->mRenamedAttributes[ mFieldIndex ] = mNewName;
449+
if ( mProviderField )
450+
{
451+
mBuffer->mRenamedAttributes[ mFieldIndex ] = mNewName;
452+
}
453+
else
454+
{
455+
// newly added attribute
456+
mBuffer->mAddedAttributes[mOriginIndex].setName( mNewName );
457+
}
438458
mBuffer->updateLayerFields();
439459
emit mBuffer->attributeRenamed( mFieldIndex, mNewName );
440460
}

‎src/core/qgsvectorlayerundocommand.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ class CORE_EXPORT QgsVectorLayerUndoCommandRenameAttribute : public QgsVectorLay
253253

254254
private:
255255
int mFieldIndex;
256+
bool mProviderField;
257+
int mOriginIndex;
256258
QString mOldName;
257259
QString mNewName;
258260
};

‎tests/src/core/testqgsfields.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class TestQgsFields: public QObject
3939
void count();
4040
void isEmpty();
4141
void remove();
42+
void rename();
4243
void extend();
4344
void byIndex();
4445
void byName();
@@ -237,6 +238,25 @@ void TestQgsFields::remove()
237238
QCOMPARE( fields.indexFromName( "testfield2" ), 0 );
238239
}
239240

241+
void TestQgsFields::rename()
242+
{
243+
QgsFields fields;
244+
245+
QVERIFY( !fields.rename( 1, "name" ) );
246+
247+
QgsField field( QStringLiteral( "testfield" ) );
248+
fields.append( field );
249+
QVERIFY( !fields.rename( 0, "" ) );
250+
251+
QgsField field2( QStringLiteral( "testfield2" ) );
252+
fields.append( field2 );
253+
QVERIFY( !fields.rename( 0, "testfield2" ) );
254+
255+
QVERIFY( fields.rename( 0, "newname" ) );
256+
QCOMPARE( fields.at( 0 ).name(), QString( "newname" ) );
257+
QCOMPARE( fields.at( 1 ).name(), QString( "testfield2" ) );
258+
}
259+
240260
void TestQgsFields::extend()
241261
{
242262
QgsFields destination;

0 commit comments

Comments
 (0)
Please sign in to comment.