OSDN Git Service

36e405b383fc318d1812f3944dd8b9d64284e66b
[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.ComponentModel;\r
10 using System.Data;\r
11 using System.Drawing;\r
12 using System.Text;\r
13 using System.Windows.Forms;\r
14 using System.IO;\r
15 using System.Threading;\r
16 using System.Diagnostics;\r
17 using System.Runtime.InteropServices;\r
18 using Microsoft.Win32;\r
19 \r
20 namespace Handbrake\r
21 {\r
22     public partial class frmActivityWindow : Form\r
23     {\r
24 \r
25         Thread monitorFile;\r
26         String read_file;\r
27         frmMain mainWindow;\r
28         frmQueue queueWindow;\r
29         int position = 0;  // Position in the arraylist reached by the current log output in the rtf box.\r
30         \r
31 \r
32         /// <summary>\r
33         /// This window should be used to display the RAW output of the handbrake CLI which is produced during an encode.\r
34         /// </summary>\r
35         /// \r
36         public frmActivityWindow(string file, frmMain fm, frmQueue fq)\r
37         {\r
38             InitializeComponent();\r
39 \r
40             mainWindow = fm;\r
41             queueWindow = fq;\r
42             read_file = file;\r
43 \r
44             // Reset some varibles\r
45             this.rtf_actLog.Text = string.Empty;\r
46             position = 0;\r
47 \r
48             string logFile = Path.Combine(Path.GetTempPath(), read_file);\r
49             if (File.Exists(logFile))\r
50             {\r
51 \r
52                 // Get the CPU Processor Name\r
53                 RegistryKey RegKey = Registry.LocalMachine;\r
54                 RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");\r
55                 Object cpuType = RegKey.GetValue("ProcessorNameString");\r
56 \r
57                 // Add a header to the log file indicating that it's from the Windows GUI and display the windows version\r
58                 rtf_actLog.AppendText("### Windows GUI \n");\r
59                 rtf_actLog.AppendText(String.Format("### Running: {0} \n###\n", Environment.OSVersion.ToString()));\r
60                 rtf_actLog.AppendText(String.Format("### CPU: {0} \n", cpuType));\r
61                 rtf_actLog.AppendText(String.Format("### Temp Dir: {0} \n", Path.GetTempPath()));\r
62                 rtf_actLog.AppendText(String.Format("### Install Dir: {0} \n", Application.StartupPath));\r
63                 rtf_actLog.AppendText(String.Format("### Data Dir: {0} \n###\n", Application.UserAppDataPath));\r
64 \r
65                 // Start a new thread to run the autoUpdate process\r
66                 monitorFile = new Thread(autoUpdate);\r
67                 monitorFile.Start();\r
68             }\r
69             else\r
70                 MessageBox.Show("The log file could not be found. Maybe you cleared your system's tempory folder or maybe you just havn't run an encode yet.", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
71 \r
72             // Handle the event of the window being disposed. This is needed to make sure HandBrake exit's cleanly.\r
73             this.Disposed += new EventHandler(forceQuit);\r
74         }\r
75 \r
76         // Ok, so, this function is called when someone closes frmMain but didn't close frmActivitWindow first.\r
77         // When you close frmMain, the activity window gets closed (disposed of) but, this doens't kill the threads that it started.\r
78         // When that thread tries to access the disposed rich text box, it causes an exception.\r
79         // Basically, this function is called when the window is disposed of, to kill the thread and close the window properly.\r
80         // This allows HandBrake to close cleanly.\r
81         private void forceQuit(object sender, EventArgs e)\r
82         {\r
83             if (monitorFile != null)\r
84                 monitorFile.Abort();\r
85 \r
86             this.Close();\r
87         }\r
88 \r
89         // Update the Activity window every 5 seconds with the latest log data.\r
90         private void autoUpdate(object state)\r
91         {\r
92             Boolean lastUpdate = false;\r
93             updateTextFromThread();\r
94             while (true)\r
95             {   \r
96                 if ((mainWindow.isEncoding() == true) || (queueWindow.isEncoding() == true))\r
97                     updateTextFromThread();\r
98                 else\r
99                 {\r
100                     // The encode may just have stoped, so, refresh the log one more time before restarting it.\r
101                     if (lastUpdate == false)\r
102                         updateTextFromThread();\r
103 \r
104                     lastUpdate = true;\r
105                     position = 0;\r
106                 }\r
107                 Thread.Sleep(5000);\r
108             }\r
109         }\r
110 \r
111         private delegate void UpdateUIHandler();\r
112         private void updateTextFromThread()\r
113         {\r
114             try\r
115             {\r
116                 if (this.InvokeRequired)\r
117                 {\r
118                     this.BeginInvoke(new UpdateUIHandler(updateTextFromThread));\r
119                     return;\r
120                 }\r
121                 // Initialize a pointer and get the log data arraylist\r
122                 ArrayList data = readFile();\r
123 \r
124                 while (position < data.Count)\r
125                 {\r
126                     rtf_actLog.AppendText(data[position].ToString());\r
127                     if (data[position].ToString().Contains("has exited"))\r
128                     {\r
129                         rtf_actLog.AppendText("\n ############ End of Encode ############## \n");\r
130                     }\r
131                     position++;\r
132                 }\r
133 \r
134                // this.rtf_actLog.SelectionStart = this.rtf_actLog.Text.Length - 1;\r
135                // this.rtf_actLog.ScrollToCaret();\r
136             }\r
137             catch (Exception exc)\r
138             {\r
139                 MessageBox.Show("An error has occured in: updateTextFromThread(). \n You may have to restart HandBrake. \n  Error Information: \n\n" + exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
140             }\r
141         }\r
142 \r
143         private ArrayList readFile()\r
144         {\r
145             // Ok, the task here is to, Get an arraylist of log data.\r
146             // And update some global varibles which are pointers to the last displayed log line.\r
147             ArrayList logData = new ArrayList();\r
148 \r
149             try\r
150             {\r
151                 // 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
152                 // we'll need to make a copy of it.\r
153                 string logFile = Path.Combine(Path.GetTempPath(), read_file);\r
154                 string logFile2 = Path.Combine(Path.GetTempPath(), "hb_encode_log_AppReadable.dat");\r
155 \r
156                 // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.\r
157                 if (File.Exists(logFile2))\r
158                     File.Delete(logFile2);\r
159 \r
160                 // Copy the log file.\r
161                 File.Copy(logFile, logFile2);\r
162 \r
163                 // Open the copied log file for reading\r
164                 StreamReader sr = new StreamReader(logFile2);\r
165                 string line = sr.ReadLine();\r
166                 while (line != null)\r
167                 {\r
168                     if (line.Trim() != "")\r
169                         logData.Add(line + System.Environment.NewLine);\r
170 \r
171                     line = sr.ReadLine();\r
172                 }\r
173                 sr.Close();\r
174                 sr.Dispose();\r
175 \r
176                 return logData;\r
177             }\r
178             catch (Exception exc)\r
179             {\r
180                 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
181             }\r
182             return null;\r
183         }\r
184 \r
185 \r
186         // Ok, We need to make sure the monitor thread is dead when we close the window.\r
187         protected override void OnClosing(CancelEventArgs e)\r
188         {\r
189             if (monitorFile != null)\r
190                 monitorFile.Abort();\r
191             e.Cancel = true;\r
192             this.Hide();\r
193             base.OnClosing(e);\r
194         }\r
195 \r
196     }\r
197 }