Skip to content

Commit 52616b6

Browse files
committedFeb 8, 2014
vector layer: save old attribute values where available to speedup undo (and rollback) (fixes #9509)
field calculator & app: use wait cursor while calculating and committing or rolling back
1 parent 48427e1 commit 52616b6

15 files changed

+60
-43
lines changed
 

‎python/core/qgsvectorlayer.sip

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,11 +732,12 @@ class QgsVectorLayer : QgsMapLayer
732732
*
733733
* @param fid The feature id of the feature to be changed
734734
* @param field The index of the field to be updated
735-
* @param value The value which will be assigned to the field
735+
* @param newValue The value which will be assigned to the field
736+
* @param oldValue The previous value to restore on undo (will otherwise be retrieved)
736737
*
737738
* @return true in case of success
738739
*/
739-
bool changeAttributeValue( QgsFeatureId fid, int field, QVariant value );
740+
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
740741

741742
/** add an attribute field (but does not commit it)
742743
returns true if the field was added

‎python/core/qgsvectorlayereditbuffer.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class QgsVectorLayerEditBuffer : QObject
3232
bool changeGeometry( QgsFeatureId fid, QgsGeometry* geom );
3333

3434
/** changed an attribute value (but does not commit it) */
35-
bool changeAttributeValue( QgsFeatureId fid, int field, QVariant value );
35+
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
3636

3737
/** add an attribute field (but does not commit it)
3838
returns true if the field was added

‎python/core/qgsvectorlayerundocommand.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class QgsVectorLayerUndoCommandChangeAttribute : QgsVectorLayerUndoCommand
6161
#include "qgsvectorlayerundocommand.h"
6262
%End
6363
public:
64-
QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer /Transfer/, QgsFeatureId fid, int fieldIndex, const QVariant& newValue );
64+
QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer /Transfer/, QgsFeatureId fid, int fieldIndex, const QVariant &newValue, const QVariant &oldValue );
6565
virtual void undo();
6666
virtual void redo();
6767
};

‎scripts/sipdiff

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#!/bin/bash
22

3-
file=$1
3+
for file in $*; do
4+
file=$1
45

5-
d=${file#*/}
6-
d=${d%/*}
7-
f=${file##*/}
8-
f=${f%.*}
6+
d=${file#*/}
7+
d=${d%/*}
8+
f=${file##*/}
9+
f=${f%.*}
910

10-
vimdiff src/$d/$f.h python/$d/$f.sip
11+
vimdiff src/$d/$f.h python/$d/$f.sip
12+
done

‎src/app/qgisapp.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5943,7 +5943,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
59435943
feature.geometry()->convertToMultiType();
59445944
}
59455945
}
5946-
if ( ! layer->addFeatures( features ) || ! layer->commitChanges() )
5946+
if ( ! layer->addFeatures( features ) || !layer->commitChanges() )
59475947
{
59485948
QgsDebugMsg( "Cannot add features or commit changes" );
59495949
delete layer;
@@ -6127,6 +6127,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
61276127
break;
61286128

61296129
case QMessageBox::Save:
6130+
QApplication::setOverrideCursor( Qt::WaitCursor );
6131+
61306132
if ( !vlayer->commitChanges() )
61316133
{
61326134
commitError( vlayer );
@@ -6137,9 +6139,13 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
61376139
}
61386140

61396141
vlayer->triggerRepaint();
6142+
6143+
QApplication::restoreOverrideCursor();
61406144
break;
61416145

61426146
case QMessageBox::Discard:
6147+
QApplication::setOverrideCursor( Qt::WaitCursor );
6148+
61436149
mMapCanvas->freeze( true );
61446150
if ( !vlayer->rollBack() )
61456151
{
@@ -6151,6 +6157,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
61516157
mMapCanvas->freeze( false );
61526158

61536159
vlayer->triggerRepaint();
6160+
6161+
QApplication::restoreOverrideCursor();
61546162
break;
61556163

61566164
default:
@@ -8115,6 +8123,7 @@ void QgisApp::hasCrsTransformEnabled( bool theFlag )
81158123
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectionsEnabled", ( theFlag ? 1 : 0 ) );
81168124
updateCRSStatusBar();
81178125
}
8126+
81188127
// slot to update the progress bar in the status bar
81198128
void QgisApp::showProgress( int theProgress, int theTotalSteps )
81208129
{

‎src/app/qgsfeatureaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ bool QgsFeatureAction::editFeature()
127127
{
128128
if ( dst[i] != src[i] )
129129
{
130-
mLayer->changeAttributeValue( mFeature.id(), i, dst[i] );
130+
mLayer->changeAttributeValue( mFeature.id(), i, dst[i], src[i] );
131131
}
132132
}
133133

‎src/app/qgsfieldcalculator.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ void QgsFieldCalculator::accept()
110110
return;
111111
}
112112

113+
QApplication::setOverrideCursor( Qt::WaitCursor );
114+
113115
mVectorLayer->beginEditCommand( "Field calculator" );
114116

115117
//update existing field
@@ -153,6 +155,7 @@ void QgsFieldCalculator::accept()
153155
if ( mAttributeId == -1 )
154156
{
155157
mVectorLayer->destroyEditCommand();
158+
QApplication::restoreOverrideCursor();
156159
return;
157160
}
158161

@@ -188,12 +191,14 @@ void QgsFieldCalculator::accept()
188191
}
189192
else
190193
{
191-
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value );
194+
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value, feature.attributes().value( mAttributeId ) );
192195
}
193196

