@@ -301,9 +301,12 @@ void QgsAttributeTableModel::fieldFormatterRemoved( QgsFieldFormatter *fieldForm
301
301
302
302
void QgsAttributeTableModel::attributeValueChanged ( QgsFeatureId fid, int idx, const QVariant &value )
303
303
{
304
- // Skip all updates if an edit command is running
304
+ // Defer all updates if an edit command is running
305
305
if ( mBulkEditCommandRunning )
306
+ {
307
+ mAttributeValueChanges .insert ( QPair<QgsFeatureId, int >( fid, idx ), value );
306
308
return ;
309
+ }
307
310
QgsDebugMsgLevel ( QStringLiteral ( " (%4) fid: %1, idx: %2, value: %3" ).arg ( fid ).arg ( idx ).arg ( value.toString () ).arg ( mFeatureRequest .filterType () ), 3 );
308
311
309
312
for ( SortCache &cache : mSortCaches )
@@ -810,13 +813,44 @@ bool QgsAttributeTableModel::fieldIsEditable( const QgsVectorLayer &layer, int f
810
813
void QgsAttributeTableModel::bulkEditCommandStarted ()
811
814
{
812
815
mBulkEditCommandRunning = true ;
816
+ mAttributeValueChanges .clear ();
813
817
}
814
818
815
819
void QgsAttributeTableModel::bulkEditCommandEnded ()
816
820
{
817
- // Invalidate the whole model
818
821
mBulkEditCommandRunning = false ;
819
- emit dataChanged ( createIndex ( 0 , 0 ), createIndex ( rowCount () - 1 , columnCount () - 1 ) );
822
+ // Full model update if the changed rows are more than half the total rows
823
+ // or if their count is > 1000
824
+ int minRow = rowCount ();
825
+ int minCol = columnCount ();
826
+ int maxRow = 0 ;
827
+ int maxCol = 0 ;
828
+ bool fullModelUpdate = mAttributeValueChanges .count () >= 1000 ||
829
+ mAttributeValueChanges .count () >= rowCount () * 0.5 ;
830
+ const auto keys = mAttributeValueChanges .keys ();
831
+ for ( const auto &key : keys )
832
+ {
833
+
834
+ attributeValueChanged ( key.first , key.second , mAttributeValueChanges .value ( key ) );
835
+ int row ( idToRow ( key.first ) );
836
+ int col ( fieldCol ( key.second ) );
837
+ if ( ! fullModelUpdate )
838
+ {
839
+ QModelIndex index ( createIndex ( row, col ) );
840
+ emit dataChanged ( index , index );
841
+ }
842
+ else
843
+ {
844
+ minRow = std::min<int >( row, minRow );
845
+ minCol = std::min<int >( col, minCol );
846
+ maxRow = std::max<int >( row, maxRow );
847
+ maxCol = std::max<int >( col, maxCol );
848
+ }
849
+ }
850
+ // Invalidates the whole model: triggers an update in the view
851
+ if ( fullModelUpdate )
852
+ emit dataChanged ( createIndex ( minRow, minCol ), createIndex ( maxRow, maxCol ) );
853
+ mAttributeValueChanges .clear ();
820
854
}
821
855
822
856
void QgsAttributeTableModel::reload ( const QModelIndex &index1, const QModelIndex &index2 )
0 commit comments