OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmMain.cs
1 /*  frmMain.cs $\r
2         \r
3            This file is part of the HandBrake source code.\r
4            Homepage: <http://handbrake.fr/>.\r
5            It may be used under the terms of the GNU General Public License. */\r
6 \r
7 namespace Handbrake\r
8 {\r
9     using System;\r
10     using System.Collections.Generic;\r
11     using System.ComponentModel;\r
12     using System.Diagnostics;\r
13     using System.Drawing;\r
14     using System.Globalization;\r
15     using System.IO;\r
16     using System.Threading;\r
17     using System.Windows.Forms;\r
18     using Functions;\r
19     using Model;\r
20     using Parsing;\r
21     using Presets;\r
22     using Services;\r
23 \r
24     public partial class frmMain : Form\r
25     {\r
26         // Objects which may be used by one or more other objects *************\r
27         private Queue encodeQueue = new Queue();\r
28         private PresetsHandler presetHandler = new PresetsHandler();\r
29 \r
30         // Globals: Mainly used for tracking. *********************************\r
31         public Title selectedTitle;\r
32         private frmQueue queueWindow;\r
33         private frmPreview qtpreview;\r
34         private frmActivityWindow ActivityWindow;\r
35         private Form splash;\r
36         public string sourcePath;\r
37         private ActivityLogMode 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         private Scan SourceScan = new Scan();\r
44 \r
45         // Delegates **********************************************************\r
46         private delegate void UpdateWindowHandler();\r
47 \r
48         // Applicaiton Startup ************************************************\r
49 \r
50         #region Application Startup\r
51 \r
52         public frmMain()\r
53         {\r
54             // Load and setup the splash screen in this thread\r
55             splash = new frmSplashScreen();\r
56             splash.Show(this);\r
57             Label lblStatus = new Label {Size = new Size(150, 20), Location = new Point(182, 102)};\r
58             splash.Controls.Add(lblStatus);\r
59 \r
60             InitializeComponent();\r
61 \r
62             // Update the users config file with the CLI version data.\r
63             lblStatus.Text = "Setting Version Data ...";\r
64             Application.DoEvents();\r
65             Main.SetCliVersionData();\r
66 \r
67             // Show the form, but leave disabled until preloading is complete then show the main form\r
68             this.Enabled = false;\r
69             this.Show();\r
70             Application.DoEvents(); // Forces frmMain to draw\r
71 \r
72             // Check for new versions, if update checking is enabled\r
73             if (Properties.Settings.Default.updateStatus)\r
74             {\r
75                 DateTime now = DateTime.Now;\r
76                 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;\r
77                 TimeSpan elapsed = now.Subtract(lastCheck);\r
78                 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)\r
79                 {\r
80                     lblStatus.Text = "Checking for updates ...";\r
81                     Application.DoEvents();\r
82 \r
83                     Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);\r
84                 }\r
85             }\r
86 \r
87             // Clear the log files in the background\r
88             if (Properties.Settings.Default.clearOldLogs)\r
89             {\r
90                 lblStatus.Text = "Clearing Old Log Files ...";\r
91                 Application.DoEvents();\r
92                 Thread clearLog = new Thread(Main.ClearOldLogs);\r
93                 clearLog.Start();\r
94             }\r
95 \r
96             // Setup the GUI components\r
97             lblStatus.Text = "Setting up the GUI ...";\r
98             Application.DoEvents();\r
99             LoadPresetPanel(); // Load the Preset Panel\r
100             treeView_presets.ExpandAll();\r
101             lbl_encode.Text = string.Empty;\r
102             drop_mode.SelectedIndex = 0;\r
103             queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue\r
104             if (!Properties.Settings.Default.QueryEditorTab)\r
105                 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.\r
106 \r
107             // Load the user's default settings or Normal Preset\r
108             if (Properties.Settings.Default.defaultPreset != string.Empty)\r
109             {\r
110                 if (presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)\r
111                 {\r
112                     string query = presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).Query;\r
113                     bool loadPictureSettings =\r
114                         presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).PictureSettings;\r
115 \r
116                     if (query != null)\r
117                     {\r
118                         x264Panel.Reset2Defaults();\r
119 \r
120                         QueryParser presetQuery = QueryParser.Parse(query);\r
121                         PresetLoader.LoadPreset(this, presetQuery, Properties.Settings.Default.defaultPreset, \r
122                                                 loadPictureSettings);\r
123 \r
124                         x264Panel.X264_StandardizeOptString();\r
125                         x264Panel.X264_SetCurrentSettingsInPanel();\r
126                     }\r
127                 }\r
128                 else\r
129                     loadNormalPreset();\r
130             }\r
131             else\r
132                 loadNormalPreset();\r
133 \r
134             // Enabled GUI tooltip's if Required\r
135             if (Properties.Settings.Default.tooltipEnable)\r
136                 ToolTip.Active = true;\r
137 \r
138             // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)\r
139             GrowlCommunicator.Register();\r
140 \r
141             // Finished Loading\r
142             lblStatus.Text = "Loading Complete!";\r
143             Application.DoEvents();\r
144             splash.Close();\r
145             splash.Dispose();\r
146             this.Enabled = true;\r
147 \r
148             // Event Handlers and Queue Recovery\r
149             events();\r
150             queueRecovery();\r
151         }\r
152 \r
153         private void UpdateCheckDone(IAsyncResult result)\r
154         {\r
155             if (InvokeRequired)\r
156             {\r
157                 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));\r
158                 return;\r
159             }\r
160 \r
161             UpdateCheckInformation info;\r
162 \r
163             try\r
164             {\r
165                 info = Main.EndCheckForUpdates(result);\r
166 \r
167                 if (info.NewVersionAvailable)\r
168                 {\r
169                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
170                     updateWindow.ShowDialog();\r
171                 }\r
172             }\r
173             catch (Exception ex)\r
174             {\r
175                 if ((bool) result.AsyncState)\r
176                     MessageBox.Show(\r
177                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex, \r
178                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
179             }\r
180         }\r
181 \r
182         // Startup Functions   \r
183         private void queueRecovery()\r
184         {\r
185             if (Main.CheckQueueRecovery())\r
186             {\r
187                 DialogResult result =\r
188                     MessageBox.Show(\r
189                         "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?", \r
190                         "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
191 \r
192                 if (result == DialogResult.Yes)\r
193                     encodeQueue.LoadQueueFromFile("hb_queue_recovery.xml"); // Start Recovery\r
194                 else\r
195                 {\r
196                     // Remove the Queue recovery file if the user doesn't want to recovery the last queue.\r
197                     string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
198                     if (File.Exists(queuePath))\r
199                         File.Delete(queuePath);\r
200                 }\r
201             }\r
202         }\r
203 \r
204         #endregion\r
205 \r
206         #region Properties\r
207 \r
208         public string SourceName\r
209         {\r
210             get\r
211             {\r
212                 if (this.selectedSourceType == SourceType.DvdDrive)\r
213                 {\r
214                     return this.dvdDriveLabel;\r
215                 }\r
216 \r
217                 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")\r
218                     return Path.GetFileNameWithoutExtension(this.sourcePath);\r
219 \r
220                 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));\r
221             }\r
222         }\r
223 \r
224         #endregion\r
225 \r
226         #region Events\r
227 \r
228         // Encoding Events for setting up the GUI\r
229         private void events()\r
230         {\r
231             // Handle Widget changes when preset is selected.\r
232             RegisterPresetEventHandler();\r
233 \r
234             // Handle Window Resize\r
235             if (Properties.Settings.Default.MainWindowMinimize)\r
236                 this.Resize += new EventHandler(frmMain_Resize);\r
237 \r
238             // Handle Encode Start / Finish / Pause\r
239 \r
240             encodeQueue.QueuePauseRequested += new EventHandler(encodePaused);\r
241             encodeQueue.EncodeStarted += new EventHandler(encodeStarted);\r
242             encodeQueue.EncodeEnded += new EventHandler(encodeEnded);\r
243 \r
244             // Handle a file being draged onto the GUI.\r
245             this.DragEnter += new DragEventHandler(frmMain_DragEnter);\r
246             this.DragDrop += new DragEventHandler(frmMain_DragDrop);\r
247         }\r
248 \r
249         // 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
250         private void RegisterPresetEventHandler()\r
251         {\r
252             // Output Settings\r
253             drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
254             check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);\r
255             check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);\r
256             check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);\r
257 \r
258             // Picture Settings\r
259             // PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);\r
260 \r
261             // Filter Settings\r
262             Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);\r
263 \r
264             // Video Tab\r
265             drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
266             check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);\r
267             check_turbo.CheckedChanged += new EventHandler(changePresetLabel);\r
268             text_filesize.TextChanged += new EventHandler(changePresetLabel);\r
269             text_bitrate.TextChanged += new EventHandler(changePresetLabel);\r
270             slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);\r
271 \r
272             // Audio Panel\r
273             AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);\r
274 \r
275             // Advanced Tab\r
276             x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);\r
277         }\r
278 \r
279         private void UnRegisterPresetEventHandler()\r
280         {\r
281             // Output Settings \r
282             drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
283             check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);\r
284             check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);\r
285             check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);\r
286 \r
287             // Picture Settings\r
288             // PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);\r
289 \r
290             // Filter Settings\r
291             Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);\r
292 \r
293             // Video Tab\r
294             drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
295             check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);\r
296             check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);\r
297             text_filesize.TextChanged -= new EventHandler(changePresetLabel);\r
298             text_bitrate.TextChanged -= new EventHandler(changePresetLabel);\r
299             slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);\r
300 \r
301             // Audio Panel\r
302             AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);\r
303 \r
304             // Advanced Tab\r
305             x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);\r
306         }\r
307 \r
308         private void changePresetLabel(object sender, EventArgs e)\r
309         {\r
310             labelPreset.Text = "Output Settings (Preset: Custom)";\r
311             CurrentlySelectedPreset = null;\r
312         }\r
313 \r
314         private static void frmMain_DragEnter(object sender, DragEventArgs e)\r
315         {\r
316             if (e.Data.GetDataPresent(DataFormats.FileDrop, false))\r
317                 e.Effect = DragDropEffects.All;\r
318         }\r
319 \r
320         private void frmMain_DragDrop(object sender, DragEventArgs e)\r
321         {\r
322             string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];\r
323             sourcePath = string.Empty;\r
324 \r
325             if (fileList != null)\r
326             {\r
327                 if (fileList[0] != string.Empty)\r
328                 {\r
329                     this.selectedSourceType = SourceType.VideoFile;\r
330                     StartScan(fileList[0], 0);\r
331                 }\r
332                 else\r
333                     UpdateSourceLabel();\r
334             }\r
335             else\r
336                 UpdateSourceLabel();\r
337         }\r
338 \r
339         private void encodeStarted(object sender, EventArgs e)\r
340         {\r
341             lastAction = ActivityLogMode.Encode;\r
342             SetEncodeStarted();\r
343 \r
344             // Experimental HBProc Process Monitoring.\r
345             if (Properties.Settings.Default.enocdeStatusInGui)\r
346             {\r
347                 Thread encodeMon = new Thread(EncodeMonitorThread);\r
348                 encodeMon.Start();\r
349             }\r
350         }\r
351 \r
352         private void encodeEnded(object sender, EventArgs e)\r
353         {\r
354             SetEncodeFinished();\r
355         }\r
356 \r
357         private void encodePaused(object sender, EventArgs e)\r
358         {\r
359             SetEncodeFinished();\r
360         }\r
361 \r
362         #endregion\r
363 \r
364         // User Interface Menus / Tool Strips *********************************\r
365 \r
366         #region File Menu\r
367 \r
368         private void mnu_killCLI_Click(object sender, EventArgs e)\r
369         {\r
370             KillScan();\r
371         }\r
372 \r
373         private void mnu_exit_Click(object sender, EventArgs e)\r
374         {\r
375             Application.Exit();\r
376         }\r
377 \r
378         #endregion\r
379 \r
380         #region Tools Menu\r
381 \r
382         private void mnu_encode_Click(object sender, EventArgs e)\r
383         {\r
384             queueWindow.Show();\r
385         }\r
386 \r
387         private void mnu_encodeLog_Click(object sender, EventArgs e)\r
388         {\r
389             frmActivityWindow dvdInfoWindow = new frmActivityWindow(lastAction, encodeQueue, SourceScan);\r
390             dvdInfoWindow.Show();\r
391         }\r
392 \r
393         private void mnu_options_Click(object sender, EventArgs e)\r
394         {\r
395             Form options = new frmOptions(this);\r
396             options.ShowDialog();\r
397         }\r
398 \r
399         #endregion\r
400 \r
401         #region Presets Menu\r
402 \r
403         private void mnu_presetReset_Click(object sender, EventArgs e)\r
404         {\r
405             presetHandler.UpdateBuiltInPresets();\r
406             LoadPresetPanel();\r
407             if (treeView_presets.Nodes.Count == 0)\r
408                 MessageBox.Show(\r
409                     "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
410                     "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
411             else\r
412                 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
413 \r
414             treeView_presets.ExpandAll();\r
415         }\r
416 \r
417         private void mnu_delete_preset_Click(object sender, EventArgs e)\r
418         {\r
419             presetHandler.RemoveBuiltInPresets();\r
420             LoadPresetPanel(); // Reload the preset panel\r
421         }\r
422 \r
423         private void mnu_SelectDefault_Click(object sender, EventArgs e)\r
424         {\r
425             loadNormalPreset();\r
426         }\r
427 \r
428         private void mnu_importMacPreset_Click(object sender, EventArgs e)\r
429         {\r
430             importPreset();\r
431         }\r
432 \r
433         private void btn_new_preset_Click(object sender, EventArgs e)\r
434         {\r
435             Form preset = new frmAddPreset(this, QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null), \r
436                                            presetHandler);\r
437             preset.ShowDialog();\r
438         }\r
439 \r
440         #endregion\r
441 \r
442         #region Help Menu\r
443 \r
444         private void mnu_user_guide_Click(object sender, EventArgs e)\r
445         {\r
446             Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");\r
447         }\r
448 \r
449         private void mnu_handbrake_home_Click(object sender, EventArgs e)\r
450         {\r
451             Process.Start("http://handbrake.fr");\r
452         }\r
453 \r
454         private void mnu_UpdateCheck_Click(object sender, EventArgs e)\r
455         {\r
456             lbl_updateCheck.Visible = true;\r
457             Main.BeginCheckForUpdates(new AsyncCallback(updateCheckDoneMenu), false);\r
458         }\r
459 \r
460         private void updateCheckDoneMenu(IAsyncResult result)\r
461         {\r
462             // Make sure it's running on the calling thread\r
463             if (InvokeRequired)\r
464             {\r
465                 Invoke(new MethodInvoker(() => updateCheckDoneMenu(result)));\r
466                 return;\r
467             }\r
468             UpdateCheckInformation info;\r
469             try\r
470             {\r
471                 // Get the information about the new build, if any, and close the window\r
472                 info = Main.EndCheckForUpdates(result);\r
473 \r
474                 if (info.NewVersionAvailable && info.BuildInformation != null)\r
475                 {\r
476                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
477                     updateWindow.ShowDialog();\r
478                 }\r
479                 else\r
480                     MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, \r
481                                     MessageBoxIcon.Information);\r
482                 lbl_updateCheck.Visible = false;\r
483                 return;\r
484             }\r
485             catch (Exception ex)\r
486             {\r
487                 if ((bool) result.AsyncState)\r
488                     MessageBox.Show(\r
489                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex, \r
490                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
491             }\r
492         }\r
493 \r
494         private void mnu_about_Click(object sender, EventArgs e)\r
495         {\r
496             using (frmAbout About = new frmAbout())\r
497             {\r
498                 About.ShowDialog();\r
499             }\r
500         }\r
501 \r
502         #endregion\r
503 \r
504         #region Preset Bar\r
505 \r
506         // Right Click Menu Code\r
507         private void pmnu_expandAll_Click(object sender, EventArgs e)\r
508         {\r
509             treeView_presets.ExpandAll();\r
510         }\r
511 \r
512         private void pmnu_collapse_Click(object sender, EventArgs e)\r
513         {\r
514             treeView_presets.CollapseAll();\r
515         }\r
516 \r
517         private void pmnu_import_Click(object sender, EventArgs e)\r
518         {\r
519             importPreset();\r
520         }\r
521 \r
522         private void pmnu_saveChanges_Click(object sender, EventArgs e)\r
523         {\r
524             DialogResult result =\r
525                 MessageBox.Show(\r
526                     "Do you wish to include picture settings when updating the preset: " +\r
527                     treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel, \r
528                     MessageBoxIcon.Question);\r
529             if (result == DialogResult.Yes)\r
530                 presetHandler.Update(treeView_presets.SelectedNode.Text, \r
531                                      QueryGenerator.GenerateTabbedComponentsQuery(this), true);\r
532             else if (result == DialogResult.No)\r
533                 presetHandler.Update(treeView_presets.SelectedNode.Text, \r
534                                      QueryGenerator.GenerateTabbedComponentsQuery(this), false);\r
535         }\r
536 \r
537         private void pmnu_delete_click(object sender, EventArgs e)\r
538         {\r
539             if (treeView_presets.SelectedNode != null)\r
540             {\r
541                 presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
542                 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
543             }\r
544             treeView_presets.Select();\r
545         }\r
546 \r
547         private void presets_menu_Opening(object sender, CancelEventArgs e)\r
548         {\r
549             // Make sure that the save menu is always disabled by default\r
550             pmnu_saveChanges.Enabled = false;\r
551 \r
552             // Now enable the save menu if the selected preset is a user preset\r
553             if (treeView_presets.SelectedNode != null)\r
554                 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))\r
555                     pmnu_saveChanges.Enabled = true;\r
556 \r
557             treeView_presets.Select();\r
558         }\r
559 \r
560         // Presets Management\r
561         private void btn_addPreset_Click(object sender, EventArgs e)\r
562         {\r
563             Form preset = new frmAddPreset(this, QueryGenerator.GenerateTabbedComponentsQuery(this), presetHandler);\r
564             preset.ShowDialog();\r
565         }\r
566 \r
567         private void btn_removePreset_Click(object sender, EventArgs e)\r
568         {\r
569             DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", \r
570                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
571             if (result == DialogResult.Yes)\r
572             {\r
573                 if (treeView_presets.SelectedNode != null)\r
574                 {\r
575                     presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
576                     treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
577                 }\r
578             }\r
579             treeView_presets.Select();\r
580         }\r
581 \r
582         private void btn_setDefault_Click(object sender, EventArgs e)\r
583         {\r
584             if (treeView_presets.SelectedNode != null)\r
585             {\r
586                 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", \r
587                                                       "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
588                 if (result == DialogResult.Yes)\r
589                 {\r
590                     Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;\r
591                     Properties.Settings.Default.Save();\r
592                     MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
593                 }\r
594             }\r
595             else\r
596                 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
597         }\r
598 \r
599         private void treeview_presets_mouseUp(object sender, MouseEventArgs e)\r
600         {\r
601             if (e.Button == MouseButtons.Right)\r
602                 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);\r
603             else if (e.Button == MouseButtons.Left)\r
604             {\r
605                 if (treeView_presets.GetNodeAt(e.Location) != null)\r
606                 {\r
607                     if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))\r
608                         selectPreset();\r
609                 }\r
610             }\r
611 \r
612             treeView_presets.Select();\r
613         }\r
614 \r
615         private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)\r
616         {\r
617             selectPreset();\r
618         }\r
619 \r
620         private void treeView_presets_deleteKey(object sender, KeyEventArgs e)\r
621         {\r
622             if (e.KeyCode == Keys.Delete)\r
623             {\r
624                 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", \r
625                                                       MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
626                 if (result == DialogResult.Yes)\r
627                 {\r
628                     if (treeView_presets.SelectedNode != null)\r
629                         presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
630 \r
631                     // Remember each nodes expanded status so we can reload it\r
632                     List<bool> nodeStatus = new List<bool>();\r
633                     foreach (TreeNode node in treeView_presets.Nodes)\r
634                         nodeStatus.Add(node.IsExpanded);\r
635 \r
636                     // Now reload the preset panel\r
637                     LoadPresetPanel();\r
638 \r
639                     // And finally, re-expand any of the nodes if required\r
640                     int i = 0;\r
641                     foreach (TreeNode node in treeView_presets.Nodes)\r
642                     {\r
643                         if (nodeStatus[i])\r
644                             node.Expand();\r
645 \r
646                         i++;\r
647                     }\r
648                 }\r
649             }\r
650         }\r
651 \r
652         private void selectPreset()\r
653         {\r
654             if (treeView_presets.SelectedNode != null)\r
655             {\r
656                 // Ok, so, we've selected a preset. Now we want to load it.\r
657                 string presetName = treeView_presets.SelectedNode.Text;\r
658                 Preset preset = presetHandler.GetPreset(presetName);\r
659                 if (preset != null)\r
660                 {\r
661                     string query = presetHandler.GetPreset(presetName).Query;\r
662                     bool loadPictureSettings = presetHandler.GetPreset(presetName).PictureSettings;\r
663 \r
664                     if (query != null)\r
665                     {\r
666                         // Ok, Reset all the H264 widgets before changing the preset\r
667                         x264Panel.Reset2Defaults();\r
668 \r
669                         // Send the query from the file to the Query Parser class\r
670                         QueryParser presetQuery = QueryParser.Parse(query);\r
671 \r
672                         // Now load the preset\r
673                         PresetLoader.LoadPreset(this, presetQuery, presetName, loadPictureSettings);\r
674 \r
675                         // The x264 widgets will need updated, so do this now:\r
676                         x264Panel.X264_StandardizeOptString();\r
677                         x264Panel.X264_SetCurrentSettingsInPanel();\r
678 \r
679                         // Finally, let this window have a copy of the preset settings.\r
680                         CurrentlySelectedPreset = preset;\r
681                         PictureSettings.SetPresetCropWarningLabel(preset);\r
682                     }\r
683                 }\r
684             }\r
685         }\r
686 \r
687         private void loadNormalPreset()\r
688         {\r
689             foreach (TreeNode treenode in treeView_presets.Nodes)\r
690             {\r
691                 foreach (TreeNode node in treenode.Nodes)\r
692                 {\r
693                     if (node.Text.Equals("Normal"))\r
694                         treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];\r
695                 }\r
696             }\r
697         }\r
698 \r
699         private void importPreset()\r
700         {\r
701             if (openPreset.ShowDialog() == DialogResult.OK)\r
702             {\r
703                 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);\r
704                 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))\r
705                 {\r
706                     DialogResult result =\r
707                         MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?", \r
708                                         "Overwrite preset?", \r
709                                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
710                     if (result == DialogResult.Yes)\r
711                     {\r
712                         PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
713                         presetHandler.Update(parsed.PresetName + " (Imported)", \r
714                                              QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null), \r
715                                              parsed.UsesPictureSettings);\r
716                     }\r
717                 }\r
718                 else\r
719                 {\r
720                     PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
721                     presetHandler.Add(parsed.PresetName, \r
722                                       QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null), \r
723                                       parsed.UsesPictureSettings);\r
724 \r
725                     if (presetHandler.Add(parsed.PresetName + " (Imported)", \r
726                                           QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null), \r
727                                           parsed.UsesPictureSettings))\r
728                     {\r
729                         TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")\r
730                                                        {\r
731                                                           ForeColor = Color.Black\r
732                                                        };\r
733                         treeView_presets.Nodes.Add(preset_treeview);\r
734                     }\r
735                 }\r
736             }\r
737         }\r
738 \r
739         #endregion\r
740 \r
741         #region ToolStrip\r
742 \r
743         private void btn_source_Click(object sender, EventArgs e)\r
744         {\r
745             mnu_dvd_drive.Visible = true;\r
746             Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);\r
747             driveInfoThread.Start();\r
748         }\r
749 \r
750         private void btn_start_Click(object sender, EventArgs e)\r
751         {\r
752             if (btn_start.Text == "Stop")\r
753             {\r
754                 DialogResult result;\r
755                 if (Properties.Settings.Default.enocdeStatusInGui &&\r
756                     !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
757                 {\r
758                     result = MessageBox.Show(\r
759                         "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
760                         "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
761                 }\r
762                 else\r
763                 {\r
764                     result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", \r
765                                              MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
766                 }\r
767 \r
768                 if (result == DialogResult.Yes)\r
769                 {\r
770                     // Pause The Queue\r
771                     encodeQueue.Pause();\r
772 \r
773                     if (Properties.Settings.Default.enocdeStatusInGui &&\r
774                         !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
775                     {\r
776                         encodeQueue.Stop();\r
777                         if (encodeQueue.HbProcess != null)\r
778                             encodeQueue.HbProcess.WaitForExit();\r
779                     }\r
780                     else\r
781                     {\r
782                         encodeQueue.SafelyClose();\r
783                     }\r
784 \r
785                     // Update the GUI\r
786                     SetEncodeFinished();\r
787                 }\r
788             }\r
789             else\r
790             {\r
791                 if (encodeQueue.Count != 0 ||\r
792                     (!string.IsNullOrEmpty(sourcePath) && !string.IsNullOrEmpty(text_destination.Text)))\r
793                 {\r
794                     string generatedQuery = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
795                     string specifiedQuery = rtf_query.Text != string.Empty\r
796                                                 ? rtf_query.Text\r
797                                                 : QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
798                     string query = string.Empty;\r
799 \r
800                     // Check to make sure the generated query matches the GUI settings\r
801                     if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&\r
802                         generatedQuery != specifiedQuery)\r
803                     {\r
804                         DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +\r
805                                                               "does not match the current GUI settings.\n\nBecause the manual query takes " +\r
806                                                               "priority over the GUI, your recently updated settings will not be taken " +\r
807                                                               "into account when encoding this job." +\r
808                                                               Environment.NewLine + Environment.NewLine +\r
809                                                               "Do you want to replace the manual query with the updated GUI-generated query?", \r
810                                                               "Manual Query does not Match GUI", \r
811                                                               MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk, \r
812                                                               MessageBoxDefaultButton.Button3);\r
813 \r
814                         switch (result)\r
815                         {\r
816                             case DialogResult.Yes:\r
817                                 // Replace the manual query with the generated one\r
818                                 query = generatedQuery;\r
819                                 rtf_query.Text = generatedQuery;\r
820                                 break;\r
821                             case DialogResult.No:\r
822                                 // Use the manual query\r
823                                 query = specifiedQuery;\r
824                                 break;\r
825                             case DialogResult.Cancel:\r
826                                 // Don't start the encode\r
827                                 return;\r
828                         }\r
829                     }\r
830                     else\r
831                     {\r
832                         query = specifiedQuery;\r
833                     }\r
834 \r
835                     DialogResult overwrite = DialogResult.Yes;\r
836                     if (text_destination.Text != string.Empty)\r
837                         if (File.Exists(text_destination.Text))\r
838                             overwrite =\r
839                                 MessageBox.Show(\r
840                                     "The destination file already exists. Are you sure you want to overwrite it?", \r
841                                     "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
842 \r
843                     if (overwrite == DialogResult.Yes)\r
844                     {\r
845                         if (encodeQueue.Count == 0)\r
846                             encodeQueue.Add(query, sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
847 \r
848                         queueWindow.SetQueue();\r
849                         if (encodeQueue.Count > 1)\r
850                             queueWindow.Show(false);\r
851 \r
852                         SetEncodeStarted(); // Encode is running, so setup the GUI appropriately\r
853                         encodeQueue.Start(); // Start The Queue Encoding Process\r
854                         lastAction = ActivityLogMode.Encode; // Set the last action to encode - Used for activity window.\r
855                     }\r
856                     if (ActivityWindow != null)\r
857                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
858 \r
859                     this.Focus();\r
860                 }\r
861                 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
862                     MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, \r
863                                     MessageBoxIcon.Warning);\r
864             }\r
865         }\r
866 \r
867         private void btn_add2Queue_Click(object sender, EventArgs e)\r
868         {\r
869             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
870                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, \r
871                                 MessageBoxIcon.Warning);\r
872             else\r
873             {\r
874                 string query = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
875                 if (rtf_query.Text != string.Empty)\r
876                     query = rtf_query.Text;\r
877 \r
878                 if (encodeQueue.CheckForDestinationDuplicate(text_destination.Text))\r
879                 {\r
880                     DialogResult result =\r
881                         MessageBox.Show(\r
882                             "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
883                             "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
884                     if (result == DialogResult.Yes)\r
885                         encodeQueue.Add(query, sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
886                 }\r
887                 else\r
888                     encodeQueue.Add(query, sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
889 \r
890                 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";\r
891 \r
892                 queueWindow.Show();\r
893             }\r
894         }\r
895 \r
896         private void btn_showQueue_Click(object sender, EventArgs e)\r
897         {\r
898             queueWindow.Show();\r
899             queueWindow.Activate();\r
900         }\r
901 \r
902         private void tb_preview_Click(object sender, EventArgs e)\r
903         {\r
904             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
905                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, \r
906                                 MessageBoxIcon.Warning);\r
907             else\r
908             {\r
909                 if (qtpreview == null)\r
910                 {\r
911                     qtpreview = new frmPreview(this);\r
912                     qtpreview.Show();\r
913                 }\r
914                 else if (qtpreview.IsDisposed)\r
915                 {\r
916                     qtpreview = new frmPreview(this);\r
917                     qtpreview.Show();\r
918                 }\r
919                 else\r
920                     MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, \r
921                                     MessageBoxIcon.Warning);\r
922             }\r
923         }\r
924 \r
925         private void btn_ActivityWindow_Click(object sender, EventArgs e)\r
926         {\r
927             if (ActivityWindow == null || !ActivityWindow.IsHandleCreated)\r
928                 ActivityWindow = new frmActivityWindow(lastAction, encodeQueue, SourceScan);\r
929             else\r
930                 switch (lastAction)\r
931                 {\r
932                     case ActivityLogMode.Scan:\r
933                         ActivityWindow.SetMode(ActivityLogMode.Scan);\r
934                         break;\r
935                     case ActivityLogMode.Encode:\r
936                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
937                         break;\r
938                     default:\r
939                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
940                         break;\r
941                 }\r
942 \r
943             ActivityWindow.Show();\r
944             ActivityWindow.Activate();\r
945         }\r
946 \r
947         #endregion\r
948 \r
949         #region System Tray Icon\r
950 \r
951         private void frmMain_Resize(object sender, EventArgs e)\r
952         {\r
953             if (FormWindowState.Minimized == this.WindowState)\r
954             {\r
955                 notifyIcon.Visible = true;\r
956                 this.Hide();\r
957             }\r
958             else if (FormWindowState.Normal == this.WindowState)\r
959                 notifyIcon.Visible = false;\r
960         }\r
961 \r
962         private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)\r
963         {\r
964             this.Visible = true;\r
965             this.Activate();\r
966             this.WindowState = FormWindowState.Normal;\r
967             notifyIcon.Visible = false;\r
968         }\r
969 \r
970         private void btn_restore_Click(object sender, EventArgs e)\r
971         {\r
972             this.Visible = true;\r
973             this.Activate();\r
974             this.WindowState = FormWindowState.Normal;\r
975             notifyIcon.Visible = false;\r
976         }\r
977 \r
978         #endregion\r
979 \r
980         #region Tab Control\r
981 \r
982         // Source\r
983         private void btn_dvd_source_Click(object sender, EventArgs e)\r
984         {\r
985             if (DVD_Open.ShowDialog() == DialogResult.OK)\r
986             {\r
987                 this.selectedSourceType = SourceType.Folder;\r
988                 SelectSource(DVD_Open.SelectedPath);\r
989             }\r
990             else\r
991                 UpdateSourceLabel();\r
992         }\r
993 \r
994         private void btn_file_source_Click(object sender, EventArgs e)\r
995         {\r
996             if (ISO_Open.ShowDialog() == DialogResult.OK)\r
997             {\r
998                 this.selectedSourceType = SourceType.VideoFile;\r
999                 SelectSource(ISO_Open.FileName);\r
1000             }\r
1001             else\r
1002                 UpdateSourceLabel();\r
1003         }\r
1004 \r
1005         private void mnu_dvd_drive_Click(object sender, EventArgs e)\r
1006         {\r
1007             if (this.dvdDrivePath == null) return;\r
1008             this.selectedSourceType = SourceType.DvdDrive;\r
1009             SelectSource(this.dvdDrivePath);\r
1010         }\r
1011 \r
1012         private void SelectSource(string file)\r
1013         {\r
1014             Check_ChapterMarkers.Enabled = true;\r
1015             lastAction = ActivityLogMode.Scan;\r
1016             sourcePath = string.Empty;\r
1017 \r
1018             if (file == string.Empty) // Must have a file or path\r
1019             {\r
1020                 UpdateSourceLabel();\r
1021                 return;\r
1022             }\r
1023 \r
1024             sourcePath = Path.GetFileName(file);\r
1025             StartScan(file, 0);\r
1026         }\r
1027 \r
1028         private void drp_dvdtitle_Click(object sender, EventArgs e)\r
1029         {\r
1030             if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))\r
1031                 MessageBox.Show(\r
1032                     "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.", \r
1033                     "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\r
1034         }\r
1035 \r
1036         private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)\r
1037         {\r
1038             UnRegisterPresetEventHandler();\r
1039             drop_mode.SelectedIndex = 0;\r
1040 \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 \r
1635         private void StartScan(string filename, int title)\r
1636         {\r
1637             // Setup the GUI components for the scan.\r
1638             sourcePath = filename;\r
1639             foreach (Control ctrl in Controls)\r
1640                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
1641                     ctrl.Enabled = false;\r
1642 \r
1643             lbl_encode.Visible = true;\r
1644             lbl_encode.Text = "Scanning ...";\r
1645             btn_source.Enabled = false;\r
1646             btn_start.Enabled = false;\r
1647             btn_showQueue.Enabled = false;\r
1648             btn_add2Queue.Enabled = false;\r
1649             tb_preview.Enabled = false;\r
1650             mnu_killCLI.Visible = true;\r
1651 \r
1652             if (ActivityWindow != null)\r
1653                 ActivityWindow.SetMode(ActivityLogMode.Scan);\r
1654 \r
1655             // Start the Scan\r
1656             try\r
1657             {\r
1658                 isScanning = true;\r
1659                 SourceScan = new Scan();\r
1660                 SourceScan.ScanSource(sourcePath, title);\r
1661                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
1662                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
1663             }\r
1664             catch (Exception exc)\r
1665             {\r
1666                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1667             }\r
1668         }\r
1669 \r
1670         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
1671         {\r
1672             UpdateScanStatusLabel();\r
1673         }\r
1674 \r
1675         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
1676         {\r
1677             UpdateGuiAfterScan();\r
1678         }\r
1679 \r
1680         private void UpdateScanStatusLabel()\r
1681         {\r
1682             if (InvokeRequired)\r
1683             {\r
1684                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
1685                 return;\r
1686             }\r
1687             lbl_encode.Text = SourceScan.ScanStatus();\r
1688         }\r
1689 \r
1690         private void UpdateGuiAfterScan()\r
1691         {\r
1692             if (InvokeRequired)\r
1693             {\r
1694                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
1695                 return;\r
1696             }\r
1697 \r
1698             try\r
1699             {\r
1700                 currentSource = SourceScan.SouceData();\r
1701 \r
1702                 // Setup some GUI components\r
1703                 drp_dvdtitle.Items.Clear();\r
1704                 if (currentSource.Titles.Count != 0)\r
1705                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
1706 \r
1707                 // Now select the longest title\r
1708                 if (currentSource.Titles.Count != 0)\r
1709                     drp_dvdtitle.SelectedItem = Main.SelectLongestTitle(currentSource);\r
1710 \r
1711                 // Enable the creation of chapter markers if the file is an image of a dvd.\r
1712                 if (sourcePath.ToLower().Contains(".iso") || sourcePath.Contains("VIDEO_TS") ||\r
1713                     Directory.Exists(Path.Combine(sourcePath, "VIDEO_TS")))\r
1714                     Check_ChapterMarkers.Enabled = true;\r
1715                 else\r
1716                 {\r
1717                     Check_ChapterMarkers.Enabled = false;\r
1718                     Check_ChapterMarkers.Checked = false;\r
1719                     data_chpt.Rows.Clear();\r
1720                 }\r
1721 \r
1722                 // If no titles were found, Display an error message\r
1723                 if (drp_dvdtitle.Items.Count == 0)\r
1724                 {\r
1725                     MessageBox.Show(\r
1726                         "No Title(s) found. \n\nYour Source may be copy protected, badly mastered or in a format which HandBrake does not support. \nPlease refer to the Documentation and FAQ (see Help Menu).", \r
1727                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
1728                     sourcePath = string.Empty;\r
1729                 }\r
1730                 UpdateSourceLabel();\r
1731 \r
1732                 // Enable the GUI components and enable any disabled components\r
1733                 EnableGUI();\r
1734             }\r
1735             catch (Exception exc)\r
1736             {\r
1737                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, \r
1738                                 MessageBoxIcon.Error);\r
1739                 EnableGUI();\r
1740             }\r
1741         }\r
1742 \r
1743         private void EnableGUI()\r
1744         {\r
1745             try\r
1746             {\r
1747                 if (InvokeRequired)\r
1748                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
1749                 lbl_encode.Text = "Scan Completed";\r
1750                 foreach (Control ctrl in Controls)\r
1751                     ctrl.Enabled = true;\r
1752                 btn_start.Enabled = true;\r
1753                 btn_showQueue.Enabled = true;\r
1754                 btn_add2Queue.Enabled = true;\r
1755                 tb_preview.Enabled = true;\r
1756                 btn_source.Enabled = true;\r
1757                 mnu_killCLI.Visible = false;\r
1758             }\r
1759             catch (Exception exc)\r
1760             {\r
1761                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1762             }\r
1763         }\r
1764 \r
1765         private void KillScan()\r
1766         {\r
1767             try\r
1768             {\r
1769                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
1770                 EnableGUI();\r
1771                 ResetGUI();\r
1772 \r
1773                 if (SourceScan.ScanProcess() != null)\r
1774                     SourceScan.ScanProcess().Kill();\r
1775 \r
1776                 lbl_encode.Text = "Scan Cancelled!";\r
1777             }\r
1778             catch (Exception ex)\r
1779             {\r
1780                 MessageBox.Show(\r
1781                     "Unable to kill HandBrakeCLI.exe \nYou may need to manually kill HandBrakeCLI.exe using the Windows Task Manager if it does not close automatically within the next few minutes. \n\nError Information: \n" +\r
1782                     ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1783             }\r
1784         }\r
1785 \r
1786         private void ResetGUI()\r
1787         {\r
1788             drp_dvdtitle.Items.Clear();\r
1789             drop_chapterStart.Items.Clear();\r
1790             drop_chapterFinish.Items.Clear();\r
1791             lbl_duration.Text = "Select a Title";\r
1792             PictureSettings.lbl_src_res.Text = "Select a Title";\r
1793             sourcePath = String.Empty;\r
1794             text_destination.Text = String.Empty;\r
1795             selectedTitle = null;\r
1796             isScanning = false;\r
1797         }\r
1798 \r
1799         private void UpdateSourceLabel()\r
1800         {\r
1801             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
1802 \r
1803             if (selectedTitle != null)\r
1804                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1805                     // If it's one of multiple source files, make sure we don't use the folder name\r
1806                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1807         }\r
1808 \r
1809         public void RecievingJob(Job job)\r
1810         {\r
1811             string query = job.Query;\r
1812             StartScan(job.Source, 0);\r
1813 \r
1814 \r
1815             if (query != null)\r
1816             {\r
1817                 // Ok, Reset all the H264 widgets before changing the preset\r
1818                 x264Panel.Reset2Defaults();\r
1819 \r
1820                 // Send the query from the file to the Query Parser class\r
1821                 QueryParser presetQuery = QueryParser.Parse(query);\r
1822 \r
1823                 // Now load the preset\r
1824                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);\r
1825 \r
1826                 // The x264 widgets will need updated, so do this now:\r
1827                 x264Panel.X264_StandardizeOptString();\r
1828                 x264Panel.X264_SetCurrentSettingsInPanel();\r
1829 \r
1830                 // Finally, let this window have a copy of the preset settings.\r
1831                 CurrentlySelectedPreset = null;\r
1832                 PictureSettings.SetPresetCropWarningLabel(null);\r
1833             }\r
1834         }\r
1835 \r
1836         #endregion\r
1837 \r
1838         #region GUI Functions and Actions\r
1839 \r
1840         /// <summary>\r
1841         /// Set the GUI to it's finished encoding state.\r
1842         /// </summary>\r
1843         private void SetEncodeFinished()\r
1844         {\r
1845             try\r
1846             {\r
1847                 if (InvokeRequired)\r
1848                 {\r
1849                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
1850                     return;\r
1851                 }\r
1852 \r
1853                 lbl_encode.Text = "Encoding Finished";\r
1854                 btn_start.Text = "Start";\r
1855                 btn_start.ToolTipText = "Start the encoding process";\r
1856                 btn_start.Image = Properties.Resources.Play;\r
1857 \r
1858                 // If the window is minimized, display the notification in a popup.\r
1859                 if (Properties.Settings.Default.trayIconAlerts)\r
1860                     if (FormWindowState.Minimized == this.WindowState)\r
1861                     {\r
1862                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
1863                         notifyIcon.ShowBalloonTip(500);\r
1864                     }\r
1865             }\r
1866             catch (Exception exc)\r
1867             {\r
1868                 MessageBox.Show(exc.ToString());\r
1869             }\r
1870         }\r
1871 \r
1872         /// <summary>\r
1873         /// Set the GUI to it's started encoding state.\r
1874         /// </summary>\r
1875         private void SetEncodeStarted()\r
1876         {\r
1877             try\r
1878             {\r
1879                 if (InvokeRequired)\r
1880                 {\r
1881                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
1882                     return;\r
1883                 }\r
1884 \r
1885                 lbl_encode.Visible = true;\r
1886                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
1887                 btn_start.Text = "Stop";\r
1888                 btn_start.ToolTipText = "Stop the encoding process.";\r
1889                 btn_start.Image = Properties.Resources.stop;\r
1890             }\r
1891             catch (Exception exc)\r
1892             {\r
1893                 MessageBox.Show(exc.ToString());\r
1894             }\r
1895         }\r
1896 \r
1897         /// <summary>\r
1898         /// Set the DVD Drive selection in the "Source" Menu\r
1899         /// </summary>\r
1900         private void SetDriveSelectionMenuItem()\r
1901         {\r
1902             try\r
1903             {\r
1904                 if (InvokeRequired)\r
1905                 {\r
1906                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
1907                     return;\r
1908                 }\r
1909 \r
1910                 List<DriveInformation> drives = Main.GetDrives();\r
1911 \r
1912                 if (drives.Count == 0)\r
1913                 {\r
1914                     mnu_dvd_drive.Text = "[No DVD Drive Ready]";\r
1915                     return;\r
1916                 }\r
1917 \r
1918                 this.dvdDrivePath = drives[0].RootDirectory;\r
1919                 this.dvdDriveLabel = drives[0].VolumeLabel;\r
1920                 mnu_dvd_drive.Text = this.dvdDrivePath + " (" + this.dvdDriveLabel + ")";\r
1921             }\r
1922             catch (Exception)\r
1923             {\r
1924                 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";\r
1925             }\r
1926         }\r
1927 \r
1928         /// <summary>\r
1929         /// Access the preset Handler and setup the preset panel.\r
1930         /// </summary>\r
1931         private void LoadPresetPanel()\r
1932         {\r
1933             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
1934                 if (!Properties.Settings.Default.presetNotification)\r
1935                     MessageBox.Show(splash, \r
1936                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.", \r
1937                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
1938 \r
1939             presetHandler.GetPresetPanel(ref treeView_presets);\r
1940             treeView_presets.Update();\r
1941         }\r
1942 \r
1943         #endregion\r
1944 \r
1945         #region Overrides\r
1946 \r
1947         /// <summary>\r
1948         /// Handle GUI shortcuts\r
1949         /// </summary>\r
1950         /// <param name="msg"></param>\r
1951         /// <param name="keyData"></param>\r
1952         /// <returns></returns>\r
1953         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
1954         {\r
1955             if (keyData == (Keys.Control | Keys.S))\r
1956             {\r
1957                 btn_start_Click(this, new EventArgs());\r
1958                 return true;\r
1959             }\r
1960 \r
1961             if (keyData == (Keys.Control | Keys.A))\r
1962             {\r
1963                 btn_add2Queue_Click(this, new EventArgs());\r
1964                 return true;\r
1965             }\r
1966             return base.ProcessCmdKey(ref msg, keyData);\r
1967         }\r
1968 \r
1969         /// <summary>\r
1970         /// If the queue is being processed, prompt the user to confirm application close.\r
1971         /// </summary>\r
1972         /// <param name="e"></param>\r
1973         protected override void OnFormClosing(FormClosingEventArgs e)\r
1974         {\r
1975             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
1976             if ((encodeQueue.IsEncoding) && (!encodeQueue.PauseRequested) && (encodeQueue.Count > 0))\r
1977             {\r
1978                 DialogResult result =\r
1979                     MessageBox.Show(\r
1980                         "HandBrake has queue items to process. Closing HandBrake will not stop the current encoding, but will stop processing the queue.\n\nDo you want to close HandBrake?", \r
1981                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
1982                 if (result == DialogResult.No)\r
1983                     e.Cancel = true;\r
1984             }\r
1985             base.OnFormClosing(e);\r
1986         }\r
1987 \r
1988         #endregion\r
1989 \r
1990         #region In-GUI Encode Status (Experimental)\r
1991 \r
1992         /// <summary>\r
1993         /// Starts a new thread to monitor and process the CLI encode status\r
1994         /// </summary>\r
1995         private void EncodeMonitorThread()\r
1996         {\r
1997             try\r
1998             {\r
1999                 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);\r
2000                 encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
2001                 while (!encode.EndOfStream)\r
2002                     encode.ReadEncodeStatus();\r
2003             }\r
2004             catch (Exception exc)\r
2005             {\r
2006                 MessageBox.Show(exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2007             }\r
2008         }\r
2009 \r
2010         /// <summary>\r
2011         /// Displays the Encode status in the GUI\r
2012         /// </summary>\r
2013         /// <param name="Sender"></param>\r
2014         /// <param name="CurrentTask"></param>\r
2015         /// <param name="TaskCount"></param>\r
2016         /// <param name="PercentComplete"></param>\r
2017         /// <param name="CurrentFps"></param>\r
2018         /// <param name="AverageFps"></param>\r
2019         /// <param name="TimeRemaining"></param>\r
2020         private void EncodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, \r
2021                                             float CurrentFps, float AverageFps, TimeSpan TimeRemaining)\r
2022         {\r
2023             if (this.InvokeRequired)\r
2024             {\r
2025                 this.BeginInvoke(new EncodeProgressEventHandler(EncodeOnEncodeProgress), \r
2026                                  new[]\r
2027                                      {\r
2028                                          Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, \r
2029                                          TimeRemaining\r
2030                                      });\r
2031                 return;\r
2032             }\r
2033             lbl_encode.Text =\r
2034                 string.Format("Encode Progress: {0}%,       FPS: {1},       Avg FPS: {2},       Time Remaining: {3} ", \r
2035                               PercentComplete, CurrentFps, AverageFps, TimeRemaining);\r
2036         }\r
2037 \r
2038         #endregion\r
2039 \r
2040         // This is the END of the road ****************************************\r
2041     }\r
2042 }