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