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