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