OSDN Git Service

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