Recent

Author Topic: how to redo or undo in fpspreadsheet [done with snippet]  (Read 412 times)

Mongkey

  • Sr. Member
  • ****
  • Posts: 452
how to redo or undo in fpspreadsheet [done with snippet]
« on: December 19, 2025, 05:12:57 am »
is there anyone here could do redo or undo under fpspreadsheet worksheetgrid editor?

Thank you.
« Last Edit: December 20, 2025, 02:44:13 am by Mongkey »

Xenno

  • Jr. Member
  • **
  • Posts: 62
    • BS Programs
Re: how to redo or undo in fpspreadsheet
« Reply #1 on: December 19, 2025, 03:26:41 pm »
The simplest way would be saving the sheet to (temporary) files before any action. Keep the file names in a LIFO list (stack). Just load the file in reverse order to Undo or the opposite to Redo. These snapshot files must be removed when no longer needed. To save space, you may use compression with a little consequences.
Lazarus 4.0, Windows 10, https://www.youtube.com/@bsprograms

Mongkey

  • Sr. Member
  • ****
  • Posts: 452
Re: how to redo or undo in fpspreadsheet
« Reply #2 on: December 20, 2025, 02:27:40 am »
thank you bro,
I got vision from gr*k, this code fully worked:

Code: Pascal  [Select][+][-]
  1. type
  2.   TCellEdit_ = record
  3.     Row, Col: integer;
  4.     OldValue, NewValue: variant;
  5.   end;
  6.  
  7.   TUndoRedoList = array of TCellEdit_;
  8.  
  9. var
  10.   UndoStack, RedoStack: array of TUndoRedoList;
  11.  
  12.   OldCellValue, NewCellValue: variant;
  13.  
  14. procedure Undo;
  15. var
  16.   LastActions: TUndoRedoList;
  17.   Act: TCellEdit_;
  18.   i: integer;
  19. begin
  20.   if Length(UndoStack) = 0 then Exit;
  21.  
  22.   // Pop the last group of actions
  23.   LastActions := UndoStack[High(UndoStack)];
  24.   SetLength(UndoStack, Length(UndoStack) - 1);
  25.  
  26.   // Push the whole group to Redo stack (important for batch undo)
  27.   SetLength(RedoStack, Length(RedoStack) + 1);
  28.   RedoStack[High(RedoStack)] := LastActions;
  29.  
  30.   // Revert all actions in the group
  31.   for i := 0 to High(LastActions) do
  32.   begin
  33.     Act := LastActions[i];
  34.     Form1.WorksheetGrid.Cells[Act.Col, Act.Row] := Act.OldValue;
  35.   end;
  36.  
  37.   // Optional: if you want the edit box to show the current (now old) value
  38.   if Length(LastActions) > 0 then
  39.   begin
  40.     Act := LastActions[High(LastActions)]; // last edited cell
  41.   end;
  42. end;
  43.  
  44. procedure Redo;
  45. var
  46.   LastActions: TUndoRedoList;
  47.   Act: TCellEdit_;
  48.   i: integer;
  49. begin
  50.   if Length(RedoStack) = 0 then Exit;
  51.  
  52.   // Pop the last group from redo
  53.   LastActions := RedoStack[High(RedoStack)];
  54.   SetLength(RedoStack, Length(RedoStack) - 1);
  55.  
  56.   // Push the whole group back to Undo stack
  57.   SetLength(UndoStack, Length(UndoStack) + 1);
  58.   UndoStack[High(UndoStack)] := LastActions;
  59.  
  60.   // Reapply all actions
  61.   for i := 0 to High(LastActions) do
  62.   begin
  63.     Act := LastActions[i];
  64.     Form1.WorksheetGrid.Cells[Act.Col, Act.Row] := Act.NewValue;
  65.   end;
  66.  
  67.   // Update edit box to show the new value of the last edited cell
  68.   if Length(LastActions) > 0 then
  69.   begin
  70.     Act := LastActions[High(LastActions)];
  71.   end;
  72. end;
  73.  
  74. procedure TForm1.WorksheetGridEditingDone(Sender: TObject);
  75. var
  76.   Action_: TCellEdit_;
  77.   CurrentValue: variant;
  78. begin
  79.   CurrentValue := WorksheetGrid.Cells[WorksheetGrid.Col, WorksheetGrid.Row];
  80.   edit1.Text := vartostr(OldCellValue);
  81.   // Only record if value actually changed
  82.   if vartostr(CurrentValue) <> vartostr(OldCellValue) then
  83.   begin
  84.     Action_.Row := WorksheetGrid.Row;
  85.     Action_.Col := WorksheetGrid.Col;
  86.     Action_.OldValue := OldCellValue;
  87.     Action_.NewValue := CurrentValue;
  88.  
  89.     // Add a new group containing this single edit
  90.     SetLength(UndoStack, Length(UndoStack) + 1);
  91.     SetLength(UndoStack[High(UndoStack)], 1);
  92.     UndoStack[High(UndoStack)][0] := Action_;
  93.  
  94.     // Clear redo stack when new edit is made (standard undo/redo behavior)
  95.     SetLength(RedoStack, 0);
  96.  
  97.     //ShowMessage('add data');
  98.   end;
  99. end;
  100.  
  101. procedure TForm1.WorksheetGridSelectCell(Sender: TObject; aCol, aRow: integer;
  102.   var CanSelect: boolean);
  103. begin
  104.   OldCellValue := WorksheetGrid.Cells[aCol, aRow];
  105.  
  106. end;
  107.  
  108.  
  109.  

i hope this one usable for others, cheers!

Thank you
« Last Edit: December 20, 2025, 02:42:12 am by Mongkey »

 

TinyPortal © 2005-2018