HexEditor.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using System.IO;
  2. using System.Text;
  3. using Terminal.Gui;
  4. namespace UICatalog.Scenarios;
  5. [ScenarioMetadata ("HexEditor", "A binary (hex) editor using the HexView control.")]
  6. [ScenarioCategory ("Controls")]
  7. [ScenarioCategory ("Dialogs")]
  8. [ScenarioCategory ("Text and Formatting")]
  9. [ScenarioCategory ("Top Level Windows")]
  10. [ScenarioCategory ("Files and IO")]
  11. public class HexEditor : Scenario
  12. {
  13. private string _fileName = "demo.bin";
  14. private HexView _hexView;
  15. private MenuItem _miAllowEdits;
  16. private bool _saved = true;
  17. private Shortcut _siPositionChanged;
  18. private StatusBar _statusBar;
  19. public override void Main ()
  20. {
  21. Application.Init ();
  22. Toplevel app = new Toplevel ()
  23. {
  24. ColorScheme = Colors.ColorSchemes ["Base"]
  25. };
  26. CreateDemoFile (_fileName);
  27. _hexView = new HexView (new MemoryStream (Encoding.UTF8.GetBytes ("Demo text.")))
  28. {
  29. X = 0,
  30. Y = 1,
  31. Width = Dim.Fill (),
  32. Height = Dim.Fill (1),
  33. Title = _fileName ?? "Untitled",
  34. BorderStyle = LineStyle.Rounded,
  35. };
  36. _hexView.Edited += _hexView_Edited;
  37. _hexView.PositionChanged += _hexView_PositionChanged;
  38. app.Add (_hexView);
  39. var menu = new MenuBar
  40. {
  41. Menus =
  42. [
  43. new MenuBarItem (
  44. "_File",
  45. new MenuItem []
  46. {
  47. new ("_New", "", () => New ()),
  48. new ("_Open", "", () => Open ()),
  49. new ("_Save", "", () => Save ()),
  50. null,
  51. new ("_Quit", "", () => Quit ())
  52. }
  53. ),
  54. new MenuBarItem (
  55. "_Edit",
  56. new MenuItem []
  57. {
  58. new ("_Copy", "", () => Copy ()),
  59. new ("C_ut", "", () => Cut ()),
  60. new ("_Paste", "", () => Paste ())
  61. }
  62. ),
  63. new MenuBarItem (
  64. "_Options",
  65. new []
  66. {
  67. _miAllowEdits = new MenuItem (
  68. "_AllowEdits",
  69. "",
  70. () => ToggleAllowEdits ()
  71. )
  72. {
  73. Checked = _hexView.AllowEdits,
  74. CheckType = MenuItemCheckStyle
  75. .Checked
  76. }
  77. }
  78. )
  79. ]
  80. };
  81. app.Add (menu);
  82. _statusBar = new StatusBar (
  83. new []
  84. {
  85. new (Key.F2, "Open", () => Open ()),
  86. new (Key.F3, "Save", () => Save ()),
  87. new (
  88. Application.QuitKey,
  89. $"Quit",
  90. () => Quit ()
  91. ),
  92. _siPositionChanged = new Shortcut (
  93. Key.Empty,
  94. $"Position: {
  95. _hexView.Position
  96. } Line: {
  97. _hexView.CursorPosition.Y
  98. } Col: {
  99. _hexView.CursorPosition.X
  100. } Line length: {
  101. _hexView.BytesPerLine
  102. }",
  103. () => { }
  104. )
  105. }
  106. )
  107. {
  108. AlignmentModes = AlignmentModes.IgnoreFirstOrLast
  109. };
  110. app.Add (_statusBar);
  111. _hexView.Source = LoadFile ();
  112. Application.Run (app);
  113. app.Dispose ();
  114. Application.Shutdown ();
  115. }
  116. private void _hexView_Edited (object sender, HexViewEditEventArgs e) { _saved = false; }
  117. private void _hexView_PositionChanged (object sender, HexViewEventArgs obj)
  118. {
  119. _siPositionChanged.Title =
  120. $"Position: {obj.Position} Line: {obj.CursorPosition.Y} Col: {obj.CursorPosition.X} Line length: {obj.BytesPerLine}";
  121. }
  122. private void Copy () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok"); }
  123. private void CreateDemoFile (string fileName)
  124. {
  125. var sb = new StringBuilder ();
  126. sb.Append ("Hello world.\n");
  127. sb.Append ("This is a test of the Emergency Broadcast System.\n");
  128. StreamWriter sw = File.CreateText (fileName);
  129. sw.Write (sb.ToString ());
  130. sw.Close ();
  131. }
  132. private void CreateUnicodeDemoFile (string fileName)
  133. {
  134. var sb = new StringBuilder ();
  135. sb.Append ("Hello world.\n");
  136. sb.Append ("This is a test of the Emergency Broadcast System.\n");
  137. byte [] buffer = Encoding.Unicode.GetBytes (sb.ToString ());
  138. var ms = new MemoryStream (buffer);
  139. var file = new FileStream (fileName, FileMode.Create, FileAccess.Write);
  140. ms.WriteTo (file);
  141. file.Close ();
  142. ms.Close ();
  143. }
  144. private void Cut () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok"); }
  145. private Stream LoadFile ()
  146. {
  147. var stream = new MemoryStream ();
  148. if (!_saved && _hexView.Edits.Count > 0)
  149. {
  150. if (MessageBox.ErrorQuery (
  151. "Save",
  152. "The changes were not saved. Want to open without saving?",
  153. "Yes",
  154. "No"
  155. )
  156. == 1)
  157. {
  158. return _hexView.Source;
  159. }
  160. _hexView.DiscardEdits ();
  161. _saved = true;
  162. }
  163. if (_fileName != null)
  164. {
  165. byte [] bin = File.ReadAllBytes (_fileName);
  166. stream.Write (bin);
  167. _hexView.Title = _fileName;
  168. _saved = true;
  169. }
  170. else
  171. {
  172. _hexView.Title = (_fileName ?? "Untitled");
  173. }
  174. return stream;
  175. }
  176. private void New ()
  177. {
  178. _fileName = null;
  179. _hexView.Source = LoadFile ();
  180. }
  181. private void Open ()
  182. {
  183. var d = new OpenDialog { Title = "Open", AllowsMultipleSelection = false };
  184. Application.Run (d);
  185. if (!d.Canceled)
  186. {
  187. _fileName = d.FilePaths [0];
  188. _hexView.Source = LoadFile ();
  189. _hexView.DisplayStart = 0;
  190. }
  191. d.Dispose ();
  192. }
  193. private void Paste () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok"); }
  194. private void Quit () { Application.RequestStop (); }
  195. private void Save ()
  196. {
  197. if (_fileName != null)
  198. {
  199. using (var fs = new FileStream (_fileName, FileMode.OpenOrCreate))
  200. {
  201. _hexView.ApplyEdits (fs);
  202. //_hexView.Source.Position = 0;
  203. //_hexView.Source.CopyTo (fs);
  204. //fs.Flush ();
  205. }
  206. _saved = true;
  207. }
  208. else
  209. {
  210. _hexView.ApplyEdits ();
  211. }
  212. }
  213. private void ToggleAllowEdits () { _hexView.AllowEdits = (bool)(_miAllowEdits.Checked = !_miAllowEdits.Checked); }
  214. }