OSDN Git Service

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