OSDN Git Service

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