DefaultFileOperations.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.IO.Abstractions;
  5. using System.Linq;
  6. using Terminal.Gui.Resources;
  7. namespace Terminal.Gui {
  8. /// <summary>
  9. /// Default file operation handlers using modal dialogs.
  10. /// </summary>
  11. public class DefaultFileOperations : IFileOperations {
  12. /// <inheritdoc/>
  13. public bool Delete (IEnumerable<IFileSystemInfo> toDelete)
  14. {
  15. // Default implementation does not allow deleting multiple files
  16. if (toDelete.Count () != 1) {
  17. return false;
  18. }
  19. var d = toDelete.Single ();
  20. var adjective = d.Name;
  21. int result = MessageBox.Query (
  22. string.Format (Strings.fdDeleteTitle, adjective),
  23. string.Format (Strings.fdDeleteBody, adjective),
  24. Strings.fdYes, Strings.fdNo);
  25. try {
  26. if (result == 0) {
  27. if (d is IFileInfo) {
  28. d.Delete ();
  29. } else {
  30. ((IDirectoryInfo)d).Delete (true);
  31. }
  32. return true;
  33. }
  34. } catch (Exception ex) {
  35. MessageBox.ErrorQuery (Strings.fdDeleteFailedTitle, ex.Message, "Ok");
  36. }
  37. return false;
  38. }
  39. private bool Prompt (string title, string defaultText, out string result)
  40. {
  41. bool confirm = false;
  42. var btnOk = new Button ("Ok") {
  43. IsDefault = true,
  44. };
  45. btnOk.Clicked += (s, e) => {
  46. confirm = true;
  47. Application.RequestStop ();
  48. };
  49. var btnCancel = new Button ("Cancel");
  50. btnCancel.Clicked += (s, e) => {
  51. confirm = false;
  52. Application.RequestStop ();
  53. };
  54. var lbl = new Label (Strings.fdRenamePrompt);
  55. var tf = new TextField (defaultText) {
  56. X = Pos.Right (lbl),
  57. Width = Dim.Fill (),
  58. };
  59. tf.SelectAll ();
  60. var dlg = new Dialog (title) {
  61. Width = Dim.Percent (50),
  62. Height = 4
  63. };
  64. dlg.Add (lbl);
  65. dlg.Add (tf);
  66. // Add buttons last so tab order is friendly
  67. // and TextField gets focus
  68. dlg.AddButton (btnOk);
  69. dlg.AddButton (btnCancel);
  70. Application.Run (dlg);
  71. result = tf.Text?.ToString ();
  72. return confirm;
  73. }
  74. /// <inheritdoc/>
  75. public IFileSystemInfo Rename (IFileSystem fileSystem, IFileSystemInfo toRename)
  76. {
  77. // Don't allow renaming C: or D: or / (on linux) etc
  78. if (toRename is IDirectoryInfo dir && dir.Parent == null) {
  79. return null;
  80. }
  81. if (Prompt (Strings.fdRenameTitle, toRename.Name, out var newName)) {
  82. if (!string.IsNullOrWhiteSpace (newName)) {
  83. try {
  84. if (toRename is IFileInfo f) {
  85. var newLocation = fileSystem.FileInfo.New (Path.Combine (f.Directory.FullName, newName));
  86. f.MoveTo (newLocation.FullName);
  87. return newLocation;
  88. } else {
  89. var d = (IDirectoryInfo)toRename;
  90. var newLocation = fileSystem.DirectoryInfo.New (Path.Combine (d.Parent.FullName, newName));
  91. d.MoveTo (newLocation.FullName);
  92. return newLocation;
  93. }
  94. } catch (Exception ex) {
  95. MessageBox.ErrorQuery (Strings.fdRenameFailedTitle, ex.Message, "Ok");
  96. }
  97. }
  98. }
  99. return null;
  100. }
  101. /// <inheritdoc/>
  102. public IFileSystemInfo New (IFileSystem fileSystem, IDirectoryInfo inDirectory)
  103. {
  104. if (Prompt (Strings.fdNewTitle, "", out var named)) {
  105. if (!string.IsNullOrWhiteSpace (named)) {
  106. try {
  107. var newDir = fileSystem.DirectoryInfo.New (Path.Combine (inDirectory.FullName, named));
  108. newDir.Create ();
  109. return newDir;
  110. } catch (Exception ex) {
  111. MessageBox.ErrorQuery (Strings.fdNewFailed, ex.Message, "Ok");
  112. }
  113. }
  114. }
  115. return null;
  116. }
  117. }
  118. }