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