diff --git a/src/app/qgsattributetabledialog.cpp b/src/app/qgsattributetabledialog.cpp index e5cc01d2387..9e8f0f05319 100644 --- a/src/app/qgsattributetabledialog.cpp +++ b/src/app/qgsattributetabledialog.cpp @@ -53,6 +53,8 @@ #include "qgsgui.h" #include "qgsclipboard.h" #include "qgsfeaturestore.h" +#include "qgsguiutils.h" +#include "qgsproxyprogresstask.h" QgsExpressionContext QgsAttributeTableDialog::createExpressionContext() const { @@ -503,10 +505,6 @@ void QgsAttributeTableDialog::formFilterSet( const QString &filter, QgsAttribute void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer *layer, const QString &fieldName, const QString &expression, const QgsFeatureIds &filteredIds ) { - QApplication::setOverrideCursor( Qt::WaitCursor ); - - mLayer->beginEditCommand( QStringLiteral( "Field calculator" ) ); - int fieldindex = layer->fields().indexFromName( fieldName ); if ( fieldindex < 0 ) { @@ -516,6 +514,9 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer *layer, const return; } + QgsTemporaryCursorOverride cursorOverride( Qt::WaitCursor ); + mLayer->beginEditCommand( QStringLiteral( "Field calculator" ) ); + bool calculationSuccess = true; QString error; @@ -542,6 +543,12 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer *layer, const //go through all the features and change the new attributes QgsFeatureIterator fit = layer->getFeatures( request ); + + std::unique_ptr< QgsScopedProxyProgressTask > task = qgis::make_unique< QgsScopedProxyProgressTask >( tr( "Calculating field" ) ); + + long long count = !filteredIds.isEmpty() ? filteredIds.size() : layer->featureCount(); + long long i = 0; + QgsFeature feature; while ( fit.nextFeature( feature ) ) { @@ -550,6 +557,9 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer *layer, const continue; } + i++; + task->setProgress( i / static_cast< double >( count ) * 100 ); + context.setFeature( feature ); context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), rownum, true ) ); @@ -571,7 +581,8 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer *layer, const rownum++; } - QApplication::restoreOverrideCursor(); + cursorOverride.release(); + task.reset(); if ( !calculationSuccess ) { diff --git a/src/app/qgsfieldcalculator.cpp b/src/app/qgsfieldcalculator.cpp index 7c5e8317f34..39b772a13ba 100644 --- a/src/app/qgsfieldcalculator.cpp +++ b/src/app/qgsfieldcalculator.cpp @@ -27,6 +27,7 @@ #include "qgssettings.h" #include "qgsgui.h" #include "qgsguiutils.h" +#include "qgsproxyprogresstask.h" #include @@ -289,8 +290,15 @@ void QgsFieldCalculator::accept() req.setFilterFids( mVectorLayer->selectedFeatureIds() ); } QgsFeatureIterator fit = mVectorLayer->getFeatures( req ); + + std::unique_ptr< QgsScopedProxyProgressTask > task = qgis::make_unique< QgsScopedProxyProgressTask >( tr( "Calculating field" ) ); + long long count = mOnlyUpdateSelectedCheckBox->isChecked() ? mVectorLayer->selectedFeatureCount() : mVectorLayer->featureCount(); + long long i = 0; while ( fit.nextFeature( feature ) ) { + i++; + task->setProgress( i / static_cast< double >( count ) * 100 ); + expContext.setFeature( feature ); expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), rownum, true ) ); @@ -323,6 +331,7 @@ void QgsFieldCalculator::accept() if ( !calculationSuccess ) { cursorOverride.release(); + task.reset(); QMessageBox::critical( nullptr, tr( "Evaluation Error" ), tr( "An error occurred while evaluating the calculation string:\n%1" ).arg( error ) ); mVectorLayer->destroyEditCommand(); return;