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
30 frmQueue queueWindow;
\r
31 int position = 0; // Position in the arraylist reached by the current log output in the rtf box.
\r
34 /// This window should be used to display the RAW output of the handbrake CLI which is produced during an encode.
\r
36 public frmActivityWindow(string file, frmMain fm, frmQueue fq)
\r
38 InitializeComponent();
\r
39 this.rtf_actLog.Text = string.Empty;
\r
41 // When the window closes, we want to abort the monitor thread.
\r
42 this.Disposed += new EventHandler(forceQuit);
\r
49 // Print the Log header in the Rich text box.
\r
52 if (file == "dvdinfo.dat")
\r
53 txt_log.Text = "Scan Log";
\r
54 else if (file == "hb_encode_log.dat")
\r
55 txt_log.Text = "Encode Log";
\r
57 // Start a new thread which will montior and keep the log window up to date if required/
\r
58 startLogThread(read_file);
\r
62 /// Displays the Log header
\r
64 private void displayLogHeader()
\r
66 // Add a header to the log file indicating that it's from the Windows GUI and display the windows version
\r
67 rtf_actLog.AppendText(String.Format("### Windows GUI {1} {0} \n", Properties.Settings.Default.hb_build, Properties.Settings.Default.hb_version));
\r
68 rtf_actLog.AppendText(String.Format("### Running: {0} \n###\n", Environment.OSVersion.ToString()));
\r
69 rtf_actLog.AppendText(String.Format("### CPU: {0} \n", getCpuCount()));
\r
70 rtf_actLog.AppendText(String.Format("### Ram: {0} MB \n", TotalPhysicalMemory()));
\r
71 rtf_actLog.AppendText(String.Format("### Screen: {0}x{1} \n", screenBounds().Bounds.Width, screenBounds().Bounds.Height));
\r
72 rtf_actLog.AppendText(String.Format("### Temp Dir: {0} \n", Path.GetTempPath()));
\r
73 rtf_actLog.AppendText(String.Format("### Install Dir: {0} \n", Application.StartupPath));
\r
74 rtf_actLog.AppendText(String.Format("### Data Dir: {0} \n", Application.UserAppDataPath));
\r
75 rtf_actLog.AppendText("#########################################\n\n");
\r
79 /// Starts a new thread which runs the autoUpdate function.
\r
81 /// <param name="file"> File which will be used to populate the Rich text box.</param>
\r
82 private void startLogThread(string file)
\r
86 string logFile = Path.Combine(Path.GetTempPath(), file);
\r
87 if (File.Exists(logFile))
\r
89 // Start a new thread to run the autoUpdate process
\r
90 monitor = new Thread(autoUpdate);
\r
91 monitor.IsBackground = true;
\r
95 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
98 catch (Exception exc)
\r
100 MessageBox.Show("startLogThread(): Exception: \n" + exc);
\r
105 /// Change the log file to be displayed to hb_encode_log.dat
\r
107 /// <param name="sender"></param>
\r
108 /// <param name="e"></param>
\r
109 private void btn_scan_log_Click(object sender, EventArgs e)
\r
111 if (monitor != null)
\r
114 rtf_actLog.Clear();
\r
115 read_file = "dvdinfo.dat";
\r
116 displayLogHeader();
\r
117 startLogThread(read_file);
\r
118 txt_log.Text = "Scan Log";
\r
122 /// Change the log file to be displayed to dvdinfo.dat
\r
124 /// <param name="sender"></param>
\r
125 /// <param name="e"></param>
\r
126 private void btn_encode_log_Click(object sender, EventArgs e)
\r
128 if (monitor != null)
\r
131 rtf_actLog.Clear();
\r
132 read_file = "hb_encode_log.dat";
\r
134 displayLogHeader();
\r
135 startLogThread(read_file);
\r
136 txt_log.Text = "Encode Log";
\r
140 /// Copy to Clipboard
\r
142 /// <param name="sender"></param>
\r
143 /// <param name="e"></param>
\r
144 private void btn_copy_Click(object sender, EventArgs e)
\r
146 if (rtf_actLog.SelectedText != "")
\r
147 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
149 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
153 /// Updates the log window with any new data which is in the log file.
\r
154 /// This is done every 5 seconds.
\r
156 /// <param name="state"></param>
\r
157 private void autoUpdate(object state)
\r
161 Boolean lastUpdate = false;
\r
162 updateTextFromThread();
\r
165 if ((mainWindow.isEncoding() == true) || (queueWindow.isEncoding() == true))
\r
166 updateTextFromThread();
\r
169 // The encode may just have stoped, so, refresh the log one more time before restarting it.
\r
170 if (lastUpdate == false)
\r
171 updateTextFromThread();
\r
173 lastUpdate = true; // Prevents the log window from being updated when there is no encode going.
\r
174 position = 0; // There is no encoding, so reset the log position counter to 0 so it can be reused
\r
176 Thread.Sleep(5000);
\r
179 catch (ThreadAbortException)
\r
181 // Do Nothing. This is needed since we run thread.abort().
\r
182 // Should probably find a better way of making this work at some point.
\r
184 catch (Exception exc)
\r
186 MessageBox.Show("autoUpdate(): Exception: \n" + exc);
\r
191 /// Finds any new text in the log file and calls a funciton to display this new text.
\r
193 private void updateTextFromThread()
\r
198 List<string> data = readFile();
\r
199 int count = data.Count;
\r
201 while (position < count)
\r
203 text = data[position].ToString();
\r
204 if (data[position].ToString().Contains("has exited"))
\r
205 text = "\n ############ End of Log ############## \n";
\r
211 catch (Exception exc)
\r
213 MessageBox.Show("updateTextFromThread(): Exception: \n" + exc);
\r
218 /// Updates the rich text box with anything in the string text.
\r
220 /// <param name="text"></param>
\r
221 private void SetText(string text)
\r
225 // InvokeRequired required compares the thread ID of the
\r
226 // calling thread to the thread ID of the creating thread.
\r
227 // If these threads are different, it returns true.
\r
228 if (this.IsHandleCreated) // Make sure the windows has a handle before doing anything
\r
230 if (this.rtf_actLog.InvokeRequired)
\r
232 SetTextCallback d = new SetTextCallback(SetText);
\r
233 this.Invoke(d, new object[] { text });
\r
236 this.rtf_actLog.AppendText(text);
\r
239 catch (Exception exc)
\r
241 MessageBox.Show("SetText(): Exception: \n" + exc);
\r
246 /// Read the log file, and store the data in a List.
\r
248 /// <returns></returns>
\r
249 private List<string> readFile()
\r
251 // Ok, the task here is to, Get an arraylist of log data.
\r
252 // And update some global varibles which are pointers to the last displayed log line.
\r
253 List<string> logData = new List<string>();
\r
257 // 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
258 // we'll need to make a copy of it.
\r
259 string logFile = Path.Combine(Path.GetTempPath(), read_file);
\r
260 string logFile2 = Path.Combine(Path.GetTempPath(), "hb_encode_log_AppReadable.dat");
\r
262 // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.
\r
263 if (File.Exists(logFile2))
\r
264 File.Delete(logFile2);
\r
266 // Copy the log file.
\r
267 File.Copy(logFile, logFile2);
\r
269 // Open the copied log file for reading
\r
270 StreamReader sr = new StreamReader(logFile2);
\r
271 string line = sr.ReadLine();
\r
272 while (line != null)
\r
274 if (line.Trim() != "")
\r
275 logData.Add(line + System.Environment.NewLine);
\r
277 line = sr.ReadLine();
\r
284 catch (Exception exc)
\r
286 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
292 /// Kills the montior thead when the window is disposed of.
\r
294 /// <param name="sender"></param>
\r
295 /// <param name="e"></param>
\r
296 private void forceQuit(object sender, EventArgs e)
\r
298 if (monitor != null)
\r
300 while (monitor.IsAlive)
\r
308 /// Copy Log Menu Item on the right click menu for the log rtf box
\r
310 /// <param name="sender"></param>
\r
311 /// <param name="e"></param>
\r
312 private void mnu_copy_log_Click(object sender, EventArgs e)
\r
314 if (rtf_actLog.SelectedText != "")
\r
315 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
317 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
320 #region System Information
\r
321 private struct MEMORYSTATUS
\r
323 public UInt32 dwLength;
\r
324 public UInt32 dwMemoryLoad;
\r
325 public UInt32 dwTotalPhys; // Used
\r
326 public UInt32 dwAvailPhys;
\r
327 public UInt32 dwTotalPageFile;
\r
328 public UInt32 dwAvailPageFile;
\r
329 public UInt32 dwTotalVirtual;
\r
330 public UInt32 dwAvailVirtual;
\r
333 [DllImport("kernel32.dll")]
\r
334 private static extern void GlobalMemoryStatus
\r
336 ref MEMORYSTATUS lpBuffer
\r
340 /// Returns the total physical ram in a system
\r
342 /// <returns></returns>
\r
343 public uint TotalPhysicalMemory()
\r
345 MEMORYSTATUS memStatus = new MEMORYSTATUS();
\r
346 GlobalMemoryStatus(ref memStatus);
\r
348 uint MemoryInfo = memStatus.dwTotalPhys;
\r
349 MemoryInfo = MemoryInfo / 1024 / 1024;
\r
355 /// Get the number of CPU Cores
\r
357 /// <returns>Object</returns>
\r
358 public Object getCpuCount()
\r
360 RegistryKey RegKey = Registry.LocalMachine;
\r
361 RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
\r
362 return RegKey.GetValue("ProcessorNameString");
\r
366 /// Get the System screen size information.
\r
368 /// <returns>System.Windows.Forms.Scree</returns>
\r
369 public System.Windows.Forms.Screen screenBounds()
\r
371 return System.Windows.Forms.Screen.PrimaryScreen;
\r