OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Functions / Main.cs
1 /*  Main.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake.Functions\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.Diagnostics;\r
11     using System.IO;\r
12     using System.Net;\r
13     using System.Reflection;\r
14     using System.Text;\r
15     using System.Text.RegularExpressions;\r
16     using System.Threading;\r
17     using System.Windows.Forms;\r
18     using System.Xml.Serialization;\r
19 \r
20     using HandBrake.ApplicationServices.Model;\r
21     using HandBrake.ApplicationServices.Parsing;\r
22     using HandBrake.ApplicationServices.Services.Interfaces;\r
23 \r
24     using Model;\r
25 \r
26     /// <summary>\r
27     /// Useful functions which various screens can use.\r
28     /// </summary>\r
29     public static class Main\r
30     {\r
31         /// <summary>\r
32         /// The XML Serializer\r
33         /// </summary>\r
34         private static readonly XmlSerializer Ser = new XmlSerializer(typeof(List<Job>));\r
35 \r
36         /// <summary>\r
37         /// Calculate the duration of the selected title and chapters\r
38         /// </summary>\r
39         /// <param name="chapterStart">\r
40         /// The chapter Start.\r
41         /// </param>\r
42         /// <param name="chapterEnd">\r
43         /// The chapter End.\r
44         /// </param>\r
45         /// <param name="selectedTitle">\r
46         /// The selected Title.\r
47         /// </param>\r
48         /// <returns>\r
49         /// The calculated duration.\r
50         /// </returns>\r
51         public static TimeSpan CalculateDuration(int chapterStart, int chapterEnd, Title selectedTitle)\r
52         {\r
53             TimeSpan duration = TimeSpan.FromSeconds(0.0);\r
54             chapterStart++;\r
55             chapterEnd++;\r
56             if (chapterStart != 0 && chapterEnd != 0 && chapterEnd <= selectedTitle.Chapters.Count)\r
57             {\r
58                 for (int i = chapterStart; i <= chapterEnd; i++)\r
59                     duration += selectedTitle.Chapters[i - 1].Duration;\r
60             }\r
61 \r
62             return duration;\r
63         }\r
64 \r
65         /// <summary>\r
66         /// Set's up the DataGridView on the Chapters tab (frmMain)\r
67         /// </summary>\r
68         /// <param name="dataChpt">\r
69         /// The DataGridView Control\r
70         /// </param>\r
71         /// <param name="chapterEnd">\r
72         /// The chapter End.\r
73         /// </param>\r
74         /// <returns>\r
75         /// The chapter naming.\r
76         /// </returns>\r
77         public static DataGridView ChapterNaming(DataGridView dataChpt, string chapterEnd)\r
78         {\r
79             int i = 0, finish = 0;\r
80 \r
81             if (chapterEnd != "Auto")\r
82                 int.TryParse(chapterEnd, out finish);\r
83 \r
84             while (i < finish)\r
85             {\r
86                 int n = dataChpt.Rows.Add();\r
87                 dataChpt.Rows[n].Cells[0].Value = i + 1;\r
88                 dataChpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
89                 dataChpt.Rows[n].Cells[0].ValueType = typeof(int);\r
90                 dataChpt.Rows[n].Cells[1].ValueType = typeof(string);\r
91                 i++;\r
92             }\r
93 \r
94             return dataChpt;\r
95         }\r
96 \r
97         /// <summary>\r
98         /// Import a CSV file which contains Chapter Names\r
99         /// </summary>\r
100         /// <param name="dataChpt">\r
101         /// The DataGridView Control\r
102         /// </param>\r
103         /// <param name="filename">\r
104         /// The filepath and name\r
105         /// </param>\r
106         /// <returns>A Populated DataGridView</returns>\r
107         public static DataGridView ImportChapterNames(DataGridView dataChpt, string filename)\r
108         {\r
109             IDictionary<int, string> chapterMap = new Dictionary<int, string>();\r
110             try\r
111             {\r
112                 StreamReader sr = new StreamReader(filename);\r
113                 string csv = sr.ReadLine();\r
114                 while (csv != null)\r
115                 {\r
116                     if (csv.Trim() != string.Empty)\r
117                     {\r
118                         csv = csv.Replace("\\,", "<!comma!>");\r
119                         string[] contents = csv.Split(',');\r
120                         int chapter;\r
121                         int.TryParse(contents[0], out chapter);\r
122                         chapterMap.Add(chapter, contents[1].Replace("<!comma!>", ","));\r
123                     }\r
124                     csv = sr.ReadLine();\r
125                 }\r
126             }\r
127             catch (Exception)\r
128             {\r
129                 return null;\r
130             }\r
131 \r
132             foreach (DataGridViewRow item in dataChpt.Rows)\r
133             {\r
134                 string name;\r
135                 chapterMap.TryGetValue((int)item.Cells[0].Value, out name);\r
136                 item.Cells[1].Value = name ?? "Chapter " + item.Cells[0].Value;\r
137             }\r
138 \r
139             return dataChpt;\r
140         }\r
141 \r
142         /// <summary>\r
143         /// Create a CSV file with the data from the Main Window Chapters tab\r
144         /// </summary>\r
145         /// <param name="mainWindow">Main Window</param>\r
146         /// <param name="filePathName">Path to save the csv file</param>\r
147         /// <returns>True if successful </returns>\r
148         public static bool SaveChapterMarkersToCsv(frmMain mainWindow, string filePathName)\r
149         {\r
150             try\r
151             {\r
152                 string csv = string.Empty;\r
153 \r
154                 foreach (DataGridViewRow row in mainWindow.data_chpt.Rows)\r
155                 {\r
156                     csv += row.Cells[0].Value.ToString();\r
157                     csv += ",";\r
158                     csv += row.Cells[1].Value.ToString().Replace(",", "\\,");\r
159                     csv += Environment.NewLine;\r
160                 }\r
161                 StreamWriter file = new StreamWriter(filePathName);\r
162                 file.Write(csv);\r
163                 file.Close();\r
164                 file.Dispose();\r
165                 return true;\r
166             }\r
167             catch (Exception exc)\r
168             {\r
169                 frmExceptionWindow exceptionWindow = new frmExceptionWindow();\r
170                 exceptionWindow.Setup("Unable to save Chapter Makrers file! \nChapter marker names will NOT be saved in your encode", exc.ToString());\r
171                 exceptionWindow.ShowDialog();\r
172                 return false;\r
173             }\r
174         }\r
175 \r
176         /// <summary>\r
177         /// Function which generates the filename and path automatically based on \r
178         /// the Source Name, DVD title and DVD Chapters\r
179         /// </summary>\r
180         /// <param name="mainWindow">\r
181         /// The main Window.\r
182         /// </param>\r
183         /// <returns>\r
184         /// The Generated FileName\r
185         /// </returns>\r
186         public static string AutoName(frmMain mainWindow)\r
187         {\r
188             string autoNamePath = string.Empty;\r
189             if (mainWindow.drp_dvdtitle.Text != "Automatic")\r
190             {\r
191                 // Get the Source Name \r
192                 string sourceName = mainWindow.SourceName;\r
193 \r
194                 // Remove any illeagal characters from the source name\r
195                 foreach (char character in Path.GetInvalidFileNameChars())\r
196                 {\r
197                     if (autoNamePath != null)\r
198                     {\r
199                         sourceName = sourceName.Replace(character.ToString(), string.Empty);\r
200                     }\r
201                 }\r
202 \r
203                 if (Properties.Settings.Default.AutoNameRemoveUnderscore)\r
204                     sourceName = sourceName.Replace("_", " ");\r
205 \r
206                 if (Properties.Settings.Default.AutoNameTitleCase)\r
207                     sourceName = TitleCase(sourceName);\r
208 \r
209                 // Get the Selected Title Number\r
210                 string[] titlesplit = mainWindow.drp_dvdtitle.Text.Split(' ');\r
211                 string dvdTitle = titlesplit[0].Replace("Automatic", string.Empty);\r
212 \r
213                 // Get the Chapter Start and Chapter End Numbers\r
214                 string chapterStart = mainWindow.drop_chapterStart.Text.Replace("Auto", string.Empty);\r
215                 string chapterFinish = mainWindow.drop_chapterFinish.Text.Replace("Auto", string.Empty);\r
216                 string combinedChapterTag = chapterStart;\r
217                 if (chapterFinish != chapterStart && chapterFinish != string.Empty)\r
218                     combinedChapterTag = chapterStart + "-" + chapterFinish;\r
219 \r
220                 // Get the destination filename.\r
221                 string destinationFilename;\r
222                 if (Properties.Settings.Default.autoNameFormat != string.Empty)\r
223                 {\r
224                     destinationFilename = Properties.Settings.Default.autoNameFormat;\r
225                     destinationFilename =\r
226                         destinationFilename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace(\r
227                             "{chapters}", combinedChapterTag);\r
228                 }\r
229                 else\r
230                     destinationFilename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
231 \r
232                 // Add the appropriate file extension\r
233                 if (mainWindow.drop_format.SelectedIndex == 0)\r
234                 {\r
235                     if (Properties.Settings.Default.useM4v || mainWindow.Check_ChapterMarkers.Checked ||\r
236                         mainWindow.AudioSettings.RequiresM4V() || mainWindow.Subtitles.RequiresM4V())\r
237                         destinationFilename += ".m4v";\r
238                     else\r
239                         destinationFilename += ".mp4";\r
240                 }\r
241                 else if (mainWindow.drop_format.SelectedIndex == 1)\r
242                     destinationFilename += ".mkv";\r
243 \r
244                 // Now work out the path where the file will be stored.\r
245                 // First case: If the destination box doesn't already contain a path, make one.\r
246                 if (!mainWindow.text_destination.Text.Contains(Path.DirectorySeparatorChar.ToString()))\r
247                 {\r
248                     // If there is an auto name path, use it...\r
249                     if (Properties.Settings.Default.autoNamePath.Trim() != string.Empty &&\r
250                         Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
251                         autoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destinationFilename);\r
252                     else // ...otherwise, output to the source directory\r
253                         autoNamePath = null;\r
254                 }\r
255                 else // Otherwise, use the path that is already there.\r
256                 {\r
257                     // Use the path and change the file extension to match the previous destination\r
258                     autoNamePath = Path.Combine(Path.GetDirectoryName(mainWindow.text_destination.Text),\r
259                                                 destinationFilename);\r
260 \r
261                     if (Path.HasExtension(mainWindow.text_destination.Text))\r
262                         autoNamePath = Path.ChangeExtension(autoNamePath,\r
263                                                             Path.GetExtension(mainWindow.text_destination.Text));\r
264                 }\r
265             }\r
266 \r
267             return autoNamePath;\r
268         }\r
269 \r
270         /// <summary>\r
271         /// Get's HandBrakes version data from the CLI.\r
272         /// </summary>\r
273         public static void SetCliVersionData()\r
274         {\r
275             string line;\r
276 \r
277             // 0 = SVN Build / Version\r
278             // 1 = Build Date\r
279             DateTime lastModified = File.GetLastWriteTime("HandBrakeCLI.exe");\r
280 \r
281             if (Properties.Settings.Default.hb_build != 0 && Properties.Settings.Default.cliLastModified == lastModified)\r
282             {\r
283                 return;\r
284             }   \r
285 \r
286             Properties.Settings.Default.cliLastModified = lastModified;\r
287 \r
288             Process cliProcess = new Process();\r
289             ProcessStartInfo handBrakeCli = new ProcessStartInfo("HandBrakeCLI.exe", " -u -v0")\r
290                                                 {\r
291                                                     UseShellExecute = false,\r
292                                                     RedirectStandardError = true,\r
293                                                     RedirectStandardOutput = true,\r
294                                                     CreateNoWindow = true\r
295                                                 };\r
296             cliProcess.StartInfo = handBrakeCli;\r
297 \r
298             try\r
299             {\r
300                 cliProcess.Start();\r
301 \r
302                 // Retrieve standard output and report back to parent thread until the process is complete\r
303                 TextReader stdOutput = cliProcess.StandardError;\r
304 \r
305                 while (!cliProcess.HasExited)\r
306                 {\r
307                     line = stdOutput.ReadLine() ?? string.Empty;\r
308                     Match m = Regex.Match(line, @"HandBrake ([svnM0-9.]*) \(([0-9]*)\)");\r
309                     Match platform = Regex.Match(line, @"- ([A-Za-z0-9\s ]*) -");\r
310 \r
311                     if (m.Success)\r
312                     {\r
313                         string version = m.Groups[1].Success ? m.Groups[1].Value : string.Empty;\r
314                         string build = m.Groups[2].Success ? m.Groups[2].Value : string.Empty;\r
315 \r
316                         int buildValue;\r
317                         int.TryParse(build, out buildValue);\r
318 \r
319                         Properties.Settings.Default.hb_build = buildValue;\r
320                         Properties.Settings.Default.hb_version = version;\r
321                     }\r
322 \r
323                     if (platform.Success)\r
324                     {\r
325                         Properties.Settings.Default.hb_platform = platform.Value.Replace("-", string.Empty).Trim();\r
326                     }\r
327 \r
328                     if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.\r
329                     {\r
330                         Process cli = Process.GetProcessById(cliProcess.Id);\r
331                         if (!cli.HasExited)\r
332                         {\r
333                             cli.Kill();\r
334                         }\r
335                     }\r
336                 }\r
337 \r
338                 Properties.Settings.Default.Save();\r
339             }\r
340             catch (Exception e)\r
341             {\r
342                 Properties.Settings.Default.hb_build = 0;\r
343                 Properties.Settings.Default.Save();\r
344 \r
345                 frmExceptionWindow exceptionWindow = new frmExceptionWindow();\r
346                 exceptionWindow.Setup("Unable to retrieve version information from the CLI.", e.ToString());\r
347                 exceptionWindow.ShowDialog();\r
348             }\r
349         }\r
350 \r
351         /// <summary>\r
352         /// Check if the queue recovery file contains records.\r
353         /// If it does, it means the last queue did not complete before HandBrake closed.\r
354         /// So, return a boolean if true. \r
355         /// </summary>\r
356         /// <returns>\r
357         /// True if there is a queue to recover.\r
358         /// </returns>\r
359         public static List<string> CheckQueueRecovery()\r
360         {\r
361             try\r
362             {\r
363                 string tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");\r
364                 List<string> queueFiles = new List<string>();\r
365 \r
366                 DirectoryInfo info = new DirectoryInfo(tempPath);\r
367                 FileInfo[] logFiles = info.GetFiles("*.xml");\r
368                 foreach (FileInfo file in logFiles)\r
369                 {\r
370                     if (!file.Name.Contains("hb_queue_recovery"))\r
371                         continue;\r
372 \r
373                     using (FileStream strm = new FileStream(Path.Combine(file.DirectoryName, file.Name), FileMode.Open, FileAccess.Read))\r
374                     {\r
375                         List<Job> list = Ser.Deserialize(strm) as List<Job>;\r
376                         if (list != null)\r
377                         {\r
378                             if (list.Count != 0)\r
379                             {\r
380                                 queueFiles.Add(file.Name);\r
381                             }\r
382                         }\r
383                     }\r
384                 }\r
385 \r
386                 return queueFiles;\r
387             }\r
388             catch (Exception)\r
389             {\r
390                 return new List<string>(); // Keep quiet about the error.\r
391             }\r
392         }\r
393 \r
394         /// <summary>\r
395         /// Recover a queue from file.\r
396         /// </summary>\r
397         /// <param name="encodeQueue">\r
398         /// The encode Queue.\r
399         /// </param>\r
400         public static void RecoverQueue(IQueue encodeQueue)\r
401         {\r
402             DialogResult result = DialogResult.None;\r
403             List<string> queueFiles = CheckQueueRecovery();\r
404             if (queueFiles.Count == 1)\r
405             {\r
406                 result = MessageBox.Show(\r
407                         "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",\r
408                         "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
409             }\r
410             else if (queueFiles.Count > 1)\r
411             {\r
412                 result = MessageBox.Show(\r
413                         "HandBrake has detected multiple unfinished queue files. These will be from multiple instances of HandBrake running. Would you like to recover all unfinished jobs?",\r
414                         "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
415             }\r
416 \r
417             if (result == DialogResult.Yes)\r
418             {\r
419                 foreach (string file in queueFiles)\r
420                 {\r
421                     encodeQueue.LoadQueueFromFile(file); // Start Recovery\r
422                 }\r
423             }\r
424             else\r
425             {\r
426                 if (IsMultiInstance) return; // Don't tamper with the files if we are multi instance\r
427 \r
428                 string tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");\r
429                 foreach (string file in queueFiles)\r
430                 {\r
431                     if (File.Exists(Path.Combine(tempPath, file)))\r
432                         File.Delete(Path.Combine(tempPath, file));\r
433                 }\r
434             }\r
435         }\r
436 \r
437         /// <summary>\r
438         /// Gets a value indicating whether HandBrake is running in multi instance mode\r
439         /// </summary>\r
440         /// <returns>True if the UI has another instance running</returns>\r
441         public static bool IsMultiInstance\r
442         {\r
443             get\r
444             {\r
445                 return Process.GetProcessesByName("HandBrake").Length > 0 ? true : false;\r
446             }\r
447         }\r
448 \r
449         /// <summary>\r
450         ///  Clear all the encode log files.\r
451         /// </summary>\r
452         public static void ClearLogs()\r
453         {\r
454             string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
455             if (Directory.Exists(logDir))\r
456             {\r
457                 DirectoryInfo info = new DirectoryInfo(logDir);\r
458                 FileInfo[] logFiles = info.GetFiles("*.txt");\r
459                 foreach (FileInfo file in logFiles)\r
460                 {\r
461                     if (!file.Name.Contains("last_scan_log") && !file.Name.Contains("last_encode_log"))\r
462                         File.Delete(file.FullName);\r
463                 }\r
464             }\r
465         }\r
466 \r
467         /// <summary>\r
468         /// Clear old log files x days in the past\r
469         /// </summary>\r
470         public static void ClearOldLogs()\r
471         {\r
472             string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
473             if (Directory.Exists(logDir))\r
474             {\r
475                 DirectoryInfo info = new DirectoryInfo(logDir);\r
476                 FileInfo[] logFiles = info.GetFiles("*.txt");\r
477 \r
478                 foreach (FileInfo file in logFiles)\r
479                 {\r
480                     if (file.LastWriteTime < DateTime.Now.AddDays(-30))\r
481                     {\r
482                         if (!file.Name.Contains("last_scan_log.txt") && !file.Name.Contains("last_encode_log.txt"))\r
483                             File.Delete(file.FullName);\r
484                     }\r
485                 }\r
486             }\r
487         }\r
488 \r
489         /// <summary>\r
490         /// Begins checking for an update to HandBrake.\r
491         /// </summary>\r
492         /// <param name="callback">The method that will be called when the check is finished.</param>\r
493         /// <param name="debug">Whether or not to execute this in debug mode.</param>\r
494         public static void BeginCheckForUpdates(AsyncCallback callback, bool debug)\r
495         {\r
496             ThreadPool.QueueUserWorkItem(new WaitCallback(delegate\r
497                                                               {\r
498                                                                   try\r
499                                                                   {\r
500                                                                       // Is this a stable or unstable build?\r
501                                                                       string url =\r
502                                                                           Properties.Settings.Default.hb_build.ToString()\r
503                                                                               .EndsWith("1")\r
504                                                                               ? Properties.Settings.Default.\r
505                                                                                     appcast_unstable\r
506                                                                               : Properties.Settings.Default.appcast;\r
507 \r
508                                                                       // Initialize variables\r
509                                                                       WebRequest request = WebRequest.Create(url);\r
510                                                                       WebResponse response = request.GetResponse();\r
511                                                                       AppcastReader reader = new AppcastReader();\r
512 \r
513                                                                       // Get the data, convert it to a string, and parse it into the AppcastReader\r
514                                                                       reader.GetInfo(\r
515                                                                           new StreamReader(response.GetResponseStream())\r
516                                                                               .ReadToEnd());\r
517 \r
518                                                                       // Further parse the information\r
519                                                                       string build = reader.Build;\r
520 \r
521                                                                       int latest = int.Parse(build);\r
522                                                                       int current = Properties.Settings.Default.hb_build;\r
523                                                                       int skip = Properties.Settings.Default.skipversion;\r
524 \r
525                                                                       // If the user wanted to skip this version, don't report the update\r
526                                                                       if (latest == skip)\r
527                                                                       {\r
528                                                                           UpdateCheckInformation info =\r
529                                                                               new UpdateCheckInformation\r
530                                                                                   {\r
531                                                                                       NewVersionAvailable = false,\r
532                                                                                       BuildInformation = null\r
533                                                                                   };\r
534                                                                           callback(new UpdateCheckResult(debug, info));\r
535                                                                           return;\r
536                                                                       }\r
537 \r
538                                                                       // Set when the last update was\r
539                                                                       Properties.Settings.Default.lastUpdateCheckDate =\r
540                                                                           DateTime.Now;\r
541                                                                       Properties.Settings.Default.Save();\r
542 \r
543                                                                       UpdateCheckInformation info2 =\r
544                                                                           new UpdateCheckInformation\r
545                                                                               {\r
546                                                                                   NewVersionAvailable = latest > current,\r
547                                                                                   BuildInformation = reader\r
548                                                                               };\r
549                                                                       callback(new UpdateCheckResult(debug, info2));\r
550                                                                   }\r
551                                                                   catch (Exception exc)\r
552                                                                   {\r
553                                                                       callback(new UpdateCheckResult(debug, new UpdateCheckInformation { Error = exc }));\r
554                                                                   }\r
555                                                               }));\r
556         }\r
557 \r
558         /// <summary>\r
559         /// End Check for Updates\r
560         /// </summary>\r
561         /// <param name="result">\r
562         /// The result.\r
563         /// </param>\r
564         /// <returns>\r
565         /// Update Check information\r
566         /// </returns>\r
567         public static UpdateCheckInformation EndCheckForUpdates(IAsyncResult result)\r
568         {\r
569             UpdateCheckResult checkResult = (UpdateCheckResult)result;\r
570             return checkResult.Result;\r
571         }\r
572 \r
573         /// <summary>\r
574         /// Map languages and their iso639_2 value into a IDictionary\r
575         /// </summary>\r
576         /// <returns>A Dictionary containing the language and iso code</returns>\r
577         public static IDictionary<string, string> MapLanguages()\r
578         {\r
579             IDictionary<string, string> languageMap = new Dictionary<string, string>\r
580                                                           {\r
581                                                               {"Any", "und"}, \r
582                                                               {"Afar", "aar"}, \r
583                                                               {"Abkhazian", "abk"}, \r
584                                                               {"Afrikaans", "afr"}, \r
585                                                               {"Akan", "aka"}, \r
586                                                               {"Albanian", "sqi"}, \r
587                                                               {"Amharic", "amh"}, \r
588                                                               {"Arabic", "ara"}, \r
589                                                               {"Aragonese", "arg"}, \r
590                                                               {"Armenian", "hye"}, \r
591                                                               {"Assamese", "asm"}, \r
592                                                               {"Avaric", "ava"}, \r
593                                                               {"Avestan", "ave"}, \r
594                                                               {"Aymara", "aym"}, \r
595                                                               {"Azerbaijani", "aze"}, \r
596                                                               {"Bashkir", "bak"}, \r
597                                                               {"Bambara", "bam"}, \r
598                                                               {"Basque", "eus"}, \r
599                                                               {"Belarusian", "bel"}, \r
600                                                               {"Bengali", "ben"}, \r
601                                                               {"Bihari", "bih"}, \r
602                                                               {"Bislama", "bis"}, \r
603                                                               {"Bosnian", "bos"}, \r
604                                                               {"Breton", "bre"}, \r
605                                                               {"Bulgarian", "bul"}, \r
606                                                               {"Burmese", "mya"}, \r
607                                                               {"Catalan", "cat"}, \r
608                                                               {"Chamorro", "cha"}, \r
609                                                               {"Chechen", "che"}, \r
610                                                               {"Chinese", "zho"}, \r
611                                                               {"Church Slavic", "chu"}, \r
612                                                               {"Chuvash", "chv"}, \r
613                                                               {"Cornish", "cor"}, \r
614                                                               {"Corsican", "cos"}, \r
615                                                               {"Cree", "cre"}, \r
616                                                               {"Czech", "ces"}, \r
617                                                               {"Dansk", "dan"}, \r
618                                                               {"Divehi", "div"}, \r
619                                                               {"Nederlands", "nld"}, \r
620                                                               {"Dzongkha", "dzo"}, \r
621                                                               {"English", "eng"}, \r
622                                                               {"Esperanto", "epo"}, \r
623                                                               {"Estonian", "est"}, \r
624                                                               {"Ewe", "ewe"}, \r
625                                                               {"Faroese", "fao"}, \r
626                                                               {"Fijian", "fij"}, \r
627                                                               {"Suomi", "fin"}, \r
628                                                               {"Francais", "fra"}, \r
629                                                               {"Western Frisian", "fry"}, \r
630                                                               {"Fulah", "ful"}, \r
631                                                               {"Georgian", "kat"}, \r
632                                                               {"Deutsch", "deu"}, \r
633                                                               {"Gaelic (Scots)", "gla"}, \r
634                                                               {"Irish", "gle"}, \r
635                                                               {"Galician", "glg"}, \r
636                                                               {"Manx", "glv"}, \r
637                                                               {"Greek Modern", "ell"}, \r
638                                                               {"Guarani", "grn"}, \r
639                                                               {"Gujarati", "guj"}, \r
640                                                               {"Haitian", "hat"}, \r
641                                                               {"Hausa", "hau"}, \r
642                                                               {"Hebrew", "heb"}, \r
643                                                               {"Herero", "her"}, \r
644                                                               {"Hindi", "hin"}, \r
645                                                               {"Hiri Motu", "hmo"}, \r
646                                                               {"Magyar", "hun"}, \r
647                                                               {"Igbo", "ibo"}, \r
648                                                               {"Islenska", "isl"}, \r
649                                                               {"Ido", "ido"}, \r
650                                                               {"Sichuan Yi", "iii"}, \r
651                                                               {"Inuktitut", "iku"}, \r
652                                                               {"Interlingue", "ile"}, \r
653                                                               {"Interlingua", "ina"}, \r
654                                                               {"Indonesian", "ind"}, \r
655                                                               {"Inupiaq", "ipk"}, \r
656                                                               {"Italiano", "ita"}, \r
657                                                               {"Javanese", "jav"}, \r
658                                                               {"Japanese", "jpn"}, \r
659                                                               {"Kalaallisut", "kal"}, \r
660                                                               {"Kannada", "kan"}, \r
661                                                               {"Kashmiri", "kas"}, \r
662                                                               {"Kanuri", "kau"}, \r
663                                                               {"Kazakh", "kaz"}, \r
664                                                               {"Central Khmer", "khm"}, \r
665                                                               {"Kikuyu", "kik"}, \r
666                                                               {"Kinyarwanda", "kin"}, \r
667                                                               {"Kirghiz", "kir"}, \r
668                                                               {"Komi", "kom"}, \r
669                                                               {"Kongo", "kon"}, \r
670                                                               {"Korean", "kor"}, \r
671                                                               {"Kuanyama", "kua"}, \r
672                                                               {"Kurdish", "kur"}, \r
673                                                               {"Lao", "lao"}, \r
674                                                               {"Latin", "lat"}, \r
675                                                               {"Latvian", "lav"}, \r
676                                                               {"Limburgan", "lim"}, \r
677                                                               {"Lingala", "lin"}, \r
678                                                               {"Lithuanian", "lit"}, \r
679                                                               {"Luxembourgish", "ltz"}, \r
680                                                               {"Luba-Katanga", "lub"}, \r
681                                                               {"Ganda", "lug"}, \r
682                                                               {"Macedonian", "mkd"}, \r
683                                                               {"Marshallese", "mah"}, \r
684                                                               {"Malayalam", "mal"}, \r
685                                                               {"Maori", "mri"}, \r
686                                                               {"Marathi", "mar"}, \r
687                                                               {"Malay", "msa"}, \r
688                                                               {"Malagasy", "mlg"}, \r
689                                                               {"Maltese", "mlt"}, \r
690                                                               {"Moldavian", "mol"}, \r
691                                                               {"Mongolian", "mon"}, \r
692                                                               {"Nauru", "nau"}, \r
693                                                               {"Navajo", "nav"}, \r
694                                                               {"Ndebele, South", "nbl"}, \r
695                                                               {"Ndebele, North", "nde"}, \r
696                                                               {"Ndonga", "ndo"}, \r
697                                                               {"Nepali", "nep"}, \r
698                                                               {"Norwegian Nynorsk", "nno"}, \r
699                                                               {"Norwegian Bokmål", "nob"}, \r
700                                                               {"Norsk", "nor"}, \r
701                                                               {"Chichewa; Nyanja", "nya"}, \r
702                                                               {"Occitan", "oci"}, \r
703                                                               {"Ojibwa", "oji"}, \r
704                                                               {"Oriya", "ori"}, \r
705                                                               {"Oromo", "orm"}, \r
706                                                               {"Ossetian", "oss"}, \r
707                                                               {"Panjabi", "pan"}, \r
708                                                               {"Persian", "fas"}, \r
709                                                               {"Pali", "pli"}, \r
710                                                               {"Polish", "pol"}, \r
711                                                               {"Portugues", "por"}, \r
712                                                               {"Pushto", "pus"}, \r
713                                                               {"Quechua", "que"}, \r
714                                                               {"Romansh", "roh"}, \r
715                                                               {"Romanian", "ron"}, \r
716                                                               {"Rundi", "run"}, \r
717                                                               {"Russian", "rus"}, \r
718                                                               {"Sango", "sag"}, \r
719                                                               {"Sanskrit", "san"}, \r
720                                                               {"Serbian", "srp"}, \r
721                                                               {"Hrvatski", "hrv"}, \r
722                                                               {"Sinhala", "sin"}, \r
723                                                               {"Slovak", "slk"}, \r
724                                                               {"Slovenian", "slv"}, \r
725                                                               {"Northern Sami", "sme"}, \r
726                                                               {"Samoan", "smo"}, \r
727                                                               {"Shona", "sna"}, \r
728                                                               {"Sindhi", "snd"}, \r
729                                                               {"Somali", "som"}, \r
730                                                               {"Sotho Southern", "sot"}, \r
731                                                               {"Espanol", "spa"}, \r
732                                                               {"Sardinian", "srd"}, \r
733                                                               {"Swati", "ssw"}, \r
734                                                               {"Sundanese", "sun"}, \r
735                                                               {"Swahili", "swa"}, \r
736                                                               {"Svenska", "swe"}, \r
737                                                               {"Tahitian", "tah"}, \r
738                                                               {"Tamil", "tam"}, \r
739                                                               {"Tatar", "tat"}, \r
740                                                               {"Telugu", "tel"}, \r
741                                                               {"Tajik", "tgk"}, \r
742                                                               {"Tagalog", "tgl"}, \r
743                                                               {"Thai", "tha"}, \r
744                                                               {"Tibetan", "bod"}, \r
745                                                               {"Tigrinya", "tir"}, \r
746                                                               {"Tonga", "ton"}, \r
747                                                               {"Tswana", "tsn"}, \r
748                                                               {"Tsonga", "tso"}, \r
749                                                               {"Turkmen", "tuk"}, \r
750                                                               {"Turkish", "tur"}, \r
751                                                               {"Twi", "twi"}, \r
752                                                               {"Uighur", "uig"}, \r
753                                                               {"Ukrainian", "ukr"}, \r
754                                                               {"Urdu", "urd"}, \r
755                                                               {"Uzbek", "uzb"}, \r
756                                                               {"Venda", "ven"}, \r
757                                                               {"Vietnamese", "vie"}, \r
758                                                               {"Volapük", "vol"}, \r
759                                                               {"Welsh", "cym"}, \r
760                                                               {"Walloon", "wln"}, \r
761                                                               {"Wolof", "wol"}, \r
762                                                               {"Xhosa", "xho"}, \r
763                                                               {"Yiddish", "yid"}, \r
764                                                               {"Yoruba", "yor"}, \r
765                                                               {"Zhuang", "zha"}, \r
766                                                               {"Zulu", "zul"}\r
767                                                           };\r
768             return languageMap;\r
769         }\r
770 \r
771         /// <summary>\r
772         /// Get a list of available DVD drives which are ready and contain DVD content.\r
773         /// </summary>\r
774         /// <returns>A List of Drives with their details</returns>\r
775         public static List<DriveInformation> GetDrives()\r
776         {\r
777             List<DriveInformation> drives = new List<DriveInformation>();\r
778             DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();\r
779             int id = 0;\r
780             foreach (DriveInfo curDrive in theCollectionOfDrives)\r
781             {\r
782                 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady &&\r
783                     File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))\r
784                 {\r
785                     drives.Add(new DriveInformation\r
786                                    {\r
787                                        Id = id,\r
788                                        VolumeLabel = curDrive.VolumeLabel,\r
789                                        RootDirectory = curDrive.RootDirectory + "VIDEO_TS"\r
790                                    });\r
791                     id++;\r
792                 }\r
793             }\r
794             return drives;\r
795         }\r
796 \r
797         /// <summary>\r
798         /// Change a string to Title Case/\r
799         /// </summary>\r
800         /// <param name="input">\r
801         /// The input.\r
802         /// </param>\r
803         /// <returns>\r
804         /// A string in title case.\r
805         /// </returns>\r
806         public static string TitleCase(string input)\r
807         {\r
808             string[] tokens = input.Split(' ');\r
809             StringBuilder sb = new StringBuilder(input.Length);\r
810             foreach (string s in tokens)\r
811             {\r
812                 sb.Append(s[0].ToString().ToUpper());\r
813                 sb.Append(s.Substring(1).ToLower());\r
814                 sb.Append(" ");\r
815             }\r
816 \r
817             return sb.ToString().Trim();\r
818         }\r
819 \r
820         /// <summary>\r
821         /// Show the Exception Window\r
822         /// </summary>\r
823         /// <param name="shortError">\r
824         /// The short error.\r
825         /// </param>\r
826         /// <param name="longError">\r
827         /// The long error.\r
828         /// </param>\r
829         public static void ShowExceptiowWindow(string shortError, string longError)\r
830         {\r
831             frmExceptionWindow exceptionWindow = new frmExceptionWindow();\r
832             exceptionWindow.Setup(shortError, longError);\r
833             exceptionWindow.Show();\r
834         }\r
835 \r
836         /// <summary>\r
837         /// Get The Source from the CLI Query\r
838         /// </summary>\r
839         /// <param name="query">Full CLI Query</param>\r
840         /// <returns>The Source Path</returns>\r
841         public static string GetSourceFromQuery(string query)\r
842         {\r
843             int startIndex = query.IndexOf("-i \"");\r
844             if (startIndex != -1)\r
845             {\r
846                 string input = query.Substring(startIndex).Replace("-i \"", string.Empty).Trim();\r
847 \r
848                 int closeIndex = input.IndexOf('"');\r
849 \r
850                 return closeIndex == -1 ? "Unknown" : input.Substring(0, closeIndex);\r
851             }\r
852 \r
853             return "Unknown";\r
854         }\r
855 \r
856         /// <summary>\r
857         /// Get the Destination from the CLI Query\r
858         /// </summary>\r
859         /// <param name="query">Full CLI Query</param>\r
860         /// <returns>The Destination path</returns>\r
861         public static string GetDestinationFromQuery(string query)\r
862         {\r
863             int startIndex = query.IndexOf("-o \"");\r
864             if (startIndex != -1)\r
865             {\r
866                 string output = query.Substring(startIndex).Replace("-o \"", string.Empty).Trim();\r
867 \r
868                 int closeIndex = output.IndexOf('"');\r
869 \r
870                 return closeIndex == -1 ? "Unknown" : output.Substring(0, closeIndex);\r
871             }\r
872 \r
873             return "Unknown";\r
874         }\r
875     }\r
876 }