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