OSDN Git Service

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