ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater.Logging/LogWriter.cs
Revision: 298
Committed: Tue Jun 5 11:35:37 2012 UTC (11 years, 5 months ago) by william
File size: 10122 byte(s)
Log Message:
+ bring back BackgroundWorker for LogWriter from r105 (this helps to not block the main form for long log entries)

File Contents

# Content
1 #define ALLOW_LOG_CLEARING // when defined will allow the log to be cleared
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Drawing;
6 using System.Data;
7 using System.Linq;
8 using System.Text;
9 using System.Windows.Forms;
10 using System.IO;
11 using System.Reflection;
12
13 namespace RomCheater.Logging
14 {
15 public partial class LogWriter : UserControl
16 {
17 private static string LOG_PATH { get { return string.Format(@"{0}\{1}", typeof(LogWriter).Assembly.Location.Replace("RomCheater.Logging.dll", ""), LoggingConstants.AppLogFile); } }
18
19 private delegate string OnGetLogText();
20 private delegate void OnSetLogText(string value);
21 private delegate void GenericVoidDelegate();
22
23 private OnGetLogText HandleGetLogText = null;
24 private OnSetLogText HandleSetLogText = null;
25 private GenericVoidDelegate delegate_EndLogUpdate = null;
26
27 public LogWriter() : this(false) { }
28 public LogWriter(bool redirectConsole)
29 {
30 InitializeComponent();
31 this.Log = new LogStream(this);
32 HandleGetLogText += new OnGetLogText(GetLogText);
33 HandleSetLogText += new OnSetLogText(SetLogText);
34
35 delegate_EndLogUpdate += new GenericVoidDelegate(EndLogUpdate);
36
37 this.RedirectConsoleOutput = redirectConsole;
38 toolTip1.SetToolTip(btnClearLog, "Clears the Log");
39 toolTip1.SetToolTip(btnCopyLogToClipboard, "Copies the Log to the Clipboard");
40
41 ms = new MemoryStream();
42 sw = new StreamWriter(ms);
43 sw.AutoFlush = true;
44 sr = new StreamReader(ms);
45 }
46 private LogStream _Log;
47 public LogStream Log { get { return _Log; } private set { _Log = value; } }
48
49
50 private MemoryStream ms;
51 private StreamWriter sw;
52 private StreamReader sr;
53 private bool _AutoScroll;
54 new public bool AutoScroll { get { return _AutoScroll; } set { _AutoScroll = value; autoscroll_timer.Enabled = value; } }
55
56 private bool _RedirectConsoleOutput;
57 public bool RedirectConsoleOutput
58 {
59 get { return _RedirectConsoleOutput; }
60 set
61 {
62 _RedirectConsoleOutput = value;
63 if (value) { Console.SetOut(this.Log); }
64 else
65 {
66 Stream stream = Console.OpenStandardOutput(0x100);
67 TextWriter writer = null;
68 if (stream == Stream.Null) { writer = TextWriter.Synchronized(StreamWriter.Null); }
69 Encoding encoding = this.Log.Encoding;
70 StreamWriter writer2 = new StreamWriter(stream, encoding, 0x100);
71 //writer2.HaveWrittenPreamble = true;
72 writer2.AutoFlush = true;
73 writer = TextWriter.Synchronized(writer2);
74 Console.SetOut(writer);
75 }
76 }
77 }
78
79 private void btnClearLog_Click(object sender, EventArgs e) { this.Clear(true); }
80 private void btnCopyLogToClipboard_Click(object sender, EventArgs e) { Clipboard.SetText(GetLogText()); }
81
82
83 private string PreserveLineEndings(string text) { return text.Replace("\n", System.Environment.NewLine); }
84
85
86 private bool BeginUpdate;
87 public void BeginLogUpdate()
88 {
89 BeginUpdate = true;
90 }
91 public void EndLogUpdate()
92 {
93 if (txtLog.InvokeRequired)
94 {
95 this.Invoke(delegate_EndLogUpdate);
96 }
97 else
98 {
99 StringReader _sr = new StringReader(GetLogText());
100 List<string> lines = new List<string>();
101 string line = "";
102 while ((line = _sr.ReadLine()) != null)
103 {
104 lines.Add(line);
105 }
106 txtLog.Lines = lines.ToArray();
107 BeginUpdate = false;
108 }
109 }
110 private string StreamToString()
111 {
112 try
113 {
114 string value = "";
115 sr = new StreamReader(ms);
116 sr.BaseStream.Seek(0, SeekOrigin.Begin);
117 value = sr.ReadToEnd();
118 return value;
119 }
120 catch (Exception ex)
121 {
122 return "";
123 }
124 }
125 public string GetLogText()
126 {
127 //if (txtLog.InvokeRequired)
128 //{
129 // return (string)this.Invoke(HandleGetLogText, new object[] { });
130 //}
131 //else
132 //{
133 return PreserveLineEndings(StreamToString());
134 //}
135
136 }
137 public void SetLogText(string value)
138 {
139 FileStream fs = new FileStream(LOG_PATH, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
140 StreamWriter writer = new StreamWriter(fs);
141 writer.AutoFlush = true;
142 if (value == Log.NewLine) { writer.Write(System.Environment.NewLine); }
143 else { writer.Write(value); }
144 writer.Close();
145 //string text = value.Replace(System.Environment.NewLine,"");
146 string text = value.Replace(System.Environment.NewLine, Log.NewLine);
147 //if (text.StartsWith(Log.NewLine))
148 //{
149 // text = text.Remove(0, Log.NewLine.Length);
150 //}
151 sw.Write(text);
152 Application.DoEvents();
153 }
154
155 new public string Text
156 {
157 get
158 {
159 throw new InvalidOperationException("Please use GetLogText()");
160 }
161 private set
162 {
163 throw new InvalidOperationException("Please use SetLogText(string value)");
164 }
165 }
166 public void CreateNewLog(bool delete)
167 {
168 if (delete)
169 {
170 FileInfo fi = new FileInfo(LOG_PATH);
171 if (fi.Exists)
172 fi.Delete();
173 }
174 Log.WriteLine("{0} ({2} v{3} {4}) created on {1}", LoggingConstants.AppLogFile, DateTime.Now.ToString(), LoggingConstants.AppName, LoggingConstants.AppVersion, LoggingConstants.AppBuild);
175 }
176 public void Clear()
177 {
178 Clear(false);
179 }
180 private void Clear(bool force)
181 {
182 bool allow_log_clearing = false;
183 #if ALLOW_LOG_CLEARING
184 allow_log_clearing = true;
185 #endif
186 if (force || allow_log_clearing)
187 {
188
189 txtLog.Clear();
190 ms = new MemoryStream();
191 sw = new StreamWriter(ms);
192 sw.AutoFlush = true;
193 sr = new StreamReader(ms);
194 }
195 }
196 #region sub-classes
197 public class LogStream : TextWriter
198 {
199 private StringBuilder strMessage = new StringBuilder();
200 public LogStream() : this(null) { }
201 public LogStream(LogWriter text) : base() { _text_writer = text; this.NewLine = "\n"; }
202 private LogWriter _text_writer;
203 private void _write(string message)
204 {
205 if (_text_writer == null) return;
206
207 if (message.EndsWith("\n"))
208 {
209 //_text_writer.SetLogText(string.Format("{0}", strMessage.ToString()));
210 while (_text_writer.logupdater.IsBusy)
211 {
212 Application.DoEvents();
213 }
214 _text_writer.logupdater.RunWorkerAsync((string.Format("{0}", strMessage.ToString())));
215 strMessage = new StringBuilder();
216 }
217 strMessage.Append(message);
218 }
219 #region Overriden Methods
220 public override Encoding Encoding { get { return Encoding.UTF8; } }
221 public override void Write(char value) { base.Write(value); _write(value.ToString()); if (!_text_writer.BeginUpdate) _text_writer.EndLogUpdate(); }
222 #endregion
223 }
224 #endregion
225
226 private void autoscroll_timer_Tick(object sender, EventArgs e)
227 {
228 try
229 {
230 if (this.DesignMode) { return; }
231 ////txtLog.ScrollToEnd();
232 //txtLog.SelectionStart = txtLog.Text.Length - 100;
233 //txtLog.ScrollToCaret();
234 //txtLog.Refresh();
235
236 //txtLog.SelectionStart = 0;
237 //txtLog.ScrollToCaret();
238 //txtLog.Refresh();
239
240 //int last_line_position = -1;
241 //int position = -1;
242 int len = txtLog.Text.Length;
243 //StringReader sr = new StringReader(this.StreamToString());
244 //string line = "";
245 //while ((line = sr.ReadLine()) != null)
246 //{
247 // position += (line.Length * 2);
248 // last_line_position = (line.Length * 2);
249 // //if (line.EndsWith("/n"))
250 // //{
251 // // position++;
252 // //}
253 // //logger.VerboseDebug.WriteLine("current line: {0}", line);
254 //}
255 txtLog.SelectionStart = len;
256 txtLog.ScrollToCaret();
257 txtLog.Refresh();
258 //autoscroll_timer.Enabled = false;
259 }
260 catch { }
261
262 }
263
264 private void logupdater_DoWork(object sender, DoWorkEventArgs e)
265 {
266 string message = e.Argument.ToString();
267 SetLogText(string.Format("{0}", message));
268 }
269
270 private void logupdater_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
271 {
272
273 }
274 }
275 }
276