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 (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
81 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
83 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
89 #region Application Startup
\r
92 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
94 /// <param name="args">
\r
95 /// The arguments passed in on application startup.
\r
97 public frmMain(string[] args)
\r
99 InitializeComponent();
\r
101 // Update the users config file with the CLI version data.
\r
102 Main.SetCliVersionData();
\r
104 if (Settings.Default.hb_version.Contains("svn"))
\r
106 this.Text += " " + Settings.Default.hb_version;
\r
109 // Check for new versions, if update checking is enabled
\r
110 if (Settings.Default.updateStatus)
\r
112 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
114 // Set when the last update was
\r
115 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
116 Settings.Default.Save();
\r
117 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
118 ? Settings.Default.appcast_unstable
\r
119 : Settings.Default.appcast;
\r
120 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
124 // Clear the log files in the background
\r
125 if (Settings.Default.clearOldLogs)
\r
127 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
131 // Setup the GUI components
\r
132 LoadPresetPanel(); // Load the Preset Panel
\r
133 treeView_presets.ExpandAll();
\r
134 lbl_encode.Text = string.Empty;
\r
135 drop_mode.SelectedIndex = 0;
\r
136 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
137 if (!Settings.Default.QueryEditorTab)
\r
138 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
139 if (Settings.Default.tooltipEnable)
\r
140 ToolTip.Active = true;
\r
142 // Load the user's default settings or Normal Preset
\r
143 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
145 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
148 x264Panel.Reset2Defaults();
\r
150 QueryParser presetQuery = QueryParser.Parse(query);
\r
151 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
153 x264Panel.StandardizeOptString();
\r
154 x264Panel.SetCurrentSettingsInPanel();
\r
158 loadNormalPreset();
\r
160 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
161 GrowlCommunicator.Register();
\r
163 // Event Handlers and Queue Recovery
\r
165 Main.RecoverQueue(encodeQueue);
\r
167 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
168 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
170 this.StartScan(args[0], 0);
\r
175 /// When the update check is done, process the results.
\r
177 /// <param name="result">IAsyncResult result</param>
\r
178 private void UpdateCheckDone(IAsyncResult result)
\r
180 if (InvokeRequired)
\r
182 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
188 UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
\r
190 if (info.NewVersionAvailable)
\r
192 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
193 updateWindow.ShowDialog();
\r
196 catch (Exception ex)
\r
198 if ((bool)result.AsyncState)
\r
199 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
207 // Encoding Events for setting up the GUI
\r
208 private void events()
\r
210 // Handle Widget changes when preset is selected.
\r
211 RegisterPresetEventHandler();
\r
213 // Handle Window Resize
\r
214 if (Properties.Settings.Default.MainWindowMinimize)
\r
215 this.Resize += new EventHandler(frmMain_Resize);
\r
217 // Handle Encode Start / Finish / Pause
\r
218 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
219 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
221 // Handle a file being draged onto the GUI.
\r
222 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
223 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
226 // 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
227 private void RegisterPresetEventHandler()
\r
230 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
231 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
232 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
233 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
235 // Picture Settings
\r
236 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
239 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
242 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
243 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
244 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
245 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
246 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
247 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
250 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
253 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
256 private void UnRegisterPresetEventHandler()
\r
258 // Output Settings
\r
259 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
260 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
261 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
262 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
264 // Picture Settings
\r
265 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
268 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
271 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
272 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
273 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
274 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
275 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
276 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
279 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
282 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
285 private void changePresetLabel(object sender, EventArgs e)
\r
287 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
288 this.currentlySelectedPreset = null;
\r
291 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
293 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
294 e.Effect = DragDropEffects.All;
\r
297 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
299 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
300 sourcePath = string.Empty;
\r
302 if (fileList != null)
\r
304 if (!string.IsNullOrEmpty(fileList[0]))
\r
306 this.selectedSourceType = SourceType.VideoFile;
\r
307 StartScan(fileList[0], 0);
\r
310 UpdateSourceLabel();
\r
313 UpdateSourceLabel();
\r
316 private void encodeStarted(object sender, EventArgs e)
\r
318 SetEncodeStarted();
\r
319 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
322 private void encodeEnded(object sender, EventArgs e)
\r
324 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
325 SetEncodeFinished();
\r
329 // User Interface Menus / Tool Strips *********************************
\r
334 /// Kill The scan menu Item
\r
336 /// <param name="sender">
\r
339 /// <param name="e">
\r
342 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
348 /// Exit the Application Menu Item
\r
350 /// <param name="sender">
\r
353 /// <param name="e">
\r
356 private void mnu_exit_Click(object sender, EventArgs e)
\r
358 Application.Exit();
\r
366 /// Menu - Start Button
\r
368 /// <param name="sender">
\r
371 /// <param name="e">
\r
374 private void mnu_encode_Click(object sender, EventArgs e)
\r
376 queueWindow.Show();
\r
380 /// Menu - Display the Log Window
\r
382 /// <param name="sender">
\r
385 /// <param name="e">
\r
388 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
390 this.btn_ActivityWindow_Click(this, null);
\r
394 /// Menu - Display the Options Window
\r
396 /// <param name="sender">
\r
399 /// <param name="e">
\r
402 private void mnu_options_Click(object sender, EventArgs e)
\r
404 Form options = new frmOptions(this);
\r
405 options.ShowDialog();
\r
410 #region Presets Menu
\r
413 /// Reset the Built in Presets
\r
415 /// <param name="sender">
\r
418 /// <param name="e">
\r
421 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
423 presetHandler.UpdateBuiltInPresets();
\r
425 if (treeView_presets.Nodes.Count == 0)
\r
427 "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
428 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
430 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
432 treeView_presets.ExpandAll();
\r
436 /// Delete the selected preset
\r
438 /// <param name="sender">
\r
441 /// <param name="e">
\r
444 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
446 presetHandler.RemoveBuiltInPresets();
\r
447 LoadPresetPanel(); // Reload the preset panel
\r
451 /// Select the Normal preset
\r
453 /// <param name="sender">
\r
456 /// <param name="e">
\r
459 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
461 loadNormalPreset();
\r
465 /// Import a plist Preset
\r
467 /// <param name="sender">
\r
470 /// <param name="e">
\r
473 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
479 /// Export a Plist Preset
\r
481 /// <param name="sender">
\r
484 /// <param name="e">
\r
487 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
493 /// Create a new Preset
\r
495 /// <param name="sender">
\r
498 /// <param name="e">
\r
501 private void btn_new_preset_Click(object sender, EventArgs e)
\r
503 Form preset = new frmAddPreset(this, presetHandler);
\r
504 if (preset.ShowDialog() == DialogResult.OK)
\r
506 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
507 treeView_presets.Nodes.Add(presetTreeview);
\r
508 presetHandler.LastPresetAdded = null;
\r
517 /// Menu - Display the User Guide Web Page
\r
519 /// <param name="sender">
\r
522 /// <param name="e">
\r
525 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
527 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
531 /// Menu - Check for Updates
\r
533 /// <param name="sender">
\r
536 /// <param name="e">
\r
539 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
541 lbl_updateCheck.Visible = true;
\r
542 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
543 Settings.Default.Save();
\r
544 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
545 ? Settings.Default.appcast_unstable
\r
546 : Settings.Default.appcast;
\r
547 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDoneMenu), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
551 /// Menu - Display the About Window
\r
553 /// <param name="sender">
\r
556 /// <param name="e">
\r
559 private void mnu_about_Click(object sender, EventArgs e)
\r
561 using (frmAbout About = new frmAbout())
\r
563 About.ShowDialog();
\r
572 /// RMenu - Expand All
\r
574 /// <param name="sender">
\r
577 /// <param name="e">
\r
580 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
582 treeView_presets.ExpandAll();
\r
586 /// RMenu - Collaspe All
\r
588 /// <param name="sender">
\r
591 /// <param name="e">
\r
594 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
596 treeView_presets.CollapseAll();
\r
600 /// Menu - Import Preset
\r
602 /// <param name="sender">
\r
605 /// <param name="e">
\r
608 private void pmnu_import_Click(object sender, EventArgs e)
\r
614 /// RMenu - Save Changes to Preset
\r
616 /// <param name="sender">
\r
619 /// <param name="e">
\r
622 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
624 // TODO this requires a re-think since the Query Editor has changed.
\r
625 DialogResult result =
\r
627 "Do you wish to include picture settings when updating the preset: " +
\r
628 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
629 MessageBoxIcon.Question);
\r
630 if (result == DialogResult.Yes)
\r
631 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
632 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
633 else if (result == DialogResult.No)
\r
634 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
635 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
639 /// RMenu - Delete Preset
\r
641 /// <param name="sender">
\r
644 /// <param name="e">
\r
647 private void pmnu_delete_click(object sender, EventArgs e)
\r
649 if (treeView_presets.SelectedNode != null)
\r
651 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
652 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
654 treeView_presets.Select();
\r
658 /// Preset Menu Is Opening. Setup the Menu
\r
660 /// <param name="sender">
\r
663 /// <param name="e">
\r
666 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
668 // Make sure that the save menu is always disabled by default
\r
669 pmnu_saveChanges.Enabled = false;
\r
671 // Now enable the save menu if the selected preset is a user preset
\r
672 if (treeView_presets.SelectedNode != null)
\r
673 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
674 pmnu_saveChanges.Enabled = true;
\r
676 treeView_presets.Select();
\r
679 // Presets Management
\r
682 /// Button - Add a preset
\r
684 /// <param name="sender">
\r
687 /// <param name="e">
\r
690 private void btn_addPreset_Click(object sender, EventArgs e)
\r
692 Form preset = new frmAddPreset(this, presetHandler);
\r
693 if (preset.ShowDialog() == DialogResult.OK)
\r
695 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
696 treeView_presets.Nodes.Add(presetTreeview);
\r
697 presetHandler.LastPresetAdded = null;
\r
702 /// Button - remove a Preset
\r
704 /// <param name="sender">
\r
707 /// <param name="e">
\r
710 private void btn_removePreset_Click(object sender, EventArgs e)
\r
712 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
713 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
714 if (result == DialogResult.Yes)
\r
716 if (treeView_presets.SelectedNode != null)
\r
718 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
719 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
722 treeView_presets.Select();
\r
726 /// Button - Set the selected preset as the default
\r
728 /// <param name="sender">
\r
731 /// <param name="e">
\r
734 private void btn_setDefault_Click(object sender, EventArgs e)
\r
736 if (treeView_presets.SelectedNode != null)
\r
738 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
739 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
740 if (result == DialogResult.Yes)
\r
742 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
743 Properties.Settings.Default.Save();
\r
744 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
748 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
752 /// PresetBar Mouse Down event
\r
754 /// <param name="sender">
\r
757 /// <param name="e">
\r
760 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
762 if (e.Button == MouseButtons.Right)
\r
763 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
764 else if (e.Button == MouseButtons.Left)
\r
766 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
768 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
773 treeView_presets.Select();
\r
777 /// Preset Bar after selecting the preset
\r
779 /// <param name="sender">
\r
782 /// <param name="e">
\r
785 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
791 /// Preset Bar - Handle the Delete Key
\r
793 /// <param name="sender">
\r
796 /// <param name="e">
\r
799 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
801 if (e.KeyCode == Keys.Delete)
\r
803 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
804 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
805 if (result == DialogResult.Yes)
\r
807 if (treeView_presets.SelectedNode != null)
\r
808 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
810 // Remember each nodes expanded status so we can reload it
\r
811 List<bool> nodeStatus = new List<bool>();
\r
812 foreach (TreeNode node in treeView_presets.Nodes)
\r
813 nodeStatus.Add(node.IsExpanded);
\r
815 // Now reload the preset panel
\r
818 // And finally, re-expand any of the nodes if required
\r
820 foreach (TreeNode node in treeView_presets.Nodes)
\r
832 /// Select the selected preset and setup the GUI
\r
834 private void selectPreset()
\r
836 if (treeView_presets.SelectedNode != null)
\r
838 // Ok, so, we've selected a preset. Now we want to load it.
\r
839 string presetName = treeView_presets.SelectedNode.Text;
\r
840 Preset preset = presetHandler.GetPreset(presetName);
\r
841 if (preset != null)
\r
843 string query = presetHandler.GetPreset(presetName).Query;
\r
847 // Ok, Reset all the H264 widgets before changing the preset
\r
848 x264Panel.Reset2Defaults();
\r
850 // Send the query from the file to the Query Parser class
\r
851 QueryParser presetQuery = QueryParser.Parse(query);
\r
853 // Now load the preset
\r
854 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
856 // The x264 widgets will need updated, so do this now:
\r
857 x264Panel.StandardizeOptString();
\r
858 x264Panel.SetCurrentSettingsInPanel();
\r
860 // Finally, let this window have a copy of the preset settings.
\r
861 this.currentlySelectedPreset = preset;
\r
862 PictureSettings.SetPresetCropWarningLabel(preset);
\r
869 /// Load the Normal Preset
\r
871 private void loadNormalPreset()
\r
873 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
875 foreach (TreeNode node in treenode.Nodes)
\r
877 if (node.Text.Equals("Normal"))
\r
878 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
884 /// Import a plist preset
\r
886 private void ImportPreset()
\r
888 if (openPreset.ShowDialog() == DialogResult.OK)
\r
890 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
891 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
893 DialogResult result =
\r
894 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
895 "Overwrite preset?",
\r
896 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
897 if (result == DialogResult.Yes)
\r
899 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
900 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
901 QueryGenerator.GenerateFullQuery(this),
\r
902 parsed.UsesPictureSettings);
\r
907 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
908 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
909 QueryGenerator.GenerateFullQuery(this),
\r
910 parsed.UsesPictureSettings))
\r
912 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
914 ForeColor = Color.Black
\r
916 treeView_presets.Nodes.Add(preset_treeview);
\r
923 /// Export a plist Preset
\r
925 private void ExportPreset()
\r
927 MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
930 /*SaveFileDialog savefiledialog = new SaveFileDialog();
\r
931 savefiledialog.Filter = "plist|*.plist";
\r
933 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 = 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
2205 if (selectedTitle != null)
\r
2206 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
2207 // If it's one of multiple source files, make sure we don't use the folder name
\r
2208 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
2212 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2214 /// <param name="job">
\r
2217 public void RecievingJob(Job job)
\r
2219 string query = job.Query;
\r
2220 StartScan(job.Source, job.Title);
\r
2222 if (query != null)
\r
2224 // Ok, Reset all the H264 widgets before changing the preset
\r
2225 x264Panel.Reset2Defaults();
\r
2227 // Send the query from the file to the Query Parser class
\r
2228 QueryParser presetQuery = QueryParser.Parse(query);
\r
2230 // Now load the preset
\r
2231 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2233 // The x264 widgets will need updated, so do this now:
\r
2234 x264Panel.StandardizeOptString();
\r
2235 x264Panel.SetCurrentSettingsInPanel();
\r
2237 // Finally, let this window have a copy of the preset settings.
\r
2238 this.currentlySelectedPreset = null;
\r
2239 PictureSettings.SetPresetCropWarningLabel(null);
\r
2245 #region GUI Functions and Actions
\r
2248 /// Set the GUI to it's finished encoding state.
\r
2250 private void SetEncodeFinished()
\r
2254 if (InvokeRequired)
\r
2256 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2260 lbl_encode.Text = "Encoding Finished";
\r
2261 ProgressBarStatus.Visible = false;
\r
2262 btn_start.Text = "Start";
\r
2263 btn_start.ToolTipText = "Start the encoding process";
\r
2264 btn_start.Image = Properties.Resources.Play;
\r
2266 // If the window is minimized, display the notification in a popup.
\r
2267 if (Properties.Settings.Default.trayIconAlerts)
\r
2268 if (FormWindowState.Minimized == this.WindowState)
\r
2270 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2271 notifyIcon.ShowBalloonTip(500);
\r
2274 catch (Exception exc)
\r
2276 MessageBox.Show(exc.ToString());
\r
2281 /// Set the GUI to it's started encoding state.
\r
2283 private void SetEncodeStarted()
\r
2287 if (InvokeRequired)
\r
2289 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2292 lbl_encode.Visible = true;
\r
2293 ProgressBarStatus.Value = 0;
\r
2294 ProgressBarStatus.Visible = true;
\r
2295 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2296 btn_start.Text = "Stop";
\r
2297 btn_start.ToolTipText = "Stop the encoding process.";
\r
2298 btn_start.Image = Properties.Resources.stop;
\r
2300 catch (Exception exc)
\r
2302 MessageBox.Show(exc.ToString());
\r
2307 /// Display the Encode Status
\r
2309 /// <param name="sender">
\r
2312 /// <param name="e">
\r
2315 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2317 if (this.InvokeRequired)
\r
2319 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2325 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2326 e.PercentComplete,
\r
2327 e.CurrentFrameRate,
\r
2328 e.AverageFrameRate,
\r
2329 e.EstimatedTimeLeft,
\r
2330 encodeQueue.Count);
\r
2332 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2336 /// Set the DVD Drive selection in the "Source" Menu
\r
2338 private void SetDriveSelectionMenuItem()
\r
2342 if (InvokeRequired)
\r
2344 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2348 drives = Main.GetDrives();
\r
2350 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2351 foreach (DriveInformation drive in drives)
\r
2353 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2355 Name = drive.ToString(),
\r
2356 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2357 Image = Resources.disc_small
\r
2359 menuItem.Click += new EventHandler(MnuDvdDriveClick);
\r
2360 menuItems.Add(menuItem);
\r
2363 foreach (ToolStripMenuItem item in menuItems)
\r
2364 btn_source.DropDownItems.Add(item);
\r
2366 catch (Exception exc)
\r
2368 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2373 /// Access the preset Handler and setup the preset panel.
\r
2375 private void LoadPresetPanel()
\r
2377 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2378 if (!Settings.Default.presetNotification)
\r
2379 MessageBox.Show(this,
\r
2380 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2381 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2383 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2384 treeView_presets.Update();
\r
2388 /// Get the title from the selected item in the title dropdown.
\r
2393 private int GetTitle()
\r
2396 if (drp_dvdtitle.SelectedItem != null)
\r
2398 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2399 int.TryParse(titleInfo[0], out title);
\r
2406 /// Handle the Update Check Finishing.
\r
2408 /// <param name="result">
\r
2411 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2413 // Make sure it's running on the calling thread
\r
2414 if (InvokeRequired)
\r
2416 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2419 UpdateCheckInformation info;
\r
2422 // Get the information about the new build, if any, and close the window
\r
2423 info = UpdateService.EndCheckForUpdates(result);
\r
2425 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2427 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
2428 updateWindow.ShowDialog();
\r
2431 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2432 MessageBoxIcon.Information);
\r
2433 lbl_updateCheck.Visible = false;
\r
2436 catch (Exception ex)
\r
2438 if ((bool)result.AsyncState)
\r
2440 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2441 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2450 /// Handle GUI shortcuts
\r
2452 /// <param name="msg">Message</param>
\r
2453 /// <param name="keyData">Keys</param>
\r
2454 /// <returns>Bool</returns>
\r
2455 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2457 if (keyData == (Keys.Control | Keys.S))
\r
2459 btn_start_Click(this, new EventArgs());
\r
2463 if (keyData == (Keys.Control | Keys.Shift | Keys.A))
\r
2465 btn_add2Queue_Click(this, new EventArgs());
\r
2468 return base.ProcessCmdKey(ref msg, keyData);
\r
2472 /// If the queue is being processed, prompt the user to confirm application close.
\r
2474 /// <param name="e">FormClosingEventArgs</param>
\r
2475 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2479 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2480 if (encodeQueue.IsEncoding)
\r
2482 DialogResult result =
\r
2484 "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
2485 "Close HandBrake?",
\r
2486 MessageBoxButtons.YesNo,
\r
2487 MessageBoxIcon.Question);
\r
2489 if (result == DialogResult.No)
\r
2495 encodeQueue.Stop();
\r
2498 if (SourceScan.IsScanning)
\r
2500 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2501 SourceScan.Stop();
\r
2504 catch (Exception exc)
\r
2506 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
2510 base.OnFormClosing(e);
\r
2516 // This is the END of the road ****************************************
\r