Skip to content

Commit afc873d

Browse files
committed
Block signals in the cache only
much better approach ...
1 parent d79e3ad commit afc873d

File tree

2 files changed

+124
-126
lines changed

2 files changed

+124
-126
lines changed

src/app/qgsattributetabledialog.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -715,15 +715,20 @@ void QgsAttributeTableDialog::mActionOpenFieldCalculator_triggered()
715715
QgsAttributeTableModel *masterModel = mMainView->masterModel();
716716

717717
QgsFieldCalculator calc( mLayer, this );
718+
masterModel->layerCache()->blockSignals( true );
718719
if ( calc.exec() == QDialog::Accepted )
719720
{
721+
masterModel->layerCache()->blockSignals( false );
720722
int col = masterModel->fieldCol( calc.changedAttributeId() );
721-
722723
if ( col >= 0 )
723724
{
724725
masterModel->reload( masterModel->index( 0, col ), masterModel->index( masterModel->rowCount() - 1, col ) );
725726
}
726727
}
728+
else
729+
{
730+
masterModel->layerCache()->blockSignals( false );
731+
}
727732
}
728733

729734
void QgsAttributeTableDialog::mActionSaveEdits_triggered()

src/app/qgsfieldcalculator.cpp

+118-125
Original file line numberDiff line numberDiff line change
@@ -167,173 +167,166 @@ void QgsFieldCalculator::accept()
167167
{
168168
return;
169169
}
170-
else // Need a scope for the blocker let's keep the else for clarity
171-
{
172-
173-
QgsSignalBlocker<QgsVectorLayer> vectorBlocker( mVectorLayer );
174170

175-
// Set up QgsDistanceArea each time we (re-)calculate
176-
QgsDistanceArea myDa;
171+
// Set up QgsDistanceArea each time we (re-)calculate
172+
QgsDistanceArea myDa;
177173

178-
myDa.setSourceCrs( mVectorLayer->crs(), QgsProject::instance()->transformContext() );
179-
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
174+
myDa.setSourceCrs( mVectorLayer->crs(), QgsProject::instance()->transformContext() );
175+
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
180176

181-
QString calcString = builder->expressionText();
182-
QgsExpression exp( calcString );
183-
exp.setGeomCalculator( &myDa );
184-
exp.setDistanceUnits( QgsProject::instance()->distanceUnits() );
185-
exp.setAreaUnits( QgsProject::instance()->areaUnits() );
177+
QString calcString = builder->expressionText();
178+
QgsExpression exp( calcString );
179+
exp.setGeomCalculator( &myDa );
180+
exp.setDistanceUnits( QgsProject::instance()->distanceUnits() );
181+
exp.setAreaUnits( QgsProject::instance()->areaUnits() );
186182

187-
QgsExpressionContext expContext( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );
183+
QgsExpressionContext expContext( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );
188184

189-
if ( !exp.prepare( &expContext ) )
190-
{
191-
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), exp.evalErrorString() );
192-
return;
193-
}
185+
if ( !exp.prepare( &expContext ) )
186+
{
187+
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), exp.evalErrorString() );
188+
return;
189+
}
194190

195-
bool updatingGeom = false;
191+
bool updatingGeom = false;
196192

