You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

LogForm.cs 10 kB

9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. using System;
  2. using System.Drawing;
  3. using System.IO;
  4. using System.Windows.Forms;
  5. using Shadowsocks.Controller;
  6. using Shadowsocks.Properties;
  7. using Shadowsocks.Model;
  8. using Shadowsocks.Util;
  9. namespace Shadowsocks.View
  10. {
  11. public partial class LogForm : Form
  12. {
  13. long lastOffset;
  14. string filename;
  15. Timer timer;
  16. const int BACK_OFFSET = 65536;
  17. ShadowsocksController controller;
  18. public LogForm(ShadowsocksController controller, string filename)
  19. {
  20. this.controller = controller;
  21. this.filename = filename;
  22. InitializeComponent();
  23. Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
  24. LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
  25. if (config == null)
  26. {
  27. config = new LogViewerConfig();
  28. }
  29. else {
  30. topMostTrigger = config.topMost;
  31. wrapTextTrigger = config.wrapText;
  32. toolbarTrigger = config.toolbarShown;
  33. LogMessageTextBox.BackColor = config.GetBackgroundColor();
  34. LogMessageTextBox.ForeColor = config.GetTextColor();
  35. LogMessageTextBox.Font = config.GetFont();
  36. }
  37. UpdateTexts();
  38. }
  39. private void UpdateTexts()
  40. {
  41. FileMenuItem.Text = I18N.GetString("&File");
  42. OpenLocationMenuItem.Text = I18N.GetString("&Open Location");
  43. ExitMenuItem.Text = I18N.GetString("E&xit");
  44. CleanLogsButton.Text = I18N.GetString("&Clean Logs");
  45. ChangeFontButton.Text = I18N.GetString("Change &Font");
  46. WrapTextCheckBox.Text = I18N.GetString("&Wrap Text");
  47. TopMostCheckBox.Text = I18N.GetString("&Top Most");
  48. ViewMenuItem.Text = I18N.GetString("&View");
  49. CleanLogsMenuItem.Text = I18N.GetString("&Clean Logs");
  50. ChangeFontMenuItem.Text = I18N.GetString("Change &Font");
  51. WrapTextMenuItem.Text = I18N.GetString("&Wrap Text");
  52. TopMostMenuItem.Text = I18N.GetString("&Top Most");
  53. ShowToolbarMenuItem.Text = I18N.GetString("&Show Toolbar");
  54. Text = I18N.GetString("Log Viewer");
  55. }
  56. private void Timer_Tick(object sender, EventArgs e)
  57. {
  58. UpdateContent();
  59. }
  60. private void InitContent()
  61. {
  62. using (StreamReader reader = new StreamReader(new FileStream(filename,
  63. FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
  64. {
  65. if (reader.BaseStream.Length > BACK_OFFSET)
  66. {
  67. reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End);
  68. reader.ReadLine();
  69. }
  70. string line = "";
  71. while ((line = reader.ReadLine()) != null)
  72. LogMessageTextBox.AppendText(line + Environment.NewLine);
  73. LogMessageTextBox.ScrollToCaret();
  74. lastOffset = reader.BaseStream.Position;
  75. }
  76. }
  77. private void UpdateContent()
  78. {
  79. using (StreamReader reader = new StreamReader(new FileStream(filename,
  80. FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
  81. {
  82. reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin);
  83. string line = "";
  84. bool changed = false;
  85. while ((line = reader.ReadLine()) != null)
  86. {
  87. changed = true;
  88. LogMessageTextBox.AppendText(line + Environment.NewLine);
  89. }
  90. if (changed)
  91. {
  92. LogMessageTextBox.ScrollToCaret();
  93. }
  94. lastOffset = reader.BaseStream.Position;
  95. }
  96. this.Text = $"Log Viewer [in: {Utils.FormatBandwide(controller.inboundCounter)}, out: {Utils.FormatBandwide(controller.outboundCounter)}]";
  97. }
  98. private void LogForm_Load(object sender, EventArgs e)
  99. {
  100. InitContent();
  101. timer = new Timer();
  102. timer.Interval = 300;
  103. timer.Tick += Timer_Tick;
  104. timer.Start();
  105. LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
  106. if (config == null)
  107. config = new LogViewerConfig();
  108. Height = config.height;
  109. Width = config.width;
  110. Top = config.GetBestTop();
  111. Left = config.GetBestLeft();
  112. topMostTriggerLock = true;
  113. TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
  114. topMostTriggerLock = false;
  115. wrapTextTriggerLock = true;
  116. LogMessageTextBox.WordWrap = WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
  117. wrapTextTriggerLock = false;
  118. ToolbarFlowLayoutPanel.Visible = ShowToolbarMenuItem.Checked = toolbarTrigger;
  119. }
  120. private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
  121. {
  122. timer.Stop();
  123. LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
  124. if (config == null)
  125. config = new LogViewerConfig();
  126. config.topMost = topMostTrigger;
  127. config.wrapText = wrapTextTrigger;
  128. config.toolbarShown = toolbarTrigger;
  129. config.SetFont(LogMessageTextBox.Font);
  130. config.SetBackgroundColor(LogMessageTextBox.BackColor);
  131. config.SetTextColor(LogMessageTextBox.ForeColor);
  132. config.top = Top;
  133. config.left = Left;
  134. config.height = Height;
  135. config.width = Width;
  136. controller.SaveLogViewerConfig(config);
  137. }
  138. private void OpenLocationMenuItem_Click(object sender, EventArgs e)
  139. {
  140. string argument = "/select, \"" + filename + "\"";
  141. Logging.Debug(argument);
  142. System.Diagnostics.Process.Start("explorer.exe", argument);
  143. }
  144. private void ExitMenuItem_Click(object sender, EventArgs e)
  145. {
  146. Close();
  147. }
  148. private void LogForm_Shown(object sender, EventArgs e)
  149. {
  150. LogMessageTextBox.ScrollToCaret();
  151. }
  152. #region Clean up the content in LogMessageTextBox.
  153. private void DoCleanLogs()
  154. {
  155. LogMessageTextBox.Clear();
  156. }
  157. private void CleanLogsMenuItem_Click(object sender, EventArgs e)
  158. {
  159. DoCleanLogs();
  160. }
  161. private void CleanLogsButton_Click(object sender, EventArgs e)
  162. {
  163. DoCleanLogs();
  164. }
  165. #endregion
  166. #region Change the font settings applied in LogMessageTextBox.
  167. private void DoChangeFont()
  168. {
  169. try
  170. {
  171. FontDialog fd = new FontDialog();
  172. fd.Font = LogMessageTextBox.Font;
  173. if (fd.ShowDialog() == DialogResult.OK)
  174. {
  175. LogMessageTextBox.Font = new Font(fd.Font.FontFamily, fd.Font.Size, fd.Font.Style);
  176. }
  177. }
  178. catch (Exception ex)
  179. {
  180. Logging.LogUsefulException(ex);
  181. MessageBox.Show(ex.Message);
  182. }
  183. }
  184. private void ChangeFontMenuItem_Click(object sender, EventArgs e)
  185. {
  186. DoChangeFont();
  187. }
  188. private void ChangeFontButton_Click(object sender, EventArgs e)
  189. {
  190. DoChangeFont();
  191. }
  192. #endregion
  193. #region Trigger the log messages to wrapable, or not.
  194. bool wrapTextTrigger = false;
  195. bool wrapTextTriggerLock = false;
  196. private void TriggerWrapText()
  197. {
  198. wrapTextTriggerLock = true;
  199. wrapTextTrigger = !wrapTextTrigger;
  200. LogMessageTextBox.WordWrap = wrapTextTrigger;
  201. LogMessageTextBox.ScrollToCaret();
  202. WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
  203. wrapTextTriggerLock = false;
  204. }
  205. private void WrapTextMenuItem_Click(object sender, EventArgs e)
  206. {
  207. if (!wrapTextTriggerLock)
  208. {
  209. TriggerWrapText();
  210. }
  211. }
  212. private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
  213. {
  214. if (!wrapTextTriggerLock)
  215. {
  216. TriggerWrapText();
  217. }
  218. }
  219. #endregion
  220. #region Trigger the window to top most, or not.
  221. bool topMostTrigger = false;
  222. bool topMostTriggerLock = false;
  223. private void TriggerTopMost()
  224. {
  225. topMostTriggerLock = true;
  226. topMostTrigger = !topMostTrigger;
  227. TopMost = topMostTrigger;
  228. TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
  229. topMostTriggerLock = false;
  230. }
  231. private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e)
  232. {
  233. if (!topMostTriggerLock)
  234. {
  235. TriggerTopMost();
  236. }
  237. }
  238. private void TopMostMenuItem_Click(object sender, EventArgs e)
  239. {
  240. if (!topMostTriggerLock)
  241. {
  242. TriggerTopMost();
  243. }
  244. }
  245. #endregion
  246. private bool toolbarTrigger = false;
  247. private void ShowToolbarMenuItem_Click(object sender, EventArgs e)
  248. {
  249. toolbarTrigger = !toolbarTrigger;
  250. ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
  251. ShowToolbarMenuItem.Checked = toolbarTrigger;
  252. }
  253. }
  254. }