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