197-
// Test for creating expression field based on ! mUpdateExistingGroupBox checked rather
198-
// than on mNewFieldGroupBox checked, as if the provider does not support adding attributes
199-
// then mUpdateExistingGroupBox is set to not checkable, and hence is not checked. This
200-
// is a minimum fix to resolve this - better would be some GUI redesign...
201-
if ( ! mUpdateExistingGroupBox->isChecked() && mCreateVirtualFieldCheckbox->isChecked() )
202-
{
203-
mVectorLayer->addExpressionField( calcString, fieldDefinition() );
204-
}
205-
else
206-
{
207-
if ( !mVectorLayer->isEditable() )
208-
mVectorLayer->startEditing();
193+
// Test for creating expression field based on ! mUpdateExistingGroupBox checked rather
194+
// than on mNewFieldGroupBox checked, as if the provider does not support adding attributes
195+
// then mUpdateExistingGroupBox is set to not checkable, and hence is not checked. This
196+
// is a minimum fix to resolve this - better would be some GUI redesign...
197+
if ( ! mUpdateExistingGroupBox->isChecked() && mCreateVirtualFieldCheckbox->isChecked() )
198+
{
199+
mVectorLayer->addExpressionField( calcString, fieldDefinition() );
200+
}
201+
else
202+
{
203+
if ( !mVectorLayer->isEditable() )
204+
mVectorLayer->startEditing();
209205

210-
QApplication::setOverrideCursor( Qt::WaitCursor );
206+
QApplication::setOverrideCursor( Qt::WaitCursor );
211207

212-
mVectorLayer->beginEditCommand( QStringLiteral( "Field calculator" ) );
208+
mVectorLayer->beginEditCommand( QStringLiteral( "Field calculator" ) );
213209

214-
//update existing field
215-
if ( mUpdateExistingGroupBox->isChecked() || !mNewFieldGroupBox->isEnabled() )
210+
//update existing field
211+
if ( mUpdateExistingGroupBox->isChecked() || !mNewFieldGroupBox->isEnabled() )
212+
{
213+
if ( mExistingFieldComboBox->currentData().toString() == QLatin1String( "geom" ) )
216214
{
217-
if ( mExistingFieldComboBox->currentData().toString() == QLatin1String( "geom" ) )
218-
{
219-
//update geometry
220-
mAttributeId = -1;
221-
updatingGeom = true;
222-
}
223-
else
224-
{
225-
QMap<QString, int>::const_iterator fieldIt = mFieldMap.constFind( mExistingFieldComboBox->currentText() );
226-
if ( fieldIt != mFieldMap.constEnd() )
227-
{
228-
mAttributeId = fieldIt.value();
229-
}
230-
}
215+
//update geometry
216+
mAttributeId = -1;
217+
updatingGeom = true;
231218
}
232219
else
233220
{
234-
//create new field
235-
const QgsField newField = fieldDefinition();
236-
237-
if ( !mVectorLayer->addAttribute( newField ) )
221+
QMap<QString, int>::const_iterator fieldIt = mFieldMap.constFind( mExistingFieldComboBox->currentText() );
222+
if ( fieldIt != mFieldMap.constEnd() )
238223
{
239-
QApplication::restoreOverrideCursor();
240-
QMessageBox::critical( nullptr, tr( "Create New Field" ), tr( "Could not add the new field to the provider." ) );
241-
mVectorLayer->destroyEditCommand();
242-
return;
224+
mAttributeId = fieldIt.value();
243225
}
226+
}
227+
}
228+
else
229+
{
230+
//create new field
231+
const QgsField newField = fieldDefinition();
244232

245-
//get index of the new field
246-
const QgsFields &fields = mVectorLayer->fields();
233+
if ( !mVectorLayer->addAttribute( newField ) )
234+
{
235+
QApplication::restoreOverrideCursor();
236+
QMessageBox::critical( nullptr, tr( "Create New Field" ), tr( "Could not add the new field to the provider." ) );
237+
mVectorLayer->destroyEditCommand();
238+
return;
239+
}
247240

248-
for ( int idx = 0; idx < fields.count(); ++idx )
249-
{
250-
if ( fields.at( idx ).name() == mOutputFieldNameLineEdit->text() )
251-
{
252-
mAttributeId = idx;
253-
break;
254-
}
255-
}
241+
//get index of the new field
242+
const QgsFields &fields = mVectorLayer->fields();
256243

257-
//update expression context with new fields
258-
expContext.setFields( mVectorLayer->fields() );
259-
if ( ! exp.prepare( &expContext ) )
244+
for ( int idx = 0; idx < fields.count(); ++idx )
245+
{
246+
if ( fields.at( idx ).name() == mOutputFieldNameLineEdit->text() )
260247
{
261-
QApplication::restoreOverrideCursor();
262-
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), exp.evalErrorString() );
263-
return;
248+
mAttributeId = idx;
249+
break;
264250
}
265251
}
266252

267-
if ( mAttributeId == -1 && !updatingGeom )
253+
//update expression context with new fields
254+
expContext.setFields( mVectorLayer->fields() );
255+
if ( ! exp.prepare( &expContext ) )
268256
{
269-
mVectorLayer->destroyEditCommand();
270257
QApplication::restoreOverrideCursor();
258+
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), exp.evalErrorString() );
271259
return;
272260
}
261+
}
273262

