@@ -98,7 +98,8 @@ class DataGridStagingBuffer extends ChangeNotifier {
9898 return '' ;
9999 }
100100 final insertIdx = row - _originalRows.length;
101- if (insertIdx < _insertedRows.length && col < _insertedRows[insertIdx].length) {
101+ if (insertIdx < _insertedRows.length &&
102+ col < _insertedRows[insertIdx].length) {
102103 final ins = _insertedRows[insertIdx][col];
103104 return ins == TableMutationEngine .kNullSentinel ? 'NULL' : ins;
104105 }
@@ -118,7 +119,8 @@ class DataGridStagingBuffer extends ChangeNotifier {
118119 return false ;
119120 }
120121 final insertIdx = row - _originalRows.length;
121- if (insertIdx < _insertedRows.length && col < _insertedRows[insertIdx].length) {
122+ if (insertIdx < _insertedRows.length &&
123+ col < _insertedRows[insertIdx].length) {
122124 final ins = _insertedRows[insertIdx][col];
123125 return ins == 'NULL' || ins == TableMutationEngine .kNullSentinel;
124126 }
@@ -127,7 +129,10 @@ class DataGridStagingBuffer extends ChangeNotifier {
127129
128130 /// Returns original baseline cell value, or null if row is inserted.
129131 String ? getOriginalCellValue (int row, int col) {
130- if (row >= 0 && row < _originalRows.length && col >= 0 && col < _originalRows[row].length) {
132+ if (row >= 0 &&
133+ row < _originalRows.length &&
134+ col >= 0 &&
135+ col < _originalRows[row].length) {
131136 return _originalRows[row][col];
132137 }
133138 return null ;
@@ -169,7 +174,8 @@ class DataGridStagingBuffer extends ChangeNotifier {
169174 if (row < 0 || col < 0 ) return ;
170175
171176 if (row < _originalRows.length) {
172- final orig = col < _originalRows[row].length ? _originalRows[row][col] : '' ;
177+ final orig =
178+ col < _originalRows[row].length ? _originalRows[row][col] : '' ;
173179 if (value == orig) {
174180 if (_modifiedCells.containsKey (row)) {
175181 _modifiedCells[row]! .remove (col);
@@ -281,7 +287,8 @@ class DataGridStagingBuffer extends ChangeNotifier {
281287 /// Read-only snapshot of modified cells mapping.
282288 Map <int , Map <int , String >> get modifiedCells =>
283289 Map <int , Map <int , String >>.unmodifiable (
284- _modifiedCells.map ((k, v) => MapEntry (k, Map <int , String >.unmodifiable (v))),
290+ _modifiedCells
291+ .map ((k, v) => MapEntry (k, Map <int , String >.unmodifiable (v))),
285292 );
286293
287294 /// Read-only list of newly inserted rows.
@@ -317,6 +324,10 @@ class DataGridStagingBuffer extends ChangeNotifier {
317324
318325 /// Returns the full list of effective rows (original with modifications applied + inserted rows).
319326 ///
327+ /// Row indices stay aligned with the grid (rows marked for deletion are still
328+ /// present so they can render struck through); use [committedRows] for the
329+ /// baseline after a successful save. Staged NULLs are shown as `'NULL'` .
330+ ///
320331 /// Optimized for zero allocations when [isDirty] is false, and caches
321332 /// the effective row list to prevent breaking widget memoization.
322333 List <List <String >> get effectiveRows {
@@ -326,14 +337,27 @@ class DataGridStagingBuffer extends ChangeNotifier {
326337 if (_cachedEffectiveRows != null ) {
327338 return _cachedEffectiveRows! ;
328339 }
340+ _cachedEffectiveRows = List .unmodifiable (_buildRows (includeDeleted: true ));
341+ return _cachedEffectiveRows! ;
342+ }
343+
344+ /// Rows as they exist in the database once the staged changes are applied:
345+ /// deleted baseline rows are dropped and staged NULLs become `'NULL'` .
346+ ///
347+ /// Use this as the new baseline after a successful save.
348+ List <List <String >> get committedRows =>
349+ List .unmodifiable (_buildRows (includeDeleted: false ));
350+
351+ List <List <String >> _buildRows ({required bool includeDeleted}) {
329352 final result = < List <String >> [];
330353 for (var r = 0 ; r < _originalRows.length; r++ ) {
354+ if (! includeDeleted && _deletedRowIndices.contains (r)) continue ;
331355 final mods = _modifiedCells[r];
332356 if (mods != null ) {
333357 final row = List <String >.from (_originalRows[r]);
334358 for (final entry in mods.entries) {
335359 if (entry.key < row.length) {
336- row[entry.key] = entry.value;
360+ row[entry.key] = _sanitizeNull ( entry.value) ;
337361 }
338362 }
339363 result.add (row);
@@ -342,12 +366,18 @@ class DataGridStagingBuffer extends ChangeNotifier {
342366 }
343367 }
344368 for (final ins in _insertedRows) {
345- result.add (ins);
369+ result.add (
370+ ins.any ((v) => v == TableMutationEngine .kNullSentinel)
371+ ? ins.map (_sanitizeNull).toList ()
372+ : ins,
373+ );
346374 }
347- _cachedEffectiveRows = List .unmodifiable (result);
348- return _cachedEffectiveRows! ;
375+ return result;
349376 }
350377
378+ static String _sanitizeNull (String value) =>
379+ value == TableMutationEngine .kNullSentinel ? 'NULL' : value;
380+
351381 @override
352382 void dispose () {
353383 UnsavedWorkRegistry .instance.unregister (this );
@@ -358,4 +388,3 @@ class DataGridStagingBuffer extends ChangeNotifier {
358388 super .dispose ();
359389 }
360390}
361-
0 commit comments