FileDialogExamples.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.IO;
  3. using System.IO.Abstractions;
  4. using System.Linq;
  5. using Terminal.Gui;
  6. namespace UICatalog.Scenarios;
  7. [ScenarioMetadata ("FileDialog", "Demonstrates how to the FileDialog class")]
  8. [ScenarioCategory ("Dialogs")]
  9. [ScenarioCategory ("Files and IO")]
  10. public class FileDialogExamples : Scenario
  11. {
  12. private CheckBox _cbAllowMultipleSelection;
  13. private CheckBox _cbAlwaysTableShowHeaders;
  14. private CheckBox _cbCaseSensitive;
  15. private CheckBox _cbDrivesOnlyInTree;
  16. private CheckBox _cbFlipButtonOrder;
  17. private CheckBox _cbMustExist;
  18. private CheckBox _cbShowTreeBranchLines;
  19. private CheckBox _cbUseColors;
  20. private RadioGroup _rgAllowedTypes;
  21. private RadioGroup _rgCaption;
  22. private RadioGroup _rgIcons;
  23. private RadioGroup _rgOpenMode;
  24. private TextField _tbCancelButton;
  25. private TextField _tbOkButton;
  26. public override void Setup ()
  27. {
  28. var y = 0;
  29. var x = 1;
  30. _cbMustExist = new CheckBox { Checked = true, Y = y++, X = x, Text = "Must Exist" };
  31. Win.Add (_cbMustExist);
  32. _cbUseColors = new CheckBox { Checked = FileDialogStyle.DefaultUseColors, Y = y++, X = x, Text = "Use Colors" };
  33. Win.Add (_cbUseColors);
  34. _cbCaseSensitive = new CheckBox { Checked = false, Y = y++, X = x, Text = "Case Sensitive Search" };
  35. Win.Add (_cbCaseSensitive);
  36. _cbAllowMultipleSelection = new CheckBox { Checked = false, Y = y++, X = x, Text = "Multiple" };
  37. Win.Add (_cbAllowMultipleSelection);
  38. _cbShowTreeBranchLines = new CheckBox { Checked = true, Y = y++, X = x, Text = "Tree Branch Lines" };
  39. Win.Add (_cbShowTreeBranchLines);
  40. _cbAlwaysTableShowHeaders = new CheckBox { Checked = true, Y = y++, X = x, Text = "Always Show Headers" };
  41. Win.Add (_cbAlwaysTableShowHeaders);
  42. _cbDrivesOnlyInTree = new CheckBox { Checked = false, Y = y++, X = x, Text = "Only Show Drives" };
  43. Win.Add (_cbDrivesOnlyInTree);
  44. y = 0;
  45. x = 24;
  46. Win.Add (
  47. new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
  48. );
  49. Win.Add (new Label { X = x++, Y = y++, Text = "Caption" });
  50. _rgCaption = new RadioGroup { X = x, Y = y };
  51. _rgCaption.RadioLabels = new [] { "Ok", "Open", "Save" };
  52. Win.Add (_rgCaption);
  53. y = 0;
  54. x = 34;
  55. Win.Add (
  56. new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
  57. );
  58. Win.Add (new Label { X = x++, Y = y++, Text = "OpenMode" });
  59. _rgOpenMode = new RadioGroup { X = x, Y = y };
  60. _rgOpenMode.RadioLabels = new [] { "File", "Directory", "Mixed" };
  61. Win.Add (_rgOpenMode);
  62. y = 0;
  63. x = 48;
  64. Win.Add (
  65. new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
  66. );
  67. Win.Add (new Label { X = x++, Y = y++, Text = "Icons" });
  68. _rgIcons = new RadioGroup { X = x, Y = y };
  69. _rgIcons.RadioLabels = new [] { "None", "Unicode", "Nerd*" };
  70. Win.Add (_rgIcons);
  71. Win.Add (new Label { Y = Pos.AnchorEnd (2), Text = "* Requires installing Nerd fonts" });
  72. Win.Add (new Label { Y = Pos.AnchorEnd (1), Text = " (see: https://github.com/devblackops/Terminal-Icons)" });
  73. y = 5;
  74. x = 24;
  75. Win.Add (
  76. new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
  77. );
  78. Win.Add (new Label { X = x++, Y = y++, Text = "Allowed" });
  79. _rgAllowedTypes = new RadioGroup { X = x, Y = y };
  80. _rgAllowedTypes.RadioLabels = new [] { "Any", "Csv (Recommended)", "Csv (Strict)" };
  81. Win.Add (_rgAllowedTypes);
  82. y = 5;
  83. x = 45;
  84. Win.Add (
  85. new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
  86. );
  87. Win.Add (new Label { X = x++, Y = y++, Text = "Buttons" });
  88. Win.Add (new Label { X = x, Y = y++, Text = "Ok Text:" });
  89. _tbOkButton = new TextField { X = x, Y = y++, Width = 12 };
  90. Win.Add (_tbOkButton);
  91. Win.Add (new Label { X = x, Y = y++, Text = "Cancel Text:" });
  92. _tbCancelButton = new TextField { X = x, Y = y++, Width = 12 };
  93. Win.Add (_tbCancelButton);
  94. _cbFlipButtonOrder = new CheckBox { X = x, Y = y++, Text = "Flip Order" };
  95. Win.Add (_cbFlipButtonOrder);
  96. var btn = new Button { X = 1, Y = 9, Text = "Run Dialog" };
  97. SetupHandler (btn);
  98. Win.Add (btn);
  99. }
  100. private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e)
  101. {
  102. if (!string.IsNullOrWhiteSpace (e.Dialog.Path))
  103. {
  104. if (File.Exists (e.Dialog.Path))
  105. {
  106. int result = MessageBox.Query ("Overwrite?", "File already exists", "Yes", "No");
  107. e.Cancel = result == 1;
  108. }
  109. }
  110. }
  111. private void CreateDialog ()
  112. {
  113. var fd = new FileDialog
  114. {
  115. OpenMode = Enum.Parse<OpenMode> (
  116. _rgOpenMode.RadioLabels [_rgOpenMode.SelectedItem]
  117. ),
  118. MustExist = _cbMustExist.Checked ?? false,
  119. AllowsMultipleSelection = _cbAllowMultipleSelection.Checked ?? false
  120. };
  121. fd.Style.OkButtonText = _rgCaption.RadioLabels [_rgCaption.SelectedItem];
  122. // If Save style dialog then give them an overwrite prompt
  123. if (_rgCaption.SelectedItem == 2)
  124. {
  125. fd.FilesSelected += ConfirmOverwrite;
  126. }
  127. fd.Style.IconProvider.UseUnicodeCharacters = _rgIcons.SelectedItem == 1;
  128. fd.Style.IconProvider.UseNerdIcons = _rgIcons.SelectedItem == 2;
  129. if (_cbCaseSensitive.Checked ?? false)
  130. {
  131. fd.SearchMatcher = new CaseSensitiveSearchMatcher ();
  132. }
  133. fd.Style.UseColors = _cbUseColors.Checked ?? false;
  134. fd.Style.TreeStyle.ShowBranchLines = _cbShowTreeBranchLines.Checked ?? false;
  135. fd.Style.TableStyle.AlwaysShowHeaders = _cbAlwaysTableShowHeaders.Checked ?? false;
  136. IDirectoryInfoFactory dirInfoFactory = new FileSystem ().DirectoryInfo;
  137. if (_cbDrivesOnlyInTree.Checked ?? false)
  138. {
  139. fd.Style.TreeRootGetter = () => { return Environment.GetLogicalDrives ().ToDictionary (dirInfoFactory.New, k => k); };
  140. }
  141. if (_rgAllowedTypes.SelectedItem > 0)
  142. {
  143. fd.AllowedTypes.Add (new AllowedType ("Data File", ".csv", ".tsv"));
  144. if (_rgAllowedTypes.SelectedItem == 1)
  145. {
  146. fd.AllowedTypes.Insert (1, new AllowedTypeAny ());
  147. }
  148. }
  149. if (!string.IsNullOrWhiteSpace (_tbOkButton.Text))
  150. {
  151. fd.Style.OkButtonText = _tbOkButton.Text;
  152. }
  153. if (!string.IsNullOrWhiteSpace (_tbCancelButton.Text))
  154. {
  155. fd.Style.CancelButtonText = _tbCancelButton.Text;
  156. }
  157. if (_cbFlipButtonOrder.Checked ?? false)
  158. {
  159. fd.Style.FlipOkCancelButtonLayoutOrder = true;
  160. }
  161. Application.Run (fd);
  162. var canceled = fd.Canceled;
  163. var multiSelected = fd.MultiSelected;
  164. var path = fd.Path;
  165. // This needs to be disposed before opening other toplevel
  166. fd.Dispose ();
  167. if (canceled)
  168. {
  169. MessageBox.Query (
  170. "Canceled",
  171. "You canceled navigation and did not pick anything",
  172. "Ok"
  173. );
  174. }
  175. else if (_cbAllowMultipleSelection.Checked ?? false)
  176. {
  177. MessageBox.Query (
  178. "Chosen!",
  179. "You chose:" + Environment.NewLine + string.Join (Environment.NewLine, multiSelected.Select (m => m)),
  180. "Ok"
  181. );
  182. }
  183. else
  184. {
  185. MessageBox.Query (
  186. "Chosen!",
  187. "You chose:" + Environment.NewLine + path,
  188. "Ok"
  189. );
  190. }
  191. }
  192. private void SetupHandler (Button btn)
  193. {
  194. btn.Accept += (s, e) =>
  195. {
  196. try
  197. {
  198. CreateDialog ();
  199. }
  200. catch (Exception ex)
  201. {
  202. MessageBox.ErrorQuery ("Error", ex.ToString (), "Ok");
  203. }
  204. };
  205. }
  206. private class CaseSensitiveSearchMatcher : ISearchMatcher
  207. {
  208. private string _terms;
  209. public void Initialize (string terms) { _terms = terms; }
  210. public bool IsMatch (IFileSystemInfo f) { return f.Name.Contains (_terms, StringComparison.CurrentCulture); }
  211. }
  212. }