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
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
15 using System.Threading;
\r
16 using System.Windows.Forms;
\r
19 using HandBrake.Framework.Model;
\r
20 using HandBrake.Framework.Services;
\r
21 using HandBrake.Framework.Views;
\r
22 using HandBrake.ApplicationServices.Functions;
\r
23 using HandBrake.ApplicationServices.Model;
\r
24 using HandBrake.ApplicationServices.Parsing;
\r
25 using HandBrake.ApplicationServices.Services;
\r
26 using HandBrake.ApplicationServices.Services.Interfaces;
\r
28 using Handbrake.ToolWindows;
\r
34 using Main = Handbrake.Functions.Main;
\r
39 public partial class frmMain : Form
\r
41 // Objects which may be used by one or more other objects *************
\r
42 private IQueue encodeQueue = new Queue();
\r
43 private PresetsHandler presetHandler = new PresetsHandler();
\r
45 // Windows ************************************************************
\r
46 private frmQueue queueWindow;
\r
47 private frmPreview qtpreview;
\r
48 private frmActivityWindow activityWindow;
\r
50 // Globals: Mainly used for tracking. *********************************
\r
51 public Title selectedTitle;
\r
52 public string sourcePath;
\r
53 private SourceType selectedSourceType;
\r
54 private string dvdDrivePath;
\r
55 private string dvdDriveLabel;
\r
56 private Preset currentlySelectedPreset;
\r
57 private DVD currentSource;
\r
58 private IScan SourceScan = new ScanService();
\r
59 private List<DriveInformation> drives;
\r
61 // Delegates **********************************************************
\r
62 private delegate void UpdateWindowHandler();
\r
64 // Applicaiton Startup ************************************************
\r
69 /// Gets SourceName.
\r
71 public string SourceName
\r
75 if (this.selectedSourceType == SourceType.DvdDrive)
\r
77 return this.dvdDriveLabel;
\r
80 if (selectedTitle != null && !string.IsNullOrEmpty(selectedTitle.SourceName))
\r
82 return Path.GetFileName(selectedTitle.SourceName);
\r
85 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
86 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
88 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
94 #region Application Startup
\r
97 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
99 /// <param name="args">
\r
100 /// The arguments passed in on application startup.
\r
102 public frmMain(string[] args)
\r
104 InitializeComponent();
\r
106 // Update the users config file with the CLI version data.
\r
107 Main.SetCliVersionData();
\r
109 if (Settings.Default.hb_version.Contains("svn"))
\r
111 this.Text += " " + Settings.Default.hb_version;
\r
114 // Check for new versions, if update checking is enabled
\r
115 if (Settings.Default.updateStatus)
\r
117 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
119 // Set when the last update was
\r
120 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
121 Settings.Default.Save();
\r
122 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
123 ? Settings.Default.appcast_unstable
\r
124 : Settings.Default.appcast;
\r
125 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
129 // Clear the log files in the background
\r
130 if (Settings.Default.clearOldLogs)
\r
132 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
136 // Setup the GUI components
\r
137 LoadPresetPanel(); // Load the Preset Panel
\r
138 treeView_presets.ExpandAll();
\r
139 lbl_encode.Text = string.Empty;
\r
140 drop_mode.SelectedIndex = 0;
\r
141 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
142 if (!Settings.Default.QueryEditorTab)
\r
143 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
144 if (Settings.Default.tooltipEnable)
\r
145 ToolTip.Active = true;
\r
147 // Load the user's default settings or Normal Preset
\r
148 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
150 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
153 x264Panel.Reset2Defaults();
\r
155 QueryParser presetQuery = QueryParser.Parse(query);
\r
156 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
158 x264Panel.StandardizeOptString();
\r
159 x264Panel.SetCurrentSettingsInPanel();
\r
163 loadNormalPreset();
\r
165 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
166 GrowlCommunicator.Register();
\r
168 // Event Handlers and Queue Recovery
\r
170 Main.RecoverQueue(encodeQueue);
\r
172 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
173 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
175 this.StartScan(args[0], 0);
\r
180 /// When the update check is done, process the results.
\r
182 /// <param name="result">IAsyncResult result</param>
\r
183 private void UpdateCheckDone(IAsyncResult result)
\r
185 if (InvokeRequired)
\r
187 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
193 UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
\r
195 if (info.NewVersionAvailable)
\r
197 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
198 updateWindow.ShowDialog();
\r
201 catch (Exception ex)
\r
203 if ((bool)result.AsyncState)
\r
204 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
212 // Encoding Events for setting up the GUI
\r
213 private void events()
\r
215 // Handle Widget changes when preset is selected.
\r
216 RegisterPresetEventHandler();
\r
218 // Handle Window Resize
\r
219 if (Properties.Settings.Default.MainWindowMinimize)
\r
220 this.Resize += new EventHandler(frmMain_Resize);
\r
222 // Handle Encode Start / Finish / Pause
\r
223 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
224 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
226 // Handle a file being draged onto the GUI.
\r
227 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
228 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
231 // 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
232 private void RegisterPresetEventHandler()
\r
235 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
236 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
237 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
238 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
240 // Picture Settings
\r
241 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
244 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
247 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
248 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
249 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
250 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
251 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
252 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
255 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
258 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
261 private void UnRegisterPresetEventHandler()
\r
263 // Output Settings
\r
264 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
265 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
266 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
267 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
269 // Picture Settings
\r
270 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
273 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
276 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
277 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
278 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
279 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
280 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
281 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
284 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
287 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
290 private void changePresetLabel(object sender, EventArgs e)
\r
292 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
293 this.currentlySelectedPreset = null;
\r
296 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
298 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
299 e.Effect = DragDropEffects.All;
\r
302 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
304 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
305 sourcePath = string.Empty;
\r
307 if (fileList != null)
\r
309 if (!string.IsNullOrEmpty(fileList[0]))
\r
311 this.selectedSourceType = SourceType.VideoFile;
\r
312 StartScan(fileList[0], 0);
\r
315 UpdateSourceLabel();
\r
318 UpdateSourceLabel();
\r
321 private void encodeStarted(object sender, EventArgs e)
\r
323 SetEncodeStarted();
\r
324 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
327 private void encodeEnded(object sender, EventArgs e)
\r
329 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
330 SetEncodeFinished();
\r
334 // User Interface Menus / Tool Strips *********************************
\r
339 /// Kill The scan menu Item
\r
341 /// <param name="sender">
\r
344 /// <param name="e">
\r
347 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
353 /// Exit the Application Menu Item
\r
355 /// <param name="sender">
\r
358 /// <param name="e">
\r
361 private void mnu_exit_Click(object sender, EventArgs e)
\r
363 Application.Exit();
\r
371 /// Menu - Start Button
\r
373 /// <param name="sender">
\r
376 /// <param name="e">
\r
379 private void mnu_encode_Click(object sender, EventArgs e)
\r
381 queueWindow.Show();
\r
385 /// Menu - Display the Log Window
\r
387 /// <param name="sender">
\r
390 /// <param name="e">
\r
393 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
395 this.btn_ActivityWindow_Click(this, null);
\r
399 /// Menu - Display the Options Window
\r
401 /// <param name="sender">
\r
404 /// <param name="e">
\r
407 private void mnu_options_Click(object sender, EventArgs e)
\r
409 Form options = new frmOptions(this);
\r
410 options.ShowDialog();
\r
415 #region Presets Menu
\r
418 /// Reset the Built in Presets
\r
420 /// <param name="sender">
\r
423 /// <param name="e">
\r
426 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
428 presetHandler.UpdateBuiltInPresets();
\r
430 if (treeView_presets.Nodes.Count == 0)
\r
432 "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
433 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
435 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
437 treeView_presets.ExpandAll();
\r
441 /// Delete the selected preset
\r
443 /// <param name="sender">
\r
446 /// <param name="e">
\r
449 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
451 presetHandler.RemoveBuiltInPresets();
\r
452 LoadPresetPanel(); // Reload the preset panel
\r
456 /// Select the Normal preset
\r
458 /// <param name="sender">
\r
461 /// <param name="e">
\r
464 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
466 loadNormalPreset();
\r
470 /// Import a plist Preset
\r
472 /// <param name="sender">
\r
475 /// <param name="e">
\r
478 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
484 /// Export a Plist Preset
\r
486 /// <param name="sender">
\r
489 /// <param name="e">
\r
492 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
498 /// Create a new Preset
\r
500 /// <param name="sender">
\r
503 /// <param name="e">
\r
506 private void btn_new_preset_Click(object sender, EventArgs e)
\r
508 Form preset = new frmAddPreset(this, presetHandler);
\r
509 if (preset.ShowDialog() == DialogResult.OK)
\r
511 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
512 treeView_presets.Nodes.Add(presetTreeview);
\r
513 presetHandler.LastPresetAdded = null;
\r
522 /// Menu - Display the User Guide Web Page
\r
524 /// <param name="sender">
\r
527 /// <param name="e">
\r
530 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
532 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
536 /// Menu - Check for Updates
\r
538 /// <param name="sender">
\r
541 /// <param name="e">
\r
544 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
546 lbl_updateCheck.Visible = true;
\r
547 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
548 Settings.Default.Save();
\r
549 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
550 ? Settings.Default.appcast_unstable
\r
551 : Settings.Default.appcast;
\r
552 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDoneMenu), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
556 /// Menu - Display the About Window
\r
558 /// <param name="sender">
\r
561 /// <param name="e">
\r
564 private void mnu_about_Click(object sender, EventArgs e)
\r
566 using (frmAbout About = new frmAbout())
\r
568 About.ShowDialog();
\r
577 /// RMenu - Expand All
\r
579 /// <param name="sender">
\r
582 /// <param name="e">
\r
585 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
587 treeView_presets.ExpandAll();
\r
591 /// RMenu - Collaspe All
\r
593 /// <param name="sender">
\r
596 /// <param name="e">
\r
599 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
601 treeView_presets.CollapseAll();
\r
605 /// Menu - Import Preset
\r
607 /// <param name="sender">
\r
610 /// <param name="e">
\r
613 private void pmnu_import_Click(object sender, EventArgs e)
\r
619 /// RMenu - Save Changes to Preset
\r
621 /// <param name="sender">
\r
624 /// <param name="e">
\r
627 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
629 // TODO this requires a re-think since the Query Editor has changed.
\r
630 DialogResult result =
\r
632 "Do you wish to include picture settings when updating the preset: " +
\r
633 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
634 MessageBoxIcon.Question);
\r
635 if (result == DialogResult.Yes)
\r
636 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
637 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
638 else if (result == DialogResult.No)
\r
639 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
640 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
644 /// RMenu - Delete Preset
\r
646 /// <param name="sender">
\r
649 /// <param name="e">
\r
652 private void pmnu_delete_click(object sender, EventArgs e)
\r
654 if (treeView_presets.SelectedNode != null)
\r
656 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
657 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
659 treeView_presets.Select();
\r
663 /// Preset Menu Is Opening. Setup the Menu
\r
665 /// <param name="sender">
\r
668 /// <param name="e">
\r
671 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
673 // Make sure that the save menu is always disabled by default
\r
674 pmnu_saveChanges.Enabled = false;
\r
676 // Now enable the save menu if the selected preset is a user preset
\r
677 if (treeView_presets.SelectedNode != null)
\r
678 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
679 pmnu_saveChanges.Enabled = true;
\r
681 treeView_presets.Select();
\r
684 // Presets Management
\r
687 /// Button - Add a preset
\r
689 /// <param name="sender">
\r
692 /// <param name="e">
\r
695 private void btn_addPreset_Click(object sender, EventArgs e)
\r
697 Form preset = new frmAddPreset(this, presetHandler);
\r
698 if (preset.ShowDialog() == DialogResult.OK)
\r
700 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
701 treeView_presets.Nodes.Add(presetTreeview);
\r
702 presetHandler.LastPresetAdded = null;
\r
707 /// Button - remove a Preset
\r
709 /// <param name="sender">
\r
712 /// <param name="e">
\r
715 private void btn_removePreset_Click(object sender, EventArgs e)
\r
717 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
718 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
719 if (result == DialogResult.Yes)
\r
721 if (treeView_presets.SelectedNode != null)
\r
723 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
724 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
727 treeView_presets.Select();
\r
731 /// Button - Set the selected preset as the default
\r
733 /// <param name="sender">
\r
736 /// <param name="e">
\r
739 private void btn_setDefault_Click(object sender, EventArgs e)
\r
741 if (treeView_presets.SelectedNode != null)
\r
743 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
744 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
745 if (result == DialogResult.Yes)
\r
747 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
748 Properties.Settings.Default.Save();
\r
749 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
753 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
757 /// PresetBar Mouse Down event
\r
759 /// <param name="sender">
\r
762 /// <param name="e">
\r
765 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
767 if (e.Button == MouseButtons.Right)
\r
768 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
769 else if (e.Button == MouseButtons.Left)
\r
771 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
773 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
778 treeView_presets.Select();
\r
782 /// Preset Bar after selecting the preset
\r
784 /// <param name="sender">
\r
787 /// <param name="e">
\r
790 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
796 /// Preset Bar - Handle the Delete Key
\r
798 /// <param name="sender">
\r
801 /// <param name="e">
\r
804 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
806 if (e.KeyCode == Keys.Delete)
\r
808 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
809 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
810 if (result == DialogResult.Yes)
\r
812 if (treeView_presets.SelectedNode != null)
\r
813 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
815 // Remember each nodes expanded status so we can reload it
\r
816 List<bool> nodeStatus = new List<bool>();
\r
817 foreach (TreeNode node in treeView_presets.Nodes)
\r
818 nodeStatus.Add(node.IsExpanded);
\r
820 // Now reload the preset panel
\r
823 // And finally, re-expand any of the nodes if required
\r
825 foreach (TreeNode node in treeView_presets.Nodes)
\r
837 /// Select the selected preset and setup the GUI
\r
839 private void selectPreset()
\r
841 if (treeView_presets.SelectedNode != null)
\r
843 // Ok, so, we've selected a preset. Now we want to load it.
\r
844 string presetName = treeView_presets.SelectedNode.Text;
\r
845 Preset preset = presetHandler.GetPreset(presetName);
\r
846 if (preset != null)
\r
848 string query = presetHandler.GetPreset(presetName).Query;
\r
852 // Ok, Reset all the H264 widgets before changing the preset
\r
853 x264Panel.Reset2Defaults();
\r
855 // Send the query from the file to the Query Parser class
\r
856 QueryParser presetQuery = QueryParser.Parse(query);
\r
858 // Now load the preset
\r
859 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
861 // The x264 widgets will need updated, so do this now:
\r
862 x264Panel.StandardizeOptString();
\r
863 x264Panel.SetCurrentSettingsInPanel();
\r
865 // Finally, let this window have a copy of the preset settings.
\r
866 this.currentlySelectedPreset = preset;
\r
867 PictureSettings.SetPresetCropWarningLabel(preset);
\r
874 /// Load the Normal Preset
\r
876 private void loadNormalPreset()
\r
878 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
880 foreach (TreeNode node in treenode.Nodes)
\r
882 if (node.Text.Equals("Normal"))
\r
883 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
889 /// Import a plist preset
\r
891 private void ImportPreset()
\r
893 if (openPreset.ShowDialog() == DialogResult.OK)
\r
895 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
896 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
898 DialogResult result =
\r
899 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
900 "Overwrite preset?",
\r
901 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
902 if (result == DialogResult.Yes)
\r
904 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
905 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
906 QueryGenerator.GenerateFullQuery(this),
\r
907 parsed.UsesPictureSettings);
\r
912 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
913 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
914 QueryGenerator.GenerateFullQuery(this),
\r
915 parsed.UsesPictureSettings))
\r
917 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
919 ForeColor = Color.Black
\r
921 treeView_presets.Nodes.Add(preset_treeview);
\r
928 /// Export a plist Preset
\r
930 private void ExportPreset()
\r
932 SaveFileDialog savefiledialog = new SaveFileDialog { Filter = "plist|*.plist" };
\r
934 if (treeView_presets.SelectedNode != null)
\r
936 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
938 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
939 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
949 /// Toolbar - When the Source button is clicked, Clear any DVD drives and add any available DVD drives that can be used as a source.
\r
951 /// <param name="sender">
\r
954 /// <param name="e">
\r
957 private void btn_source_Click(object sender, EventArgs e)
\r
959 // Remove old Drive Menu Items.
\r
960 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
961 foreach (var item in btn_source.DropDownItems)
\r
963 if (item.GetType() == typeof(ToolStripMenuItem))
\r
965 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
966 if (menuItem.Name.StartsWith("Drive"))
\r
968 itemsToRemove.Add(menuItem);
\r
973 foreach (ToolStripMenuItem item in itemsToRemove)
\r
974 btn_source.DropDownItems.Remove(item);
\r
976 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
977 driveInfoThread.Start();
\r
981 /// Toolbar - Start The Encode
\r
983 /// <param name="sender">
\r
986 /// <param name="e">
\r
989 private void btn_start_Click(object sender, EventArgs e)
\r
991 if (btn_start.Text == "Stop")
\r
993 DialogResult result = !Properties.Settings.Default.showCliForInGuiEncodeStatus
\r
995 "Are you sure you wish to cancel the encode?\n\nPlease note: Stopping this encode will render the file unplayable. ",
\r
997 MessageBoxButtons.YesNo,
\r
998 MessageBoxIcon.Question)
\r
1000 "Are you sure you wish to cancel the encode?",
\r
1002 MessageBoxButtons.YesNo,
\r
1003 MessageBoxIcon.Question);
\r
1005 if (result == DialogResult.Yes)
\r
1007 // Pause The Queue
\r
1008 encodeQueue.Pause();
\r
1010 if (Settings.Default.showCliForInGuiEncodeStatus)
\r
1011 encodeQueue.SafelyClose();
\r
1013 encodeQueue.Stop();
\r
1018 // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.
\r
1019 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1020 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1022 if (encodeQueue.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))
\r
1024 string generatedQuery = QueryGenerator.GenerateFullQuery(this);
\r
1025 string specifiedQuery = rtf_query.Text != string.Empty
\r
1027 : QueryGenerator.GenerateFullQuery(this);
\r
1028 string query = string.Empty;
\r
1030 // Check to make sure the generated query matches the GUI settings
\r
1031 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1032 generatedQuery != specifiedQuery)
\r
1034 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1035 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1036 "priority over the GUI, your recently updated settings will not be taken " +
\r
1037 "into account when encoding this job." +
\r
1038 Environment.NewLine + Environment.NewLine +
\r
1039 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1040 "Manual Query does not Match GUI",
\r
1041 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1042 MessageBoxDefaultButton.Button3);
\r
1046 case DialogResult.Yes:
\r
1047 // Replace the manual query with the generated one
\r
1048 query = generatedQuery;
\r
1049 rtf_query.Text = generatedQuery;
\r
1051 case DialogResult.No:
\r
1052 // Use the manual query
\r
1053 query = specifiedQuery;
\r
1055 case DialogResult.Cancel:
\r
1056 // Don't start the encode
\r
1062 query = specifiedQuery;
\r
1065 DialogResult overwrite = DialogResult.Yes;
\r
1066 if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))
\r
1068 overwrite = MessageBox.Show(
\r
1069 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1070 "Overwrite File?",
\r
1071 MessageBoxButtons.YesNo,
\r
1072 MessageBoxIcon.Question);
\r
1075 if (overwrite == DialogResult.Yes)
\r
1077 if (encodeQueue.Count == 0)
\r
1078 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1080 queueWindow.SetQueue();
\r
1081 if (encodeQueue.Count > 1)
\r
1082 queueWindow.Show(false);
\r
1084 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1085 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1090 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1091 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1092 MessageBoxIcon.Warning);
\r
1097 /// Toolbar - Add the current job to the Queue
\r
1099 /// <param name="sender">
\r
1102 /// <param name="e">
\r
1105 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1107 // Get the CLI query or use the query editor if it's not empty.
\r
1108 string query = QueryGenerator.GenerateFullQuery(this);
\r
1109 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1110 query = rtf_query.Text;
\r
1112 // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.
\r
1113 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1114 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1116 // Make sure we have a Source and Destination.
\r
1117 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1119 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1123 // Make sure the destination path exists.
\r
1124 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1126 MessageBox.Show(string.Format("Destination Path does not exist.\nPath: {0}\n\nThis item was not added to the Queue.", Path.GetDirectoryName(jobDestination)), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1130 // Make sure we don't have a duplciate on the queue.
\r
1131 if (encodeQueue.CheckForDestinationDuplicate(jobDestination))
\r
1133 DialogResult result =
\r
1135 string.Format("There is already a queue item for this destination path.\nDestination Path: {0} \n\nIf you continue, the encode will be overwritten. Do you wish to continue?", jobDestination),
\r
1136 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
1137 if (result == DialogResult.Yes)
\r
1138 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1141 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1143 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1145 queueWindow.Show();
\r
1149 /// Toolbar - Show the Queue
\r
1151 /// <param name="sender">
\r
1154 /// <param name="e">
\r
1157 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1159 queueWindow.Show();
\r
1160 queueWindow.Activate();
\r
1164 /// Toolbar - Show the Preview Window
\r
1166 /// <param name="sender">
\r
1169 /// <param name="e">
\r
1172 private void tb_preview_Click(object sender, EventArgs e)
\r
1174 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1175 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1176 MessageBoxIcon.Warning);
\r
1179 if (qtpreview == null)
\r
1181 qtpreview = new frmPreview(this);
\r
1184 else if (qtpreview.IsDisposed)
\r
1186 qtpreview = new frmPreview(this);
\r
1190 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1191 MessageBoxIcon.Warning);
\r
1196 /// Toolbar - Show the Activity log Window
\r
1198 /// <param name="sender">
\r
1201 /// <param name="e">
\r
1204 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1206 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1207 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1209 this.activityWindow.Show();
\r
1210 this.activityWindow.Activate();
\r
1215 #region System Tray Icon
\r
1218 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1220 /// <param name="sender">
\r
1223 /// <param name="e">
\r
1226 private void frmMain_Resize(object sender, EventArgs e)
\r
1228 if (FormWindowState.Minimized == this.WindowState)
\r
1230 notifyIcon.Visible = true;
\r
1233 else if (FormWindowState.Normal == this.WindowState)
\r
1234 notifyIcon.Visible = false;
\r
1238 /// Double Click the Tray Icon
\r
1240 /// <param name="sender">
\r
1243 /// <param name="e">
\r
1246 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1248 this.Visible = true;
\r
1250 this.WindowState = FormWindowState.Normal;
\r
1251 notifyIcon.Visible = false;
\r
1255 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1257 /// <param name="sender">
\r
1260 /// <param name="e">
\r
1263 private void btn_restore_Click(object sender, EventArgs e)
\r
1265 this.Visible = true;
\r
1267 this.WindowState = FormWindowState.Normal;
\r
1268 notifyIcon.Visible = false;
\r
1273 #region Main Window and Tab Control
\r
1276 private void BtnFolderScanClicked(object sender, EventArgs e)
\r
1278 this.btn_source.HideDropDown();
\r
1279 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1281 this.selectedSourceType = SourceType.Folder;
\r
1282 SelectSource(DVD_Open.SelectedPath, 0);
\r
1285 UpdateSourceLabel();
\r
1288 private void BtnFileScanClicked(object sender, EventArgs e)
\r
1290 this.btn_source.HideDropDown();
\r
1291 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1293 this.selectedSourceType = SourceType.VideoFile;
\r
1294 SelectSource(ISO_Open.FileName, 0);
\r
1297 UpdateSourceLabel();
\r
1300 private void MnuDvdDriveClick(object sender, EventArgs e)
\r
1302 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1305 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1307 if (int.TryParse(driveId, out id))
\r
1309 this.dvdDrivePath = drives[id].RootDirectory;
\r
1310 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1312 if (this.dvdDrivePath == null) return;
\r
1313 this.selectedSourceType = SourceType.DvdDrive;
\r
1314 SelectSource(this.dvdDrivePath, 0);
\r
1319 private void VideoTitleSpecificScanClick(object sender, EventArgs e)
\r
1321 this.btn_source.HideDropDown();
\r
1322 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1324 this.selectedSourceType = SourceType.VideoFile;
\r
1326 int sourceTitle = 0;
\r
1327 TitleSpecificScan title = new TitleSpecificScan();
\r
1328 if (title.ShowDialog() == DialogResult.OK)
\r
1330 sourceTitle = title.Title;
\r
1331 SelectSource(ISO_Open.FileName, sourceTitle);
\r
1335 UpdateSourceLabel();
\r
1338 private void FolderTitleSpecificScanClick(object sender, EventArgs e)
\r
1340 this.btn_source.HideDropDown();
\r
1341 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1343 this.selectedSourceType = SourceType.Folder;
\r
1345 int sourceTitle = 0;
\r
1346 TitleSpecificScan title = new TitleSpecificScan();
\r
1347 if (title.ShowDialog() == DialogResult.OK)
\r
1349 sourceTitle = title.Title;
\r
1350 SelectSource(DVD_Open.SelectedPath, sourceTitle);
\r
1354 UpdateSourceLabel();
\r
1357 private void SelectSource(string file, int titleSpecific)
\r
1359 Check_ChapterMarkers.Enabled = true;
\r
1360 sourcePath = string.Empty;
\r
1362 if (file == string.Empty) // Must have a file or path
\r
1364 UpdateSourceLabel();
\r
1368 sourcePath = Path.GetFileName(file);
\r
1369 StartScan(file, titleSpecific);
\r
1372 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1374 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1376 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1377 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1380 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1382 UnRegisterPresetEventHandler();
\r
1383 drop_mode.SelectedIndex = 0;
\r
1385 drop_chapterStart.Items.Clear();
\r
1386 drop_chapterFinish.Items.Clear();
\r
1388 // If the dropdown is set to automatic nothing else needs to be done.
\r
1389 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1390 if (drp_dvdtitle.Text != "Automatic")
\r
1392 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1393 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1394 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1395 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1397 // Populate the Angles dropdown
\r
1398 drop_angle.Items.Clear();
\r
1399 if (!Properties.Settings.Default.noDvdNav)
\r
1401 drop_angle.Visible = true;
\r
1402 lbl_angle.Visible = true;
\r
1404 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1405 drop_angle.Items.Add(i.ToString());
\r
1407 if (drop_angle.Items.Count == 0)
\r
1409 drop_angle.Visible = false;
\r
1410 lbl_angle.Visible = false;
\r
1413 if (drop_angle.Items.Count != 0)
\r
1414 drop_angle.SelectedIndex = 0;
\r
1418 drop_angle.Visible = false;
\r
1419 lbl_angle.Visible = false;
\r
1422 // Populate the Start chapter Dropdown
\r
1423 drop_chapterStart.Items.Clear();
\r
1424 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1425 if (drop_chapterStart.Items.Count > 0)
\r
1426 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1428 // Populate the Final Chapter Dropdown
\r
1429 drop_chapterFinish.Items.Clear();
\r
1430 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1431 if (drop_chapterFinish.Items.Count > 0)
\r
1432 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1434 // Populate the Audio Channels Dropdown
\r
1435 AudioSettings.SetTrackListFromPreset(selectedTitle, this.currentlySelectedPreset);
\r
1437 // Populate the Subtitles dropdown
\r
1438 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1440 // Update the source label if we have multiple streams
\r
1441 if (selectedTitle != null)
\r
1442 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1443 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1445 // Run the AutoName & ChapterNaming functions
\r
1446 if (Properties.Settings.Default.autoNaming)
\r
1448 string autoPath = Main.AutoName(this);
\r
1449 if (autoPath != null)
\r
1450 text_destination.Text = autoPath;
\r
1453 "You currently have \"Automatically name output files\" enabled for the destination file box, but you do not have a valid default directory set.\n\nYou should set a \"Default Path\" in HandBrakes preferences. (See 'Tools' menu -> 'Options' -> 'General' Tab -> 'Default Path')",
\r
1454 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1457 data_chpt.Rows.Clear();
\r
1458 if (selectedTitle.Chapters.Count != 1)
\r
1460 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1461 if (chapterGridView != null)
\r
1462 data_chpt = chapterGridView;
\r
1466 Check_ChapterMarkers.Checked = false;
\r
1467 Check_ChapterMarkers.Enabled = false;
\r
1470 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1471 data_chpt.Columns[0].Width = 166;
\r
1472 data_chpt.Columns[0].Width = 165;
\r
1474 RegisterPresetEventHandler();
\r
1477 private void chapersChanged(object sender, EventArgs e)
\r
1479 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1482 Control ctl = (Control)sender;
\r
1483 int chapterStart, chapterEnd;
\r
1484 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1485 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1489 case "drop_chapterStart":
\r
1490 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1491 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1493 if (chapterEnd != 0)
\r
1494 if (chapterStart > chapterEnd)
\r
1495 drop_chapterFinish.Text = chapterStart.ToString();
\r
1497 case "drop_chapterFinish":
\r
1498 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1499 drop_chapterStart.SelectedIndex = 0;
\r
1501 if (chapterStart != 0)
\r
1502 if (chapterEnd < chapterStart)
\r
1503 drop_chapterFinish.Text = chapterStart.ToString();
\r
1505 // Add more rows to the Chapter menu if needed.
\r
1506 if (Check_ChapterMarkers.Checked)
\r
1508 int i = data_chpt.Rows.Count, finish = 0;
\r
1509 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1511 while (i < finish)
\r
1513 int n = data_chpt.Rows.Add();
\r
1514 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1515 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1516 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1517 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1524 // Update the Duration
\r
1525 lbl_duration.Text =
\r
1526 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1529 // Run the Autonaming function
\r
1530 if (Properties.Settings.Default.autoNaming)
\r
1531 text_destination.Text = Main.AutoName(this);
\r
1533 // Disable chapter markers if only 1 chapter is selected.
\r
1534 if (chapterStart == chapterEnd)
\r
1536 Check_ChapterMarkers.Enabled = false;
\r
1537 btn_importChapters.Enabled = false;
\r
1538 data_chpt.Enabled = false;
\r
1542 Check_ChapterMarkers.Enabled = true;
\r
1543 if (Check_ChapterMarkers.Checked)
\r
1545 btn_importChapters.Enabled = true;
\r
1546 data_chpt.Enabled = true;
\r
1551 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1554 int.TryParse(drop_chapterStart.Text, out start);
\r
1555 int.TryParse(drop_chapterFinish.Text, out end);
\r
1556 double duration = end - start;
\r
1558 switch (drop_mode.SelectedIndex)
\r
1561 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1564 if (selectedTitle != null)
\r
1566 duration = duration / selectedTitle.Fps;
\r
1567 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1570 lbl_duration.Text = "--:--:--";
\r
1576 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1579 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1580 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1583 switch (drop_mode.SelectedIndex)
\r
1586 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1587 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1588 if (drop_chapterStart.Items.Count != 0)
\r
1590 drop_chapterStart.SelectedIndex = 0;
\r
1591 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1594 lbl_duration.Text = "--:--:--";
\r
1597 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1598 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1599 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1600 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1601 if (selectedTitle != null)
\r
1603 drop_chapterStart.Text = "0";
\r
1604 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1608 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1609 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1610 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1611 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1612 if (selectedTitle != null)
\r
1614 drop_chapterStart.Text = "0";
\r
1615 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1622 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1624 // This removes the file extension from the filename box on the save file dialog.
\r
1625 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1626 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1628 if (Path.IsPathRooted(text_destination.Text))
\r
1629 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1631 // Show the dialog and set the main form file path
\r
1632 if (drop_format.SelectedIndex.Equals(0))
\r
1633 DVD_Save.FilterIndex = 1;
\r
1634 else if (drop_format.SelectedIndex.Equals(1))
\r
1635 DVD_Save.FilterIndex = 2;
\r
1637 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1639 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1640 switch (DVD_Save.FilterIndex)
\r
1644 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1645 StringComparison.InvariantCultureIgnoreCase))
\r
1646 if (Properties.Settings.Default.useM4v)
\r
1647 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1649 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1653 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1654 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1660 text_destination.Text = DVD_Save.FileName;
\r
1662 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1663 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1664 SetExtension(".m4v");
\r
1668 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1670 string path = text_destination.Text;
\r
1671 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1672 drop_format.SelectedIndex = 0;
\r
1673 else if (path.EndsWith(".mkv"))
\r
1674 drop_format.SelectedIndex = 1;
\r
1677 // Output Settings
\r
1678 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1680 switch (drop_format.SelectedIndex)
\r
1683 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1684 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1685 SetExtension(".m4v");
\r
1687 SetExtension(".mp4");
\r
1690 SetExtension(".mkv");
\r
1694 AudioSettings.SetContainer(drop_format.Text);
\r
1696 if (drop_format.Text.Contains("MP4"))
\r
1698 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1700 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1701 drp_videoEncoder.SelectedIndex = 1;
\r
1704 else if (drop_format.Text.Contains("MKV"))
\r
1705 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1708 public void SetExtension(string newExtension)
\r
1710 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1711 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1712 Subtitles.RequiresM4V())
\r
1713 newExtension = ".m4v";
\r
1715 newExtension = ".mp4";
\r
1717 if (Path.HasExtension(newExtension))
\r
1718 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1722 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1724 setContainerOpts();
\r
1726 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1727 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1729 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1730 check_turbo.Enabled = true;
\r
1732 tab_advanced.Enabled = true;
\r
1733 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1734 check_iPodAtom.Enabled = true;
\r
1736 check_iPodAtom.Enabled = false;
\r
1740 check_turbo.CheckState = CheckState.Unchecked;
\r
1741 check_turbo.Enabled = false;
\r
1742 tab_advanced.Enabled = false;
\r
1743 x264Panel.X264Query = string.Empty;
\r
1744 check_iPodAtom.Enabled = false;
\r
1745 check_iPodAtom.Checked = false;
\r
1748 // Setup the CQ Slider
\r
1749 switch (drp_videoEncoder.Text)
\r
1751 case "MPEG-4 (FFmpeg)":
\r
1752 if (slider_videoQuality.Value > 31)
\r
1753 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1754 slider_videoQuality.Minimum = 1;
\r
1755 slider_videoQuality.Maximum = 31;
\r
1757 case "H.264 (x264)":
\r
1758 slider_videoQuality.Minimum = 0;
\r
1759 slider_videoQuality.TickFrequency = 1;
\r
1761 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1762 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1763 double multiplier = 1.0 / cqStep;
\r
1764 double value = slider_videoQuality.Value * multiplier;
\r
1766 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1768 if (value < slider_videoQuality.Maximum)
\r
1769 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1772 case "VP3 (Theora)":
\r
1773 if (slider_videoQuality.Value > 63)
\r
1774 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1775 slider_videoQuality.Minimum = 0;
\r
1776 slider_videoQuality.Maximum = 63;
\r
1782 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1784 /// <param name="sender">
\r
1787 /// <param name="e">
\r
1790 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1792 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1794 this.checkMaximumFramerate.Visible = false;
\r
1795 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1799 this.checkMaximumFramerate.Visible = true;
\r
1804 /// Set the container format options
\r
1806 public void setContainerOpts()
\r
1808 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1810 check_largeFile.Enabled = true;
\r
1811 check_optimiseMP4.Enabled = true;
\r
1812 check_iPodAtom.Enabled = true;
\r
1816 check_largeFile.Enabled = false;
\r
1817 check_optimiseMP4.Enabled = false;
\r
1818 check_iPodAtom.Enabled = false;
\r
1819 check_largeFile.Checked = false;
\r
1820 check_optimiseMP4.Checked = false;
\r
1821 check_iPodAtom.Checked = false;
\r
1825 private double cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1828 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1830 public void setQualityFromSlider()
\r
1832 // Work out the current RF value.
\r
1833 double cqStep = this.cachedCqStep;
\r
1834 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1836 // Change the maximum value for the slider
\r
1837 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1839 // Reset the CQ slider to RF0
\r
1840 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1842 // Reset the CQ slider back to the previous value as close as possible
\r
1843 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1844 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1845 while (rfValueCurrent < rfValue)
\r
1847 slider_videoQuality.Value--;
\r
1848 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1851 // Cache the CQ step for the next calculation
\r
1852 this.cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1855 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1857 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1858 switch (drp_videoEncoder.Text)
\r
1860 case "MPEG-4 (FFmpeg)":
\r
1861 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1863 case "H.264 (x264)":
\r
1864 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1865 rfValue = Math.Round(rfValue, 2);
\r
1866 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1868 case "VP3 (Theora)":
\r
1869 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1874 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1876 text_bitrate.Enabled = false;
\r
1877 text_filesize.Enabled = true;
\r
1878 slider_videoQuality.Enabled = false;
\r
1880 check_2PassEncode.Enabled = true;
\r
1883 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1885 text_bitrate.Enabled = true;
\r
1886 text_filesize.Enabled = false;
\r
1887 slider_videoQuality.Enabled = false;
\r
1889 check_2PassEncode.Enabled = true;
\r
1892 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1894 text_bitrate.Enabled = false;
\r
1895 text_filesize.Enabled = false;
\r
1896 slider_videoQuality.Enabled = true;
\r
1898 check_2PassEncode.Enabled = false;
\r
1899 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1902 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1904 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1906 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1907 check_turbo.Enabled = true;
\r
1911 check_turbo.Enabled = false;
\r
1912 check_turbo.CheckState = CheckState.Unchecked;
\r
1916 // Chapter Marker Tab
\r
1917 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1919 if (Check_ChapterMarkers.Checked)
\r
1921 if (drop_format.SelectedIndex != 1)
\r
1922 SetExtension(".m4v");
\r
1923 data_chpt.Enabled = true;
\r
1924 btn_importChapters.Enabled = true;
\r
1928 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
1929 SetExtension(".mp4");
\r
1930 data_chpt.Enabled = false;
\r
1931 btn_importChapters.Enabled = false;
\r
1935 private void btn_importChapters_Click(object sender, EventArgs e)
\r
1937 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
1939 string filename = File_ChapterImport.FileName;
\r
1940 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
1941 if (imported != null)
\r
1942 data_chpt = imported;
\r
1946 private void btn_export_Click(object sender, EventArgs e)
\r
1948 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
1949 saveFileDialog.Filter = "Csv File|*.csv";
\r
1950 saveFileDialog.DefaultExt = "csv";
\r
1951 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
1953 string filename = saveFileDialog.FileName;
\r
1955 Main.SaveChapterMarkersToCsv(this, filename);
\r
1959 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
1961 data_chpt.Rows.Clear();
\r
1962 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1963 if (chapterGridView != null)
\r
1965 data_chpt = chapterGridView;
\r
1969 // Query Editor Tab
\r
1970 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1972 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
1975 private void btn_clear_Click(object sender, EventArgs e)
\r
1977 rtf_query.Clear();
\r
1982 // MainWindow Components, Actions and Functions ***********************
\r
1984 #region Source Scan
\r
1987 /// Start the Scan Process
\r
1989 /// <param name="filename">
\r
1992 /// <param name="title">
\r
1995 private void StartScan(string filename, int title)
\r
1997 // Setup the GUI components for the scan.
\r
1998 sourcePath = filename;
\r
2000 this.DisableGUI();
\r
2005 SourceScan.Scan(sourcePath, title);
\r
2006 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
2007 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
2009 catch (Exception exc)
\r
2011 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2016 /// Update the Status label for the scan
\r
2018 /// <param name="sender">
\r
2021 /// <param name="e">
\r
2024 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
2026 UpdateScanStatusLabel();
\r
2030 /// Update the UI after the scan has completed
\r
2032 /// <param name="sender">
\r
2035 /// <param name="e">
\r
2038 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
2040 UpdateGuiAfterScan();
\r
2044 /// Update the Scan Status Label
\r
2046 private void UpdateScanStatusLabel()
\r
2048 if (InvokeRequired)
\r
2050 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
2053 labelSource.Text = SourceScan.ScanStatus;
\r
2057 /// Reset the GUI when the scan has completed
\r
2059 private void UpdateGuiAfterScan()
\r
2061 if (InvokeRequired)
\r
2063 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2069 currentSource = SourceScan.SouceData;
\r
2071 // Setup some GUI components
\r
2072 drp_dvdtitle.Items.Clear();
\r
2073 if (currentSource.Titles.Count != 0)
\r
2074 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2076 foreach (Title title in currentSource.Titles)
\r
2078 if (title.MainTitle)
\r
2080 drp_dvdtitle.SelectedItem = title;
\r
2084 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2086 drp_dvdtitle.SelectedIndex = 0;
\r
2089 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2090 if (drop_chapterStart.Items.Count > 0)
\r
2093 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2094 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2095 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2098 Check_ChapterMarkers.Enabled = false;
\r
2099 Check_ChapterMarkers.Checked = false;
\r
2100 data_chpt.Rows.Clear();
\r
2104 // If no titles were found, Display an error message
\r
2105 if (drp_dvdtitle.Items.Count == 0)
\r
2108 "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
2109 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2110 sourcePath = string.Empty;
\r
2112 UpdateSourceLabel();
\r
2114 // Enable the GUI components and enable any disabled components
\r
2117 catch (Exception exc)
\r
2119 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2120 MessageBoxIcon.Error);
\r
2126 /// Enable the GUI
\r
2128 private void EnableGUI()
\r
2132 if (InvokeRequired)
\r
2133 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2134 foreach (Control ctrl in Controls)
\r
2135 ctrl.Enabled = true;
\r
2136 btn_start.Enabled = true;
\r
2137 btn_showQueue.Enabled = true;
\r
2138 btn_add2Queue.Enabled = true;
\r
2139 tb_preview.Enabled = true;
\r
2140 btn_source.Enabled = true;
\r
2141 mnu_killCLI.Visible = false;
\r
2143 catch (Exception exc)
\r
2145 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2150 /// Disable the GUI
\r
2152 private void DisableGUI()
\r
2154 foreach (Control ctrl in Controls)
\r
2155 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2156 ctrl.Enabled = false;
\r
2158 labelSource.Enabled = true;
\r
2159 labelStaticSource.Enabled = true;
\r
2160 SourceLayoutPanel.Enabled = true;
\r
2161 btn_source.Enabled = false;
\r
2162 btn_start.Enabled = false;
\r
2163 btn_showQueue.Enabled = false;
\r
2164 btn_add2Queue.Enabled = false;
\r
2165 tb_preview.Enabled = false;
\r
2166 mnu_killCLI.Visible = true;
\r
2172 private void KillScan()
\r
2174 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2178 SourceScan.Stop();
\r
2180 labelSource.Text = "Scan Cancelled";
\r
2186 private void ResetGUI()
\r
2188 drp_dvdtitle.Items.Clear();
\r
2189 drop_chapterStart.Items.Clear();
\r
2190 drop_chapterFinish.Items.Clear();
\r
2191 lbl_duration.Text = "Select a Title";
\r
2192 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2193 sourcePath = String.Empty;
\r
2194 text_destination.Text = String.Empty;
\r
2195 selectedTitle = null;
\r
2199 /// Update the Source Label
\r
2201 private void UpdateSourceLabel()
\r
2203 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2207 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2209 /// <param name="job">
\r
2212 public void RecievingJob(Job job)
\r
2214 string query = job.Query;
\r
2215 StartScan(job.Source, job.Title);
\r
2217 if (query != null)
\r
2219 // Ok, Reset all the H264 widgets before changing the preset
\r
2220 x264Panel.Reset2Defaults();
\r
2222 // Send the query from the file to the Query Parser class
\r
2223 QueryParser presetQuery = QueryParser.Parse(query);
\r
2225 // Now load the preset
\r
2226 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2228 // The x264 widgets will need updated, so do this now:
\r
2229 x264Panel.StandardizeOptString();
\r
2230 x264Panel.SetCurrentSettingsInPanel();
\r
2232 // Finally, let this window have a copy of the preset settings.
\r
2233 this.currentlySelectedPreset = null;
\r
2234 PictureSettings.SetPresetCropWarningLabel(null);
\r
2240 #region GUI Functions and Actions
\r
2243 /// Set the GUI to it's finished encoding state.
\r
2245 private void SetEncodeFinished()
\r
2249 if (InvokeRequired)
\r
2251 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2255 lbl_encode.Text = "Encoding Finished";
\r
2256 ProgressBarStatus.Visible = false;
\r
2257 btn_start.Text = "Start";
\r
2258 btn_start.ToolTipText = "Start the encoding process";
\r
2259 btn_start.Image = Properties.Resources.Play;
\r
2261 // If the window is minimized, display the notification in a popup.
\r
2262 if (Properties.Settings.Default.trayIconAlerts)
\r
2263 if (FormWindowState.Minimized == this.WindowState)
\r
2265 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2266 notifyIcon.ShowBalloonTip(500);
\r
2269 catch (Exception exc)
\r
2271 MessageBox.Show(exc.ToString());
\r
2276 /// Set the GUI to it's started encoding state.
\r
2278 private void SetEncodeStarted()
\r
2282 if (InvokeRequired)
\r
2284 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2287 lbl_encode.Visible = true;
\r
2288 ProgressBarStatus.Value = 0;
\r
2289 ProgressBarStatus.Visible = true;
\r
2290 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2291 btn_start.Text = "Stop";
\r
2292 btn_start.ToolTipText = "Stop the encoding process.";
\r
2293 btn_start.Image = Properties.Resources.stop;
\r
2295 catch (Exception exc)
\r
2297 MessageBox.Show(exc.ToString());
\r
2302 /// Display the Encode Status
\r
2304 /// <param name="sender">
\r
2307 /// <param name="e">
\r
2310 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2312 if (this.InvokeRequired)
\r
2314 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2320 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2321 e.PercentComplete,
\r
2322 e.CurrentFrameRate,
\r
2323 e.AverageFrameRate,
\r
2324 e.EstimatedTimeLeft,
\r
2325 encodeQueue.Count);
\r
2327 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2331 /// Set the DVD Drive selection in the "Source" Menu
\r
2333 private void SetDriveSelectionMenuItem()
\r
2337 if (InvokeRequired)
\r
2339 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2343 drives = Main.GetDrives();
\r
2345 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2346 foreach (DriveInformation drive in drives)
\r
2348 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2350 Name = drive.ToString(),
\r
2351 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2352 Image = Resources.disc_small
\r
2354 menuItem.Click += new EventHandler(MnuDvdDriveClick);
\r
2355 menuItems.Add(menuItem);
\r
2358 foreach (ToolStripMenuItem item in menuItems)
\r
2359 btn_source.DropDownItems.Add(item);
\r
2361 catch (Exception exc)
\r
2363 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2368 /// Access the preset Handler and setup the preset panel.
\r
2370 private void LoadPresetPanel()
\r
2372 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2373 if (!Settings.Default.presetNotification)
\r
2374 MessageBox.Show(this,
\r
2375 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2376 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2378 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2379 treeView_presets.Update();
\r
2383 /// Get the title from the selected item in the title dropdown.
\r
2388 private int GetTitle()
\r
2391 if (drp_dvdtitle.SelectedItem != null)
\r
2393 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2394 int.TryParse(titleInfo[0], out title);
\r
2401 /// Handle the Update Check Finishing.
\r
2403 /// <param name="result">
\r
2406 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2408 // Make sure it's running on the calling thread
\r
2409 if (InvokeRequired)
\r
2411 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2414 UpdateCheckInformation info;
\r
2417 // Get the information about the new build, if any, and close the window
\r
2418 info = UpdateService.EndCheckForUpdates(result);
\r
2420 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2422 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
2423 updateWindow.ShowDialog();
\r
2426 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2427 MessageBoxIcon.Information);
\r
2428 lbl_updateCheck.Visible = false;
\r
2431 catch (Exception ex)
\r
2433 if ((bool)result.AsyncState)
\r
2435 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2436 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2445 /// Handle GUI shortcuts
\r
2447 /// <param name="msg">Message</param>
\r
2448 /// <param name="keyData">Keys</param>
\r
2449 /// <returns>Bool</returns>
\r
2450 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2452 if (keyData == (Keys.Control | Keys.S))
\r
2454 btn_start_Click(this, new EventArgs());
\r
2458 if (keyData == (Keys.Control | Keys.Shift | Keys.A))
\r
2460 btn_add2Queue_Click(this, new EventArgs());
\r
2463 return base.ProcessCmdKey(ref msg, keyData);
\r
2467 /// If the queue is being processed, prompt the user to confirm application close.
\r
2469 /// <param name="e">FormClosingEventArgs</param>
\r
2470 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2474 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2475 if (encodeQueue.IsEncoding)
\r
2477 DialogResult result =
\r
2479 "HandBrake is currently encoding. Closing HandBrake will stop the current encode and will result in an unplayable file.\n\nDo you want to close HandBrake?",
\r
2480 "Close HandBrake?",
\r
2481 MessageBoxButtons.YesNo,
\r
2482 MessageBoxIcon.Question);
\r
2484 if (result == DialogResult.No)
\r
2490 encodeQueue.Stop();
\r
2493 if (SourceScan.IsScanning)
\r
2495 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2496 SourceScan.Stop();
\r
2499 catch (Exception exc)
\r
2501 Main.ShowExceptiowWindow("HandBrake was not able to shutdown properly. You may need to forcefully quit HandBrake CLI from TaskManager if it's still running.", exc.ToString());
\r
2505 base.OnFormClosing(e);
\r
2511 // This is the END of the road ****************************************
\r