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