194197
rownum++;
195198
}
196199

200+
QApplication::restoreOverrideCursor();
201+
197202
if ( !calculationSuccess )
198203
{
199204
QMessageBox::critical( 0, tr( "Error" ), tr( "An error occured while evaluating the calculation string:\n%1" ).arg( error ) );

‎src/core/qgsvectorlayer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ bool QgsVectorLayer::updateFeature( QgsFeature &f )
13281328
{
13291329
if ( fa[attr] != ca[attr] )
13301330
{
1331-
if ( !changeAttributeValue( f.id(), attr, fa[attr] ) )
1331+
if ( !changeAttributeValue( f.id(), attr, fa[attr], ca[attr] ) )
13321332
{
13331333
QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
13341334
return false;
@@ -2559,12 +2559,12 @@ bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, QVariant
25592559
return changeAttributeValue( fid, field, value );
25602560
}
25612561

2562-
bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, QVariant value )
2562+
bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
25632563
{
25642564
if ( !mEditBuffer || !mDataProvider )
25652565
return false;
25662566

2567-
return mEditBuffer->changeAttributeValue( fid, field, value );
2567+
return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
25682568
}
25692569

25702570
bool QgsVectorLayer::addAttribute( const QgsField &field )

‎src/core/qgsvectorlayer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,11 +1083,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
10831083
*
10841084
* @param fid The feature id of the feature to be changed
10851085
* @param field The index of the field to be updated
1086-
* @param value The value which will be assigned to the field
1086+
* @param newValue The value which will be assigned to the field
1087+
* @param oldValue The previous value to restore on undo (will otherwise be retrieved)
10871088
*
10881089
* @return true in case of success
10891090
*/
1090-
bool changeAttributeValue( QgsFeatureId fid, int field, QVariant value );
1091+
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
10911092

10921093
/** add an attribute field (but does not commit it)
10931094
returns true if the field was added

‎src/core/qgsvectorlayereditbuffer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ bool QgsVectorLayerEditBuffer::changeGeometry( QgsFeatureId fid, QgsGeometry* ge
169169
}
170170

171171

172-
bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, QVariant value )
172+
bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
173173
{
174174
if ( !( L->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) )
175175
return false;
@@ -184,7 +184,7 @@ bool QgsVectorLayerEditBuffer::changeAttributeValue( QgsFeatureId fid, int field
184184
L->pendingFields().fieldOrigin( field ) == QgsFields::OriginJoin )
185185
return false;
186186

187-
L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, value ) );
187+
L->undoStack()->push( new QgsVectorLayerUndoCommandChangeAttribute( this, fid, field, newValue, oldValue ) );
188188
return true;
189189
}
190190

‎src/core/qgsvectorlayereditbuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
5858
bool changeGeometry( QgsFeatureId fid, QgsGeometry* geom );
5959

6060
/** changed an attribute value (but does not commit it) */
61-
bool changeAttributeValue( QgsFeatureId fid, int field, QVariant value );
61+
bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant() );
6262

6363
/** add an attribute field (but does not commit it)
6464
returns true if the field was added

‎src/core/qgsvectorlayerundocommand.cpp

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,11 @@ void QgsVectorLayerUndoCommandChangeGeometry::redo()
217217
}
218218

219219

220-
QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant& newValue )
220+
QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant &newValue, const QVariant &oldValue )
221221
: QgsVectorLayerUndoCommand( buffer )
222222
, mFid( fid )
223223
, mFieldIndex( fieldIndex )
224+
, mOldValue( oldValue )
224225
, mNewValue( newValue )
225226
, mFirstChange( true )
226227
{
@@ -235,13 +236,10 @@ QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribu
235236
mFirstChange = false;
236237
}
237238
}
238-
else
239+
else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
239240
{
240-
if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
241-
{
242-
mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
243-
mFirstChange = false;
244-
}
241+
mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
242+
mFirstChange = false;
245243
}
246244

247245
}
@@ -257,15 +255,15 @@ void QgsVectorLayerUndoCommandChangeAttribute::undo()
257255
Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
258256
it.value().setAttribute( mFieldIndex, mOldValue );
259257
}
260-
else
258+
else if ( mFirstChange )
261259
{
262260
// existing feature
263-
if ( mFirstChange )
264-
{
265-
mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
266-
if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
267-
mBuffer->mChangedAttributeValues.remove( mFid );
261+
mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
262+
if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
263+
mBuffer->mChangedAttributeValues.remove( mFid );
268264

265+
if ( !mOldValue.isValid() )
266+
{
269267
// get old value from provider
270268
QgsFeature tmp;
271269
QgsFeatureRequest request;
@@ -276,10 +274,10 @@ void QgsVectorLayerUndoCommandChangeAttribute::undo()
276274
if ( fi.nextFeature( tmp ) )
277275
original = tmp.attribute( mFieldIndex );
278276
}
279-
else
280-
{
281-
mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
282-
}
277+
}
278+
else
279+
{
280+
mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
283281
}
284282

285283
emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );

‎src/core/qgsvectorlayerundocommand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class CORE_EXPORT QgsVectorLayerUndoCommandChangeGeometry : public QgsVectorLaye
9898
class CORE_EXPORT QgsVectorLayerUndoCommandChangeAttribute : public QgsVectorLayerUndoCommand
9999
{
100100
public:
101-
QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant& newValue );
101+
QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant &newValue, const QVariant &oldValue );
102102
virtual void undo();
103103
virtual void redo();
104104

‎src/gui/attributetable/qgsattributetabledelegate.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,14 @@ void QgsAttributeTableDelegate::setModelData( QWidget *editor, QAbstractItemMode
8787

8888
int fieldIdx = model->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
8989
QgsFeatureId fid = model->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
90+
QVariant oldValue = model->data( index, Qt::EditRole );
9091

91-
QVariant value;
92-
if ( !QgsAttributeEditor::retrieveValue( editor, vl, fieldIdx, value ) )
92+
QVariant newValue;
93+
if ( !QgsAttributeEditor::retrieveValue( editor, vl, fieldIdx, newValue ) )
9394
return;
9495

9596
vl->beginEditCommand( tr( "Attribute changed" ) );
96-
vl->changeAttributeValue( fid, fieldIdx, value );
97+
vl->changeAttributeValue( fid, fieldIdx, newValue, oldValue );
9798
vl->endEditCommand();
9899
}
99100

‎src/gui/attributetable/qgsdualview.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ bool QgsDualView::saveEditChanges()
350350
if ( dst[i] == src[i] )
351351
continue;
352352

353-
mLayerCache->layer()->changeAttributeValue( fid, i, dst[i] );
353+
mLayerCache->layer()->changeAttributeValue( fid, i, dst[i], src[i] );
354354
}
355355

356356
mLayerCache->layer()->endEditCommand();

0 commit comments

Comments
 (0)
Please sign in to comment.