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