OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Functions / Main.cs
1 /*  Main.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.Windows.Forms;\r
9 using System.IO;\r
10 using System.Diagnostics;\r
11 using System.Text.RegularExpressions;\r
12 using System.Collections.Generic;\r
13 using System.Xml.Serialization;\r
14 using System.Threading;\r
15 using Handbrake.EncodeQueue;\r
16 \r
17 namespace Handbrake.Functions\r
18 {\r
19     static class Main\r
20     {\r
21         // Private Variables\r
22         private static readonly XmlSerializer ser = new XmlSerializer(typeof(List<Job>));\r
23 \r
24         /// <summary>\r
25         /// Calculate the duration of the selected title and chapters\r
26         /// </summary>\r
27         public static TimeSpan calculateDuration(string chapter_start, string chapter_end, Parsing.Title selectedTitle)\r
28         {\r
29             TimeSpan Duration = TimeSpan.FromSeconds(0.0);\r
30 \r
31             // Get the durations between the 2 chapter points and add them together.\r
32             if (chapter_start != "Auto" && chapter_end != "Auto")\r
33             {\r
34                 int start_chapter, end_chapter;\r
35                 int.TryParse(chapter_start, out start_chapter);\r
36                 int.TryParse(chapter_end, out end_chapter);\r
37 \r
38                 int position = start_chapter - 1;\r
39 \r
40                 if (start_chapter <= end_chapter)\r
41                 {\r
42                     if (end_chapter > selectedTitle.Chapters.Count)\r
43                         end_chapter = selectedTitle.Chapters.Count;\r
44 \r
45                     while (position != end_chapter)\r
46                     {\r
47                         TimeSpan dur = selectedTitle.Chapters[position].Duration;\r
48                         Duration = Duration + dur;\r
49                         position++;\r
50                     }\r
51                 }\r
52             }\r
53             return Duration;\r
54         }\r
55 \r
56         /// <summary>\r
57         /// Select the longest title in the DVD title dropdown menu on frmMain\r
58         /// </summary>\r
59         public static Parsing.Title selectLongestTitle(ComboBox drp_dvdtitle)\r
60         {\r
61             int current_largest = 0;\r
62             Parsing.Title title2Select;\r
63 \r
64             // Check if there are titles in the DVD title dropdown menu and make sure, it's not just "Automatic"\r
65             if (drp_dvdtitle.Items[0].ToString() != "Automatic")\r
66                 title2Select = (Parsing.Title)drp_dvdtitle.Items[0];\r
67             else\r
68                 title2Select = null;\r
69 \r
70             // So, If there are titles in the DVD Title dropdown menu, lets select the longest.\r
71             if (title2Select != null)\r
72             {\r
73                 foreach (Parsing.Title x in drp_dvdtitle.Items)\r
74                 {\r
75                     string title = x.ToString();\r
76                     if (title != "Automatic")\r
77                     {\r
78                         string[] y = title.Split(' ');\r
79                         string time = y[1].Replace("(", "").Replace(")", "");\r
80                         string[] z = time.Split(':');\r
81 \r
82                         int hours = int.Parse(z[0]) * 60 * 60;\r
83                         int minutes = int.Parse(z[1]) * 60;\r
84                         int seconds = int.Parse(z[2]);\r
85                         int total_sec = hours + minutes + seconds;\r
86 \r
87                         if (current_largest == 0)\r
88                         {\r
89                             current_largest = hours + minutes + seconds;\r
90                             title2Select = x;\r
91                         }\r
92                         else\r
93                         {\r
94                             if (total_sec > current_largest)\r
95                             {\r
96                                 current_largest = total_sec;\r
97                                 title2Select = x;\r
98                             }\r
99                         }\r
100                     }\r
101                 }\r
102             }\r
103             return title2Select;\r
104         }\r
105 \r
106         /// <summary>\r
107         /// Set's up the DataGridView on the Chapters tab (frmMain)\r
108         /// </summary>\r
109         public static DataGridView chapterNaming(DataGridView data_chpt, string chapter_end)\r
110         {\r
111             int i = 0, finish = 0;\r
112 \r
113             if (chapter_end != "Auto")\r
114                 int.TryParse(chapter_end, out finish);\r
115 \r
116             while (i < finish)\r
117             {\r
118                 int n = data_chpt.Rows.Add();\r
119                 data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
120                 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
121                 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
122                 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
123                 i++;\r
124             }\r
125 \r
126             return data_chpt;\r
127         }\r
128 \r
129         /// <summary>\r
130         /// Function which generates the filename and path automatically based on \r
131         /// the Source Name, DVD title and DVD Chapters\r
132         /// </summary>\r
133         public static string autoName(ComboBox drp_dvdtitle, string chapter_start, string chatper_end, string source, string dest, int format)\r
134         {\r
135             string AutoNamePath = string.Empty;\r
136             if (drp_dvdtitle.Text != "Automatic")\r
137             {\r
138                 // Get the Source Name \r
139                 string sourceName = Path.GetFileNameWithoutExtension(source);\r
140 \r
141                 // Get the Selected Title Number\r
142                 string[] titlesplit = drp_dvdtitle.Text.Split(' ');\r
143                 string dvdTitle = titlesplit[0].Replace("Automatic", "");\r
144 \r
145                 // Get the Chapter Start and Chapter End Numbers\r
146                 string chapterStart = chapter_start.Replace("Auto", "");\r
147                 string chapterFinish = chatper_end.Replace("Auto", "");\r
148                 string combinedChapterTag = chapterStart;\r
149                 if (chapterFinish != chapterStart && chapterFinish != "")\r
150                     combinedChapterTag = chapterStart + "-" + chapterFinish;\r
151 \r
152                 // Get the destination filename.\r
153                 string destination_filename;\r
154                 if (Properties.Settings.Default.autoNameFormat != "")\r
155                 {\r
156                     destination_filename = Properties.Settings.Default.autoNameFormat;\r
157                     destination_filename = destination_filename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);\r
158                 }\r
159                 else\r
160                     destination_filename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
161 \r
162                 // Add the appropriate file extension\r
163                 if (format == 0)\r
164                     destination_filename += ".mp4";\r
165                 else if (format == 1)\r
166                     destination_filename += ".m4v";\r
167                 else if (format == 2)\r
168                     destination_filename += ".mkv";\r
169 \r
170                 // Now work out the path where the file will be stored.\r
171                 // First case: If the destination box doesn't already contain a path, make one.\r
172                 if (!dest.Contains(Path.DirectorySeparatorChar.ToString()))\r
173                 {\r
174                     // If there is an auto name path, use it...\r
175                     if (Properties.Settings.Default.autoNamePath.Trim() != "" && Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
176                         AutoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destination_filename);\r
177                     else // ...otherwise, output to the source directory\r
178                         AutoNamePath = null;\r
179                 }\r
180                 else // Otherwise, use the path that is already there.\r
181                 {\r
182                     // Use the path and change the file extension to match the previous destination\r
183                     AutoNamePath = Path.Combine(Path.GetDirectoryName(dest), destination_filename);\r
184                     AutoNamePath = Path.ChangeExtension(AutoNamePath, Path.GetExtension(dest));\r
185                 }\r
186             }\r
187 \r
188             return AutoNamePath;\r
189         }\r
190 \r
191         /// <summary>\r
192         /// Checks for updates and returns true if an update is available.\r
193         /// </summary>\r
194         /// <param name="debug">Turns on debug mode. Don't use on program startup</param>\r
195         /// <returns>Boolean True = Update available</returns>\r
196         public static Boolean updateCheck(Boolean debug)\r
197         {\r
198             try\r
199             {\r
200                 AppcastReader rssRead = new AppcastReader();\r
201                 rssRead.getInfo(); // Initializes the class.\r
202                 string build = rssRead.build();\r
203 \r
204                 int latest = int.Parse(build);\r
205                 int current = Properties.Settings.Default.hb_build;\r
206                 int skip = Properties.Settings.Default.skipversion;\r
207 \r
208                 if (latest == skip)\r
209                     return false;\r
210 \r
211                 Boolean update = (latest > current);\r
212                 return update;\r
213             }\r
214             catch (Exception exc)\r
215             {\r
216                 if (debug)\r
217                     MessageBox.Show("Unable to check for updates, Please try again later. \n" + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
218                 return false;\r
219             }\r
220         }\r
221 \r
222         /// <summary>\r
223         /// Get's HandBrakes version data from the CLI.\r
224         /// </summary>\r
225         /// <returns>Arraylist of Version Data. 0 = hb_version 1 = hb_build</returns>\r
226         public static void setCliVersionData()\r
227         {\r
228             String line;\r
229 \r
230             // 0 = SVN Build / Version\r
231             // 1 = Build Date\r
232             Process cliProcess = new Process();\r
233             ProcessStartInfo handBrakeCLI = new ProcessStartInfo("HandBrakeCLI.exe", " -u")\r
234                                                 {\r
235                                                     UseShellExecute = false,\r
236                                                     RedirectStandardError = true,\r
237                                                     RedirectStandardOutput = true,\r
238                                                     CreateNoWindow = true\r
239                                                 };\r
240             cliProcess.StartInfo = handBrakeCLI;\r
241 \r
242             try\r
243             {\r
244                 cliProcess.Start();\r
245                 // Retrieve standard output and report back to parent thread until the process is complete\r
246                 TextReader stdOutput = cliProcess.StandardError;\r
247 \r
248                 while (!cliProcess.HasExited)\r
249                 {\r
250                     line = stdOutput.ReadLine() ?? "";\r
251                     Match m = Regex.Match(line, @"HandBrake ([0-9.]*)(svn[0-9M]*) \([0-9]*\)");\r
252 \r
253                     if (m.Success)\r
254                     {\r
255                         string data = line.Replace("(", "").Replace(")", "").Replace("HandBrake ", "");\r
256                         string[] arr = data.Split(' ');\r
257 \r
258                         Properties.Settings.Default.hb_build = int.Parse(arr[1]);\r
259                         Properties.Settings.Default.hb_version = arr[0];\r
260                     }\r
261                     if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.\r
262                     {\r
263                         Process cli = Process.GetProcessById(cliProcess.Id);\r
264                         if (!cli.HasExited)\r
265                             cli.Kill();\r
266                     }\r
267                 }\r
268             }\r
269             catch (Exception e)\r
270             {\r
271                 MessageBox.Show("Unable to retrieve version information from the CLI. \nError:\n" + e);\r
272             }\r
273         }\r
274 \r
275         /// <summary>\r
276         /// Check if the queue recovery file contains records.\r
277         /// If it does, it means the last queue did not complete before HandBrake closed.\r
278         /// So, return a boolean if true. \r
279         /// </summary>\r
280         public static Boolean check_queue_recovery()\r
281         {\r
282             try\r
283             {\r
284                 string tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
285                 if (File.Exists(tempPath))\r
286                 {\r
287                     using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
288                     {\r
289                         List<Job> list = ser.Deserialize(strm) as List<Job>;\r
290                         if (list != null)\r
291                             if (list.Count != 0)\r
292                                 return true;\r
293                     }\r
294                 }\r
295                 return false;\r
296             }\r
297             catch (Exception)\r
298             {\r
299                 return false; // Keep quiet about the error.\r
300             }\r
301         }\r
302 \r
303         /// <summary>\r
304         /// Get the Process ID of HandBrakeCLI for the current instance.\r
305         /// </summary>\r
306         /// <param name="before">List of processes before the new process was started</param>\r
307         /// <returns>Int - Process ID</returns>\r
308         public static int getCliProcess(Process[] before)\r
309         {\r
310             // This is a bit of a cludge. Maybe someone has a better idea on how to impliment this.\r
311             // Since we used CMD to start HandBrakeCLI, we don't get the process ID from hbProc.\r
312             // Instead we take the processes before and after, and get the ID of HandBrakeCLI.exe\r
313             // avoiding any previous instances of HandBrakeCLI.exe in before.\r
314             // Kill the current process.\r
315 \r
316             Process[] hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
317 \r
318             // Another hack. We maybe need to wait a few seconds for HandBrakeCLI to launch\r
319             if (hbProcesses.Length == 0)\r
320             {\r
321                 Thread.Sleep(2000);\r
322                 hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
323             }\r
324 \r
325             Process hbProcess = null;\r
326             if (hbProcesses.Length > 0)\r
327                 foreach (Process process in hbProcesses)\r
328                 {\r
329                     Boolean found = false;\r
330                     // Check if the current CLI instance was running before we started the current one\r
331                     foreach (Process bprocess in before)\r
332                     {\r
333                         if (process.Id == bprocess.Id)\r
334                             found = true;\r
335                     }\r
336 \r
337                     // If it wasn't running before, we found the process we want.\r
338                     if (!found)\r
339                     {\r
340                         hbProcess = process;\r
341                         break;\r
342                     }\r
343                 }\r
344             if (hbProcess != null)\r
345                 return hbProcess.Id;\r
346 \r
347             return -1;\r
348         }\r
349 \r
350     }\r
351 }\r