OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmMain.cs
1 /*  frmMain.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr/>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.ComponentModel;\r
11     using System.Diagnostics;\r
12     using System.Drawing;\r
13     using System.Globalization;\r
14     using System.IO;\r
15     using System.Reflection;\r
16     using System.Threading;\r
17     using System.Windows.Forms;\r
18     using Functions;\r
19     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                     drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());\r
1381                     if (drop_angle.Items.Count != 0)\r
1382                         drop_angle.SelectedIndex = 0;\r
1383                 }\r
1384                 else\r
1385                 {\r
1386                     drop_angle.Visible = false;\r
1387                     lbl_angle.Visible = false;\r
1388                 }\r
1389 \r
1390                 // Populate the Start chapter Dropdown\r
1391                 drop_chapterStart.Items.Clear();\r
1392                 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1393                 if (drop_chapterStart.Items.Count > 0)\r
1394                     drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();\r
1395 \r
1396                 // Populate the Final Chapter Dropdown\r
1397                 drop_chapterFinish.Items.Clear();\r
1398                 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1399                 if (drop_chapterFinish.Items.Count > 0)\r
1400                     drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();\r
1401 \r
1402                 // Populate the Audio Channels Dropdown\r
1403                 AudioSettings.SetTrackList(selectedTitle, CurrentlySelectedPreset);\r
1404 \r
1405                 // Populate the Subtitles dropdown\r
1406                 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());\r
1407             }\r
1408             // Update the source label if we have multiple streams\r
1409             if (selectedTitle != null)\r
1410                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1411                     labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1412 \r
1413             // Run the AutoName & ChapterNaming functions\r
1414             if (Properties.Settings.Default.autoNaming)\r
1415             {\r
1416                 string autoPath = Main.AutoName(this);\r
1417                 if (autoPath != null)\r
1418                     text_destination.Text = autoPath;\r
1419                 else\r
1420                     MessageBox.Show(\r
1421                         "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
1422                         "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1423             }\r
1424 \r
1425             data_chpt.Rows.Clear();\r
1426             if (selectedTitle.Chapters.Count != 1)\r
1427             {\r
1428                 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1429                 if (chapterGridView != null)\r
1430                     data_chpt = chapterGridView;\r
1431             }\r
1432             else\r
1433             {\r
1434                 Check_ChapterMarkers.Checked = false;\r
1435                 Check_ChapterMarkers.Enabled = false;\r
1436             }\r
1437 \r
1438             // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.\r
1439             data_chpt.Columns[0].Width = 166;\r
1440             data_chpt.Columns[0].Width = 165;\r
1441 \r
1442             RegisterPresetEventHandler();\r
1443         }\r
1444 \r
1445         private void chapersChanged(object sender, EventArgs e)\r
1446         {\r
1447             if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.\r
1448                 return;\r
1449 \r
1450             Control ctl = (Control)sender;\r
1451             int chapterStart, chapterEnd;\r
1452             int.TryParse(drop_chapterStart.Text, out chapterStart);\r
1453             int.TryParse(drop_chapterFinish.Text, out chapterEnd);\r
1454 \r
1455             switch (ctl.Name)\r
1456             {\r
1457                 case "drop_chapterStart":\r
1458                     if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)\r
1459                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1460 \r
1461                     if (chapterEnd != 0)\r
1462                         if (chapterStart > chapterEnd)\r
1463                             drop_chapterFinish.Text = chapterStart.ToString();\r
1464                     break;\r
1465                 case "drop_chapterFinish":\r
1466                     if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)\r
1467                         drop_chapterStart.SelectedIndex = 0;\r
1468 \r
1469                     if (chapterStart != 0)\r
1470                         if (chapterEnd < chapterStart)\r
1471                             drop_chapterFinish.Text = chapterStart.ToString();\r
1472 \r
1473                     // Add more rows to the Chapter menu if needed.\r
1474                     if (Check_ChapterMarkers.Checked)\r
1475                     {\r
1476                         int i = data_chpt.Rows.Count, finish = 0;\r
1477                         int.TryParse(drop_chapterFinish.Text, out finish);\r
1478 \r
1479                         while (i < finish)\r
1480                         {\r
1481                             int n = data_chpt.Rows.Add();\r
1482                             data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
1483                             data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
1484                             data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
1485                             data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
1486                             i++;\r
1487                         }\r
1488                     }\r
1489                     break;\r
1490             }\r
1491 \r
1492             // Update the Duration\r
1493             lbl_duration.Text =\r
1494                 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)\r
1495                     .ToString();\r
1496 \r
1497             // Run the Autonaming function\r
1498             if (Properties.Settings.Default.autoNaming)\r
1499                 text_destination.Text = Main.AutoName(this);\r
1500 \r
1501             // Disable chapter markers if only 1 chapter is selected.\r
1502             if (chapterStart == chapterEnd)\r
1503             {\r
1504                 Check_ChapterMarkers.Enabled = false;\r
1505                 btn_importChapters.Enabled = false;\r
1506                 data_chpt.Enabled = false;\r
1507             }\r
1508             else\r
1509             {\r
1510                 Check_ChapterMarkers.Enabled = true;\r
1511                 if (Check_ChapterMarkers.Checked)\r
1512                 {\r
1513                     btn_importChapters.Enabled = true;\r
1514                     data_chpt.Enabled = true;\r
1515                 }\r
1516             }\r
1517         }\r
1518 \r
1519         private void SecondsOrFramesChanged(object sender, EventArgs e)\r
1520         {\r
1521             int start, end;\r
1522             int.TryParse(drop_chapterStart.Text, out start);\r
1523             int.TryParse(drop_chapterFinish.Text, out end);\r
1524             double duration = end - start;\r
1525 \r
1526             switch (drop_mode.SelectedIndex)\r
1527             {\r
1528                 case 1:\r
1529                     lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1530                     return;\r
1531                 case 2:\r
1532                     if (selectedTitle != null)\r
1533                     {\r
1534                         duration = duration / selectedTitle.Fps;\r
1535                         lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1536                     }\r
1537                     else\r
1538                         lbl_duration.Text = "--:--:--";\r
1539 \r
1540                     return;\r
1541             }\r
1542         }\r
1543 \r
1544         private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)\r
1545         {\r
1546             // Reset\r
1547             this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1548             this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1549 \r
1550             // Do Work\r
1551             switch (drop_mode.SelectedIndex)\r
1552             {\r
1553                 case 0:\r
1554                     drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;\r
1555                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;\r
1556                     if (drop_chapterStart.Items.Count != 0)\r
1557                     {\r
1558                         drop_chapterStart.SelectedIndex = 0;\r
1559                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1560                     }\r
1561                     else\r
1562                         lbl_duration.Text = "--:--:--";\r
1563                     return;\r
1564                 case 1:\r
1565                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1566                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1567                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1568                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1569                     if (selectedTitle != null)\r
1570                     {\r
1571                         drop_chapterStart.Text = "0";\r
1572                         drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();\r
1573                     }\r
1574                     return;\r
1575                 case 2:\r
1576                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1577                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1578                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1579                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1580                     if (selectedTitle != null)\r
1581                     {\r
1582                         drop_chapterStart.Text = "0";\r
1583                         drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();\r
1584                     }\r
1585                     return;\r
1586             }\r
1587         }\r
1588 \r
1589         // Destination\r
1590         private void btn_destBrowse_Click(object sender, EventArgs e)\r
1591         {\r
1592             // This removes the file extension from the filename box on the save file dialog.\r
1593             // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.\r
1594             DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);\r
1595 \r
1596             if (Path.IsPathRooted(text_destination.Text))\r
1597                 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);\r
1598 \r
1599             // Show the dialog and set the main form file path\r
1600             if (drop_format.SelectedIndex.Equals(0))\r
1601                 DVD_Save.FilterIndex = 1;\r
1602             else if (drop_format.SelectedIndex.Equals(1))\r
1603                 DVD_Save.FilterIndex = 2;\r
1604 \r
1605             if (DVD_Save.ShowDialog() == DialogResult.OK)\r
1606             {\r
1607                 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames\r
1608                 switch (DVD_Save.FilterIndex)\r
1609                 {\r
1610                     case 1:\r
1611                         if (\r
1612                             !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",\r
1613                                                                          StringComparison.InvariantCultureIgnoreCase))\r
1614                             if (Properties.Settings.Default.useM4v)\r
1615                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");\r
1616                             else\r
1617                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");\r
1618                         break;\r
1619                     case 2:\r
1620                         if (\r
1621                             !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))\r
1622                             DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");\r
1623                         break;\r
1624                     default:\r
1625                         // do nothing  \r
1626                         break;\r
1627                 }\r
1628                 text_destination.Text = DVD_Save.FileName;\r
1629 \r
1630                 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)\r
1631                 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)\r
1632                     SetExtension(".m4v");\r
1633             }\r
1634         }\r
1635 \r
1636         private void text_destination_TextChanged(object sender, EventArgs e)\r
1637         {\r
1638             string path = text_destination.Text;\r
1639             if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))\r
1640                 drop_format.SelectedIndex = 0;\r
1641             else if (path.EndsWith(".mkv"))\r
1642                 drop_format.SelectedIndex = 1;\r
1643         }\r
1644 \r
1645         // Output Settings\r
1646         private void drop_format_SelectedIndexChanged(object sender, EventArgs e)\r
1647         {\r
1648             switch (drop_format.SelectedIndex)\r
1649             {\r
1650                 case 0:\r
1651                     if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||\r
1652                         AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())\r
1653                         SetExtension(".m4v");\r
1654                     else\r
1655                         SetExtension(".mp4");\r
1656                     break;\r
1657                 case 1:\r
1658                     SetExtension(".mkv");\r
1659                     break;\r
1660             }\r
1661 \r
1662             AudioSettings.SetContainer(drop_format.Text);\r
1663             Subtitles.SetContainer(drop_format.SelectedIndex);\r
1664 \r
1665             if (drop_format.Text.Contains("MP4"))\r
1666             {\r
1667                 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))\r
1668                 {\r
1669                     drp_videoEncoder.Items.Remove("VP3 (Theora)");\r
1670                     drp_videoEncoder.SelectedIndex = 1;\r
1671                 }\r
1672             }\r
1673             else if (drop_format.Text.Contains("MKV"))\r
1674                 drp_videoEncoder.Items.Add("VP3 (Theora)");\r
1675         }\r
1676 \r
1677         public void SetExtension(string newExtension)\r
1678         {\r
1679             if (newExtension == ".mp4" || newExtension == ".m4v")\r
1680                 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||\r
1681                     Subtitles.RequiresM4V())\r
1682                     newExtension = ".m4v";\r
1683                 else\r
1684                     newExtension = ".mp4";\r
1685 \r
1686             if (Path.HasExtension(newExtension))\r
1687                 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);\r
1688         }\r
1689 \r
1690         // Video Tab\r
1691         private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)\r
1692         {\r
1693             setContainerOpts();\r
1694 \r
1695             // Turn off some options which are H.264 only when the user selects a non h.264 encoder\r
1696             if (drp_videoEncoder.Text.Contains("H.264"))\r
1697             {\r
1698                 if (check_2PassEncode.CheckState == CheckState.Checked)\r
1699                     check_turbo.Enabled = true;\r
1700 \r
1701                 tab_advanced.Enabled = true;\r
1702                 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1703                     check_iPodAtom.Enabled = true;\r
1704                 else\r
1705                     check_iPodAtom.Enabled = false;\r
1706             }\r
1707             else\r
1708             {\r
1709                 check_turbo.CheckState = CheckState.Unchecked;\r
1710                 check_turbo.Enabled = false;\r
1711                 tab_advanced.Enabled = false;\r
1712                 x264Panel.X264Query = string.Empty;\r
1713                 check_iPodAtom.Enabled = false;\r
1714                 check_iPodAtom.Checked = false;\r
1715             }\r
1716 \r
1717             // Setup the CQ Slider\r
1718             switch (drp_videoEncoder.Text)\r
1719             {\r
1720                 case "MPEG-4 (FFmpeg)":\r
1721                     if (slider_videoQuality.Value > 31)\r
1722                         slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.\r
1723                     slider_videoQuality.Minimum = 1;\r
1724                     slider_videoQuality.Maximum = 31;\r
1725                     break;\r
1726                 case "H.264 (x264)":\r
1727                     slider_videoQuality.Minimum = 0;\r
1728                     slider_videoQuality.TickFrequency = 1;\r
1729 \r
1730                     CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");\r
1731                     double cqStep = Properties.Settings.Default.x264cqstep;\r
1732                     double multiplier = 1.0 / cqStep;\r
1733                     double value = slider_videoQuality.Value * multiplier;\r
1734 \r
1735                     slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1736 \r
1737                     if (value < slider_videoQuality.Maximum)\r
1738                         slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;\r
1739 \r
1740                     break;\r
1741                 case "VP3 (Theora)":\r
1742                     if (slider_videoQuality.Value > 63)\r
1743                         slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.\r
1744                     slider_videoQuality.Minimum = 0;\r
1745                     slider_videoQuality.Maximum = 63;\r
1746                     break;\r
1747             }\r
1748         }\r
1749 \r
1750         /// <summary>\r
1751         /// Set the container format options\r
1752         /// </summary>\r
1753         public void setContainerOpts()\r
1754         {\r
1755             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1756             {\r
1757                 check_largeFile.Enabled = true;\r
1758                 check_optimiseMP4.Enabled = true;\r
1759                 check_iPodAtom.Enabled = true;\r
1760             }\r
1761             else\r
1762             {\r
1763                 check_largeFile.Enabled = false;\r
1764                 check_optimiseMP4.Enabled = false;\r
1765                 check_iPodAtom.Enabled = false;\r
1766                 check_largeFile.Checked = false;\r
1767                 check_optimiseMP4.Checked = false;\r
1768                 check_iPodAtom.Checked = false;\r
1769             }\r
1770         }\r
1771 \r
1772         private double _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1773 \r
1774         /// <summary>\r
1775         /// Update the CQ slider for x264 for a new CQ step. This is set from option\r
1776         /// </summary>\r
1777         public void setQualityFromSlider()\r
1778         {\r
1779             // Work out the current RF value.\r
1780             double cqStep = _cachedCqStep;\r
1781             double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1782 \r
1783             // Change the maximum value for the slider\r
1784             slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1785 \r
1786             // Reset the CQ slider to RF0\r
1787             slider_videoQuality.Value = slider_videoQuality.Maximum;\r
1788 \r
1789             // Reset the CQ slider back to the previous value as close as possible\r
1790             double cqStepNew = Properties.Settings.Default.x264cqstep;\r
1791             double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1792             while (rfValueCurrent < rfValue)\r
1793             {\r
1794                 slider_videoQuality.Value--;\r
1795                 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1796             }\r
1797 \r
1798             // Cache the CQ step for the next calculation\r
1799             _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1800         }\r
1801 \r
1802         private void slider_videoQuality_Scroll(object sender, EventArgs e)\r
1803         {\r
1804             double cqStep = Properties.Settings.Default.x264cqstep;\r
1805             switch (drp_videoEncoder.Text)\r
1806             {\r
1807                 case "MPEG-4 (FFmpeg)":\r
1808                     lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);\r
1809                     break;\r
1810                 case "H.264 (x264)":\r
1811                     double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1812                     rfValue = Math.Round(rfValue, 2);\r
1813                     lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));\r
1814                     break;\r
1815                 case "VP3 (Theora)":\r
1816                     lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;\r
1817                     break;\r
1818             }\r
1819         }\r
1820 \r
1821         private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)\r
1822         {\r
1823             text_bitrate.Enabled = false;\r
1824             text_filesize.Enabled = true;\r
1825             slider_videoQuality.Enabled = false;\r
1826 \r
1827             check_2PassEncode.Enabled = true;\r
1828         }\r
1829 \r
1830         private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)\r
1831         {\r
1832             text_bitrate.Enabled = true;\r
1833             text_filesize.Enabled = false;\r
1834             slider_videoQuality.Enabled = false;\r
1835 \r
1836             check_2PassEncode.Enabled = true;\r
1837         }\r
1838 \r
1839         private void radio_cq_CheckedChanged(object sender, EventArgs e)\r
1840         {\r
1841             text_bitrate.Enabled = false;\r
1842             text_filesize.Enabled = false;\r
1843             slider_videoQuality.Enabled = true;\r
1844 \r
1845             check_2PassEncode.Enabled = false;\r
1846             check_2PassEncode.CheckState = CheckState.Unchecked;\r
1847         }\r
1848 \r
1849         private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)\r
1850         {\r
1851             if (check_2PassEncode.CheckState.ToString() == "Checked")\r
1852             {\r
1853                 if (drp_videoEncoder.Text.Contains("H.264"))\r
1854                     check_turbo.Enabled = true;\r
1855             }\r
1856             else\r
1857             {\r
1858                 check_turbo.Enabled = false;\r
1859                 check_turbo.CheckState = CheckState.Unchecked;\r
1860             }\r
1861         }\r
1862 \r
1863         // Chapter Marker Tab\r
1864         private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)\r
1865         {\r
1866             if (Check_ChapterMarkers.Checked)\r
1867             {\r
1868                 if (drop_format.SelectedIndex != 1)\r
1869                     SetExtension(".m4v");\r
1870                 data_chpt.Enabled = true;\r
1871                 btn_importChapters.Enabled = true;\r
1872             }\r
1873             else\r
1874             {\r
1875                 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)\r
1876                     SetExtension(".mp4");\r
1877                 data_chpt.Enabled = false;\r
1878                 btn_importChapters.Enabled = false;\r
1879             }\r
1880         }\r
1881 \r
1882         private void btn_importChapters_Click(object sender, EventArgs e)\r
1883         {\r
1884             if (File_ChapterImport.ShowDialog() == DialogResult.OK)\r
1885             {\r
1886                 string filename = File_ChapterImport.FileName;\r
1887                 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);\r
1888                 if (imported != null)\r
1889                     data_chpt = imported;\r
1890             }\r
1891         }\r
1892 \r
1893         private void btn_export_Click(object sender, EventArgs e)\r
1894         {\r
1895             SaveFileDialog saveFileDialog = new SaveFileDialog();\r
1896             saveFileDialog.Filter = "Csv File|*.csv";\r
1897             saveFileDialog.DefaultExt = "csv";\r
1898             if (saveFileDialog.ShowDialog() == DialogResult.OK)\r
1899             {\r
1900                 string filename = saveFileDialog.FileName;\r
1901 \r
1902                 Main.SaveChapterMarkersToCsv(this, filename);\r
1903             }\r
1904         }\r
1905 \r
1906         private void mnu_resetChapters_Click(object sender, EventArgs e)\r
1907         {\r
1908             data_chpt.Rows.Clear();\r
1909             DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1910             if (chapterGridView != null)\r
1911             {\r
1912                 data_chpt = chapterGridView;\r
1913             }\r
1914         }\r
1915 \r
1916         // Query Editor Tab\r
1917         private void btn_generate_Query_Click(object sender, EventArgs e)\r
1918         {\r
1919             rtf_query.Text = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
1920         }\r
1921 \r
1922         private void btn_clear_Click(object sender, EventArgs e)\r
1923         {\r
1924             rtf_query.Clear();\r
1925         }\r
1926 \r
1927         #endregion\r
1928 \r
1929         // MainWindow Components, Actions and Functions ***********************\r
1930 \r
1931         #region Source Scan\r
1932 \r
1933         /// <summary>\r
1934         /// Start the Scan Process\r
1935         /// </summary>\r
1936         /// <param name="filename">\r
1937         /// The filename.\r
1938         /// </param>\r
1939         /// <param name="title">\r
1940         /// The title.\r
1941         /// </param>\r
1942         private void StartScan(string filename, int title)\r
1943         {\r
1944             // Setup the GUI components for the scan.\r
1945             sourcePath = filename;\r
1946 \r
1947             this.DisableGUI();\r
1948 \r
1949             // Start the Scan\r
1950             try\r
1951             {\r
1952                 SourceScan.Scan(sourcePath, title);\r
1953                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
1954                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
1955             }\r
1956             catch (Exception exc)\r
1957             {\r
1958                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1959             }\r
1960         }\r
1961 \r
1962         /// <summary>\r
1963         /// Update the Status label for the scan\r
1964         /// </summary>\r
1965         /// <param name="sender">\r
1966         /// The sender.\r
1967         /// </param>\r
1968         /// <param name="e">\r
1969         /// The e.\r
1970         /// </param>\r
1971         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
1972         {\r
1973             UpdateScanStatusLabel();\r
1974         }\r
1975 \r
1976         /// <summary>\r
1977         /// Update the UI after the scan has completed\r
1978         /// </summary>\r
1979         /// <param name="sender">\r
1980         /// The sender.\r
1981         /// </param>\r
1982         /// <param name="e">\r
1983         /// The e.\r
1984         /// </param>\r
1985         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
1986         {\r
1987             UpdateGuiAfterScan();\r
1988         }\r
1989 \r
1990         /// <summary>\r
1991         /// Update the Scan Status Label\r
1992         /// </summary>\r
1993         private void UpdateScanStatusLabel()\r
1994         {\r
1995             if (InvokeRequired)\r
1996             {\r
1997                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
1998                 return;\r
1999             }\r
2000             lbl_encode.Text = SourceScan.ScanStatus;\r
2001         }\r
2002 \r
2003         /// <summary>\r
2004         /// Reset the GUI when the scan has completed\r
2005         /// </summary>\r
2006         private void UpdateGuiAfterScan()\r
2007         {\r
2008             if (InvokeRequired)\r
2009             {\r
2010                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
2011                 return;\r
2012             }\r
2013 \r
2014             try\r
2015             {\r
2016                 currentSource = SourceScan.SouceData;\r
2017 \r
2018                 // Setup some GUI components\r
2019                 drp_dvdtitle.Items.Clear();\r
2020                 if (currentSource.Titles.Count != 0)\r
2021                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
2022 \r
2023                 foreach (Title title in currentSource.Titles)\r
2024                 {\r
2025                     if (title.MainTitle)\r
2026                     {\r
2027                         drp_dvdtitle.SelectedItem = title;\r
2028                     }\r
2029                 }\r
2030 \r
2031                 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)\r
2032                 {\r
2033                     drp_dvdtitle.SelectedIndex = 0;\r
2034                 }\r
2035 \r
2036                 // Enable the creation of chapter markers if the file is an image of a dvd.\r
2037                 int start, end;\r
2038                 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);\r
2039                 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);\r
2040                 if (end > start)\r
2041                     Check_ChapterMarkers.Enabled = true;\r
2042                 else\r
2043                 {\r
2044                     Check_ChapterMarkers.Enabled = false;\r
2045                     Check_ChapterMarkers.Checked = false;\r
2046                     data_chpt.Rows.Clear();\r
2047                 }\r
2048 \r
2049                 // If no titles were found, Display an error message\r
2050                 if (drp_dvdtitle.Items.Count == 0)\r
2051                 {\r
2052                     MessageBox.Show(\r
2053                         "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
2054                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
2055                     sourcePath = string.Empty;\r
2056                 }\r
2057                 UpdateSourceLabel();\r
2058 \r
2059                 // Enable the GUI components and enable any disabled components\r
2060                 EnableGUI();\r
2061             }\r
2062             catch (Exception exc)\r
2063             {\r
2064                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,\r
2065                                 MessageBoxIcon.Error);\r
2066                 EnableGUI();\r
2067             }\r
2068         }\r
2069 \r
2070         /// <summary>\r
2071         /// Enable the GUI\r
2072         /// </summary>\r
2073         private void EnableGUI()\r
2074         {\r
2075             try\r
2076             {\r
2077                 if (InvokeRequired)\r
2078                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
2079                 lbl_encode.Text = "Scan Completed";\r
2080                 foreach (Control ctrl in Controls)\r
2081                     ctrl.Enabled = true;\r
2082                 btn_start.Enabled = true;\r
2083                 btn_showQueue.Enabled = true;\r
2084                 btn_add2Queue.Enabled = true;\r
2085                 tb_preview.Enabled = true;\r
2086                 btn_source.Enabled = true;\r
2087                 mnu_killCLI.Visible = false;\r
2088             }\r
2089             catch (Exception exc)\r
2090             {\r
2091                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2092             }\r
2093         }\r
2094 \r
2095         /// <summary>\r
2096         /// Disable the GUI\r
2097         /// </summary>\r
2098         private void DisableGUI()\r
2099         {\r
2100             foreach (Control ctrl in Controls)\r
2101                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
2102                     ctrl.Enabled = false;\r
2103 \r
2104             lbl_encode.Visible = true;\r
2105             lbl_encode.Text = "Scanning ...";\r
2106             btn_source.Enabled = false;\r
2107             btn_start.Enabled = false;\r
2108             btn_showQueue.Enabled = false;\r
2109             btn_add2Queue.Enabled = false;\r
2110             tb_preview.Enabled = false;\r
2111             mnu_killCLI.Visible = true;\r
2112         }\r
2113 \r
2114         /// <summary>\r
2115         /// Kill the Scan\r
2116         /// </summary>\r
2117         private void KillScan()\r
2118         {\r
2119             SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2120             EnableGUI();\r
2121             ResetGUI();\r
2122 \r
2123             SourceScan.Stop();\r
2124 \r
2125             lbl_encode.Text = "Scan Cancelled!";\r
2126         }\r
2127 \r
2128         /// <summary>\r
2129         /// Reset the GUI\r
2130         /// </summary>\r
2131         private void ResetGUI()\r
2132         {\r
2133             drp_dvdtitle.Items.Clear();\r
2134             drop_chapterStart.Items.Clear();\r
2135             drop_chapterFinish.Items.Clear();\r
2136             lbl_duration.Text = "Select a Title";\r
2137             PictureSettings.lbl_src_res.Text = "Select a Title";\r
2138             sourcePath = String.Empty;\r
2139             text_destination.Text = String.Empty;\r
2140             selectedTitle = null;\r
2141         }\r
2142 \r
2143         /// <summary>\r
2144         /// Update the Source Label\r
2145         /// </summary>\r
2146         private void UpdateSourceLabel()\r
2147         {\r
2148             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
2149 \r
2150             if (selectedTitle != null)\r
2151                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
2152                     // If it's one of multiple source files, make sure we don't use the folder name\r
2153                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
2154         }\r
2155 \r
2156         /// <summary>\r
2157         /// Take a job from the Queue, rescan it, and reload the GUI for that job.\r
2158         /// </summary>\r
2159         /// <param name="job">\r
2160         /// The job.\r
2161         /// </param>\r
2162         public void RecievingJob(Job job)\r
2163         {\r
2164             string query = job.Query;\r
2165             StartScan(job.Source, job.Title);\r
2166 \r
2167             if (query != null)\r
2168             {\r
2169                 // Ok, Reset all the H264 widgets before changing the preset\r
2170                 x264Panel.Reset2Defaults();\r
2171 \r
2172                 // Send the query from the file to the Query Parser class\r
2173                 QueryParser presetQuery = QueryParser.Parse(query);\r
2174 \r
2175                 // Now load the preset\r
2176                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);\r
2177 \r
2178                 // The x264 widgets will need updated, so do this now:\r
2179                 x264Panel.X264_StandardizeOptString();\r
2180                 x264Panel.X264_SetCurrentSettingsInPanel();\r
2181 \r
2182                 // Finally, let this window have a copy of the preset settings.\r
2183                 CurrentlySelectedPreset = null;\r
2184                 PictureSettings.SetPresetCropWarningLabel(null);\r
2185             }\r
2186         }\r
2187 \r
2188         #endregion\r
2189 \r
2190         #region GUI Functions and Actions\r
2191 \r
2192         /// <summary>\r
2193         /// Set the GUI to it's finished encoding state.\r
2194         /// </summary>\r
2195         private void SetEncodeFinished()\r
2196         {\r
2197             try\r
2198             {\r
2199                 if (InvokeRequired)\r
2200                 {\r
2201                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
2202                     return;\r
2203                 }\r
2204 \r
2205                 lbl_encode.Text = "Encoding Finished";\r
2206                 ProgressBarStatus.Visible = false;\r
2207                 btn_start.Text = "Start";\r
2208                 btn_start.ToolTipText = "Start the encoding process";\r
2209                 btn_start.Image = Properties.Resources.Play;\r
2210 \r
2211                 // If the window is minimized, display the notification in a popup.\r
2212                 if (Properties.Settings.Default.trayIconAlerts)\r
2213                     if (FormWindowState.Minimized == this.WindowState)\r
2214                     {\r
2215                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
2216                         notifyIcon.ShowBalloonTip(500);\r
2217                     }\r
2218             }\r
2219             catch (Exception exc)\r
2220             {\r
2221                 MessageBox.Show(exc.ToString());\r
2222             }\r
2223         }\r
2224 \r
2225         /// <summary>\r
2226         /// Set the GUI to it's started encoding state.\r
2227         /// </summary>\r
2228         private void SetEncodeStarted()\r
2229         {\r
2230             try\r
2231             {\r
2232                 if (InvokeRequired)\r
2233                 {\r
2234                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
2235                     return;\r
2236                 }\r
2237                 lbl_encode.Visible = true;\r
2238                 ProgressBarStatus.Value = 0;\r
2239                 ProgressBarStatus.Visible = true;\r
2240                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
2241                 btn_start.Text = "Stop";\r
2242                 btn_start.ToolTipText = "Stop the encoding process.";\r
2243                 btn_start.Image = Properties.Resources.stop;\r
2244             }\r
2245             catch (Exception exc)\r
2246             {\r
2247                 MessageBox.Show(exc.ToString());\r
2248             }\r
2249         }\r
2250 \r
2251         /// <summary>\r
2252         /// Set the DVD Drive selection in the "Source" Menu\r
2253         /// </summary>\r
2254         private void SetDriveSelectionMenuItem()\r
2255         {\r
2256             try\r
2257             {\r
2258                 if (InvokeRequired)\r
2259                 {\r
2260                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
2261                     return;\r
2262                 }\r
2263 \r
2264                 drives = Main.GetDrives();\r
2265 \r
2266                 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();\r
2267                 foreach (DriveInformation drive in drives)\r
2268                 {\r
2269                     ToolStripMenuItem menuItem = new ToolStripMenuItem\r
2270                         {\r
2271                             Name = drive.ToString(),\r
2272                             Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",\r
2273                             Image = Resources.disc_small\r
2274                         };\r
2275                     menuItem.Click += new EventHandler(mnu_dvd_drive_Click);\r
2276                     menuItems.Add(menuItem);\r
2277                 }\r
2278 \r
2279                 foreach (ToolStripMenuItem item in menuItems)\r
2280                     btn_source.DropDownItems.Add(item);\r
2281             }\r
2282             catch (Exception exc)\r
2283             {\r
2284                 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);\r
2285             }\r
2286         }\r
2287 \r
2288         /// <summary>\r
2289         /// Access the preset Handler and setup the preset panel.\r
2290         /// </summary>\r
2291         private void LoadPresetPanel()\r
2292         {\r
2293             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
2294                 if (!Properties.Settings.Default.presetNotification)\r
2295                     MessageBox.Show(splash,\r
2296                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",\r
2297                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
2298 \r
2299             presetHandler.GetPresetPanel(ref treeView_presets);\r
2300             treeView_presets.Update();\r
2301         }\r
2302 \r
2303         /// <summary>\r
2304         /// Get the title from the selected item in the title dropdown.\r
2305         /// </summary>\r
2306         /// <returns>\r
2307         /// The title.\r
2308         /// </returns>\r
2309         private int getTitle()\r
2310         {\r
2311             int title = 0;\r
2312             if (drp_dvdtitle.SelectedItem != null)\r
2313             {\r
2314                 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');\r
2315                 int.TryParse(titleInfo[0], out title);\r
2316             }\r
2317 \r
2318             return title;\r
2319         }\r
2320 \r
2321         /// <summary>\r
2322         /// Handle the Update Check Finishing.\r
2323         /// </summary>\r
2324         /// <param name="result">\r
2325         /// The result.\r
2326         /// </param>\r
2327         private void updateCheckDoneMenu(IAsyncResult result)\r
2328         {\r
2329             // Make sure it's running on the calling thread\r
2330             if (InvokeRequired)\r
2331             {\r
2332                 Invoke(new MethodInvoker(() => updateCheckDoneMenu(result)));\r
2333                 return;\r
2334             }\r
2335             UpdateCheckInformation info;\r
2336             try\r
2337             {\r
2338                 // Get the information about the new build, if any, and close the window\r
2339                 info = Main.EndCheckForUpdates(result);\r
2340 \r
2341                 if (info.NewVersionAvailable && info.BuildInformation != null)\r
2342                 {\r
2343                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
2344                     updateWindow.ShowDialog();\r
2345                 }\r
2346                 else\r
2347                     MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,\r
2348                                     MessageBoxIcon.Information);\r
2349                 lbl_updateCheck.Visible = false;\r
2350                 return;\r
2351             }\r
2352             catch (Exception ex)\r
2353             {\r
2354                 if ((bool)result.AsyncState)\r
2355                     MessageBox.Show(\r
2356                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,\r
2357                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2358             }\r
2359         }\r
2360 \r
2361         #endregion\r
2362 \r
2363         #region Overrides\r
2364 \r
2365         /// <summary>\r
2366         /// Handle GUI shortcuts\r
2367         /// </summary>\r
2368         /// <param name="msg">Message</param>\r
2369         /// <param name="keyData">Keys</param>\r
2370         /// <returns>Bool</returns>\r
2371         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
2372         {\r
2373             if (keyData == (Keys.Control | Keys.S))\r
2374             {\r
2375                 btn_start_Click(this, new EventArgs());\r
2376                 return true;\r
2377             }\r
2378 \r
2379             if (keyData == (Keys.Control | Keys.A))\r
2380             {\r
2381                 btn_add2Queue_Click(this, new EventArgs());\r
2382                 return true;\r
2383             }\r
2384             return base.ProcessCmdKey(ref msg, keyData);\r
2385         }\r
2386 \r
2387         /// <summary>\r
2388         /// If the queue is being processed, prompt the user to confirm application close.\r
2389         /// </summary>\r
2390         /// <param name="e">FormClosingEventArgs</param>\r
2391         protected override void OnFormClosing(FormClosingEventArgs e)\r
2392         {\r
2393             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
2394             if (encodeQueue.IsEncoding)\r
2395             {\r
2396                 DialogResult result =\r
2397                     MessageBox.Show(\r
2398                         "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",\r
2399                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
2400 \r
2401                 if (result == DialogResult.No)\r
2402                     e.Cancel = true;\r
2403 \r
2404                 // Try to safely close out if we can, or kill the cli if using in-gui status\r
2405                 if (Settings.Default.enocdeStatusInGui)\r
2406                     encodeQueue.Stop();\r
2407                 else\r
2408                     encodeQueue.SafelyClose();\r
2409             }\r
2410 \r
2411             if (SourceScan.IsScanning)\r
2412             {\r
2413                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2414                 SourceScan.Stop();\r
2415             }\r
2416             base.OnFormClosing(e);\r
2417         }\r
2418 \r
2419         #endregion\r
2420 \r
2421         #region In-GUI Encode Status\r
2422 \r
2423         /// <summary>\r
2424         /// Starts a new thread to monitor and process the CLI encode status\r
2425         /// </summary>\r
2426         private void EncodeMonitorThread()\r
2427         {\r
2428             try\r
2429             {\r
2430                 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);\r
2431                 encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
2432                 while (!encode.EndOfStream)\r
2433                     encode.ReadEncodeStatus();\r
2434 \r
2435                 SetEncodeFinished();\r
2436             }\r
2437             catch (Exception exc)\r
2438             {\r
2439                 MessageBox.Show(exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2440             }\r
2441         }\r
2442 \r
2443         /// <summary>\r
2444         /// Displays the Encode status in the GUI\r
2445         /// </summary>\r
2446         /// <param name="sender">The sender</param>\r
2447         /// <param name="currentTask">The current task</param>\r
2448         /// <param name="taskCount">Number of tasks</param>\r
2449         /// <param name="percentComplete">Percent complete</param>\r
2450         /// <param name="currentFps">Current encode speed in fps</param>\r
2451         /// <param name="av">Avg encode speed</param>\r
2452         /// <param name="timeRemaining">Time Left</param>\r
2453         private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float av, TimeSpan timeRemaining)\r
2454         {\r
2455             if (this.InvokeRequired)\r
2456             {\r
2457                 this.BeginInvoke(\r
2458                     new EncodeProgressEventHandler(EncodeOnEncodeProgress),\r
2459                     new[] { sender, currentTask, taskCount, percentComplete, currentFps, av, timeRemaining });\r
2460                 return;\r
2461             }\r
2462             lbl_encode.Text =\r
2463                 string.Format(\r
2464                 "{0:00.00}%,    FPS: {1:000.0},    Avg FPS: {2:000.0},    Time Remaining: {3}",\r
2465                 percentComplete,\r
2466                 currentFps,\r
2467                 av,\r
2468                 timeRemaining);\r
2469 \r
2470             ProgressBarStatus.Value = (int)Math.Round(percentComplete);\r
2471         }\r
2472 \r
2473         #endregion\r
2474 \r
2475         // This is the END of the road ****************************************\r
2476     }\r
2477 }