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