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 EncodeQueue;\r
19     using Functions;\r
20     using Model;\r
21     using Parsing;\r
22     using Presets;\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             PictureSettings.lbl_Aspect.Text = "Select a Title"; // Reset some values on the form\r
1041             drop_chapterStart.Items.Clear();\r
1042             drop_chapterFinish.Items.Clear();\r
1043 \r
1044             // If the dropdown is set to automatic nothing else needs to be done.\r
1045             // Otheriwse if its not, title data has to be loased from parsing.\r
1046             if (drp_dvdtitle.Text != "Automatic")\r
1047             {\r
1048                 selectedTitle = drp_dvdtitle.SelectedItem as Title;\r
1049                 lbl_duration.Text = selectedTitle.Duration.ToString();\r
1050                 PictureSettings.CurrentlySelectedPreset = CurrentlySelectedPreset;\r
1051                 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control\r
1052 \r
1053                 // Populate the Angles dropdown\r
1054                 drop_angle.Items.Clear();\r
1055                 if (!Properties.Settings.Default.noDvdNav)\r
1056                 {\r
1057                     drop_angle.Visible = true;\r
1058                     lbl_angle.Visible = true;\r
1059                     drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());\r
1060                     if (drop_angle.Items.Count != 0)\r
1061                         drop_angle.SelectedIndex = 0;\r
1062                 }\r
1063                 else\r
1064                 {\r
1065                     drop_angle.Visible = false;\r
1066                     lbl_angle.Visible = false;\r
1067                 }\r
1068 \r
1069                 // Populate the Start chapter Dropdown\r
1070                 drop_chapterStart.Items.Clear();\r
1071                 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1072                 if (drop_chapterStart.Items.Count > 0)\r
1073                     drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();\r
1074 \r
1075                 // Populate the Final Chapter Dropdown\r
1076                 drop_chapterFinish.Items.Clear();\r
1077                 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1078                 if (drop_chapterFinish.Items.Count > 0)\r
1079                     drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();\r
1080 \r
1081                 // Populate the Audio Channels Dropdown\r
1082                 AudioSettings.SetTrackList(selectedTitle);\r
1083 \r
1084                 // Populate the Subtitles dropdown\r
1085                 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());\r
1086             }\r
1087             // Update the source label if we have multiple streams\r
1088             if (selectedTitle != null)\r
1089                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1090                     labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1091 \r
1092             // Run the AutoName & ChapterNaming functions\r
1093             if (Properties.Settings.Default.autoNaming)\r
1094             {\r
1095                 string autoPath = Main.AutoName(this);\r
1096                 if (autoPath != null)\r
1097                     text_destination.Text = autoPath;\r
1098                 else\r
1099                     MessageBox.Show(\r
1100                         "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
1101                         "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1102             }\r
1103 \r
1104             data_chpt.Rows.Clear();\r
1105             if (selectedTitle.Chapters.Count != 1)\r
1106             {\r
1107                 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1108                 if (chapterGridView != null)\r
1109                     data_chpt = chapterGridView;\r
1110             }\r
1111             else\r
1112             {\r
1113                 Check_ChapterMarkers.Checked = false;\r
1114                 Check_ChapterMarkers.Enabled = false;\r
1115             }\r
1116 \r
1117             // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.\r
1118             data_chpt.Columns[0].Width = 166;\r
1119             data_chpt.Columns[0].Width = 165;\r
1120 \r
1121             RegisterPresetEventHandler();\r
1122         }\r
1123 \r
1124         private void chapersChanged(object sender, EventArgs e)\r
1125         {\r
1126             if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.\r
1127                 return;\r
1128 \r
1129             Control ctl = (Control) sender;\r
1130             int chapterStart, chapterEnd;\r
1131             int.TryParse(drop_chapterStart.Text, out chapterStart);\r
1132             int.TryParse(drop_chapterFinish.Text, out chapterEnd);\r
1133 \r
1134             switch (ctl.Name)\r
1135             {\r
1136                 case "drop_chapterStart":\r
1137                     if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)\r
1138                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1139 \r
1140                     if (chapterEnd != 0)\r
1141                         if (chapterStart > chapterEnd)\r
1142                             drop_chapterFinish.Text = chapterStart.ToString();\r
1143                     break;\r
1144                 case "drop_chapterFinish":\r
1145                     if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)\r
1146                         drop_chapterStart.SelectedIndex = 0;\r
1147 \r
1148                     if (chapterStart != 0)\r
1149                         if (chapterEnd < chapterStart)\r
1150                             drop_chapterFinish.Text = chapterStart.ToString();\r
1151 \r
1152                     // Add more rows to the Chapter menu if needed.\r
1153                     if (Check_ChapterMarkers.Checked)\r
1154                     {\r
1155                         int i = data_chpt.Rows.Count, finish = 0;\r
1156                         int.TryParse(drop_chapterFinish.Text, out finish);\r
1157 \r
1158                         while (i < finish)\r
1159                         {\r
1160                             int n = data_chpt.Rows.Add();\r
1161                             data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
1162                             data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
1163                             data_chpt.Rows[n].Cells[0].ValueType = typeof (int);\r
1164                             data_chpt.Rows[n].Cells[1].ValueType = typeof (string);\r
1165                             i++;\r
1166                         }\r
1167                     }\r
1168                     break;\r
1169             }\r
1170 \r
1171             // Update the Duration\r
1172             lbl_duration.Text =\r
1173                 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)\r
1174                     .ToString();\r
1175 \r
1176             // Run the Autonaming function\r
1177             if (Properties.Settings.Default.autoNaming)\r
1178                 text_destination.Text = Main.AutoName(this);\r
1179 \r
1180             // Disable chapter markers if only 1 chapter is selected.\r
1181             if (chapterStart == chapterEnd)\r
1182             {\r
1183                 Check_ChapterMarkers.Enabled = false;\r
1184                 btn_importChapters.Enabled = false;\r
1185                 data_chpt.Enabled = false;\r
1186             }\r
1187             else\r
1188             {\r
1189                 Check_ChapterMarkers.Enabled = true;\r
1190                 if (Check_ChapterMarkers.Checked)\r
1191                 {\r
1192                     btn_importChapters.Enabled = true;\r
1193                     data_chpt.Enabled = true;\r
1194                 }\r
1195             }\r
1196         }\r
1197 \r
1198         private void SecondsOrFramesChanged(object sender, EventArgs e)\r
1199         {\r
1200             int start, end;\r
1201             int.TryParse(drop_chapterStart.Text, out start);\r
1202             int.TryParse(drop_chapterFinish.Text, out end);\r
1203             double duration = end - start;\r
1204 \r
1205             switch (drop_mode.SelectedIndex)\r
1206             {\r
1207                 case 1:\r
1208                     lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1209                     return;\r
1210                 case 2:\r
1211                     if (selectedTitle != null)\r
1212                     {\r
1213                         duration = duration/selectedTitle.Fps;\r
1214                         lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1215                     }\r
1216                     else\r
1217                         lbl_duration.Text = "--:--:--";\r
1218 \r
1219                     return;\r
1220             }\r
1221         }\r
1222 \r
1223         private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)\r
1224         {\r
1225             // Reset\r
1226             this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1227             this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1228 \r
1229             // Do Work\r
1230             switch (drop_mode.SelectedIndex)\r
1231             {\r
1232                 case 0:\r
1233                     drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;\r
1234                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;\r
1235                     if (drop_chapterStart.Items.Count != 0)\r
1236                     {\r
1237                         drop_chapterStart.SelectedIndex = 0;\r
1238                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1239                     }\r
1240                     else\r
1241                         lbl_duration.Text = "--:--:--";\r
1242                     return;\r
1243                 case 1:\r
1244                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1245                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1246                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1247                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1248                     if (selectedTitle != null)\r
1249                     {\r
1250                         drop_chapterStart.Text = "0";\r
1251                         drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();\r
1252                     }\r
1253                     return;\r
1254                 case 2:\r
1255                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1256                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1257                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1258                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1259                     if (selectedTitle != null)\r
1260                     {\r
1261                         drop_chapterStart.Text = "0";\r
1262                         drop_chapterFinish.Text = (selectedTitle.Fps*selectedTitle.Duration.TotalSeconds).ToString();\r
1263                     }\r
1264                     return;\r
1265             }\r
1266         }\r
1267 \r
1268         // Destination\r
1269         private void btn_destBrowse_Click(object sender, EventArgs e)\r
1270         {\r
1271             // This removes the file extension from the filename box on the save file dialog.\r
1272             // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.\r
1273             DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);\r
1274 \r
1275             if (Path.IsPathRooted(text_destination.Text))\r
1276                 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);\r
1277 \r
1278             // Show the dialog and set the main form file path\r
1279             if (drop_format.SelectedIndex.Equals(0))\r
1280                 DVD_Save.FilterIndex = 1;\r
1281             else if (drop_format.SelectedIndex.Equals(1))\r
1282                 DVD_Save.FilterIndex = 2;\r
1283 \r
1284             if (DVD_Save.ShowDialog() == DialogResult.OK)\r
1285             {\r
1286                 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames\r
1287                 switch (DVD_Save.FilterIndex)\r
1288                 {\r
1289                     case 1:\r
1290                         if (\r
1291                             !Path.GetExtension(DVD_Save.FileName).Equals(".mp4", \r
1292                                                                          StringComparison.InvariantCultureIgnoreCase))\r
1293                             if (Properties.Settings.Default.useM4v)\r
1294                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");\r
1295                             else\r
1296                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");\r
1297                         break;\r
1298                     case 2:\r
1299                         if (\r
1300                             !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", \r
1301                                                                          StringComparison.InvariantCultureIgnoreCase))\r
1302                             DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");\r
1303                         break;\r
1304                     default:\r
1305                         // do nothing  \r
1306                         break;\r
1307                 }\r
1308                 text_destination.Text = DVD_Save.FileName;\r
1309 \r
1310                 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)\r
1311                 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)\r
1312                     SetExtension(".m4v");\r
1313             }\r
1314         }\r
1315 \r
1316         private void text_destination_TextChanged(object sender, EventArgs e)\r
1317         {\r
1318             string path = text_destination.Text;\r
1319             if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))\r
1320                 drop_format.SelectedIndex = 0;\r
1321             else if (path.EndsWith(".mkv"))\r
1322                 drop_format.SelectedIndex = 1;\r
1323         }\r
1324 \r
1325         // Output Settings\r
1326         private void drop_format_SelectedIndexChanged(object sender, EventArgs e)\r
1327         {\r
1328             switch (drop_format.SelectedIndex)\r
1329             {\r
1330                 case 0:\r
1331                     if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||\r
1332                         AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())\r
1333                         SetExtension(".m4v");\r
1334                     else\r
1335                         SetExtension(".mp4");\r
1336                     break;\r
1337                 case 1:\r
1338                     SetExtension(".mkv");\r
1339                     break;\r
1340             }\r
1341 \r
1342             AudioSettings.SetContainer(drop_format.Text);\r
1343             Subtitles.SetContainer(drop_format.SelectedIndex);\r
1344 \r
1345             if (drop_format.Text.Contains("MP4"))\r
1346             {\r
1347                 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))\r
1348                 {\r
1349                     drp_videoEncoder.Items.Remove("VP3 (Theora)");\r
1350                     drp_videoEncoder.SelectedIndex = 1;\r
1351                 }\r
1352             }\r
1353             else if (drop_format.Text.Contains("MKV"))\r
1354                 drp_videoEncoder.Items.Add("VP3 (Theora)");\r
1355         }\r
1356 \r
1357         public void SetExtension(string newExtension)\r
1358         {\r
1359             if (newExtension == ".mp4" || newExtension == ".m4v")\r
1360                 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||\r
1361                     Subtitles.RequiresM4V())\r
1362                     newExtension = ".m4v";\r
1363                 else\r
1364                     newExtension = ".mp4";\r
1365 \r
1366             if (Path.HasExtension(newExtension))\r
1367                 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);\r
1368         }\r
1369 \r
1370         // Video Tab\r
1371         private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)\r
1372         {\r
1373             setContainerOpts();\r
1374 \r
1375             // Turn off some options which are H.264 only when the user selects a non h.264 encoder\r
1376             if (drp_videoEncoder.Text.Contains("H.264"))\r
1377             {\r
1378                 if (check_2PassEncode.CheckState == CheckState.Checked)\r
1379                     check_turbo.Enabled = true;\r
1380 \r
1381                 tab_advanced.Enabled = true;\r
1382                 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1383                     check_iPodAtom.Enabled = true;\r
1384                 else\r
1385                     check_iPodAtom.Enabled = false;\r
1386             }\r
1387             else\r
1388             {\r
1389                 check_turbo.CheckState = CheckState.Unchecked;\r
1390                 check_turbo.Enabled = false;\r
1391                 tab_advanced.Enabled = false;\r
1392                 x264Panel.X264Query = string.Empty;\r
1393                 check_iPodAtom.Enabled = false;\r
1394                 check_iPodAtom.Checked = false;\r
1395             }\r
1396 \r
1397             // Setup the CQ Slider\r
1398             switch (drp_videoEncoder.Text)\r
1399             {\r
1400                 case "MPEG-4 (FFmpeg)":\r
1401                     if (slider_videoQuality.Value > 31)\r
1402                         slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.\r
1403                     slider_videoQuality.Minimum = 1;\r
1404                     slider_videoQuality.Maximum = 31;\r
1405                     break;\r
1406                 case "H.264 (x264)":\r
1407                     slider_videoQuality.Minimum = 0;\r
1408                     slider_videoQuality.TickFrequency = 1;\r
1409 \r
1410                     CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");\r
1411                     double cqStep = Properties.Settings.Default.x264cqstep;\r
1412                     double multiplier = 1.0/cqStep;\r
1413                     double value = slider_videoQuality.Value*multiplier;\r
1414 \r
1415                     switch (Properties.Settings.Default.x264cqstep.ToString(culture))\r
1416                     {\r
1417                         case "0.2":\r
1418                             slider_videoQuality.Maximum = 255;\r
1419                             break;\r
1420                         case "0.25":\r
1421                             slider_videoQuality.Maximum = 204;\r
1422                             break;\r
1423                         case "0.5":\r
1424                             slider_videoQuality.Maximum = 102;\r
1425                             break;\r
1426                         case "1":\r
1427                             slider_videoQuality.Maximum = 51;\r
1428                             break;\r
1429                         default:\r
1430                             slider_videoQuality.Maximum = 51;\r
1431                             break;\r
1432                     }\r
1433                     if (value < slider_videoQuality.Maximum)\r
1434                         slider_videoQuality.Value = slider_videoQuality.Maximum - (int) value;\r
1435 \r
1436                     break;\r
1437                 case "VP3 (Theora)":\r
1438                     if (slider_videoQuality.Value > 63)\r
1439                         slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.\r
1440                     slider_videoQuality.Minimum = 0;\r
1441                     slider_videoQuality.Maximum = 63;\r
1442                     break;\r
1443             }\r
1444         }\r
1445 \r
1446         /// <summary>\r
1447         /// Set the container format options\r
1448         /// </summary>\r
1449         public void setContainerOpts()\r
1450         {\r
1451             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1452             {\r
1453                 check_largeFile.Enabled = true;\r
1454                 check_optimiseMP4.Enabled = true;\r
1455                 check_iPodAtom.Enabled = true;\r
1456             }\r
1457             else\r
1458             {\r
1459                 check_largeFile.Enabled = false;\r
1460                 check_optimiseMP4.Enabled = false;\r
1461                 check_iPodAtom.Enabled = false;\r
1462                 check_largeFile.Checked = false;\r
1463                 check_optimiseMP4.Checked = false;\r
1464                 check_iPodAtom.Checked = false;\r
1465             }\r
1466         }\r
1467 \r
1468         private double _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1469 \r
1470         /// <summary>\r
1471         /// Update the CQ slider for x264 for a new CQ step. This is set from option\r
1472         /// </summary>\r
1473         public void setQualityFromSlider()\r
1474         {\r
1475             // Work out the current RF value.\r
1476             double cqStep = _cachedCqStep;\r
1477             double rfValue = 51.0 - slider_videoQuality.Value*cqStep;\r
1478 \r
1479             // Change the maximum value for the slider\r
1480             switch (Properties.Settings.Default.x264cqstep.ToString(new CultureInfo("en-US")))\r
1481             {\r
1482                 case "0.2":\r
1483                     slider_videoQuality.Maximum = 255;\r
1484                     break;\r
1485                 case "0.25":\r
1486                     slider_videoQuality.Maximum = 204;\r
1487                     break;\r
1488                 case "0.5":\r
1489                     slider_videoQuality.Maximum = 102;\r
1490                     break;\r
1491                 case "1":\r
1492                     slider_videoQuality.Maximum = 51;\r
1493                     break;\r
1494                 default:\r
1495                     slider_videoQuality.Maximum = 51;\r
1496                     break;\r
1497             }\r
1498 \r
1499             // Reset the CQ slider to RF0\r
1500             slider_videoQuality.Value = slider_videoQuality.Maximum;\r
1501 \r
1502             // Reset the CQ slider back to the previous value as close as possible\r
1503             double cqStepNew = Properties.Settings.Default.x264cqstep;\r
1504             double rfValueCurrent = 51.0 - slider_videoQuality.Value*cqStepNew;\r
1505             while (rfValueCurrent < rfValue)\r
1506             {\r
1507                 slider_videoQuality.Value--;\r
1508                 rfValueCurrent = 51.0 - slider_videoQuality.Value*cqStepNew;\r
1509             }\r
1510 \r
1511             // Cache the CQ step for the next calculation\r
1512             _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1513         }\r
1514 \r
1515         private void slider_videoQuality_Scroll(object sender, EventArgs e)\r
1516         {\r
1517             double cqStep = Properties.Settings.Default.x264cqstep;\r
1518             switch (drp_videoEncoder.Text)\r
1519             {\r
1520                 case "MPEG-4 (FFmpeg)":\r
1521                     lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);\r
1522                     break;\r
1523                 case "H.264 (x264)":\r
1524                     double rfValue = 51.0 - slider_videoQuality.Value*cqStep;\r
1525                     rfValue = Math.Round(rfValue, 2);\r
1526                     lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));\r
1527                     break;\r
1528                 case "VP3 (Theora)":\r
1529                     lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;\r
1530                     break;\r
1531             }\r
1532         }\r
1533 \r
1534         private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)\r
1535         {\r
1536             text_bitrate.Enabled = false;\r
1537             text_filesize.Enabled = true;\r
1538             slider_videoQuality.Enabled = false;\r
1539 \r
1540             check_2PassEncode.Enabled = true;\r
1541         }\r
1542 \r
1543         private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)\r
1544         {\r
1545             text_bitrate.Enabled = true;\r
1546             text_filesize.Enabled = false;\r
1547             slider_videoQuality.Enabled = false;\r
1548 \r
1549             check_2PassEncode.Enabled = true;\r
1550         }\r
1551 \r
1552         private void radio_cq_CheckedChanged(object sender, EventArgs e)\r
1553         {\r
1554             text_bitrate.Enabled = false;\r
1555             text_filesize.Enabled = false;\r
1556             slider_videoQuality.Enabled = true;\r
1557 \r
1558             check_2PassEncode.Enabled = false;\r
1559             check_2PassEncode.CheckState = CheckState.Unchecked;\r
1560         }\r
1561 \r
1562         private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)\r
1563         {\r
1564             if (check_2PassEncode.CheckState.ToString() == "Checked")\r
1565             {\r
1566                 if (drp_videoEncoder.Text.Contains("H.264"))\r
1567                     check_turbo.Enabled = true;\r
1568             }\r
1569             else\r
1570             {\r
1571                 check_turbo.Enabled = false;\r
1572                 check_turbo.CheckState = CheckState.Unchecked;\r
1573             }\r
1574         }\r
1575 \r
1576         // Chapter Marker Tab\r
1577         private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)\r
1578         {\r
1579             if (Check_ChapterMarkers.Checked)\r
1580             {\r
1581                 if (drop_format.SelectedIndex != 1)\r
1582                     SetExtension(".m4v");\r
1583                 data_chpt.Enabled = true;\r
1584                 btn_importChapters.Enabled = true;\r
1585             }\r
1586             else\r
1587             {\r
1588                 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)\r
1589                     SetExtension(".mp4");\r
1590                 data_chpt.Enabled = false;\r
1591                 btn_importChapters.Enabled = false;\r
1592             }\r
1593         }\r
1594 \r
1595         private void btn_importChapters_Click(object sender, EventArgs e)\r
1596         {\r
1597             if (File_ChapterImport.ShowDialog() == DialogResult.OK)\r
1598             {\r
1599                 string filename = File_ChapterImport.FileName;\r
1600                 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);\r
1601                 if (imported != null)\r
1602                     data_chpt = imported;\r
1603             }\r
1604         }\r
1605 \r
1606         private void mnu_resetChapters_Click(object sender, EventArgs e)\r
1607         {\r
1608             data_chpt.Rows.Clear();\r
1609             DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1610             if (chapterGridView != null)\r
1611             {\r
1612                 data_chpt = chapterGridView;\r
1613             }\r
1614         }\r
1615 \r
1616         // Query Editor Tab\r
1617         private void btn_generate_Query_Click(object sender, EventArgs e)\r
1618         {\r
1619             rtf_query.Text = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
1620         }\r
1621 \r
1622         private void btn_clear_Click(object sender, EventArgs e)\r
1623         {\r
1624             rtf_query.Clear();\r
1625         }\r
1626 \r
1627         #endregion\r
1628 \r
1629         // MainWindow Components, Actions and Functions ***********************\r
1630 \r
1631         #region Source Scan\r
1632 \r
1633         public bool isScanning { get; set; }\r
1634         private Scan SourceScan;\r
1635 \r
1636         private void StartScan(string filename, int title)\r
1637         {\r
1638             // Setup the GUI components for the scan.\r
1639             sourcePath = filename;\r
1640             foreach (Control ctrl in Controls)\r
1641                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
1642                     ctrl.Enabled = false;\r
1643 \r
1644             lbl_encode.Visible = true;\r
1645             lbl_encode.Text = "Scanning ...";\r
1646             btn_source.Enabled = false;\r
1647             btn_start.Enabled = false;\r
1648             btn_showQueue.Enabled = false;\r
1649             btn_add2Queue.Enabled = false;\r
1650             tb_preview.Enabled = false;\r
1651             mnu_killCLI.Visible = true;\r
1652 \r
1653             if (ActivityWindow != null)\r
1654                 ActivityWindow.SetScanMode();\r
1655 \r
1656             // Start the Scan\r
1657             try\r
1658             {\r
1659                 isScanning = true;\r
1660                 SourceScan = new Scan();\r
1661                 SourceScan.ScanSource(sourcePath, title);\r
1662                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
1663                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
1664             }\r
1665             catch (Exception exc)\r
1666             {\r
1667                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1668             }\r
1669         }\r
1670 \r
1671         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
1672         {\r
1673             UpdateScanStatusLabel();\r
1674         }\r
1675 \r
1676         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
1677         {\r
1678             UpdateGuiAfterScan();\r
1679         }\r
1680 \r
1681         private void UpdateScanStatusLabel()\r
1682         {\r
1683             if (InvokeRequired)\r
1684             {\r
1685                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
1686                 return;\r
1687             }\r
1688             lbl_encode.Text = SourceScan.ScanStatus();\r
1689         }\r
1690 \r
1691         private void UpdateGuiAfterScan()\r
1692         {\r
1693             if (InvokeRequired)\r
1694             {\r
1695                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
1696                 return;\r
1697             }\r
1698 \r
1699             try\r
1700             {\r
1701                 currentSource = SourceScan.SouceData();\r
1702 \r
1703                 // Setup some GUI components\r
1704                 drp_dvdtitle.Items.Clear();\r
1705                 if (currentSource.Titles.Count != 0)\r
1706                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
1707 \r
1708                 // Now select the longest title\r
1709                 if (currentSource.Titles.Count != 0)\r
1710                     drp_dvdtitle.SelectedItem = Main.SelectLongestTitle(currentSource);\r
1711 \r
1712                 // Enable the creation of chapter markers if the file is an image of a dvd.\r
1713                 if (sourcePath.ToLower().Contains(".iso") || sourcePath.Contains("VIDEO_TS") ||\r
1714                     Directory.Exists(Path.Combine(sourcePath, "VIDEO_TS")))\r
1715                     Check_ChapterMarkers.Enabled = true;\r
1716                 else\r
1717                 {\r
1718                     Check_ChapterMarkers.Enabled = false;\r
1719                     Check_ChapterMarkers.Checked = false;\r
1720                     data_chpt.Rows.Clear();\r
1721                 }\r
1722 \r
1723                 // If no titles were found, Display an error message\r
1724                 if (drp_dvdtitle.Items.Count == 0)\r
1725                 {\r
1726                     MessageBox.Show(\r
1727                         "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
1728                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
1729                     sourcePath = string.Empty;\r
1730                 }\r
1731                 UpdateSourceLabel();\r
1732 \r
1733                 // Enable the GUI components and enable any disabled components\r
1734                 EnableGUI();\r
1735             }\r
1736             catch (Exception exc)\r
1737             {\r
1738                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, \r
1739                                 MessageBoxIcon.Error);\r
1740                 EnableGUI();\r
1741             }\r
1742         }\r
1743 \r
1744         private void EnableGUI()\r
1745         {\r
1746             try\r
1747             {\r
1748                 if (InvokeRequired)\r
1749                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
1750                 lbl_encode.Text = "Scan Completed";\r
1751                 foreach (Control ctrl in Controls)\r
1752                     ctrl.Enabled = true;\r
1753                 btn_start.Enabled = true;\r
1754                 btn_showQueue.Enabled = true;\r
1755                 btn_add2Queue.Enabled = true;\r
1756                 tb_preview.Enabled = true;\r
1757                 btn_source.Enabled = true;\r
1758                 mnu_killCLI.Visible = false;\r
1759             }\r
1760             catch (Exception exc)\r
1761             {\r
1762                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1763             }\r
1764         }\r
1765 \r
1766         private void KillScan()\r
1767         {\r
1768             try\r
1769             {\r
1770                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
1771                 EnableGUI();\r
1772                 ResetGUI();\r
1773 \r
1774                 if (SourceScan.ScanProcess() != null)\r
1775                     SourceScan.ScanProcess().Kill();\r
1776 \r
1777                 lbl_encode.Text = "Scan Cancelled!";\r
1778             }\r
1779             catch (Exception ex)\r
1780             {\r
1781                 MessageBox.Show(\r
1782                     "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
1783                     ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1784             }\r
1785         }\r
1786 \r
1787         private void ResetGUI()\r
1788         {\r
1789             drp_dvdtitle.Items.Clear();\r
1790             drop_chapterStart.Items.Clear();\r
1791             drop_chapterFinish.Items.Clear();\r
1792             lbl_duration.Text = "Select a Title";\r
1793             PictureSettings.lbl_src_res.Text = "Select a Title";\r
1794             PictureSettings.lbl_Aspect.Text = "Select a Title";\r
1795             sourcePath = String.Empty;\r
1796             text_destination.Text = String.Empty;\r
1797             selectedTitle = null;\r
1798             isScanning = false;\r
1799         }\r
1800 \r
1801         private void UpdateSourceLabel()\r
1802         {\r
1803             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
1804 \r
1805             if (selectedTitle != null)\r
1806                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1807                     // If it's one of multiple source files, make sure we don't use the folder name\r
1808                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1809         }\r
1810 \r
1811         public void RecievingJob(Job job)\r
1812         {\r
1813             string query = job.Query;\r
1814             StartScan(job.Source, 0);\r
1815 \r
1816 \r
1817             if (query != null)\r
1818             {\r
1819                 // Ok, Reset all the H264 widgets before changing the preset\r
1820                 x264Panel.Reset2Defaults();\r
1821 \r
1822                 // Send the query from the file to the Query Parser class\r
1823                 QueryParser presetQuery = QueryParser.Parse(query);\r
1824 \r
1825                 // Now load the preset\r
1826                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);\r
1827 \r
1828                 // The x264 widgets will need updated, so do this now:\r
1829                 x264Panel.X264_StandardizeOptString();\r
1830                 x264Panel.X264_SetCurrentSettingsInPanel();\r
1831 \r
1832                 // Finally, let this window have a copy of the preset settings.\r
1833                 CurrentlySelectedPreset = null;\r
1834                 PictureSettings.SetPresetCropWarningLabel(null);\r
1835             }\r
1836         }\r
1837 \r
1838         #endregion\r
1839 \r
1840         #region GUI Functions and Actions\r
1841 \r
1842         /// <summary>\r
1843         /// Set the GUI to it's finished encoding state.\r
1844         /// </summary>\r
1845         private void SetEncodeFinished()\r
1846         {\r
1847             try\r
1848             {\r
1849                 if (InvokeRequired)\r
1850                 {\r
1851                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
1852                     return;\r
1853                 }\r
1854 \r
1855                 lbl_encode.Text = "Encoding Finished";\r
1856                 btn_start.Text = "Start";\r
1857                 btn_start.ToolTipText = "Start the encoding process";\r
1858                 btn_start.Image = Properties.Resources.Play;\r
1859 \r
1860                 // If the window is minimized, display the notification in a popup.\r
1861                 if (Properties.Settings.Default.trayIconAlerts)\r
1862                     if (FormWindowState.Minimized == this.WindowState)\r
1863                     {\r
1864                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
1865                         notifyIcon.ShowBalloonTip(500);\r
1866                     }\r
1867             }\r
1868             catch (Exception exc)\r
1869             {\r
1870                 MessageBox.Show(exc.ToString());\r
1871             }\r
1872         }\r
1873 \r
1874         /// <summary>\r
1875         /// Set the GUI to it's started encoding state.\r
1876         /// </summary>\r
1877         private void SetEncodeStarted()\r
1878         {\r
1879             try\r
1880             {\r
1881                 if (InvokeRequired)\r
1882                 {\r
1883                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
1884                     return;\r
1885                 }\r
1886 \r
1887                 lbl_encode.Visible = true;\r
1888                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
1889                 btn_start.Text = "Stop";\r
1890                 btn_start.ToolTipText = "Stop the encoding process.";\r
1891                 btn_start.Image = Properties.Resources.stop;\r
1892             }\r
1893             catch (Exception exc)\r
1894             {\r
1895                 MessageBox.Show(exc.ToString());\r
1896             }\r
1897         }\r
1898 \r
1899         /// <summary>\r
1900         /// Set the DVD Drive selection in the "Source" Menu\r
1901         /// </summary>\r
1902         private void SetDriveSelectionMenuItem()\r
1903         {\r
1904             try\r
1905             {\r
1906                 if (InvokeRequired)\r
1907                 {\r
1908                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
1909                     return;\r
1910                 }\r
1911 \r
1912                 List<DriveInformation> drives = Main.GetDrives();\r
1913 \r
1914                 if (drives.Count == 0)\r
1915                 {\r
1916                     mnu_dvd_drive.Text = "[No DVD Drive Ready]";\r
1917                     return;\r
1918                 }\r
1919 \r
1920                 this.dvdDrivePath = drives[0].RootDirectory + "VIDEO_TS";\r
1921                 this.dvdDriveLabel = drives[0].VolumeLabel;\r
1922                 mnu_dvd_drive.Text = this.dvdDrivePath + " (" + this.dvdDriveLabel + ")";\r
1923             }\r
1924             catch (Exception)\r
1925             {\r
1926                 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";\r
1927             }\r
1928         }\r
1929 \r
1930         /// <summary>\r
1931         /// Access the preset Handler and setup the preset panel.\r
1932         /// </summary>\r
1933         private void LoadPresetPanel()\r
1934         {\r
1935             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
1936                 if (!Properties.Settings.Default.presetNotification)\r
1937                     MessageBox.Show(splash, \r
1938                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.", \r
1939                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
1940 \r
1941             presetHandler.GetPresetPanel(ref treeView_presets);\r
1942             treeView_presets.Update();\r
1943         }\r
1944 \r
1945         #endregion\r
1946 \r
1947         #region Overrides\r
1948 \r
1949         /// <summary>\r
1950         /// Handle GUI shortcuts\r
1951         /// </summary>\r
1952         /// <param name="msg"></param>\r
1953         /// <param name="keyData"></param>\r
1954         /// <returns></returns>\r
1955         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
1956         {\r
1957             if (keyData == (Keys.Control | Keys.S))\r
1958             {\r
1959                 btn_start_Click(this, new EventArgs());\r
1960                 return true;\r
1961             }\r
1962 \r
1963             if (keyData == (Keys.Control | Keys.A))\r
1964             {\r
1965                 btn_add2Queue_Click(this, new EventArgs());\r
1966                 return true;\r
1967             }\r
1968             return base.ProcessCmdKey(ref msg, keyData);\r
1969         }\r
1970 \r
1971         /// <summary>\r
1972         /// If the queue is being processed, prompt the user to confirm application close.\r
1973         /// </summary>\r
1974         /// <param name="e"></param>\r
1975         protected override void OnFormClosing(FormClosingEventArgs e)\r
1976         {\r
1977             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
1978             if ((encodeQueue.IsEncoding) && (!encodeQueue.PauseRequested) && (encodeQueue.Count > 0))\r
1979             {\r
1980                 DialogResult result =\r
1981                     MessageBox.Show(\r
1982                         "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
1983                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
1984                 if (result == DialogResult.No)\r
1985                     e.Cancel = true;\r
1986             }\r
1987             base.OnFormClosing(e);\r
1988         }\r
1989 \r
1990         #endregion\r
1991 \r
1992         #region In-GUI Encode Status (Experimental)\r
1993 \r
1994         /// <summary>\r
1995         /// Starts a new thread to monitor and process the CLI encode status\r
1996         /// </summary>\r
1997         private void EncodeMonitorThread()\r
1998         {\r
1999             try\r
2000             {\r
2001                 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);\r
2002                 encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
2003                 while (!encode.EndOfStream)\r
2004                     encode.readEncodeStatus();\r
2005             }\r
2006             catch (Exception exc)\r
2007             {\r
2008                 MessageBox.Show(exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2009             }\r
2010         }\r
2011 \r
2012         /// <summary>\r
2013         /// Displays the Encode status in the GUI\r
2014         /// </summary>\r
2015         /// <param name="Sender"></param>\r
2016         /// <param name="CurrentTask"></param>\r
2017         /// <param name="TaskCount"></param>\r
2018         /// <param name="PercentComplete"></param>\r
2019         /// <param name="CurrentFps"></param>\r
2020         /// <param name="AverageFps"></param>\r
2021         /// <param name="TimeRemaining"></param>\r
2022         private void EncodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, \r
2023                                             float CurrentFps, float AverageFps, TimeSpan TimeRemaining)\r
2024         {\r
2025             if (this.InvokeRequired)\r
2026             {\r
2027                 this.BeginInvoke(new EncodeProgressEventHandler(EncodeOnEncodeProgress), \r
2028                                  new[]\r
2029                                      {\r
2030                                          Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, \r
2031                                          TimeRemaining\r
2032                                      });\r
2033                 return;\r
2034             }\r
2035             lbl_encode.Text =\r
2036                 string.Format("Encode Progress: {0}%,       FPS: {1},       Avg FPS: {2},       Time Remaining: {3} ", \r
2037                               PercentComplete, CurrentFps, AverageFps, TimeRemaining);\r
2038         }\r
2039 \r
2040         #endregion\r
2041 \r
2042         // This is the END of the road ****************************************\r
2043     }\r
2044 }