HexEditor.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using Terminal.Gui;
  5. namespace UICatalog.Scenarios {
  6. [ScenarioMetadata (Name: "HexEditor", Description: "A Terminal.Gui binary (hex) editor via HexView")]
  7. [ScenarioCategory ("Controls")]
  8. [ScenarioCategory ("Dialogs")]
  9. [ScenarioCategory ("Text")]
  10. [ScenarioCategory ("Dialogs")]
  11. [ScenarioCategory ("TopLevel")]
  12. public class HexEditor : Scenario {
  13. private string _fileName = "demo.bin";
  14. private HexView _hexView;
  15. private bool _saved = true;
  16. private MenuItem miAllowEdits;
  17. private StatusItem siPositionChanged;
  18. private StatusBar statusBar;
  19. public override void Setup ()
  20. {
  21. Win.Title = this.GetName () + "-" + _fileName ?? "Untitled";
  22. CreateDemoFile (_fileName);
  23. //CreateUnicodeDemoFile (_fileName);
  24. _hexView = new HexView (LoadFile ()) {
  25. X = 0,
  26. Y = 0,
  27. Width = Dim.Fill (),
  28. Height = Dim.Fill (),
  29. };
  30. _hexView.Edited += _hexView_Edited;
  31. _hexView.PositionChanged += _hexView_PositionChanged;
  32. Win.Add (_hexView);
  33. var menu = new MenuBar (new MenuBarItem [] {
  34. new MenuBarItem ("_File", new MenuItem [] {
  35. new MenuItem ("_New", "", () => New()),
  36. new MenuItem ("_Open", "", () => Open()),
  37. new MenuItem ("_Save", "", () => Save()),
  38. null,
  39. new MenuItem ("_Quit", "", () => Quit()),
  40. }),
  41. new MenuBarItem ("_Edit", new MenuItem [] {
  42. new MenuItem ("_Copy", "", () => Copy()),
  43. new MenuItem ("C_ut", "", () => Cut()),
  44. new MenuItem ("_Paste", "", () => Paste())
  45. }),
  46. new MenuBarItem ("_Options", new MenuItem [] {
  47. miAllowEdits = new MenuItem ("_AllowEdits", "", () => ToggleAllowEdits ()){Checked = _hexView.AllowEdits, CheckType = MenuItemCheckStyle.Checked}
  48. })
  49. });
  50. Top.Add (menu);
  51. statusBar = new StatusBar (new StatusItem [] {
  52. new StatusItem(Key.F2, "~F2~ Open", () => Open()),
  53. new StatusItem(Key.F3, "~F3~ Save", () => Save()),
  54. new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Quit()),
  55. siPositionChanged = new StatusItem(Key.Null,
  56. $"Position: {_hexView.Position} Line: {_hexView.CursorPosition.Y} Col: {_hexView.CursorPosition.X} Line length: {_hexView.BytesPerLine}", () => {})
  57. });
  58. Top.Add (statusBar);
  59. }
  60. private void _hexView_PositionChanged (HexView.HexViewEventArgs obj)
  61. {
  62. siPositionChanged.Title = $"Position: {obj.Position} Line: {obj.CursorPosition.Y} Col: {obj.CursorPosition.X} Line length: {obj.BytesPerLine}";
  63. statusBar.SetNeedsDisplay ();
  64. }
  65. private void ToggleAllowEdits ()
  66. {
  67. _hexView.AllowEdits = miAllowEdits.Checked = !miAllowEdits.Checked;
  68. }
  69. private void _hexView_Edited (System.Collections.Generic.KeyValuePair<long, byte> obj)
  70. {
  71. _saved = false;
  72. }
  73. private void New ()
  74. {
  75. _fileName = null;
  76. _hexView.Source = LoadFile ();
  77. }
  78. private Stream LoadFile ()
  79. {
  80. MemoryStream stream = new MemoryStream ();
  81. if (!_saved && _hexView != null && _hexView.Edits.Count > 0) {
  82. if (MessageBox.ErrorQuery ("Save", "The changes were not saved. Want to open without saving?", "Yes", "No") == 1)
  83. return _hexView.Source;
  84. _hexView.DiscardEdits ();
  85. _saved = true;
  86. }
  87. if (_fileName != null) {
  88. var bin = System.IO.File.ReadAllBytes (_fileName);
  89. stream.Write (bin);
  90. Win.Title = this.GetName () + "-" + _fileName;
  91. _saved = true;
  92. } else {
  93. Win.Title = this.GetName () + "-" + (_fileName ?? "Untitled");
  94. }
  95. return stream;
  96. }
  97. private void Paste ()
  98. {
  99. MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
  100. }
  101. private void Cut ()
  102. {
  103. MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
  104. }
  105. private void Copy ()
  106. {
  107. MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
  108. }
  109. private void Open ()
  110. {
  111. var d = new OpenDialog ("Open", "Open a file") { AllowsMultipleSelection = false };
  112. Application.Run (d);
  113. if (!d.Canceled) {
  114. _fileName = d.FilePaths [0];
  115. _hexView.Source = LoadFile ();
  116. _hexView.DisplayStart = 0;
  117. }
  118. }
  119. private void Save ()
  120. {
  121. if (_fileName != null) {
  122. using (FileStream fs = new FileStream (_fileName, FileMode.OpenOrCreate)) {
  123. _hexView.ApplyEdits (fs);
  124. //_hexView.Source.Position = 0;
  125. //_hexView.Source.CopyTo (fs);
  126. //fs.Flush ();
  127. }
  128. _saved = true;
  129. } else {
  130. _hexView.ApplyEdits ();
  131. }
  132. }
  133. private void Quit ()
  134. {
  135. Application.RequestStop ();
  136. }
  137. private void CreateDemoFile (string fileName)
  138. {
  139. var sb = new StringBuilder ();
  140. sb.Append ("Hello world.\n");
  141. sb.Append ("This is a test of the Emergency Broadcast System.\n");
  142. var sw = System.IO.File.CreateText (fileName);
  143. sw.Write (sb.ToString ());
  144. sw.Close ();
  145. }
  146. private void CreateUnicodeDemoFile (string fileName)
  147. {
  148. var sb = new StringBuilder ();
  149. sb.Append ("Hello world.\n");
  150. sb.Append ("This is a test of the Emergency Broadcast System.\n");
  151. byte [] buffer = Encoding.Unicode.GetBytes (sb.ToString());
  152. MemoryStream ms = new MemoryStream (buffer);
  153. FileStream file = new FileStream (fileName, FileMode.Create, FileAccess.Write);
  154. ms.WriteTo (file);
  155. file.Close ();
  156. ms.Close ();
  157. }
  158. }
  159. }