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