274-
//go through all the features and change the new attribute
275-
QgsFeature feature;
276-
bool calculationSuccess = true;
277-
QString error;
263+
if ( mAttributeId == -1 && !updatingGeom )
264+
{
265+
mVectorLayer->destroyEditCommand();
266+
QApplication::restoreOverrideCursor();
267+
return;
268+
}
269+
270+
//go through all the features and change the new attribute
271+
QgsFeature feature;
272+
bool calculationSuccess = true;
273+
QString error;
278274

279-
bool useGeometry = exp.needsGeometry();
280-
int rownum = 1;
275+
bool useGeometry = exp.needsGeometry();
276+
int rownum = 1;
281277

282-
QgsField field = !updatingGeom ? mVectorLayer->fields().at( mAttributeId ) : QgsField();
278+
QgsField field = !updatingGeom ? mVectorLayer->fields().at( mAttributeId ) : QgsField();
283279

284-
bool newField = !mUpdateExistingGroupBox->isChecked();
285-
QVariant emptyAttribute;
286-
if ( newField )
287-
emptyAttribute = QVariant( field.type() );
280+
bool newField = !mUpdateExistingGroupBox->isChecked();
281+
QVariant emptyAttribute;
282+
if ( newField )
283+
emptyAttribute = QVariant( field.type() );
284+
285+
QgsFeatureRequest req = QgsFeatureRequest().setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry );
286+
if ( mOnlyUpdateSelectedCheckBox->isChecked() )
287+
{
288+
req.setFilterFids( mVectorLayer->selectedFeatureIds() );
289+
}
290+
QgsFeatureIterator fit = mVectorLayer->getFeatures( req );
291+
while ( fit.nextFeature( feature ) )
292+
{
293+
expContext.setFeature( feature );
294+
expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), rownum, true ) );
288295

289-
QgsFeatureRequest req = QgsFeatureRequest().setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry );
290-
if ( mOnlyUpdateSelectedCheckBox->isChecked() )
296+
QVariant value = exp.evaluate( &expContext );
297+
if ( exp.hasEvalError() )
291298
{
292-
req.setFilterFids( mVectorLayer->selectedFeatureIds() );
299+
calculationSuccess = false;
300+
error = exp.evalErrorString();
301+
break;
293302
}
294-
QgsFeatureIterator fit = mVectorLayer->getFeatures( req );
295-
while ( fit.nextFeature( feature ) )
303+
else if ( updatingGeom )
296304
{
297-
expContext.setFeature( feature );
298-
expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), rownum, true ) );
299-
300-
QVariant value = exp.evaluate( &expContext );
301-
if ( exp.hasEvalError() )
302-
{
303-
calculationSuccess = false;
304-
error = exp.evalErrorString();
305-
break;
306-
}
307-
else if ( updatingGeom )
305+
if ( value.canConvert< QgsGeometry >() )
308306
{
309-
if ( value.canConvert< QgsGeometry >() )
310-
{
311-
QgsGeometry geom = value.value< QgsGeometry >();
312-
mVectorLayer->changeGeometry( feature.id(), geom );
313-
}
307+
QgsGeometry geom = value.value< QgsGeometry >();
308+
mVectorLayer->changeGeometry( feature.id(), geom );
314309
}
315-
else
316-
{
317-
( void )field.convertCompatible( value );
318-
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value, newField ? emptyAttribute : feature.attributes().value( mAttributeId ) );
319-
}
320-
321-
rownum++;
322310
}
323-
324-
QApplication::restoreOverrideCursor();
325-
326-
if ( !calculationSuccess )
311+
else
327312
{
328-
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), tr( "An error occurred while evaluating the calculation string:\n%1" ).arg( error ) );
329-
mVectorLayer->destroyEditCommand();
330-
return;
313+
( void )field.convertCompatible( value );
314+
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value, newField ? emptyAttribute : feature.attributes().value( mAttributeId ) );
331315
}
332-
mVectorLayer->endEditCommand();
316+
317+
rownum++;
318+
}
319+
320+
QApplication::restoreOverrideCursor();
321+
322+
if ( !calculationSuccess )
323+
{
324+
QMessageBox::critical( nullptr, tr( "Evaluation Error" ), tr( "An error occurred while evaluating the calculation string:\n%1" ).arg( error ) );
325+
mVectorLayer->destroyEditCommand();
326+
return;
333327
}
328+
mVectorLayer->endEditCommand();
334329
}
335-
// Vector signals unlocked! Tell the world that the layer has changed
336-
mVectorLayer->dataChanged();
337330
QDialog::accept();
338331
}
339332

0 commit comments

Comments
 (0)