FileDialogHistory.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System.IO.Abstractions;
  2. namespace Terminal.Gui;
  3. internal class FileDialogHistory
  4. {
  5. private readonly Stack<FileDialogState> back = new ();
  6. private readonly FileDialog dlg;
  7. private readonly Stack<FileDialogState> forward = new ();
  8. public FileDialogHistory (FileDialog dlg) { this.dlg = dlg; }
  9. public bool Back ()
  10. {
  11. IDirectoryInfo goTo = null;
  12. FileSystemInfoStats restoreSelection = null;
  13. string restorePath = null;
  14. if (CanBack ())
  15. {
  16. FileDialogState backTo = back.Pop ();
  17. goTo = backTo.Directory;
  18. restoreSelection = backTo.Selected;
  19. restorePath = backTo.Path;
  20. }
  21. else if (CanUp ())
  22. {
  23. goTo = dlg.State?.Directory.Parent;
  24. }
  25. // nowhere to go
  26. if (goTo is null)
  27. {
  28. return false;
  29. }
  30. forward.Push (dlg.State);
  31. dlg.PushState (goTo, false, true, false, restorePath);
  32. if (restoreSelection is { })
  33. {
  34. dlg.RestoreSelection (restoreSelection.FileSystemInfo);
  35. }
  36. return true;
  37. }
  38. internal bool CanBack () { return back.Count > 0; }
  39. internal bool CanForward () { return forward.Count > 0; }
  40. internal bool CanUp () { return dlg.State?.Directory.Parent != null; }
  41. internal void ClearForward () { forward.Clear (); }
  42. internal bool Forward ()
  43. {
  44. if (forward.Count > 0)
  45. {
  46. dlg.PushState (forward.Pop ().Directory, true, true, false);
  47. return true;
  48. }
  49. return false;
  50. }
  51. internal void Push (FileDialogState state, bool clearForward)
  52. {
  53. if (state is null)
  54. {
  55. return;
  56. }
  57. // if changing to a new directory push onto the Back history
  58. if (back.Count == 0 || back.Peek ().Directory.FullName != state.Directory.FullName)
  59. {
  60. back.Push (state);
  61. if (clearForward)
  62. {
  63. ClearForward ();
  64. }
  65. }
  66. }
  67. internal bool Up ()
  68. {
  69. IDirectoryInfo parent = dlg.State?.Directory.Parent;
  70. if (parent is { })
  71. {
  72. back.Push (new FileDialogState (parent, dlg));
  73. dlg.PushState (parent, false);
  74. return true;
  75. }
  76. return false;
  77. }
  78. }