OSDN Git Service

d21eecd51cd934418a9aaa5c429721c101565d49
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmActivityWindow.cs
1 /*  frmActivityWindow.cs $\r
2         \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
6 \r
7 using System;\r
8 using System.Collections;\r
9 using System.Collections.Generic;\r
10 using System.ComponentModel;\r
11 using System.Data;\r
12 using System.Drawing;\r
13 using System.Text;\r
14 using System.Windows.Forms;\r
15 using System.IO;\r
16 using System.Threading;\r
17 using System.Diagnostics;\r
18 using System.Runtime.InteropServices;\r
19 using Microsoft.Win32;\r
20 \r
21 \r
22 namespace Handbrake\r
23 {\r
24     public partial class frmActivityWindow : Form\r
25     {\r
26         delegate void SetTextCallback(string text);\r
27         String read_file;\r
28         Thread monitor;\r
29         frmMain mainWindow;\r
30         frmQueue queueWindow;\r
31         int position = 0;  // Position in the arraylist reached by the current log output in the rtf box.\r
32 \r
33         /// <summary>\r
34         /// This window should be used to display the RAW output of the handbrake CLI which is produced during an encode.\r
35         /// </summary>\r
36         public frmActivityWindow(string file, frmMain fm, frmQueue fq)\r
37         {\r
38             InitializeComponent();\r
39             this.rtf_actLog.Text = string.Empty;\r
40 \r
41             // When the window closes, we want to abort the monitor thread.\r
42             this.Disposed += new EventHandler(forceQuit);\r
43 \r
44             mainWindow = fm;\r
45             queueWindow = fq;\r
46             read_file = file;\r
47             position = 0;\r
48 \r
49             // Print the Log header in the Rich text box.\r
50             displayLogHeader();\r
51 \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
56 \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
59         }\r
60 \r
61         /// <summary>\r
62         /// Displays the Log header\r
63         /// </summary>\r
64         private void displayLogHeader()\r
65         {\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
76         }\r
77 \r
78         /// <summary>\r
79         /// Starts a new thread which runs the autoUpdate function.\r
80         /// </summary>\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
83         {\r
84             try\r
85             {\r
86                 string logFile = Path.Combine(Path.GetTempPath(), file);\r
87                 if (File.Exists(logFile))\r
88                 {\r
89                     // Start a new thread to run the autoUpdate process\r
90                     monitor = new Thread(autoUpdate);\r
91                     monitor.IsBackground = true;\r
92                     monitor.Start();\r
93                 }\r
94                 else\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
96 \r
97             }\r
98             catch (Exception exc)\r
99             {\r
100                 MessageBox.Show("startLogThread(): Exception: \n" + exc);\r
101             }\r
102         }\r
103 \r
104         /// <summary>\r
105         /// Change the log file to be displayed to hb_encode_log.dat\r
106         /// </summary>\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
110         {\r
111             if (monitor != null)\r
112                 monitor.Abort();\r
113 \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
119         }\r
120 \r
121         /// <summary>\r
122         /// Change the log file to be displayed to dvdinfo.dat\r
123         /// </summary>\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
127         {\r
128             if (monitor != null)\r
129                 monitor.Abort();\r
130 \r
131             rtf_actLog.Clear();\r
132             read_file = "hb_encode_log.dat";\r
133             position = 0;\r
134             displayLogHeader();\r
135             startLogThread(read_file);\r
136             txt_log.Text = "Encode Log";\r
137         }\r
138 \r
139         /// <summary>\r
140         /// Copy to Clipboard\r
141         /// </summary>\r
142         /// <param name="sender"></param>\r
143         /// <param name="e"></param>\r
144         private void btn_copy_Click(object sender, EventArgs e)\r
145         {\r
146             if (rtf_actLog.SelectedText != "")\r
147                 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);\r
148             else\r
149                 Clipboard.SetDataObject(rtf_actLog.Text, true);\r
150         }\r
151 \r
152         /// <summary>\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
155         /// </summary>\r
156         /// <param name="state"></param>\r
157         private void autoUpdate(object state)\r
158         {\r
159             try\r
160             {\r
161                 Boolean lastUpdate = false;\r
162                 updateTextFromThread();\r
163                 while (true)\r
164                 {\r
165                     if ((mainWindow.isEncoding() == true) || (queueWindow.isEncoding() == true))\r
166                         updateTextFromThread();\r
167                     else\r
168                     {\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
172 \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
175                     }\r
176                     Thread.Sleep(5000);\r
177                 }\r
178             }\r
179             catch (ThreadAbortException)\r
180             {\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
183             }\r
184             catch (Exception exc)\r
185             {\r
186                 MessageBox.Show("autoUpdate(): Exception: \n" + exc);\r
187             }\r
188         }\r
189 \r
190         /// <summary>\r
191         /// Finds any new text in the log file and calls a funciton to display this new text.\r
192         /// </summary>\r
193         private void updateTextFromThread()\r
194         {\r
195             try\r
196             {\r
197                 string text = "";\r
198                 List<string> data = readFile();\r
199                 int count = data.Count;\r
200 \r
201                 while (position < count)\r
202                 {\r
203                     text = data[position].ToString();\r
204                     if (data[position].ToString().Contains("has exited"))\r
205                         text = "\n ############ End of Log ############## \n";\r
206                     position++;\r
207 \r
208                     SetText(text);\r
209                 }\r
210             }\r
211             catch (Exception exc)\r
212             {\r
213                 MessageBox.Show("updateTextFromThread(): Exception: \n" + exc);\r
214             }\r
215         }\r
216 \r
217         /// <summary>\r
218         /// Updates the rich text box with anything in the string text.\r
219         /// </summary>\r
220         /// <param name="text"></param>\r
221         private void SetText(string text)\r
222         {\r
223             try\r
224             {\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
229                 {\r
230                     if (this.rtf_actLog.InvokeRequired)\r
231                     {\r
232                         SetTextCallback d = new SetTextCallback(SetText);\r
233                         this.Invoke(d, new object[] { text });\r
234                     }\r
235                     else\r
236                         this.rtf_actLog.AppendText(text);\r
237                 }\r
238             }\r
239             catch (Exception exc)\r
240             {\r
241                 MessageBox.Show("SetText(): Exception: \n" + exc);\r
242             }\r
243         }\r
244 \r
245         /// <summary>\r
246         /// Read the log file, and store the data in a List.\r
247         /// </summary>\r
248         /// <returns></returns>\r
249         private List<string> readFile()\r
250         {\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
254 \r
255             try\r
256             {\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
261 \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
265 \r
266                 // Copy the log file.\r
267                 File.Copy(logFile, logFile2);\r
268 \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
273                 {\r
274                     if (line.Trim() != "")\r
275                         logData.Add(line + System.Environment.NewLine);\r
276 \r
277                     line = sr.ReadLine();\r
278                 }\r
279                 sr.Close();\r
280                 sr.Dispose();\r
281 \r
282                 return logData;\r
283             }\r
284             catch (Exception exc)\r
285             {\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
287             }\r
288             return null;\r
289         }\r
290 \r
291         /// <summary>\r
292         /// Kills the montior thead when the window is disposed of.\r
293         /// </summary>\r
294         /// <param name="sender"></param>\r
295         /// <param name="e"></param>\r
296         private void forceQuit(object sender, EventArgs e)\r
297         {\r
298             if (monitor != null)\r
299             {\r
300                 while (monitor.IsAlive)\r
301                     monitor.Abort();\r
302             }\r
303 \r
304             this.Close();\r
305         }\r
306 \r
307         /// <summary>\r
308         /// Copy Log Menu Item on the right click menu for the log rtf box\r
309         /// </summary>\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
313         {\r
314             if (rtf_actLog.SelectedText != "")\r
315                 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);\r
316             else\r
317                 Clipboard.SetDataObject(rtf_actLog.Text, true);\r
318         }\r
319 \r
320         #region System Information\r
321         private struct MEMORYSTATUS\r
322         {\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
331         }\r
332 \r
333         [DllImport("kernel32.dll")]\r
334         private static extern void GlobalMemoryStatus\r
335         (\r
336             ref MEMORYSTATUS lpBuffer\r
337         );\r
338 \r
339         /// <summary>\r
340         /// Returns the total physical ram in a system\r
341         /// </summary>\r
342         /// <returns></returns>\r
343         public uint TotalPhysicalMemory()\r
344         {\r
345             MEMORYSTATUS memStatus = new MEMORYSTATUS();\r
346             GlobalMemoryStatus(ref memStatus);\r
347 \r
348             uint MemoryInfo = memStatus.dwTotalPhys;\r
349             MemoryInfo = MemoryInfo / 1024 / 1024;\r
350 \r
351             return MemoryInfo;\r
352         }\r
353 \r
354         /// <summary>\r
355         /// Get the number of CPU Cores\r
356         /// </summary>\r
357         /// <returns>Object</returns>\r
358         public Object getCpuCount()\r
359         {\r
360             RegistryKey RegKey = Registry.LocalMachine;\r
361             RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");\r
362             return RegKey.GetValue("ProcessorNameString");\r
363         }\r
364 \r
365         /// <summary>\r
366         /// Get the System screen size information.\r
367         /// </summary>\r
368         /// <returns>System.Windows.Forms.Scree</returns>\r
369         public System.Windows.Forms.Screen screenBounds()\r
370         {\r
371             return System.Windows.Forms.Screen.PrimaryScreen;\r
372         }\r
373 \r
374         #endregion\r
375 \r
376     }\r
377 }