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