2
0

DefaultFileOperations.cs 5.8 KB

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