2
0

FileDialogExamples.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. using System.IO.Abstractions;
  2. namespace UICatalog.Scenarios;
  3. [ScenarioMetadata ("FileDialog", "Demonstrates how to the FileDialog class")]
  4. [ScenarioCategory ("Dialogs")]
  5. [ScenarioCategory ("Files and IO")]
  6. public class FileDialogExamples : Scenario
  7. {
  8. private CheckBox _cbAllowMultipleSelection;
  9. private CheckBox _cbAlwaysTableShowHeaders;
  10. private CheckBox _cbCaseSensitive;
  11. private CheckBox _cbDrivesOnlyInTree;
  12. private CheckBox _cbPreserveFilenameOnDirectoryChanges;
  13. private CheckBox _cbFlipButtonOrder;
  14. private CheckBox _cbMustExist;
  15. private CheckBox _cbShowTreeBranchLines;
  16. private CheckBox _cbUseColors;
  17. private OptionSelector _osAllowedTypes;
  18. private OptionSelector _osCaption;
  19. private OptionSelector _osIcons;
  20. private OptionSelector _osOpenMode;
  21. private TextField _tbCancelButton;
  22. private TextField _tbOkButton;
  23. public override void Main ()
  24. {
  25. Application.Init ();
  26. var y = 0;
  27. var x = 1;
  28. var win = new Window { Title = GetQuitKeyAndName () };
  29. _cbMustExist = new () { CheckedState = CheckState.Checked, Y = y++, X = x, Text = "Must E_xist" };
  30. win.Add (_cbMustExist);
  31. _cbUseColors = new ()
  32. { CheckedState = FileDialogStyle.DefaultUseColors ? CheckState.Checked : CheckState.UnChecked, Y = y++, X = x, Text = "_Use Colors" };
  33. win.Add (_cbUseColors);
  34. _cbCaseSensitive = new () { CheckedState = CheckState.UnChecked, Y = y++, X = x, Text = "_Case Sensitive Search" };
  35. win.Add (_cbCaseSensitive);
  36. _cbAllowMultipleSelection = new () { CheckedState = CheckState.UnChecked, Y = y++, X = x, Text = "_Multiple" };
  37. win.Add (_cbAllowMultipleSelection);
  38. _cbShowTreeBranchLines = new () { CheckedState = CheckState.Checked, Y = y++, X = x, Text = "Tree Branch _Lines" };
  39. win.Add (_cbShowTreeBranchLines);
  40. _cbAlwaysTableShowHeaders = new () { CheckedState = CheckState.Checked, Y = y++, X = x, Text = "Always Show _Headers" };
  41. win.Add (_cbAlwaysTableShowHeaders);
  42. _cbDrivesOnlyInTree = new () { CheckedState = CheckState.UnChecked, Y = y++, X = x, Text = "Only Show _Drives" };
  43. win.Add (_cbDrivesOnlyInTree);
  44. _cbPreserveFilenameOnDirectoryChanges = new () { CheckedState = CheckState.UnChecked, Y = y++, X = x, Text = "Preserve Filename" };
  45. win.Add (_cbPreserveFilenameOnDirectoryChanges);
  46. y = 0;
  47. x = 24;
  48. win.Add (
  49. new Line { Orientation = Orientation.Vertical, X = x++, Y = 1, Height = 4 }
  50. );
  51. win.Add (new Label { X = x++, Y = y++, Text = "Caption" });
  52. _osCaption = new () { X = x, Y = y };
  53. _osCaption.Labels = ["_Ok", "O_pen", "_Save"];
  54. win.Add (_osCaption);
  55. y = 0;
  56. x = 34;
  57. win.Add (
  58. new Line { Orientation = Orientation.Vertical, X = x++, Y = 1, Height = 4 }
  59. );
  60. win.Add (new Label { X = x++, Y = y++, Text = "OpenMode" });
  61. _osOpenMode = new () { X = x, Y = y };
  62. _osOpenMode.Labels = ["_File", "D_irectory", "_Mixed"];
  63. win.Add (_osOpenMode);
  64. y = 0;
  65. x = 48;
  66. win.Add (
  67. new Line { Orientation = Orientation.Vertical, X = x++, Y = 1, Height = 4 }
  68. );
  69. win.Add (new Label { X = x++, Y = y++, Text = "Icons" });
  70. _osIcons = new () { X = x, Y = y };
  71. _osIcons.Labels = ["_None", "_Unicode", "Nerd_*"];
  72. win.Add (_osIcons);
  73. win.Add (new Label { Y = Pos.AnchorEnd (2), Text = "* Requires installing Nerd fonts" });
  74. win.Add (new Label { Y = Pos.AnchorEnd (1), Text = " (see: https://github.com/devblackops/Terminal-Icons)" });
  75. y = 5;
  76. x = 24;
  77. win.Add (
  78. new Line { Orientation = Orientation.Vertical, X = x++, Y = y + 1, Height = 4 }
  79. );
  80. win.Add (new Label { X = x++, Y = y++, Text = "Allowed" });
  81. _osAllowedTypes = new () { X = x, Y = y };
  82. _osAllowedTypes.Labels = ["An_y", "Cs_v (Recommended)", "Csv (S_trict)"];
  83. win.Add (_osAllowedTypes);
  84. y = 5;
  85. x = 45;
  86. win.Add (
  87. new Line { Orientation = Orientation.Vertical, X = x++, Y = y + 1, Height = 4 }
  88. );
  89. win.Add (new Label { X = x++, Y = y++, Text = "Buttons" });
  90. win.Add (new Label { X = x, Y = y++, Text = "O_k Text:" });
  91. _tbOkButton = new () { X = x, Y = y++, Width = 12 };
  92. win.Add (_tbOkButton);
  93. win.Add (new Label { X = x, Y = y++, Text = "_Cancel Text:" });
  94. _tbCancelButton = new () { X = x, Y = y++, Width = 12 };
  95. win.Add (_tbCancelButton);
  96. _cbFlipButtonOrder = new () { X = x, Y = y++, Text = "Flip Ord_er" };
  97. win.Add (_cbFlipButtonOrder);
  98. var btn = new Button { X = 1, Y = 9, IsDefault = true, Text = "Run Dialog" };
  99. win.Accepting += (s, e) =>
  100. {
  101. try
  102. {
  103. CreateDialog ();
  104. }
  105. catch (Exception ex)
  106. {
  107. MessageBox.ErrorQuery (Application.Instance, "Error", ex.ToString (), "_Ok");
  108. }
  109. finally
  110. {
  111. e.Handled = true;
  112. }
  113. };
  114. win.Add (btn);
  115. Application.Run (win);
  116. win.Dispose ();
  117. Application.Shutdown ();
  118. }
  119. private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e)
  120. {
  121. if (!string.IsNullOrWhiteSpace (e.Dialog.Path))
  122. {
  123. if (File.Exists (e.Dialog.Path))
  124. {
  125. int? result = MessageBox.Query (Application.Instance, "Overwrite?", "File already exists", "_Yes", "_No");
  126. e.Cancel = result == 1;
  127. }
  128. }
  129. }
  130. private void CreateDialog ()
  131. {
  132. if (_osOpenMode.Value is { })
  133. {
  134. var fd = new FileDialog
  135. {
  136. OpenMode = Enum.Parse<OpenMode> (
  137. _osOpenMode.Labels
  138. .Select (l => TextFormatter.FindHotKey (l, _osOpenMode.HotKeySpecifier, out int hotPos, out Key _)
  139. // Remove the hotkey specifier at the found position
  140. ? TextFormatter.RemoveHotKeySpecifier (l, hotPos, _osOpenMode.HotKeySpecifier)
  141. // No hotkey found, return the label as is
  142. : l)
  143. .ToArray () [_osOpenMode.Value.Value]
  144. ),
  145. MustExist = _cbMustExist.CheckedState == CheckState.Checked,
  146. AllowsMultipleSelection = _cbAllowMultipleSelection.CheckedState == CheckState.Checked
  147. };
  148. fd.Style.OkButtonText =
  149. _osCaption.Labels.Select (l => TextFormatter.RemoveHotKeySpecifier (l, 0, _osCaption.HotKeySpecifier)).ToArray ()
  150. [_osCaption.Value!.Value];
  151. // If Save style dialog then give them an overwrite prompt
  152. if (_osCaption.Value == 2)
  153. {
  154. fd.FilesSelected += ConfirmOverwrite;
  155. }
  156. fd.Style.IconProvider.UseUnicodeCharacters = _osIcons.Value == 1;
  157. fd.Style.IconProvider.UseNerdIcons = _osIcons.Value == 2;
  158. if (_cbCaseSensitive.CheckedState == CheckState.Checked)
  159. {
  160. fd.SearchMatcher = new CaseSensitiveSearchMatcher ();
  161. }
  162. fd.Style.UseColors = _cbUseColors.CheckedState == CheckState.Checked;
  163. fd.Style.TreeStyle.ShowBranchLines = _cbShowTreeBranchLines.CheckedState == CheckState.Checked;
  164. fd.Style.TableStyle.AlwaysShowHeaders = _cbAlwaysTableShowHeaders.CheckedState == CheckState.Checked;
  165. IDirectoryInfoFactory dirInfoFactory = new FileSystem ().DirectoryInfo;
  166. if (_cbDrivesOnlyInTree.CheckedState == CheckState.Checked)
  167. {
  168. fd.Style.TreeRootGetter = () => { return Environment.GetLogicalDrives ().ToDictionary (dirInfoFactory.New, k => k); };
  169. }
  170. fd.Style.PreserveFilenameOnDirectoryChanges = _cbPreserveFilenameOnDirectoryChanges.CheckedState == CheckState.Checked;
  171. if (_osAllowedTypes.Value > 0)
  172. {
  173. fd.AllowedTypes.Add (new AllowedType ("Data File", ".csv", ".tsv"));
  174. if (_osAllowedTypes.Value == 1)
  175. {
  176. fd.AllowedTypes.Insert (1, new AllowedTypeAny ());
  177. }
  178. }
  179. if (!string.IsNullOrWhiteSpace (_tbOkButton.Text))
  180. {
  181. fd.Style.OkButtonText = _tbOkButton.Text;
  182. }
  183. if (!string.IsNullOrWhiteSpace (_tbCancelButton.Text))
  184. {
  185. fd.Style.CancelButtonText = _tbCancelButton.Text;
  186. }
  187. if (_cbFlipButtonOrder.CheckedState == CheckState.Checked)
  188. {
  189. fd.Style.FlipOkCancelButtonLayoutOrder = true;
  190. }
  191. Application.Run (fd);
  192. bool canceled = fd.Canceled;
  193. IReadOnlyList<string> multiSelected = fd.MultiSelected;
  194. string path = fd.Path;
  195. // This needs to be disposed before opening other runnable
  196. fd.Dispose ();
  197. if (canceled)
  198. {
  199. MessageBox.Query (Application.Instance,
  200. "Canceled",
  201. "You canceled navigation and did not pick anything",
  202. "Ok"
  203. );
  204. }
  205. else if (_cbAllowMultipleSelection.CheckedState == CheckState.Checked)
  206. {
  207. MessageBox.Query (Application.Instance,
  208. "Chosen!",
  209. "You chose:" + Environment.NewLine + string.Join (Environment.NewLine, multiSelected.Select (m => m)),
  210. "Ok"
  211. );
  212. }
  213. else
  214. {
  215. MessageBox.Query (Application.Instance,
  216. "Chosen!",
  217. "You chose:" + Environment.NewLine + path,
  218. "Ok"
  219. );
  220. }
  221. }
  222. }
  223. private class CaseSensitiveSearchMatcher : ISearchMatcher
  224. {
  225. private string _terms;
  226. public void Initialize (string terms) { _terms = terms; }
  227. public bool IsMatch (IFileSystemInfo f) { return f.Name.Contains (_terms, StringComparison.CurrentCulture); }
  228. }
  229. }