OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmMain.cs
1 /*  frmMain.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\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.ComponentModel;\r
11     using System.Diagnostics;\r
12     using System.Drawing;\r
13     using System.Globalization;\r
14     using System.IO;\r
15     using System.Reflection;\r
16     using System.Threading;\r
17     using System.Windows.Forms;\r
18     using Functions;\r
19 \r
20     using HandBrake.ApplicationServices.Model;\r
21     using HandBrake.ApplicationServices.Parsing;\r
22     using HandBrake.ApplicationServices.Services;\r
23     using HandBrake.ApplicationServices.Services.Interfaces;\r
24 \r
25     using Model;\r
26     using Presets;\r
27     using Properties;\r
28 \r
29     public partial class frmMain : Form\r
30     {\r
31         // Objects which may be used by one or more other objects *************\r
32         private IQueue encodeQueue = new Queue();\r
33         private PresetsHandler presetHandler = new PresetsHandler();\r
34 \r
35         // Windows ************************************************************\r
36         private frmQueue queueWindow;\r
37         private frmPreview qtpreview;\r
38         private frmActivityWindow activityWindow;\r
39         private frmSplashScreen splash = new frmSplashScreen();\r
40 \r
41         // Globals: Mainly used for tracking. *********************************\r
42         public Title selectedTitle;\r
43         public string sourcePath;\r
44         private SourceType selectedSourceType;\r
45         private string dvdDrivePath;\r
46         private string dvdDriveLabel;\r
47         private Preset currentlySelectedPreset;\r
48         private DVD currentSource;\r
49         private IScan SourceScan = new ScanService();\r
50         private List<DriveInformation> drives;\r
51 \r
52         // Delegates **********************************************************\r
53         private delegate void UpdateWindowHandler();\r
54 \r
55         // Applicaiton Startup ************************************************\r
56 \r
57         #region Properties\r
58 \r
59         /// <summary>\r
60         /// Gets SourceName.\r
61         /// </summary>\r
62         public string SourceName\r
63         {\r
64             get\r
65             {\r
66                 if (this.selectedSourceType == SourceType.DvdDrive)\r
67                 {\r
68                     return this.dvdDriveLabel;\r
69                 }\r
70 \r
71                 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")\r
72                     return Path.GetFileNameWithoutExtension(this.sourcePath);\r
73 \r
74                 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));\r
75             }\r
76         }\r
77 \r
78         #endregion\r
79 \r
80         #region Application Startup\r
81 \r
82         /// <summary>\r
83         /// Initializes a new instance of the <see cref="frmMain"/> class.\r
84         /// </summary>\r
85         /// <param name="args">\r
86         /// The arguments passed in on application startup.\r
87         /// </param>\r
88         public frmMain(string[] args)\r
89         {\r
90             // Load and setup the splash screen in this thread\r
91             splash.Show(this);\r
92             Label lblStatus = new Label { Size = new Size(150, 20), Location = new Point(182, 102) };\r
93             splash.Controls.Add(lblStatus);\r
94 \r
95             InitializeComponent();\r
96 \r
97             // Update the users config file with the CLI version data.\r
98             UpdateSplashStatus(lblStatus, "Checking CLI Version Data ...");\r
99             Main.SetCliVersionData();\r
100             Main.CheckForValidCliVersion();\r
101 \r
102             if (Settings.Default.hb_version.Contains("svn"))\r
103             {\r
104                 Version v = Assembly.GetExecutingAssembly().GetName().Version;\r
105                 this.Text += " " + v.ToString(4);\r
106             }\r
107 \r
108             // Show the form, but leave disabled until preloading is complete then show the main form)\r
109             this.Enabled = false;\r
110             this.Show();\r
111             Application.DoEvents(); // Forces frmMain to draw\r
112 \r
113             // Check for new versions, if update checking is enabled\r
114             if (Properties.Settings.Default.updateStatus)\r
115             {\r
116                 DateTime now = DateTime.Now;\r
117                 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;\r
118                 TimeSpan elapsed = now.Subtract(lastCheck);\r
119                 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)\r
120                 {\r
121                     UpdateSplashStatus(lblStatus, "Checking for updates ...");\r
122                     Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);\r
123                 }\r
124             }\r
125 \r
126             // Clear the log files in the background\r
127             if (Properties.Settings.Default.clearOldLogs)\r
128             {\r
129                 UpdateSplashStatus(lblStatus, "Clearing Old Log Files ..");\r
130                 Thread clearLog = new Thread(Main.ClearOldLogs);\r
131                 clearLog.Start();\r
132             }\r
133 \r
134             // Setup the GUI components\r
135             UpdateSplashStatus(lblStatus, "Setting up the GUI ...");\r
136             LoadPresetPanel(); // Load the Preset Panel\r
137             treeView_presets.ExpandAll();\r
138             lbl_encode.Text = string.Empty;\r
139             drop_mode.SelectedIndex = 0;\r
140             queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue\r
141             if (!Properties.Settings.Default.QueryEditorTab)\r
142                 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.\r
143             if (Properties.Settings.Default.tooltipEnable)\r
144                 ToolTip.Active = true;\r
145 \r
146             // Load the user's default settings or Normal Preset\r
147             if (Properties.Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)\r
148             {\r
149                 string query = presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).Query;\r
150                 if (query != null)\r
151                 {\r
152                     x264Panel.Reset2Defaults();\r
153 \r
154                     QueryParser presetQuery = QueryParser.Parse(query);\r
155                     PresetLoader.LoadPreset(this, presetQuery, Properties.Settings.Default.defaultPreset);\r
156 \r
157                     x264Panel.StandardizeOptString();\r
158                     x264Panel.SetCurrentSettingsInPanel();\r
159                 }\r
160             }\r
161             else\r
162                 loadNormalPreset();\r
163 \r
164             // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)\r
165             GrowlCommunicator.Register();\r
166 \r
167             // Finished Loading\r
168             UpdateSplashStatus(lblStatus, "Loading Complete.");\r
169             splash.Close();\r
170             splash.Dispose();\r
171             this.Enabled = true;\r
172 \r
173             // Event Handlers and Queue Recovery\r
174             events();\r
175             queueRecovery();\r
176 \r
177             // If have a file passed in via command arguemtents, check it's a file and try scanning it.\r
178             if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))\r
179             {\r
180                 this.StartScan(args[0], 0);\r
181             }\r
182         }\r
183 \r
184         private void UpdateCheckDone(IAsyncResult result)\r
185         {\r
186             if (InvokeRequired)\r
187             {\r
188                 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));\r
189                 return;\r
190             }\r
191 \r
192             UpdateCheckInformation info;\r
193 \r
194             try\r
195             {\r
196                 info = Main.EndCheckForUpdates(result);\r
197 \r
198                 if (info.NewVersionAvailable)\r
199                 {\r
200                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
201                     updateWindow.ShowDialog();\r
202                 }\r
203             }\r
204             catch (Exception ex)\r
205             {\r
206                 if ((bool)result.AsyncState)\r
207                     Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());\r
208             }\r
209         }\r
210 \r
211         // Startup Functions   \r
212         private void queueRecovery()\r
213         {\r
214             if (Main.CheckQueueRecovery())\r
215             {\r
216                 DialogResult result =\r
217                     MessageBox.Show(\r
218                         "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",\r
219                         "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
220 \r
221                 if (result == DialogResult.Yes)\r
222                     encodeQueue.LoadQueueFromFile("hb_queue_recovery.xml"); // Start Recovery\r
223                 else\r
224                 {\r
225                     // Remove the Queue recovery file if the user doesn't want to recovery the last queue.\r
226                     string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
227                     if (File.Exists(queuePath))\r
228                         File.Delete(queuePath);\r
229                 }\r
230             }\r
231         }\r
232 \r
233         private void UpdateSplashStatus(Label status, string text)\r
234         {\r
235             status.Text = text;\r
236             Application.DoEvents();\r
237         }\r
238 \r
239         #endregion\r
240 \r
241         #region Events\r
242 \r
243         // Encoding Events for setting up the GUI\r
244         private void events()\r
245         {\r
246             // Handle Widget changes when preset is selected.\r
247             RegisterPresetEventHandler();\r
248 \r
249             // Handle Window Resize\r
250             if (Properties.Settings.Default.MainWindowMinimize)\r
251                 this.Resize += new EventHandler(frmMain_Resize);\r
252 \r
253             // Handle Encode Start / Finish / Pause\r
254             encodeQueue.EncodeStarted += new EventHandler(encodeStarted);\r
255             encodeQueue.EncodeEnded += new EventHandler(encodeEnded);\r
256 \r
257             // Handle a file being draged onto the GUI.\r
258             this.DragEnter += new DragEventHandler(frmMain_DragEnter);\r
259             this.DragDrop += new DragEventHandler(frmMain_DragDrop);\r
260         }\r
261 \r
262         // Change the preset label to custom when a user changes a setting. Don't want to give the impression that users can change settings and still be using a preset\r
263         private void RegisterPresetEventHandler()\r
264         {\r
265             // Output Settings\r
266             drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
267             check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);\r
268             check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);\r
269             check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);\r
270 \r
271             // Picture Settings\r
272             PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);\r
273 \r
274             // Filter Settings\r
275             Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);\r
276 \r
277             // Video Tab\r
278             drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
279             check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);\r
280             check_turbo.CheckedChanged += new EventHandler(changePresetLabel);\r
281             text_filesize.TextChanged += new EventHandler(changePresetLabel);\r
282             text_bitrate.TextChanged += new EventHandler(changePresetLabel);\r
283             slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);\r
284 \r
285             // Audio Panel\r
286             AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);\r
287 \r
288             // Advanced Tab\r
289             x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);\r
290         }\r
291 \r
292         private void UnRegisterPresetEventHandler()\r
293         {\r
294             // Output Settings \r
295             drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
296             check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);\r
297             check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);\r
298             check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);\r
299 \r
300             // Picture Settings\r
301             PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);\r
302 \r
303             // Filter Settings\r
304             Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);\r
305 \r
306             // Video Tab\r
307             drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
308             check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);\r
309             check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);\r
310             text_filesize.TextChanged -= new EventHandler(changePresetLabel);\r
311             text_bitrate.TextChanged -= new EventHandler(changePresetLabel);\r
312             slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);\r
313 \r
314             // Audio Panel\r
315             AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);\r
316 \r
317             // Advanced Tab\r
318             x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);\r
319         }\r
320 \r
321         private void changePresetLabel(object sender, EventArgs e)\r
322         {\r
323             labelPreset.Text = "Output Settings (Preset: Custom)";\r
324             this.currentlySelectedPreset = null;\r
325         }\r
326 \r
327         private static void frmMain_DragEnter(object sender, DragEventArgs e)\r
328         {\r
329             if (e.Data.GetDataPresent(DataFormats.FileDrop, false))\r
330                 e.Effect = DragDropEffects.All;\r
331         }\r
332 \r
333         private void frmMain_DragDrop(object sender, DragEventArgs e)\r
334         {\r
335             string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];\r
336             sourcePath = string.Empty;\r
337 \r
338             if (fileList != null)\r
339             {\r
340                 if (!string.IsNullOrEmpty(fileList[0]))\r
341                 {\r
342                     this.selectedSourceType = SourceType.VideoFile;\r
343                     StartScan(fileList[0], 0);\r
344                 }\r
345                 else\r
346                     UpdateSourceLabel();\r
347             }\r
348             else\r
349                 UpdateSourceLabel();\r
350         }\r
351 \r
352         private void encodeStarted(object sender, EventArgs e)\r
353         {\r
354             SetEncodeStarted();\r
355             encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;\r
356         }\r
357 \r
358         private void encodeEnded(object sender, EventArgs e)\r
359         {\r
360             encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;\r
361             SetEncodeFinished();\r
362         }\r
363         #endregion\r
364 \r
365         // User Interface Menus / Tool Strips *********************************\r
366 \r
367         #region File Menu\r
368 \r
369         /// <summary>\r
370         /// Kill The scan menu Item\r
371         /// </summary>\r
372         /// <param name="sender">\r
373         /// The sender.\r
374         /// </param>\r
375         /// <param name="e">\r
376         /// The e.\r
377         /// </param>\r
378         private void mnu_killCLI_Click(object sender, EventArgs e)\r
379         {\r
380             KillScan();\r
381         }\r
382 \r
383         /// <summary>\r
384         /// Exit the Application Menu Item\r
385         /// </summary>\r
386         /// <param name="sender">\r
387         /// The sender.\r
388         /// </param>\r
389         /// <param name="e">\r
390         /// The e.\r
391         /// </param>\r
392         private void mnu_exit_Click(object sender, EventArgs e)\r
393         {\r
394             Application.Exit();\r
395         }\r
396 \r
397         #endregion\r
398 \r
399         #region Tools Menu\r
400 \r
401         /// <summary>\r
402         /// Menu - Start Button\r
403         /// </summary>\r
404         /// <param name="sender">\r
405         /// The sender.\r
406         /// </param>\r
407         /// <param name="e">\r
408         /// The e.\r
409         /// </param>\r
410         private void mnu_encode_Click(object sender, EventArgs e)\r
411         {\r
412             queueWindow.Show();\r
413         }\r
414 \r
415         /// <summary>\r
416         /// Menu - Display the Log Window\r
417         /// </summary>\r
418         /// <param name="sender">\r
419         /// The sender.\r
420         /// </param>\r
421         /// <param name="e">\r
422         /// The e.\r
423         /// </param>\r
424         private void mnu_encodeLog_Click(object sender, EventArgs e)\r
425         {\r
426             frmActivityWindow dvdInfoWindow = new frmActivityWindow(encodeQueue, SourceScan);\r
427             dvdInfoWindow.Show();\r
428         }\r
429 \r
430         /// <summary>\r
431         /// Menu - Display the Options Window\r
432         /// </summary>\r
433         /// <param name="sender">\r
434         /// The sender.\r
435         /// </param>\r
436         /// <param name="e">\r
437         /// The e.\r
438         /// </param>\r
439         private void mnu_options_Click(object sender, EventArgs e)\r
440         {\r
441             Form options = new frmOptions(this);\r
442             options.ShowDialog();\r
443         }\r
444 \r
445         #endregion\r
446 \r
447         #region Presets Menu\r
448 \r
449         /// <summary>\r
450         /// Reset the Built in Presets\r
451         /// </summary>\r
452         /// <param name="sender">\r
453         /// The sender.\r
454         /// </param>\r
455         /// <param name="e">\r
456         /// The e.\r
457         /// </param>\r
458         private void mnu_presetReset_Click(object sender, EventArgs e)\r
459         {\r
460             presetHandler.UpdateBuiltInPresets();\r
461             LoadPresetPanel();\r
462             if (treeView_presets.Nodes.Count == 0)\r
463                 MessageBox.Show(\r
464                     "Unable to load the presets.xml file. Please select \"Update Built-in Presets\" from the Presets Menu. \nMake sure you are running the program in Admin mode if running on Vista. See Windows FAQ for details!",\r
465                     "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
466             else\r
467                 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
468 \r
469             treeView_presets.ExpandAll();\r
470         }\r
471 \r
472         /// <summary>\r
473         /// Delete the selected preset\r
474         /// </summary>\r
475         /// <param name="sender">\r
476         /// The sender.\r
477         /// </param>\r
478         /// <param name="e">\r
479         /// The e.\r
480         /// </param>\r
481         private void mnu_delete_preset_Click(object sender, EventArgs e)\r
482         {\r
483             presetHandler.RemoveBuiltInPresets();\r
484             LoadPresetPanel(); // Reload the preset panel\r
485         }\r
486 \r
487         /// <summary>\r
488         /// Select the Normal preset\r
489         /// </summary>\r
490         /// <param name="sender">\r
491         /// The sender.\r
492         /// </param>\r
493         /// <param name="e">\r
494         /// The e.\r
495         /// </param>\r
496         private void mnu_SelectDefault_Click(object sender, EventArgs e)\r
497         {\r
498             loadNormalPreset();\r
499         }\r
500 \r
501         /// <summary>\r
502         /// Import a plist Preset\r
503         /// </summary>\r
504         /// <param name="sender">\r
505         /// The sender.\r
506         /// </param>\r
507         /// <param name="e">\r
508         /// The e.\r
509         /// </param>\r
510         private void mnu_importMacPreset_Click(object sender, EventArgs e)\r
511         {\r
512             ImportPreset();\r
513         }\r
514 \r
515         /// <summary>\r
516         /// Export a Plist Preset\r
517         /// </summary>\r
518         /// <param name="sender">\r
519         /// The sender.\r
520         /// </param>\r
521         /// <param name="e">\r
522         /// The e.\r
523         /// </param>\r
524         private void mnu_exportMacPreset_Click(object sender, EventArgs e)\r
525         {\r
526             ExportPreset();\r
527         }\r
528 \r
529         /// <summary>\r
530         /// Create a new Preset\r
531         /// </summary>\r
532         /// <param name="sender">\r
533         /// The sender.\r
534         /// </param>\r
535         /// <param name="e">\r
536         /// The e.\r
537         /// </param>\r
538         private void btn_new_preset_Click(object sender, EventArgs e)\r
539         {\r
540             Form preset = new frmAddPreset(this, presetHandler);\r
541             if (preset.ShowDialog() == DialogResult.OK)\r
542             {\r
543                 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };\r
544                 treeView_presets.Nodes.Add(presetTreeview);\r
545                 presetHandler.LastPresetAdded = null;\r
546             }\r
547         }\r
548 \r
549         #endregion\r
550 \r
551         #region Help Menu\r
552 \r
553         /// <summary>\r
554         /// Menu - Display the User Guide Web Page\r
555         /// </summary>\r
556         /// <param name="sender">\r
557         /// The sender.\r
558         /// </param>\r
559         /// <param name="e">\r
560         /// The e.\r
561         /// </param>\r
562         private void mnu_user_guide_Click(object sender, EventArgs e)\r
563         {\r
564             Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");\r
565         }\r
566 \r
567         /// <summary>\r
568         /// Menu - Check for Updates\r
569         /// </summary>\r
570         /// <param name="sender">\r
571         /// The sender.\r
572         /// </param>\r
573         /// <param name="e">\r
574         /// The e.\r
575         /// </param>\r
576         private void mnu_UpdateCheck_Click(object sender, EventArgs e)\r
577         {\r
578             lbl_updateCheck.Visible = true;\r
579             Main.BeginCheckForUpdates(new AsyncCallback(this.UpdateCheckDoneMenu), false);\r
580         }\r
581 \r
582         /// <summary>\r
583         /// Menu - Display the About Window\r
584         /// </summary>\r
585         /// <param name="sender">\r
586         /// The sender.\r
587         /// </param>\r
588         /// <param name="e">\r
589         /// The e.\r
590         /// </param>\r
591         private void mnu_about_Click(object sender, EventArgs e)\r
592         {\r
593             using (frmAbout About = new frmAbout())\r
594             {\r
595                 About.ShowDialog();\r
596             }\r
597         }\r
598 \r
599         #endregion\r
600 \r
601         #region Preset Bar\r
602 \r
603         /// <summary>\r
604         /// RMenu - Expand All\r
605         /// </summary>\r
606         /// <param name="sender">\r
607         /// The sender.\r
608         /// </param>\r
609         /// <param name="e">\r
610         /// The e.\r
611         /// </param>\r
612         private void pmnu_expandAll_Click(object sender, EventArgs e)\r
613         {\r
614             treeView_presets.ExpandAll();\r
615         }\r
616 \r
617         /// <summary>\r
618         /// RMenu - Collaspe All\r
619         /// </summary>\r
620         /// <param name="sender">\r
621         /// The sender.\r
622         /// </param>\r
623         /// <param name="e">\r
624         /// The e.\r
625         /// </param>\r
626         private void pmnu_collapse_Click(object sender, EventArgs e)\r
627         {\r
628             treeView_presets.CollapseAll();\r
629         }\r
630 \r
631         /// <summary>\r
632         /// Menu - Import Preset\r
633         /// </summary>\r
634         /// <param name="sender">\r
635         /// The sender.\r
636         /// </param>\r
637         /// <param name="e">\r
638         /// The e.\r
639         /// </param>\r
640         private void pmnu_import_Click(object sender, EventArgs e)\r
641         {\r
642             ImportPreset();\r
643         }\r
644 \r
645         /// <summary>\r
646         /// RMenu - Save Changes to Preset\r
647         /// </summary>\r
648         /// <param name="sender">\r
649         /// The sender.\r
650         /// </param>\r
651         /// <param name="e">\r
652         /// The e.\r
653         /// </param>\r
654         private void pmnu_saveChanges_Click(object sender, EventArgs e)\r
655         {\r
656             // TODO this requires a re-think since the Query Editor has changed.\r
657             DialogResult result =\r
658                 MessageBox.Show(\r
659                     "Do you wish to include picture settings when updating the preset: " +\r
660                     treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,\r
661                     MessageBoxIcon.Question);\r
662             if (result == DialogResult.Yes)\r
663                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
664                                      QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);\r
665             else if (result == DialogResult.No)\r
666                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
667                                      QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);\r
668         }\r
669 \r
670         /// <summary>\r
671         /// RMenu - Delete Preset\r
672         /// </summary>\r
673         /// <param name="sender">\r
674         /// The sender.\r
675         /// </param>\r
676         /// <param name="e">\r
677         /// The e.\r
678         /// </param>\r
679         private void pmnu_delete_click(object sender, EventArgs e)\r
680         {\r
681             if (treeView_presets.SelectedNode != null)\r
682             {\r
683                 presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
684                 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
685             }\r
686             treeView_presets.Select();\r
687         }\r
688 \r
689         /// <summary>\r
690         /// Preset Menu Is Opening. Setup the Menu\r
691         /// </summary>\r
692         /// <param name="sender">\r
693         /// The sender.\r
694         /// </param>\r
695         /// <param name="e">\r
696         /// The e.\r
697         /// </param>\r
698         private void presets_menu_Opening(object sender, CancelEventArgs e)\r
699         {\r
700             // Make sure that the save menu is always disabled by default\r
701             pmnu_saveChanges.Enabled = false;\r
702 \r
703             // Now enable the save menu if the selected preset is a user preset\r
704             if (treeView_presets.SelectedNode != null)\r
705                 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))\r
706                     pmnu_saveChanges.Enabled = true;\r
707 \r
708             treeView_presets.Select();\r
709         }\r
710 \r
711         // Presets Management\r
712 \r
713         /// <summary>\r
714         /// Button - Add a preset\r
715         /// </summary>\r
716         /// <param name="sender">\r
717         /// The sender.\r
718         /// </param>\r
719         /// <param name="e">\r
720         /// The e.\r
721         /// </param>\r
722         private void btn_addPreset_Click(object sender, EventArgs e)\r
723         {\r
724             Form preset = new frmAddPreset(this, presetHandler);\r
725             if (preset.ShowDialog() == DialogResult.OK)\r
726             {\r
727                 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };\r
728                 treeView_presets.Nodes.Add(presetTreeview);\r
729                 presetHandler.LastPresetAdded = null;\r
730             }\r
731         }\r
732 \r
733         /// <summary>\r
734         /// Button - remove a Preset\r
735         /// </summary>\r
736         /// <param name="sender">\r
737         /// The sender.\r
738         /// </param>\r
739         /// <param name="e">\r
740         /// The e.\r
741         /// </param>\r
742         private void btn_removePreset_Click(object sender, EventArgs e)\r
743         {\r
744             DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
745                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
746             if (result == DialogResult.Yes)\r
747             {\r
748                 if (treeView_presets.SelectedNode != null)\r
749                 {\r
750                     presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
751                     treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
752                 }\r
753             }\r
754             treeView_presets.Select();\r
755         }\r
756 \r
757         /// <summary>\r
758         /// Button - Set the selected preset as the default\r
759         /// </summary>\r
760         /// <param name="sender">\r
761         /// The sender.\r
762         /// </param>\r
763         /// <param name="e">\r
764         /// The e.\r
765         /// </param>\r
766         private void btn_setDefault_Click(object sender, EventArgs e)\r
767         {\r
768             if (treeView_presets.SelectedNode != null)\r
769             {\r
770                 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",\r
771                                                       "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
772                 if (result == DialogResult.Yes)\r
773                 {\r
774                     Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;\r
775                     Properties.Settings.Default.Save();\r
776                     MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
777                 }\r
778             }\r
779             else\r
780                 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
781         }\r
782 \r
783         /// <summary>\r
784         /// PresetBar Mouse Down event\r
785         /// </summary>\r
786         /// <param name="sender">\r
787         /// The sender.\r
788         /// </param>\r
789         /// <param name="e">\r
790         /// The e.\r
791         /// </param>\r
792         private void treeview_presets_mouseUp(object sender, MouseEventArgs e)\r
793         {\r
794             if (e.Button == MouseButtons.Right)\r
795                 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);\r
796             else if (e.Button == MouseButtons.Left)\r
797             {\r
798                 if (treeView_presets.GetNodeAt(e.Location) != null)\r
799                 {\r
800                     if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))\r
801                         selectPreset();\r
802                 }\r
803             }\r
804 \r
805             treeView_presets.Select();\r
806         }\r
807 \r
808         /// <summary>\r
809         /// Preset Bar after selecting the preset\r
810         /// </summary>\r
811         /// <param name="sender">\r
812         /// The sender.\r
813         /// </param>\r
814         /// <param name="e">\r
815         /// The e.\r
816         /// </param>\r
817         private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)\r
818         {\r
819             selectPreset();\r
820         }\r
821 \r
822         /// <summary>\r
823         /// Preset Bar - Handle the Delete Key\r
824         /// </summary>\r
825         /// <param name="sender">\r
826         /// The sender.\r
827         /// </param>\r
828         /// <param name="e">\r
829         /// The e.\r
830         /// </param>\r
831         private void treeView_presets_deleteKey(object sender, KeyEventArgs e)\r
832         {\r
833             if (e.KeyCode == Keys.Delete)\r
834             {\r
835                 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
836                                                       MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
837                 if (result == DialogResult.Yes)\r
838                 {\r
839                     if (treeView_presets.SelectedNode != null)\r
840                         presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
841 \r
842                     // Remember each nodes expanded status so we can reload it\r
843                     List<bool> nodeStatus = new List<bool>();\r
844                     foreach (TreeNode node in treeView_presets.Nodes)\r
845                         nodeStatus.Add(node.IsExpanded);\r
846 \r
847                     // Now reload the preset panel\r
848                     LoadPresetPanel();\r
849 \r
850                     // And finally, re-expand any of the nodes if required\r
851                     int i = 0;\r
852                     foreach (TreeNode node in treeView_presets.Nodes)\r
853                     {\r
854                         if (nodeStatus[i])\r
855                             node.Expand();\r
856 \r
857                         i++;\r
858                     }\r
859                 }\r
860             }\r
861         }\r
862 \r
863         /// <summary>\r
864         /// Select the selected preset and setup the GUI\r
865         /// </summary>\r
866         private void selectPreset()\r
867         {\r
868             if (treeView_presets.SelectedNode != null)\r
869             {\r
870                 // Ok, so, we've selected a preset. Now we want to load it.\r
871                 string presetName = treeView_presets.SelectedNode.Text;\r
872                 Preset preset = presetHandler.GetPreset(presetName);\r
873                 if (preset != null)\r
874                 {\r
875                     string query = presetHandler.GetPreset(presetName).Query;\r
876 \r
877                     if (query != null)\r
878                     {\r
879                         // Ok, Reset all the H264 widgets before changing the preset\r
880                         x264Panel.Reset2Defaults();\r
881 \r
882                         // Send the query from the file to the Query Parser class\r
883                         QueryParser presetQuery = QueryParser.Parse(query);\r
884 \r
885                         // Now load the preset\r
886                         PresetLoader.LoadPreset(this, presetQuery, presetName);\r
887 \r
888                         // The x264 widgets will need updated, so do this now:\r
889                         x264Panel.StandardizeOptString();\r
890                         x264Panel.SetCurrentSettingsInPanel();\r
891 \r
892                         // Finally, let this window have a copy of the preset settings.\r
893                         this.currentlySelectedPreset = preset;\r
894                         PictureSettings.SetPresetCropWarningLabel(preset);\r
895                     }\r
896                 }\r
897             }\r
898         }\r
899 \r
900         /// <summary>\r
901         /// Load the Normal Preset\r
902         /// </summary>\r
903         private void loadNormalPreset()\r
904         {\r
905             foreach (TreeNode treenode in treeView_presets.Nodes)\r
906             {\r
907                 foreach (TreeNode node in treenode.Nodes)\r
908                 {\r
909                     if (node.Text.Equals("Normal"))\r
910                         treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];\r
911                 }\r
912             }\r
913         }\r
914 \r
915         /// <summary>\r
916         /// Import a plist preset\r
917         /// </summary>\r
918         private void ImportPreset()\r
919         {\r
920             if (openPreset.ShowDialog() == DialogResult.OK)\r
921             {\r
922                 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);\r
923                 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))\r
924                 {\r
925                     DialogResult result =\r
926                         MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",\r
927                                         "Overwrite preset?",\r
928                                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
929                     if (result == DialogResult.Yes)\r
930                     {\r
931                         PresetLoader.LoadPreset(this, parsed, parsed.PresetName);\r
932                         presetHandler.Update(parsed.PresetName + " (Imported)",\r
933                                              QueryGenerator.GenerateFullQuery(this),\r
934                                              parsed.UsesPictureSettings);\r
935                     }\r
936                 }\r
937                 else\r
938                 {\r
939                     PresetLoader.LoadPreset(this, parsed, parsed.PresetName);\r
940                     if (presetHandler.Add(parsed.PresetName + " (Imported)",\r
941                                           QueryGenerator.GenerateFullQuery(this),\r
942                                           parsed.UsesPictureSettings))\r
943                     {\r
944                         TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")\r
945                                                        {\r
946                                                            ForeColor = Color.Black\r
947                                                        };\r
948                         treeView_presets.Nodes.Add(preset_treeview);\r
949                     }\r
950                 }\r
951             }\r
952         }\r
953 \r
954         /// <summary>\r
955         /// Export a plist Preset\r
956         /// </summary>\r
957         private void ExportPreset()\r
958         {\r
959             MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
960             return;\r
961 \r
962             SaveFileDialog savefiledialog = new SaveFileDialog();\r
963             savefiledialog.Filter = "plist|*.plist";\r
964 \r
965             if (treeView_presets.SelectedNode != null)\r
966             {\r
967 \r
968                 if (savefiledialog.ShowDialog() == DialogResult.OK)\r
969                 {\r
970                     Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);\r
971                     PlistPresetHandler.Export(savefiledialog.FileName, preset);\r
972                 }\r
973             }\r
974         }\r
975 \r
976         #endregion\r
977 \r
978         #region ToolStrip\r
979 \r
980         /// <summary>\r
981         /// Toolbar - When the Source button is clicked, Clear any DVD drives and add any available DVD drives that can be used as a source.\r
982         /// </summary>\r
983         /// <param name="sender">\r
984         /// The sender.\r
985         /// </param>\r
986         /// <param name="e">\r
987         /// The e.\r
988         /// </param>\r
989         private void btn_source_Click(object sender, EventArgs e)\r
990         {\r
991             // Remove old Drive Menu Items.\r
992             List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();\r
993             foreach (var item in btn_source.DropDownItems)\r
994             {\r
995                 if (item.GetType() == typeof(ToolStripMenuItem))\r
996                 {\r
997                     ToolStripMenuItem menuItem = (ToolStripMenuItem)item;\r
998                     if (menuItem.Name.StartsWith("Drive"))\r
999                     {\r
1000                         itemsToRemove.Add(menuItem);\r
1001                     }\r
1002                 }\r
1003             }\r
1004 \r
1005             foreach (ToolStripMenuItem item in itemsToRemove)\r
1006                 btn_source.DropDownItems.Remove(item);\r
1007 \r
1008             Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);\r
1009             driveInfoThread.Start();\r
1010         }\r
1011 \r
1012         /// <summary>\r
1013         /// Toolbar - Start The Encode\r
1014         /// </summary>\r
1015         /// <param name="sender">\r
1016         /// The sender.\r
1017         /// </param>\r
1018         /// <param name="e">\r
1019         /// The e.\r
1020         /// </param>\r
1021         private void btn_start_Click(object sender, EventArgs e)\r
1022         {\r
1023             if (btn_start.Text == "Stop")\r
1024             {\r
1025                 DialogResult result;\r
1026                 if (Properties.Settings.Default.enocdeStatusInGui &&\r
1027                     !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
1028                 {\r
1029                     result = MessageBox.Show(\r
1030                         "Are you sure you wish to cancel the encode?\n\nPlease note, when 'Enable in-GUI encode status' is enabled, stopping this encode will render the file unplayable. ",\r
1031                         "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
1032                 }\r
1033                 else\r
1034                 {\r
1035                     result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?",\r
1036                                              MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
1037                 }\r
1038 \r
1039                 if (result == DialogResult.Yes)\r
1040                 {\r
1041                     // Pause The Queue\r
1042                     encodeQueue.Pause();\r
1043 \r
1044                     if (Settings.Default.enocdeStatusInGui && !Settings.Default.showCliForInGuiEncodeStatus)\r
1045                     {\r
1046                         encodeQueue.Stop();\r
1047                     }\r
1048                     else\r
1049                     {\r
1050                         encodeQueue.SafelyClose();\r
1051                     }\r
1052                 }\r
1053             }\r
1054             else\r
1055             {\r
1056                 // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.\r
1057                 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;\r
1058                 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;\r
1059 \r
1060                 if (encodeQueue.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))\r
1061                 {\r
1062                     string generatedQuery = QueryGenerator.GenerateFullQuery(this);\r
1063                     string specifiedQuery = rtf_query.Text != string.Empty\r
1064                                                 ? rtf_query.Text\r
1065                                                 : QueryGenerator.GenerateFullQuery(this);\r
1066                     string query = string.Empty;\r
1067 \r
1068                     // Check to make sure the generated query matches the GUI settings\r
1069                     if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&\r
1070                         generatedQuery != specifiedQuery)\r
1071                     {\r
1072                         DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +\r
1073                                                               "does not match the current GUI settings.\n\nBecause the manual query takes " +\r
1074                                                               "priority over the GUI, your recently updated settings will not be taken " +\r
1075                                                               "into account when encoding this job." +\r
1076                                                               Environment.NewLine + Environment.NewLine +\r
1077                                                               "Do you want to replace the manual query with the updated GUI-generated query?",\r
1078                                                               "Manual Query does not Match GUI",\r
1079                                                               MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,\r
1080                                                               MessageBoxDefaultButton.Button3);\r
1081 \r
1082                         switch (result)\r
1083                         {\r
1084                             case DialogResult.Yes:\r
1085                                 // Replace the manual query with the generated one\r
1086                                 query = generatedQuery;\r
1087                                 rtf_query.Text = generatedQuery;\r
1088                                 break;\r
1089                             case DialogResult.No:\r
1090                                 // Use the manual query\r
1091                                 query = specifiedQuery;\r
1092                                 break;\r
1093                             case DialogResult.Cancel:\r
1094                                 // Don't start the encode\r
1095                                 return;\r
1096                         }\r
1097                     }\r
1098                     else\r
1099                     {\r
1100                         query = specifiedQuery;\r
1101                     }\r
1102 \r
1103                     DialogResult overwrite = DialogResult.Yes;\r
1104                     if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))\r
1105                     {\r
1106                         overwrite = MessageBox.Show(\r
1107                                 "The destination file already exists. Are you sure you want to overwrite it?",\r
1108                                 "Overwrite File?",\r
1109                                 MessageBoxButtons.YesNo,\r
1110                                 MessageBoxIcon.Question);\r
1111                     }\r
1112 \r
1113                     if (overwrite == DialogResult.Yes)\r
1114                     {\r
1115                         if (encodeQueue.Count == 0)\r
1116                             encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));\r
1117 \r
1118                         queueWindow.SetQueue();\r
1119                         if (encodeQueue.Count > 1)\r
1120                             queueWindow.Show(false);\r
1121 \r
1122                         SetEncodeStarted(); // Encode is running, so setup the GUI appropriately\r
1123                         encodeQueue.Start(); // Start The Queue Encoding Process\r
1124                     }\r
1125 \r
1126                     this.Focus();\r
1127                 }\r
1128                 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
1129                     MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
1130                                     MessageBoxIcon.Warning);\r
1131             }\r
1132         }\r
1133 \r
1134         /// <summary>\r
1135         /// Toolbar - Add the current job to the Queue\r
1136         /// </summary>\r
1137         /// <param name="sender">\r
1138         /// The sender.\r
1139         /// </param>\r
1140         /// <param name="e">\r
1141         /// The e.\r
1142         /// </param>\r
1143         private void btn_add2Queue_Click(object sender, EventArgs e)\r
1144         {\r
1145             // Get the CLI query or use the query editor if it's not empty.\r
1146             string query = QueryGenerator.GenerateFullQuery(this);\r
1147             if (!string.IsNullOrEmpty(rtf_query.Text))\r
1148                 query = rtf_query.Text;\r
1149 \r
1150             // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.\r
1151             string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;\r
1152             string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;\r
1153 \r
1154             // Make sure we have a Source and Destination.\r
1155             if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))\r
1156             {\r
1157                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1158                 return;\r
1159             }\r
1160 \r
1161             // Make sure the destination path exists.\r
1162             if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))\r
1163             {\r
1164                 MessageBox.Show("Destination Path does not exist.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1165                 return;\r
1166             }\r
1167 \r
1168             // Make sure we don't have a duplciate on the queue.\r
1169             if (encodeQueue.CheckForDestinationDuplicate(jobDestination))\r
1170             {\r
1171                 DialogResult result =\r
1172                     MessageBox.Show(\r
1173                         "There is already a queue item for this destination path. \n\n If you continue, the encode will be overwritten. Do you wish to continue?",\r
1174                         "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
1175                 if (result == DialogResult.Yes)\r
1176                     encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));\r
1177             }\r
1178             else\r
1179                 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));\r
1180 \r
1181             lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";\r
1182 \r
1183             queueWindow.Show();\r
1184 \r
1185         }\r
1186 \r
1187         /// <summary>\r
1188         /// Toolbar - Show the Queue\r
1189         /// </summary>\r
1190         /// <param name="sender">\r
1191         /// The sender.\r
1192         /// </param>\r
1193         /// <param name="e">\r
1194         /// The e.\r
1195         /// </param>\r
1196         private void btn_showQueue_Click(object sender, EventArgs e)\r
1197         {\r
1198             queueWindow.Show();\r
1199             queueWindow.Activate();\r
1200         }\r
1201 \r
1202         /// <summary>\r
1203         /// Toolbar - Show the Preview Window\r
1204         /// </summary>\r
1205         /// <param name="sender">\r
1206         /// The sender.\r
1207         /// </param>\r
1208         /// <param name="e">\r
1209         /// The e.\r
1210         /// </param>\r
1211         private void tb_preview_Click(object sender, EventArgs e)\r
1212         {\r
1213             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
1214                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
1215                                 MessageBoxIcon.Warning);\r
1216             else\r
1217             {\r
1218                 if (qtpreview == null)\r
1219                 {\r
1220                     qtpreview = new frmPreview(this);\r
1221                     qtpreview.Show();\r
1222                 }\r
1223                 else if (qtpreview.IsDisposed)\r
1224                 {\r
1225                     qtpreview = new frmPreview(this);\r
1226                     qtpreview.Show();\r
1227                 }\r
1228                 else\r
1229                     MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,\r
1230                                     MessageBoxIcon.Warning);\r
1231             }\r
1232         }\r
1233 \r
1234         /// <summary>\r
1235         /// Toolbar - Show the Activity log Window\r
1236         /// </summary>\r
1237         /// <param name="sender">\r
1238         /// The sender.\r
1239         /// </param>\r
1240         /// <param name="e">\r
1241         /// The e.\r
1242         /// </param>\r
1243         private void btn_ActivityWindow_Click(object sender, EventArgs e)\r
1244         {\r
1245             if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)\r
1246                 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);\r
1247 \r
1248             this.activityWindow.Show();\r
1249             this.activityWindow.Activate();\r
1250         }\r
1251 \r
1252         #endregion\r
1253 \r
1254         #region System Tray Icon\r
1255 \r
1256         /// <summary>\r
1257         /// Handle Resizing of the main window when deaing with the Notify Icon\r
1258         /// </summary>\r
1259         /// <param name="sender">\r
1260         /// The sender.\r
1261         /// </param>\r
1262         /// <param name="e">\r
1263         /// The e.\r
1264         /// </param>\r
1265         private void frmMain_Resize(object sender, EventArgs e)\r
1266         {\r
1267             if (FormWindowState.Minimized == this.WindowState)\r
1268             {\r
1269                 notifyIcon.Visible = true;\r
1270                 this.Hide();\r
1271             }\r
1272             else if (FormWindowState.Normal == this.WindowState)\r
1273                 notifyIcon.Visible = false;\r
1274         }\r
1275 \r
1276         /// <summary>\r
1277         /// Double Click the Tray Icon\r
1278         /// </summary>\r
1279         /// <param name="sender">\r
1280         /// The sender.\r
1281         /// </param>\r
1282         /// <param name="e">\r
1283         /// The e.\r
1284         /// </param>\r
1285         private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)\r
1286         {\r
1287             this.Visible = true;\r
1288             this.Activate();\r
1289             this.WindowState = FormWindowState.Normal;\r
1290             notifyIcon.Visible = false;\r
1291         }\r
1292 \r
1293         /// <summary>\r
1294         /// Tray Icon - Restore Menu Item - Resture the Window\r
1295         /// </summary>\r
1296         /// <param name="sender">\r
1297         /// The sender.\r
1298         /// </param>\r
1299         /// <param name="e">\r
1300         /// The e.\r
1301         /// </param>\r
1302         private void btn_restore_Click(object sender, EventArgs e)\r
1303         {\r
1304             this.Visible = true;\r
1305             this.Activate();\r
1306             this.WindowState = FormWindowState.Normal;\r
1307             notifyIcon.Visible = false;\r
1308         }\r
1309 \r
1310         #endregion\r
1311 \r
1312         #region Main Window and Tab Control\r
1313 \r
1314         // Source\r
1315         private void btn_dvd_source_Click(object sender, EventArgs e)\r
1316         {\r
1317             if (DVD_Open.ShowDialog() == DialogResult.OK)\r
1318             {\r
1319                 this.selectedSourceType = SourceType.Folder;\r
1320                 SelectSource(DVD_Open.SelectedPath);\r
1321             }\r
1322             else\r
1323                 UpdateSourceLabel();\r
1324         }\r
1325 \r
1326         private void btn_file_source_Click(object sender, EventArgs e)\r
1327         {\r
1328             if (ISO_Open.ShowDialog() == DialogResult.OK)\r
1329             {\r
1330                 this.selectedSourceType = SourceType.VideoFile;\r
1331                 SelectSource(ISO_Open.FileName);\r
1332             }\r
1333             else\r
1334                 UpdateSourceLabel();\r
1335         }\r
1336 \r
1337         private void mnu_dvd_drive_Click(object sender, EventArgs e)\r
1338         {\r
1339             ToolStripMenuItem item = sender as ToolStripMenuItem;\r
1340             if (item != null)\r
1341             {\r
1342                 string driveId = item.Name.Replace("Drive", string.Empty);\r
1343                 int id;\r
1344                 if (int.TryParse(driveId, out id))\r
1345                 {\r
1346 \r
1347                     this.dvdDrivePath = drives[id].RootDirectory;\r
1348                     this.dvdDriveLabel = drives[id].VolumeLabel;\r
1349 \r
1350                     if (this.dvdDrivePath == null) return;\r
1351                     this.selectedSourceType = SourceType.DvdDrive;\r
1352                     SelectSource(this.dvdDrivePath);\r
1353                 }\r
1354             }\r
1355         }\r
1356 \r
1357         private void SelectSource(string file)\r
1358         {\r
1359             Check_ChapterMarkers.Enabled = true;\r
1360             sourcePath = string.Empty;\r
1361 \r
1362             if (file == string.Empty) // Must have a file or path\r
1363             {\r
1364                 UpdateSourceLabel();\r
1365                 return;\r
1366             }\r
1367 \r
1368             sourcePath = Path.GetFileName(file);\r
1369             StartScan(file, 0);\r
1370         }\r
1371 \r
1372         private void drp_dvdtitle_Click(object sender, EventArgs e)\r
1373         {\r
1374             if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))\r
1375                 MessageBox.Show(\r
1376                     "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",\r
1377                     "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\r
1378         }\r
1379 \r
1380         private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)\r
1381         {\r
1382             UnRegisterPresetEventHandler();\r
1383             drop_mode.SelectedIndex = 0;\r
1384 \r
1385             drop_chapterStart.Items.Clear();\r
1386             drop_chapterFinish.Items.Clear();\r
1387 \r
1388             // If the dropdown is set to automatic nothing else needs to be done.\r
1389             // Otheriwse if its not, title data has to be loaded from parsing.\r
1390             if (drp_dvdtitle.Text != "Automatic")\r
1391             {\r
1392                 selectedTitle = drp_dvdtitle.SelectedItem as Title;\r
1393                 lbl_duration.Text = selectedTitle.Duration.ToString();\r
1394                 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;\r
1395                 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control\r
1396 \r
1397                 // Populate the Angles dropdown\r
1398                 drop_angle.Items.Clear();\r
1399                 if (!Properties.Settings.Default.noDvdNav)\r
1400                 {\r
1401                     drop_angle.Visible = true;\r
1402                     lbl_angle.Visible = true;\r
1403 \r
1404                     for (int i = 1; i <= selectedTitle.AngleCount; i++)\r
1405                         drop_angle.Items.Add(i.ToString());\r
1406 \r
1407                     if (drop_angle.Items.Count != 0)\r
1408                         drop_angle.SelectedIndex = 0;\r
1409                 }\r
1410                 else\r
1411                 {\r
1412                     drop_angle.Visible = false;\r
1413                     lbl_angle.Visible = false;\r
1414                 }\r
1415 \r
1416                 // Populate the Start chapter Dropdown\r
1417                 drop_chapterStart.Items.Clear();\r
1418                 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1419                 if (drop_chapterStart.Items.Count > 0)\r
1420                     drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();\r
1421 \r
1422                 // Populate the Final Chapter Dropdown\r
1423                 drop_chapterFinish.Items.Clear();\r
1424                 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1425                 if (drop_chapterFinish.Items.Count > 0)\r
1426                     drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();\r
1427 \r
1428                 // Populate the Audio Channels Dropdown\r
1429                 AudioSettings.SetTrackList(selectedTitle, this.currentlySelectedPreset);\r
1430 \r
1431                 // Populate the Subtitles dropdown\r
1432                 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());\r
1433             }\r
1434             // Update the source label if we have multiple streams\r
1435             if (selectedTitle != null)\r
1436                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1437                     labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1438 \r
1439             // Run the AutoName & ChapterNaming functions\r
1440             if (Properties.Settings.Default.autoNaming)\r
1441             {\r
1442                 string autoPath = Main.AutoName(this);\r
1443                 if (autoPath != null)\r
1444                     text_destination.Text = autoPath;\r
1445                 else\r
1446                     MessageBox.Show(\r
1447                         "You currently have \"Automatically name output files\" enabled for the destination file box, but you do not have a default directory set.\n\nYou should set a \"Default Path\" in HandBrakes preferences. (See 'Tools' menu -> 'Options' -> 'General' Tab -> 'Default Path')",\r
1448                         "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1449             }\r
1450 \r
1451             data_chpt.Rows.Clear();\r
1452             if (selectedTitle.Chapters.Count != 1)\r
1453             {\r
1454                 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1455                 if (chapterGridView != null)\r
1456                     data_chpt = chapterGridView;\r
1457             }\r
1458             else\r
1459             {\r
1460                 Check_ChapterMarkers.Checked = false;\r
1461                 Check_ChapterMarkers.Enabled = false;\r
1462             }\r
1463 \r
1464             // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.\r
1465             data_chpt.Columns[0].Width = 166;\r
1466             data_chpt.Columns[0].Width = 165;\r
1467 \r
1468             RegisterPresetEventHandler();\r
1469         }\r
1470 \r
1471         private void chapersChanged(object sender, EventArgs e)\r
1472         {\r
1473             if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.\r
1474                 return;\r
1475 \r
1476             Control ctl = (Control)sender;\r
1477             int chapterStart, chapterEnd;\r
1478             int.TryParse(drop_chapterStart.Text, out chapterStart);\r
1479             int.TryParse(drop_chapterFinish.Text, out chapterEnd);\r
1480 \r
1481             switch (ctl.Name)\r
1482             {\r
1483                 case "drop_chapterStart":\r
1484                     if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)\r
1485                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1486 \r
1487                     if (chapterEnd != 0)\r
1488                         if (chapterStart > chapterEnd)\r
1489                             drop_chapterFinish.Text = chapterStart.ToString();\r
1490                     break;\r
1491                 case "drop_chapterFinish":\r
1492                     if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)\r
1493                         drop_chapterStart.SelectedIndex = 0;\r
1494 \r
1495                     if (chapterStart != 0)\r
1496                         if (chapterEnd < chapterStart)\r
1497                             drop_chapterFinish.Text = chapterStart.ToString();\r
1498 \r
1499                     // Add more rows to the Chapter menu if needed.\r
1500                     if (Check_ChapterMarkers.Checked)\r
1501                     {\r
1502                         int i = data_chpt.Rows.Count, finish = 0;\r
1503                         int.TryParse(drop_chapterFinish.Text, out finish);\r
1504 \r
1505                         while (i < finish)\r
1506                         {\r
1507                             int n = data_chpt.Rows.Add();\r
1508                             data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
1509                             data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
1510                             data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
1511                             data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
1512                             i++;\r
1513                         }\r
1514                     }\r
1515                     break;\r
1516             }\r
1517 \r
1518             // Update the Duration\r
1519             lbl_duration.Text =\r
1520                 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)\r
1521                     .ToString();\r
1522 \r
1523             // Run the Autonaming function\r
1524             if (Properties.Settings.Default.autoNaming)\r
1525                 text_destination.Text = Main.AutoName(this);\r
1526 \r
1527             // Disable chapter markers if only 1 chapter is selected.\r
1528             if (chapterStart == chapterEnd)\r
1529             {\r
1530                 Check_ChapterMarkers.Enabled = false;\r
1531                 btn_importChapters.Enabled = false;\r
1532                 data_chpt.Enabled = false;\r
1533             }\r
1534             else\r
1535             {\r
1536                 Check_ChapterMarkers.Enabled = true;\r
1537                 if (Check_ChapterMarkers.Checked)\r
1538                 {\r
1539                     btn_importChapters.Enabled = true;\r
1540                     data_chpt.Enabled = true;\r
1541                 }\r
1542             }\r
1543         }\r
1544 \r
1545         private void SecondsOrFramesChanged(object sender, EventArgs e)\r
1546         {\r
1547             int start, end;\r
1548             int.TryParse(drop_chapterStart.Text, out start);\r
1549             int.TryParse(drop_chapterFinish.Text, out end);\r
1550             double duration = end - start;\r
1551 \r
1552             switch (drop_mode.SelectedIndex)\r
1553             {\r
1554                 case 1:\r
1555                     lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1556                     return;\r
1557                 case 2:\r
1558                     if (selectedTitle != null)\r
1559                     {\r
1560                         duration = duration / selectedTitle.Fps;\r
1561                         lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1562                     }\r
1563                     else\r
1564                         lbl_duration.Text = "--:--:--";\r
1565 \r
1566                     return;\r
1567             }\r
1568         }\r
1569 \r
1570         private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)\r
1571         {\r
1572             // Reset\r
1573             this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1574             this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1575 \r
1576             // Do Work\r
1577             switch (drop_mode.SelectedIndex)\r
1578             {\r
1579                 case 0:\r
1580                     drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;\r
1581                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;\r
1582                     if (drop_chapterStart.Items.Count != 0)\r
1583                     {\r
1584                         drop_chapterStart.SelectedIndex = 0;\r
1585                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1586                     }\r
1587                     else\r
1588                         lbl_duration.Text = "--:--:--";\r
1589                     return;\r
1590                 case 1:\r
1591                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1592                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1593                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1594                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1595                     if (selectedTitle != null)\r
1596                     {\r
1597                         drop_chapterStart.Text = "0";\r
1598                         drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();\r
1599                     }\r
1600                     return;\r
1601                 case 2:\r
1602                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1603                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1604                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1605                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1606                     if (selectedTitle != null)\r
1607                     {\r
1608                         drop_chapterStart.Text = "0";\r
1609                         drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();\r
1610                     }\r
1611                     return;\r
1612             }\r
1613         }\r
1614 \r
1615         // Destination\r
1616         private void btn_destBrowse_Click(object sender, EventArgs e)\r
1617         {\r
1618             // This removes the file extension from the filename box on the save file dialog.\r
1619             // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.\r
1620             DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);\r
1621 \r
1622             if (Path.IsPathRooted(text_destination.Text))\r
1623                 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);\r
1624 \r
1625             // Show the dialog and set the main form file path\r
1626             if (drop_format.SelectedIndex.Equals(0))\r
1627                 DVD_Save.FilterIndex = 1;\r
1628             else if (drop_format.SelectedIndex.Equals(1))\r
1629                 DVD_Save.FilterIndex = 2;\r
1630 \r
1631             if (DVD_Save.ShowDialog() == DialogResult.OK)\r
1632             {\r
1633                 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames\r
1634                 switch (DVD_Save.FilterIndex)\r
1635                 {\r
1636                     case 1:\r
1637                         if (\r
1638                             !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",\r
1639                                                                          StringComparison.InvariantCultureIgnoreCase))\r
1640                             if (Properties.Settings.Default.useM4v)\r
1641                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");\r
1642                             else\r
1643                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");\r
1644                         break;\r
1645                     case 2:\r
1646                         if (\r
1647                             !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))\r
1648                             DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");\r
1649                         break;\r
1650                     default:\r
1651                         // do nothing  \r
1652                         break;\r
1653                 }\r
1654                 text_destination.Text = DVD_Save.FileName;\r
1655 \r
1656                 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)\r
1657                 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)\r
1658                     SetExtension(".m4v");\r
1659             }\r
1660         }\r
1661 \r
1662         private void text_destination_TextChanged(object sender, EventArgs e)\r
1663         {\r
1664             string path = text_destination.Text;\r
1665             if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))\r
1666                 drop_format.SelectedIndex = 0;\r
1667             else if (path.EndsWith(".mkv"))\r
1668                 drop_format.SelectedIndex = 1;\r
1669         }\r
1670 \r
1671         // Output Settings\r
1672         private void drop_format_SelectedIndexChanged(object sender, EventArgs e)\r
1673         {\r
1674             switch (drop_format.SelectedIndex)\r
1675             {\r
1676                 case 0:\r
1677                     if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||\r
1678                         AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())\r
1679                         SetExtension(".m4v");\r
1680                     else\r
1681                         SetExtension(".mp4");\r
1682                     break;\r
1683                 case 1:\r
1684                     SetExtension(".mkv");\r
1685                     break;\r
1686             }\r
1687 \r
1688             AudioSettings.SetContainer(drop_format.Text);\r
1689 \r
1690             if (drop_format.Text.Contains("MP4"))\r
1691             {\r
1692                 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))\r
1693                 {\r
1694                     drp_videoEncoder.Items.Remove("VP3 (Theora)");\r
1695                     drp_videoEncoder.SelectedIndex = 1;\r
1696                 }\r
1697             }\r
1698             else if (drop_format.Text.Contains("MKV"))\r
1699                 drp_videoEncoder.Items.Add("VP3 (Theora)");\r
1700         }\r
1701 \r
1702         public void SetExtension(string newExtension)\r
1703         {\r
1704             if (newExtension == ".mp4" || newExtension == ".m4v")\r
1705                 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||\r
1706                     Subtitles.RequiresM4V())\r
1707                     newExtension = ".m4v";\r
1708                 else\r
1709                     newExtension = ".mp4";\r
1710 \r
1711             if (Path.HasExtension(newExtension))\r
1712                 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);\r
1713         }\r
1714 \r
1715         // Video Tab\r
1716         private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)\r
1717         {\r
1718             setContainerOpts();\r
1719 \r
1720             // Turn off some options which are H.264 only when the user selects a non h.264 encoder\r
1721             if (drp_videoEncoder.Text.Contains("H.264"))\r
1722             {\r
1723                 if (check_2PassEncode.CheckState == CheckState.Checked)\r
1724                     check_turbo.Enabled = true;\r
1725 \r
1726                 tab_advanced.Enabled = true;\r
1727                 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1728                     check_iPodAtom.Enabled = true;\r
1729                 else\r
1730                     check_iPodAtom.Enabled = false;\r
1731             }\r
1732             else\r
1733             {\r
1734                 check_turbo.CheckState = CheckState.Unchecked;\r
1735                 check_turbo.Enabled = false;\r
1736                 tab_advanced.Enabled = false;\r
1737                 x264Panel.X264Query = string.Empty;\r
1738                 check_iPodAtom.Enabled = false;\r
1739                 check_iPodAtom.Checked = false;\r
1740             }\r
1741 \r
1742             // Setup the CQ Slider\r
1743             switch (drp_videoEncoder.Text)\r
1744             {\r
1745                 case "MPEG-4 (FFmpeg)":\r
1746                     if (slider_videoQuality.Value > 31)\r
1747                         slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.\r
1748                     slider_videoQuality.Minimum = 1;\r
1749                     slider_videoQuality.Maximum = 31;\r
1750                     break;\r
1751                 case "H.264 (x264)":\r
1752                     slider_videoQuality.Minimum = 0;\r
1753                     slider_videoQuality.TickFrequency = 1;\r
1754 \r
1755                     CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");\r
1756                     double cqStep = Properties.Settings.Default.x264cqstep;\r
1757                     double multiplier = 1.0 / cqStep;\r
1758                     double value = slider_videoQuality.Value * multiplier;\r
1759 \r
1760                     slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1761 \r
1762                     if (value < slider_videoQuality.Maximum)\r
1763                         slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;\r
1764 \r
1765                     break;\r
1766                 case "VP3 (Theora)":\r
1767                     if (slider_videoQuality.Value > 63)\r
1768                         slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.\r
1769                     slider_videoQuality.Minimum = 0;\r
1770                     slider_videoQuality.Maximum = 63;\r
1771                     break;\r
1772             }\r
1773         }\r
1774 \r
1775         /// <summary>\r
1776         /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown\r
1777         /// </summary>\r
1778         /// <param name="sender">\r
1779         /// The sender.\r
1780         /// </param>\r
1781         /// <param name="e">\r
1782         /// The e.\r
1783         /// </param>\r
1784         private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)\r
1785         {\r
1786             if (this.drp_videoFramerate.SelectedIndex == 0)\r
1787             {\r
1788                 this.checkMaximumFramerate.Visible = false;\r
1789                 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;\r
1790             }\r
1791             else\r
1792             {\r
1793                 this.checkMaximumFramerate.Visible = true;\r
1794             }\r
1795         }\r
1796 \r
1797         /// <summary>\r
1798         /// Set the container format options\r
1799         /// </summary>\r
1800         public void setContainerOpts()\r
1801         {\r
1802             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1803             {\r
1804                 check_largeFile.Enabled = true;\r
1805                 check_optimiseMP4.Enabled = true;\r
1806                 check_iPodAtom.Enabled = true;\r
1807             }\r
1808             else\r
1809             {\r
1810                 check_largeFile.Enabled = false;\r
1811                 check_optimiseMP4.Enabled = false;\r
1812                 check_iPodAtom.Enabled = false;\r
1813                 check_largeFile.Checked = false;\r
1814                 check_optimiseMP4.Checked = false;\r
1815                 check_iPodAtom.Checked = false;\r
1816             }\r
1817         }\r
1818 \r
1819         private double _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1820 \r
1821         /// <summary>\r
1822         /// Update the CQ slider for x264 for a new CQ step. This is set from option\r
1823         /// </summary>\r
1824         public void setQualityFromSlider()\r
1825         {\r
1826             // Work out the current RF value.\r
1827             double cqStep = _cachedCqStep;\r
1828             double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1829 \r
1830             // Change the maximum value for the slider\r
1831             slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1832 \r
1833             // Reset the CQ slider to RF0\r
1834             slider_videoQuality.Value = slider_videoQuality.Maximum;\r
1835 \r
1836             // Reset the CQ slider back to the previous value as close as possible\r
1837             double cqStepNew = Properties.Settings.Default.x264cqstep;\r
1838             double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1839             while (rfValueCurrent < rfValue)\r
1840             {\r
1841                 slider_videoQuality.Value--;\r
1842                 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1843             }\r
1844 \r
1845             // Cache the CQ step for the next calculation\r
1846             _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1847         }\r
1848 \r
1849         private void slider_videoQuality_Scroll(object sender, EventArgs e)\r
1850         {\r
1851             double cqStep = Properties.Settings.Default.x264cqstep;\r
1852             switch (drp_videoEncoder.Text)\r
1853             {\r
1854                 case "MPEG-4 (FFmpeg)":\r
1855                     lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);\r
1856                     break;\r
1857                 case "H.264 (x264)":\r
1858                     double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1859                     rfValue = Math.Round(rfValue, 2);\r
1860                     lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));\r
1861                     break;\r
1862                 case "VP3 (Theora)":\r
1863                     lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;\r
1864                     break;\r
1865             }\r
1866         }\r
1867 \r
1868         private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)\r
1869         {\r
1870             text_bitrate.Enabled = false;\r
1871             text_filesize.Enabled = true;\r
1872             slider_videoQuality.Enabled = false;\r
1873 \r
1874             check_2PassEncode.Enabled = true;\r
1875         }\r
1876 \r
1877         private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)\r
1878         {\r
1879             text_bitrate.Enabled = true;\r
1880             text_filesize.Enabled = false;\r
1881             slider_videoQuality.Enabled = false;\r
1882 \r
1883             check_2PassEncode.Enabled = true;\r
1884         }\r
1885 \r
1886         private void radio_cq_CheckedChanged(object sender, EventArgs e)\r
1887         {\r
1888             text_bitrate.Enabled = false;\r
1889             text_filesize.Enabled = false;\r
1890             slider_videoQuality.Enabled = true;\r
1891 \r
1892             check_2PassEncode.Enabled = false;\r
1893             check_2PassEncode.CheckState = CheckState.Unchecked;\r
1894         }\r
1895 \r
1896         private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)\r
1897         {\r
1898             if (check_2PassEncode.CheckState.ToString() == "Checked")\r
1899             {\r
1900                 if (drp_videoEncoder.Text.Contains("H.264"))\r
1901                     check_turbo.Enabled = true;\r
1902             }\r
1903             else\r
1904             {\r
1905                 check_turbo.Enabled = false;\r
1906                 check_turbo.CheckState = CheckState.Unchecked;\r
1907             }\r
1908         }\r
1909 \r
1910         // Chapter Marker Tab\r
1911         private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)\r
1912         {\r
1913             if (Check_ChapterMarkers.Checked)\r
1914             {\r
1915                 if (drop_format.SelectedIndex != 1)\r
1916                     SetExtension(".m4v");\r
1917                 data_chpt.Enabled = true;\r
1918                 btn_importChapters.Enabled = true;\r
1919             }\r
1920             else\r
1921             {\r
1922                 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)\r
1923                     SetExtension(".mp4");\r
1924                 data_chpt.Enabled = false;\r
1925                 btn_importChapters.Enabled = false;\r
1926             }\r
1927         }\r
1928 \r
1929         private void btn_importChapters_Click(object sender, EventArgs e)\r
1930         {\r
1931             if (File_ChapterImport.ShowDialog() == DialogResult.OK)\r
1932             {\r
1933                 string filename = File_ChapterImport.FileName;\r
1934                 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);\r
1935                 if (imported != null)\r
1936                     data_chpt = imported;\r
1937             }\r
1938         }\r
1939 \r
1940         private void btn_export_Click(object sender, EventArgs e)\r
1941         {\r
1942             SaveFileDialog saveFileDialog = new SaveFileDialog();\r
1943             saveFileDialog.Filter = "Csv File|*.csv";\r
1944             saveFileDialog.DefaultExt = "csv";\r
1945             if (saveFileDialog.ShowDialog() == DialogResult.OK)\r
1946             {\r
1947                 string filename = saveFileDialog.FileName;\r
1948 \r
1949                 Main.SaveChapterMarkersToCsv(this, filename);\r
1950             }\r
1951         }\r
1952 \r
1953         private void mnu_resetChapters_Click(object sender, EventArgs e)\r
1954         {\r
1955             data_chpt.Rows.Clear();\r
1956             DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1957             if (chapterGridView != null)\r
1958             {\r
1959                 data_chpt = chapterGridView;\r
1960             }\r
1961         }\r
1962 \r
1963         // Query Editor Tab\r
1964         private void btn_generate_Query_Click(object sender, EventArgs e)\r
1965         {\r
1966             rtf_query.Text = QueryGenerator.GenerateFullQuery(this);\r
1967         }\r
1968 \r
1969         private void btn_clear_Click(object sender, EventArgs e)\r
1970         {\r
1971             rtf_query.Clear();\r
1972         }\r
1973 \r
1974         #endregion\r
1975 \r
1976         // MainWindow Components, Actions and Functions ***********************\r
1977 \r
1978         #region Source Scan\r
1979 \r
1980         /// <summary>\r
1981         /// Start the Scan Process\r
1982         /// </summary>\r
1983         /// <param name="filename">\r
1984         /// The filename.\r
1985         /// </param>\r
1986         /// <param name="title">\r
1987         /// The title.\r
1988         /// </param>\r
1989         private void StartScan(string filename, int title)\r
1990         {\r
1991             // Setup the GUI components for the scan.\r
1992             sourcePath = filename;\r
1993 \r
1994             this.DisableGUI();\r
1995 \r
1996             // Start the Scan\r
1997             try\r
1998             {\r
1999                 SourceScan.Scan(sourcePath, title);\r
2000                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
2001                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
2002             }\r
2003             catch (Exception exc)\r
2004             {\r
2005                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2006             }\r
2007         }\r
2008 \r
2009         /// <summary>\r
2010         /// Update the Status label for the scan\r
2011         /// </summary>\r
2012         /// <param name="sender">\r
2013         /// The sender.\r
2014         /// </param>\r
2015         /// <param name="e">\r
2016         /// The e.\r
2017         /// </param>\r
2018         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
2019         {\r
2020             UpdateScanStatusLabel();\r
2021         }\r
2022 \r
2023         /// <summary>\r
2024         /// Update the UI after the scan has completed\r
2025         /// </summary>\r
2026         /// <param name="sender">\r
2027         /// The sender.\r
2028         /// </param>\r
2029         /// <param name="e">\r
2030         /// The e.\r
2031         /// </param>\r
2032         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
2033         {\r
2034             UpdateGuiAfterScan();\r
2035         }\r
2036 \r
2037         /// <summary>\r
2038         /// Update the Scan Status Label\r
2039         /// </summary>\r
2040         private void UpdateScanStatusLabel()\r
2041         {\r
2042             if (InvokeRequired)\r
2043             {\r
2044                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
2045                 return;\r
2046             }\r
2047             lbl_encode.Text = SourceScan.ScanStatus;\r
2048         }\r
2049 \r
2050         /// <summary>\r
2051         /// Reset the GUI when the scan has completed\r
2052         /// </summary>\r
2053         private void UpdateGuiAfterScan()\r
2054         {\r
2055             if (InvokeRequired)\r
2056             {\r
2057                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
2058                 return;\r
2059             }\r
2060 \r
2061             try\r
2062             {\r
2063                 currentSource = SourceScan.SouceData;\r
2064 \r
2065                 // Setup some GUI components\r
2066                 drp_dvdtitle.Items.Clear();\r
2067                 if (currentSource.Titles.Count != 0)\r
2068                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
2069 \r
2070                 foreach (Title title in currentSource.Titles)\r
2071                 {\r
2072                     if (title.MainTitle)\r
2073                     {\r
2074                         drp_dvdtitle.SelectedItem = title;\r
2075                     }\r
2076                 }\r
2077 \r
2078                 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)\r
2079                 {\r
2080                     drp_dvdtitle.SelectedIndex = 0;\r
2081                 }\r
2082 \r
2083                 // Enable the creation of chapter markers if the file is an image of a dvd\r
2084                 if (drop_chapterStart.Items.Count > 0)\r
2085                 {\r
2086                     int start, end;\r
2087                     int.TryParse(drop_chapterStart.Items[0].ToString(), out start);\r
2088                     int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);\r
2089                     if (end > start) Check_ChapterMarkers.Enabled = true;\r
2090                     else\r
2091                     {\r
2092                         Check_ChapterMarkers.Enabled = false;\r
2093                         Check_ChapterMarkers.Checked = false;\r
2094                         data_chpt.Rows.Clear();\r
2095                     }\r
2096                 }\r
2097 \r
2098                 // If no titles were found, Display an error message\r
2099                 if (drp_dvdtitle.Items.Count == 0)\r
2100                 {\r
2101                     MessageBox.Show(\r
2102                         "No Title(s) found. \n\nYour Source may be copy protected, badly mastered or in a format which HandBrake does not support. \nPlease refer to the Documentation and FAQ (see Help Menu).",\r
2103                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
2104                     sourcePath = string.Empty;\r
2105                 }\r
2106                 UpdateSourceLabel();\r
2107 \r
2108                 // Enable the GUI components and enable any disabled components\r
2109                 EnableGUI();\r
2110             }\r
2111             catch (Exception exc)\r
2112             {\r
2113                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,\r
2114                                 MessageBoxIcon.Error);\r
2115                 EnableGUI();\r
2116             }\r
2117         }\r
2118 \r
2119         /// <summary>\r
2120         /// Enable the GUI\r
2121         /// </summary>\r
2122         private void EnableGUI()\r
2123         {\r
2124             try\r
2125             {\r
2126                 if (InvokeRequired)\r
2127                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
2128                 lbl_encode.Text = "Scan Completed";\r
2129                 foreach (Control ctrl in Controls)\r
2130                     ctrl.Enabled = true;\r
2131                 btn_start.Enabled = true;\r
2132                 btn_showQueue.Enabled = true;\r
2133                 btn_add2Queue.Enabled = true;\r
2134                 tb_preview.Enabled = true;\r
2135                 btn_source.Enabled = true;\r
2136                 mnu_killCLI.Visible = false;\r
2137             }\r
2138             catch (Exception exc)\r
2139             {\r
2140                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2141             }\r
2142         }\r
2143 \r
2144         /// <summary>\r
2145         /// Disable the GUI\r
2146         /// </summary>\r
2147         private void DisableGUI()\r
2148         {\r
2149             foreach (Control ctrl in Controls)\r
2150                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
2151                     ctrl.Enabled = false;\r
2152 \r
2153             lbl_encode.Visible = true;\r
2154             lbl_encode.Text = "Scanning ...";\r
2155             btn_source.Enabled = false;\r
2156             btn_start.Enabled = false;\r
2157             btn_showQueue.Enabled = false;\r
2158             btn_add2Queue.Enabled = false;\r
2159             tb_preview.Enabled = false;\r
2160             mnu_killCLI.Visible = true;\r
2161         }\r
2162 \r
2163         /// <summary>\r
2164         /// Kill the Scan\r
2165         /// </summary>\r
2166         private void KillScan()\r
2167         {\r
2168             SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2169             EnableGUI();\r
2170             ResetGUI();\r
2171 \r
2172             SourceScan.Stop();\r
2173 \r
2174             lbl_encode.Text = "Scan Cancelled!";\r
2175         }\r
2176 \r
2177         /// <summary>\r
2178         /// Reset the GUI\r
2179         /// </summary>\r
2180         private void ResetGUI()\r
2181         {\r
2182             drp_dvdtitle.Items.Clear();\r
2183             drop_chapterStart.Items.Clear();\r
2184             drop_chapterFinish.Items.Clear();\r
2185             lbl_duration.Text = "Select a Title";\r
2186             PictureSettings.lbl_src_res.Text = "Select a Title";\r
2187             sourcePath = String.Empty;\r
2188             text_destination.Text = String.Empty;\r
2189             selectedTitle = null;\r
2190         }\r
2191 \r
2192         /// <summary>\r
2193         /// Update the Source Label\r
2194         /// </summary>\r
2195         private void UpdateSourceLabel()\r
2196         {\r
2197             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
2198 \r
2199             if (selectedTitle != null)\r
2200                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
2201                     // If it's one of multiple source files, make sure we don't use the folder name\r
2202                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
2203         }\r
2204 \r
2205         /// <summary>\r
2206         /// Take a job from the Queue, rescan it, and reload the GUI for that job.\r
2207         /// </summary>\r
2208         /// <param name="job">\r
2209         /// The job.\r
2210         /// </param>\r
2211         public void RecievingJob(Job job)\r
2212         {\r
2213             string query = job.Query;\r
2214             StartScan(job.Source, job.Title);\r
2215 \r
2216             if (query != null)\r
2217             {\r
2218                 // Ok, Reset all the H264 widgets before changing the preset\r
2219                 x264Panel.Reset2Defaults();\r
2220 \r
2221                 // Send the query from the file to the Query Parser class\r
2222                 QueryParser presetQuery = QueryParser.Parse(query);\r
2223 \r
2224                 // Now load the preset\r
2225                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");\r
2226 \r
2227                 // The x264 widgets will need updated, so do this now:\r
2228                 x264Panel.StandardizeOptString();\r
2229                 x264Panel.SetCurrentSettingsInPanel();\r
2230 \r
2231                 // Finally, let this window have a copy of the preset settings.\r
2232                 this.currentlySelectedPreset = null;\r
2233                 PictureSettings.SetPresetCropWarningLabel(null);\r
2234             }\r
2235         }\r
2236 \r
2237         #endregion\r
2238 \r
2239         #region GUI Functions and Actions\r
2240 \r
2241         /// <summary>\r
2242         /// Set the GUI to it's finished encoding state.\r
2243         /// </summary>\r
2244         private void SetEncodeFinished()\r
2245         {\r
2246             try\r
2247             {\r
2248                 if (InvokeRequired)\r
2249                 {\r
2250                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
2251                     return;\r
2252                 }\r
2253 \r
2254                 lbl_encode.Text = "Encoding Finished";\r
2255                 ProgressBarStatus.Visible = false;\r
2256                 btn_start.Text = "Start";\r
2257                 btn_start.ToolTipText = "Start the encoding process";\r
2258                 btn_start.Image = Properties.Resources.Play;\r
2259 \r
2260                 // If the window is minimized, display the notification in a popup.\r
2261                 if (Properties.Settings.Default.trayIconAlerts)\r
2262                     if (FormWindowState.Minimized == this.WindowState)\r
2263                     {\r
2264                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
2265                         notifyIcon.ShowBalloonTip(500);\r
2266                     }\r
2267             }\r
2268             catch (Exception exc)\r
2269             {\r
2270                 MessageBox.Show(exc.ToString());\r
2271             }\r
2272         }\r
2273 \r
2274         /// <summary>\r
2275         /// Set the GUI to it's started encoding state.\r
2276         /// </summary>\r
2277         private void SetEncodeStarted()\r
2278         {\r
2279             try\r
2280             {\r
2281                 if (InvokeRequired)\r
2282                 {\r
2283                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
2284                     return;\r
2285                 }\r
2286                 lbl_encode.Visible = true;\r
2287                 ProgressBarStatus.Value = 0;\r
2288                 ProgressBarStatus.Visible = true;\r
2289                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
2290                 btn_start.Text = "Stop";\r
2291                 btn_start.ToolTipText = "Stop the encoding process.";\r
2292                 btn_start.Image = Properties.Resources.stop;\r
2293             }\r
2294             catch (Exception exc)\r
2295             {\r
2296                 MessageBox.Show(exc.ToString());\r
2297             }\r
2298         }\r
2299 \r
2300         /// <summary>\r
2301         /// Display the Encode Status\r
2302         /// </summary>\r
2303         /// <param name="sender">\r
2304         /// The sender.\r
2305         /// </param>\r
2306         /// <param name="e">\r
2307         /// The e.\r
2308         /// </param>\r
2309         private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)\r
2310         {\r
2311             if (this.InvokeRequired)\r
2312             {\r
2313                 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });\r
2314                 return;\r
2315             }\r
2316 \r
2317             lbl_encode.Text =\r
2318                 string.Format(\r
2319                 "{0:00.00}%,    FPS: {1:000.0},    Avg FPS: {2:000.0},    Time Remaining: {3}",\r
2320                 e.PercentComplete,\r
2321                 e.CurrentFrameRate,\r
2322                 e.AverageFrameRate,\r
2323                 e.EstimatedTimeLeft);\r
2324 \r
2325             ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);\r
2326         }\r
2327 \r
2328         /// <summary>\r
2329         /// Set the DVD Drive selection in the "Source" Menu\r
2330         /// </summary>\r
2331         private void SetDriveSelectionMenuItem()\r
2332         {\r
2333             try\r
2334             {\r
2335                 if (InvokeRequired)\r
2336                 {\r
2337                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
2338                     return;\r
2339                 }\r
2340 \r
2341                 drives = Main.GetDrives();\r
2342 \r
2343                 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();\r
2344                 foreach (DriveInformation drive in drives)\r
2345                 {\r
2346                     ToolStripMenuItem menuItem = new ToolStripMenuItem\r
2347                         {\r
2348                             Name = drive.ToString(),\r
2349                             Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",\r
2350                             Image = Resources.disc_small\r
2351                         };\r
2352                     menuItem.Click += new EventHandler(mnu_dvd_drive_Click);\r
2353                     menuItems.Add(menuItem);\r
2354                 }\r
2355 \r
2356                 foreach (ToolStripMenuItem item in menuItems)\r
2357                     btn_source.DropDownItems.Add(item);\r
2358             }\r
2359             catch (Exception exc)\r
2360             {\r
2361                 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);\r
2362             }\r
2363         }\r
2364 \r
2365         /// <summary>\r
2366         /// Access the preset Handler and setup the preset panel.\r
2367         /// </summary>\r
2368         private void LoadPresetPanel()\r
2369         {\r
2370             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
2371                 if (!Properties.Settings.Default.presetNotification)\r
2372                     MessageBox.Show(splash,\r
2373                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",\r
2374                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
2375 \r
2376             presetHandler.GetPresetPanel(ref treeView_presets);\r
2377             treeView_presets.Update();\r
2378         }\r
2379 \r
2380         /// <summary>\r
2381         /// Get the title from the selected item in the title dropdown.\r
2382         /// </summary>\r
2383         /// <returns>\r
2384         /// The title.\r
2385         /// </returns>\r
2386         private int GetTitle()\r
2387         {\r
2388             int title = 0;\r
2389             if (drp_dvdtitle.SelectedItem != null)\r
2390             {\r
2391                 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');\r
2392                 int.TryParse(titleInfo[0], out title);\r
2393             }\r
2394 \r
2395             return title;\r
2396         }\r
2397 \r
2398         /// <summary>\r
2399         /// Handle the Update Check Finishing.\r
2400         /// </summary>\r
2401         /// <param name="result">\r
2402         /// The result.\r
2403         /// </param>\r
2404         private void UpdateCheckDoneMenu(IAsyncResult result)\r
2405         {\r
2406             // Make sure it's running on the calling thread\r
2407             if (InvokeRequired)\r
2408             {\r
2409                 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));\r
2410                 return;\r
2411             }\r
2412             UpdateCheckInformation info;\r
2413             try\r
2414             {\r
2415                 // Get the information about the new build, if any, and close the window\r
2416                 info = Main.EndCheckForUpdates(result);\r
2417 \r
2418                 if (info.NewVersionAvailable && info.BuildInformation != null)\r
2419                 {\r
2420                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
2421                     updateWindow.ShowDialog();\r
2422                 }\r
2423                 else\r
2424                     MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,\r
2425                                     MessageBoxIcon.Information);\r
2426                 lbl_updateCheck.Visible = false;\r
2427                 return;\r
2428             }\r
2429             catch (Exception ex)\r
2430             {\r
2431                 if ((bool)result.AsyncState)\r
2432                     MessageBox.Show(\r
2433                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,\r
2434                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2435             }\r
2436         }\r
2437 \r
2438         #endregion\r
2439 \r
2440         #region Overrides\r
2441 \r
2442         /// <summary>\r
2443         /// Handle GUI shortcuts\r
2444         /// </summary>\r
2445         /// <param name="msg">Message</param>\r
2446         /// <param name="keyData">Keys</param>\r
2447         /// <returns>Bool</returns>\r
2448         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
2449         {\r
2450             if (keyData == (Keys.Control | Keys.S))\r
2451             {\r
2452                 btn_start_Click(this, new EventArgs());\r
2453                 return true;\r
2454             }\r
2455 \r
2456             if (keyData == (Keys.Control | Keys.A))\r
2457             {\r
2458                 btn_add2Queue_Click(this, new EventArgs());\r
2459                 return true;\r
2460             }\r
2461             return base.ProcessCmdKey(ref msg, keyData);\r
2462         }\r
2463 \r
2464         /// <summary>\r
2465         /// If the queue is being processed, prompt the user to confirm application close.\r
2466         /// </summary>\r
2467         /// <param name="e">FormClosingEventArgs</param>\r
2468         protected override void OnFormClosing(FormClosingEventArgs e)\r
2469         {\r
2470             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
2471             if (encodeQueue.IsEncoding)\r
2472             {\r
2473                 DialogResult result =\r
2474                     MessageBox.Show(\r
2475                         "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",\r
2476                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
2477 \r
2478                 if (result == DialogResult.No)\r
2479                 {\r
2480                     e.Cancel = true;\r
2481                     return;\r
2482                 }\r
2483 \r
2484                 // Try to safely close out if we can, or kill the cli if using in-gui status\r
2485                 if (Settings.Default.enocdeStatusInGui)\r
2486                     encodeQueue.Stop();\r
2487                 else\r
2488                     encodeQueue.SafelyClose();\r
2489             }\r
2490 \r
2491             if (SourceScan.IsScanning)\r
2492             {\r
2493                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2494                 SourceScan.Stop();\r
2495             }\r
2496             base.OnFormClosing(e);\r
2497         }\r
2498 \r
2499         #endregion\r
2500 \r
2501         // This is the END of the road ****************************************\r
2502     }\r
2503 }