1 /* frmActivityWindow.cs $
\r
3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Collections;
\r
9 using System.Collections.Generic;
\r
10 using System.ComponentModel;
\r
12 using System.Drawing;
\r
14 using System.Windows.Forms;
\r
16 using System.Threading;
\r
17 using System.Diagnostics;
\r
18 using System.Runtime.InteropServices;
\r
19 using Microsoft.Win32;
\r
24 public partial class frmActivityWindow : Form
\r
26 delegate void SetTextCallback(string text);
\r
29 Functions.Encode encodeHandler;
\r
30 int position = 0; // Position in the arraylist reached by the current log output in the rtf box.
\r
33 /// This window should be used to display the RAW output of the handbrake CLI which is produced during an encode.
\r
35 public frmActivityWindow(string file, Functions.Encode eh)
\r
37 InitializeComponent();
\r
38 this.rtf_actLog.Text = string.Empty;
\r
40 // When the window closes, we want to abort the monitor thread.
\r
41 this.Disposed += new EventHandler(forceQuit);
\r
47 // Print the Log header in the Rich text box.
\r
50 if (file == "dvdinfo.dat")
\r
51 txt_log.Text = "Scan Log";
\r
52 else if (file == "hb_encode_log.dat")
\r
53 txt_log.Text = "Encode Log";
\r
55 // Start a new thread which will montior and keep the log window up to date if required/
\r
56 startLogThread(read_file);
\r
60 /// Displays the Log header
\r
62 private void displayLogHeader()
\r
64 // Add a header to the log file indicating that it's from the Windows GUI and display the windows version
\r
65 rtf_actLog.AppendText(String.Format("### Windows GUI {1} {0} \n", Properties.Settings.Default.hb_build, Properties.Settings.Default.hb_version));
\r
66 rtf_actLog.AppendText(String.Format("### Running: {0} \n###\n", Environment.OSVersion.ToString()));
\r
67 rtf_actLog.AppendText(String.Format("### CPU: {0} \n", getCpuCount()));
\r
68 rtf_actLog.AppendText(String.Format("### Ram: {0} MB \n", TotalPhysicalMemory()));
\r
69 rtf_actLog.AppendText(String.Format("### Screen: {0}x{1} \n", screenBounds().Bounds.Width, screenBounds().Bounds.Height));
\r
70 rtf_actLog.AppendText(String.Format("### Temp Dir: {0} \n", Path.GetTempPath()));
\r
71 rtf_actLog.AppendText(String.Format("### Install Dir: {0} \n", Application.StartupPath));
\r
72 rtf_actLog.AppendText(String.Format("### Data Dir: {0} \n", Application.UserAppDataPath));
\r
73 rtf_actLog.AppendText("#########################################\n\n");
\r
77 /// Starts a new thread which runs the autoUpdate function.
\r
79 /// <param name="file"> File which will be used to populate the Rich text box.</param>
\r
80 private void startLogThread(string file)
\r
84 string logFile = Path.Combine(Path.GetTempPath(), file);
\r
85 if (File.Exists(logFile))
\r
87 // Start a new thread to run the autoUpdate process
\r
88 monitor = new Thread(autoUpdate);
\r
89 monitor.IsBackground = true;
\r
93 rtf_actLog.AppendText("\n\n\nERROR: The log file could not be found. \nMaybe you cleared your system's tempory folder or maybe you just havn't run an encode yet. \nTried to find the log file in: " + logFile);
\r
96 catch (Exception exc)
\r
98 MessageBox.Show("startLogThread(): Exception: \n" + exc);
\r
103 /// Change the log file to be displayed to hb_encode_log.dat
\r
105 /// <param name="sender"></param>
\r
106 /// <param name="e"></param>
\r
107 private void btn_scan_log_Click(object sender, EventArgs e)
\r
109 if (monitor != null)
\r
112 rtf_actLog.Clear();
\r
113 read_file = "dvdinfo.dat";
\r
114 displayLogHeader();
\r
115 startLogThread(read_file);
\r
116 txt_log.Text = "Scan Log";
\r
120 /// Change the log file to be displayed to dvdinfo.dat
\r
122 /// <param name="sender"></param>
\r
123 /// <param name="e"></param>
\r
124 private void btn_encode_log_Click(object sender, EventArgs e)
\r
126 if (monitor != null)
\r
129 rtf_actLog.Clear();
\r
130 read_file = "hb_encode_log.dat";
\r
132 displayLogHeader();
\r
133 startLogThread(read_file);
\r
134 txt_log.Text = "Encode Log";
\r
138 /// Copy to Clipboard
\r
140 /// <param name="sender"></param>
\r
141 /// <param name="e"></param>
\r
142 private void btn_copy_Click(object sender, EventArgs e)
\r
144 if (rtf_actLog.SelectedText != "")
\r
145 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
147 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
151 /// Updates the log window with any new data which is in the log file.
\r
152 /// This is done every 5 seconds.
\r
154 /// <param name="state"></param>
\r
155 private void autoUpdate(object state)
\r
159 Boolean lastUpdate = false;
\r
160 updateTextFromThread();
\r
163 if (encodeHandler.isEncoding == true)
\r
164 updateTextFromThread();
\r
167 // The encode may just have stoped, so, refresh the log one more time before restarting it.
\r
168 if (lastUpdate == false)
\r
169 updateTextFromThread();
\r
171 lastUpdate = true; // Prevents the log window from being updated when there is no encode going.
\r
172 position = 0; // There is no encoding, so reset the log position counter to 0 so it can be reused
\r
174 Thread.Sleep(5000);
\r
177 catch (ThreadAbortException)
\r
179 // Do Nothing. This is needed since we run thread.abort().
\r
180 // Should probably find a better way of making this work at some point.
\r
182 catch (Exception exc)
\r
184 MessageBox.Show("autoUpdate(): Exception: \n" + exc);
\r
189 /// Finds any new text in the log file and calls a funciton to display this new text.
\r
191 private void updateTextFromThread()
\r
196 List<string> data = readFile();
\r
197 int count = data.Count;
\r
199 while (position < count)
\r
201 text = data[position].ToString();
\r
202 if (data[position].ToString().Contains("has exited"))
\r
203 text = "\n ############ End of Log ############## \n";
\r
209 catch (Exception exc)
\r
211 MessageBox.Show("updateTextFromThread(): Exception: \n" + exc);
\r
216 /// Updates the rich text box with anything in the string text.
\r
218 /// <param name="text"></param>
\r
219 private void SetText(string text)
\r
223 // InvokeRequired required compares the thread ID of the
\r
224 // calling thread to the thread ID of the creating thread.
\r
225 // If these threads are different, it returns true.
\r
226 if (this.IsHandleCreated) // Make sure the windows has a handle before doing anything
\r
228 if (this.rtf_actLog.InvokeRequired)
\r
230 SetTextCallback d = new SetTextCallback(SetText);
\r
231 this.Invoke(d, new object[] { text });
\r
234 this.rtf_actLog.AppendText(text);
\r
237 catch (Exception exc)
\r
239 MessageBox.Show("SetText(): Exception: \n" + exc);
\r
244 /// Read the log file, and store the data in a List.
\r
246 /// <returns></returns>
\r
247 private List<string> readFile()
\r
249 // Ok, the task here is to, Get an arraylist of log data.
\r
250 // And update some global varibles which are pointers to the last displayed log line.
\r
251 List<string> logData = new List<string>();
\r
255 // hb_encode_log.dat is the primary log file. Since .NET can't read this file whilst the CLI is outputing to it (Not even in read only mode),
\r
256 // we'll need to make a copy of it.
\r
257 string logFile = Path.Combine(Path.GetTempPath(), read_file);
\r
258 string logFile2 = Path.Combine(Path.GetTempPath(), "hb_encode_log_AppReadable.dat");
\r
260 // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.
\r
261 if (File.Exists(logFile2))
\r
262 File.Delete(logFile2);
\r
264 // Copy the log file.
\r
265 File.Copy(logFile, logFile2);
\r
267 // Open the copied log file for reading
\r
268 StreamReader sr = new StreamReader(logFile2);
\r
269 string line = sr.ReadLine();
\r
270 while (line != null)
\r
272 if (line.Trim() != "")
\r
273 logData.Add(line + System.Environment.NewLine);
\r
275 line = sr.ReadLine();
\r
282 catch (Exception exc)
\r
284 MessageBox.Show("Error in readFile() \n Unable to read the log file.\n You may have to restart HandBrake.\n Error Information: \n\n" + exc.ToString(), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
290 /// Kills the montior thead when the window is disposed of.
\r
292 /// <param name="sender"></param>
\r
293 /// <param name="e"></param>
\r
294 private void forceQuit(object sender, EventArgs e)
\r
296 if (monitor != null)
\r
298 while (monitor.IsAlive)
\r
306 /// Copy Log Menu Item on the right click menu for the log rtf box
\r
308 /// <param name="sender"></param>
\r
309 /// <param name="e"></param>
\r
310 private void mnu_copy_log_Click(object sender, EventArgs e)
\r
312 if (rtf_actLog.SelectedText != "")
\r
313 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
315 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
318 #region System Information
\r
319 private struct MEMORYSTATUS
\r
321 public UInt32 dwLength;
\r
322 public UInt32 dwMemoryLoad;
\r
323 public UInt32 dwTotalPhys; // Used
\r
324 public UInt32 dwAvailPhys;
\r
325 public UInt32 dwTotalPageFile;
\r
326 public UInt32 dwAvailPageFile;
\r
327 public UInt32 dwTotalVirtual;
\r
328 public UInt32 dwAvailVirtual;
\r
331 [DllImport("kernel32.dll")]
\r
332 private static extern void GlobalMemoryStatus
\r
334 ref MEMORYSTATUS lpBuffer
\r
338 /// Returns the total physical ram in a system
\r
340 /// <returns></returns>
\r
341 public uint TotalPhysicalMemory()
\r
343 MEMORYSTATUS memStatus = new MEMORYSTATUS();
\r
344 GlobalMemoryStatus(ref memStatus);
\r
346 uint MemoryInfo = memStatus.dwTotalPhys;
\r
347 MemoryInfo = MemoryInfo / 1024 / 1024;
\r
353 /// Get the number of CPU Cores
\r
355 /// <returns>Object</returns>
\r
356 public Object getCpuCount()
\r
358 RegistryKey RegKey = Registry.LocalMachine;
\r
359 RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
\r
360 return RegKey.GetValue("ProcessorNameString");
\r
364 /// Get the System screen size information.
\r
366 /// <returns>System.Windows.Forms.Scree</returns>
\r
367 public System.Windows.Forms.Screen screenBounds()
\r
369 return System.Windows.Forms.Screen.PrimaryScreen;
\r