DefaultFileOperations.cs 5.8 KB

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