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 // Add the item to the queue.
\r
1108 AddItemToQueue(true);
\r
1109 queueWindow.Show();
\r
1113 /// Add Multiple Items to the Queue at once.
\r
1115 /// <param name="sender">The Sender</param>
\r
1116 /// <param name="e">The EventArgs</param>
\r
1117 private void MnuAddMultiToQueueClick(object sender, EventArgs e)
\r
1119 if (!Settings.Default.autoNaming)
\r
1121 MessageBox.Show("Destination Auto Naming must be enabled in preferences for this feature to work.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1125 if (this.SourceScan.SouceData == null)
\r
1127 MessageBox.Show("You must first scan a source or collection of source to use this feature.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1131 BatchAdd batchAdd = new BatchAdd();
\r
1132 if (batchAdd.ShowDialog() == DialogResult.OK)
\r
1134 int min = batchAdd.Min;
\r
1135 int max = batchAdd.Max;
\r
1136 bool errors = false;
\r
1138 foreach (Title title in this.SourceScan.SouceData.Titles)
\r
1140 if (title.Duration.TotalMinutes > min && title.Duration.TotalMinutes < max)
\r
1143 this.drp_dvdtitle.SelectedItem = title;
\r
1145 if (!this.AddItemToQueue(false))
\r
1155 "One or more items could not be added to the queue. You should check your queue and manually add any missing jobs.",
\r
1157 MessageBoxButtons.OK,
\r
1158 MessageBoxIcon.Warning);
\r
1163 private bool AddItemToQueue(bool showError)
\r
1165 string query = QueryGenerator.GenerateFullQuery(this);
\r
1166 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1167 query = rtf_query.Text;
\r
1169 // 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
1170 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1171 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1173 // Make sure we have a Source and Destination.
\r
1174 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1177 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1181 // Make sure the destination path exists.
\r
1182 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1185 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
1189 // Make sure we don't have a duplciate on the queue.
\r
1190 if (encodeQueue.CheckForDestinationDuplicate(jobDestination))
\r
1194 DialogResult result;
\r
1198 "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?",
\r
1201 MessageBoxButtons.YesNo,
\r
1202 MessageBoxIcon.Warning);
\r
1204 if (result != DialogResult.Yes) return false;
\r
1213 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1215 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1221 /// Toolbar - Show the Queue
\r
1223 /// <param name="sender">
\r
1226 /// <param name="e">
\r
1229 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1231 queueWindow.Show();
\r
1232 queueWindow.Activate();
\r
1236 /// Toolbar - Show the Preview Window
\r
1238 /// <param name="sender">
\r
1241 /// <param name="e">
\r
1244 private void tb_preview_Click(object sender, EventArgs e)
\r
1246 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1247 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1248 MessageBoxIcon.Warning);
\r
1251 if (qtpreview == null)
\r
1253 qtpreview = new frmPreview(this);
\r
1256 else if (qtpreview.IsDisposed)
\r
1258 qtpreview = new frmPreview(this);
\r
1262 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1263 MessageBoxIcon.Warning);
\r
1268 /// Toolbar - Show the Activity log Window
\r
1270 /// <param name="sender">
\r
1273 /// <param name="e">
\r
1276 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1278 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1279 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1281 this.activityWindow.Show();
\r
1282 this.activityWindow.Activate();
\r
1287 #region System Tray Icon
\r
1290 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1292 /// <param name="sender">
\r
1295 /// <param name="e">
\r
1298 private void frmMain_Resize(object sender, EventArgs e)
\r
1300 if (FormWindowState.Minimized == this.WindowState)
\r
1302 notifyIcon.Visible = true;
\r
1305 else if (FormWindowState.Normal == this.WindowState)
\r
1306 notifyIcon.Visible = false;
\r
1310 /// Double Click the Tray Icon
\r
1312 /// <param name="sender">
\r
1315 /// <param name="e">
\r
1318 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1320 this.Visible = true;
\r
1322 this.WindowState = FormWindowState.Normal;
\r
1323 notifyIcon.Visible = false;
\r
1327 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1329 /// <param name="sender">
\r
1332 /// <param name="e">
\r
1335 private void btn_restore_Click(object sender, EventArgs e)
\r
1337 this.Visible = true;
\r
1339 this.WindowState = FormWindowState.Normal;
\r
1340 notifyIcon.Visible = false;
\r
1345 #region Main Window and Tab Control
\r
1348 private void BtnFolderScanClicked(object sender, EventArgs e)
\r
1350 this.btn_source.HideDropDown();
\r
1351 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1353 this.selectedSourceType = SourceType.Folder;
\r
1354 SelectSource(DVD_Open.SelectedPath, 0);
\r
1357 UpdateSourceLabel();
\r
1360 private void BtnFileScanClicked(object sender, EventArgs e)
\r
1362 this.btn_source.HideDropDown();
\r
1363 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1365 this.selectedSourceType = SourceType.VideoFile;
\r
1366 SelectSource(ISO_Open.FileName, 0);
\r
1369 UpdateSourceLabel();
\r
1372 private void MnuDvdDriveClick(object sender, EventArgs e)
\r
1374 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1377 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1379 if (int.TryParse(driveId, out id))
\r
1381 this.dvdDrivePath = drives[id].RootDirectory;
\r
1382 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1384 if (this.dvdDrivePath == null) return;
\r
1385 this.selectedSourceType = SourceType.DvdDrive;
\r
1386 SelectSource(this.dvdDrivePath, 0);
\r
1391 private void VideoTitleSpecificScanClick(object sender, EventArgs e)
\r
1393 this.btn_source.HideDropDown();
\r
1394 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1396 this.selectedSourceType = SourceType.VideoFile;
\r
1398 int sourceTitle = 0;
\r
1399 TitleSpecificScan title = new TitleSpecificScan();
\r
1400 if (title.ShowDialog() == DialogResult.OK)
\r
1402 sourceTitle = title.Title;
\r
1403 SelectSource(ISO_Open.FileName, sourceTitle);
\r
1407 UpdateSourceLabel();
\r
1410 private void FolderTitleSpecificScanClick(object sender, EventArgs e)
\r
1412 this.btn_source.HideDropDown();
\r
1413 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1415 this.selectedSourceType = SourceType.Folder;
\r
1417 int sourceTitle = 0;
\r
1418 TitleSpecificScan title = new TitleSpecificScan();
\r
1419 if (title.ShowDialog() == DialogResult.OK)
\r
1421 sourceTitle = title.Title;
\r
1422 SelectSource(DVD_Open.SelectedPath, sourceTitle);
\r
1426 UpdateSourceLabel();
\r
1429 private void SelectSource(string file, int titleSpecific)
\r
1431 Check_ChapterMarkers.Enabled = true;
\r
1432 sourcePath = string.Empty;
\r
1434 if (file == string.Empty) // Must have a file or path
\r
1436 UpdateSourceLabel();
\r
1440 sourcePath = Path.GetFileName(file);
\r
1441 StartScan(file, titleSpecific);
\r
1444 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1446 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1448 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1449 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1452 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1454 UnRegisterPresetEventHandler();
\r
1455 drop_mode.SelectedIndex = 0;
\r
1457 drop_chapterStart.Items.Clear();
\r
1458 drop_chapterFinish.Items.Clear();
\r
1460 // If the dropdown is set to automatic nothing else needs to be done.
\r
1461 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1462 if (drp_dvdtitle.Text != "Automatic")
\r
1464 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1465 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1466 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1467 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1469 // Populate the Angles dropdown
\r
1470 drop_angle.Items.Clear();
\r
1471 if (!Properties.Settings.Default.noDvdNav)
\r
1473 drop_angle.Visible = true;
\r
1474 lbl_angle.Visible = true;
\r
1476 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1477 drop_angle.Items.Add(i.ToString());
\r
1479 if (drop_angle.Items.Count == 0)
\r
1481 drop_angle.Visible = false;
\r
1482 lbl_angle.Visible = false;
\r
1485 if (drop_angle.Items.Count != 0)
\r
1486 drop_angle.SelectedIndex = 0;
\r
1490 drop_angle.Visible = false;
\r
1491 lbl_angle.Visible = false;
\r
1494 // Populate the Start chapter Dropdown
\r
1495 drop_chapterStart.Items.Clear();
\r
1496 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1497 if (drop_chapterStart.Items.Count > 0)
\r
1498 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1500 // Populate the Final Chapter Dropdown
\r
1501 drop_chapterFinish.Items.Clear();
\r
1502 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1503 if (drop_chapterFinish.Items.Count > 0)
\r
1504 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1506 // Populate the Audio Channels Dropdown
\r
1507 AudioSettings.SetTrackListFromPreset(selectedTitle, this.currentlySelectedPreset);
\r
1509 // Populate the Subtitles dropdown
\r
1510 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1512 // Update the source label if we have multiple streams
\r
1513 if (selectedTitle != null)
\r
1514 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1515 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1517 // Run the AutoName & ChapterNaming functions
\r
1518 if (Properties.Settings.Default.autoNaming)
\r
1520 string autoPath = Main.AutoName(this);
\r
1521 if (autoPath != null)
\r
1522 text_destination.Text = autoPath;
\r
1525 "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
1526 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1529 data_chpt.Rows.Clear();
\r
1530 if (selectedTitle.Chapters.Count != 1)
\r
1532 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1533 if (chapterGridView != null)
\r
1534 data_chpt = chapterGridView;
\r
1538 Check_ChapterMarkers.Checked = false;
\r
1539 Check_ChapterMarkers.Enabled = false;
\r
1542 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1543 data_chpt.Columns[0].Width = 166;
\r
1544 data_chpt.Columns[0].Width = 165;
\r
1546 RegisterPresetEventHandler();
\r
1549 private void chapersChanged(object sender, EventArgs e)
\r
1551 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1554 Control ctl = (Control)sender;
\r
1555 int chapterStart, chapterEnd;
\r
1556 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1557 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1561 case "drop_chapterStart":
\r
1562 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1563 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1565 if (chapterEnd != 0)
\r
1566 if (chapterStart > chapterEnd)
\r
1567 drop_chapterFinish.Text = chapterStart.ToString();
\r
1569 case "drop_chapterFinish":
\r
1570 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1571 drop_chapterStart.SelectedIndex = 0;
\r
1573 if (chapterStart != 0)
\r
1574 if (chapterEnd < chapterStart)
\r
1575 drop_chapterFinish.Text = chapterStart.ToString();
\r
1577 // Add more rows to the Chapter menu if needed.
\r
1578 if (Check_ChapterMarkers.Checked)
\r
1580 int i = data_chpt.Rows.Count, finish = 0;
\r
1581 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1583 while (i < finish)
\r
1585 int n = data_chpt.Rows.Add();
\r
1586 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1587 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1588 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1589 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1596 // Update the Duration
\r
1597 lbl_duration.Text =
\r
1598 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1601 // Run the Autonaming function
\r
1602 if (Properties.Settings.Default.autoNaming)
\r
1603 text_destination.Text = Main.AutoName(this);
\r
1605 // Disable chapter markers if only 1 chapter is selected.
\r
1606 if (chapterStart == chapterEnd)
\r
1608 Check_ChapterMarkers.Enabled = false;
\r
1609 btn_importChapters.Enabled = false;
\r
1610 data_chpt.Enabled = false;
\r
1614 Check_ChapterMarkers.Enabled = true;
\r
1615 if (Check_ChapterMarkers.Checked)
\r
1617 btn_importChapters.Enabled = true;
\r
1618 data_chpt.Enabled = true;
\r
1623 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1626 int.TryParse(drop_chapterStart.Text, out start);
\r
1627 int.TryParse(drop_chapterFinish.Text, out end);
\r
1628 double duration = end - start;
\r
1630 switch (drop_mode.SelectedIndex)
\r
1633 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1636 if (selectedTitle != null)
\r
1638 duration = duration / selectedTitle.Fps;
\r
1639 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1642 lbl_duration.Text = "--:--:--";
\r
1648 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1651 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1652 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1655 switch (drop_mode.SelectedIndex)
\r
1658 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1659 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1660 if (drop_chapterStart.Items.Count != 0)
\r
1662 drop_chapterStart.SelectedIndex = 0;
\r
1663 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1666 lbl_duration.Text = "--:--:--";
\r
1669 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1670 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1671 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1672 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1673 if (selectedTitle != null)
\r
1675 drop_chapterStart.Text = "0";
\r
1676 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1680 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1681 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1682 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1683 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1684 if (selectedTitle != null)
\r
1686 drop_chapterStart.Text = "0";
\r
1687 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1694 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1696 // This removes the file extension from the filename box on the save file dialog.
\r
1697 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1698 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1700 if (Path.IsPathRooted(text_destination.Text))
\r
1701 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1703 // Show the dialog and set the main form file path
\r
1704 if (drop_format.SelectedIndex.Equals(0))
\r
1705 DVD_Save.FilterIndex = 1;
\r
1706 else if (drop_format.SelectedIndex.Equals(1))
\r
1707 DVD_Save.FilterIndex = 2;
\r
1709 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1711 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1712 switch (DVD_Save.FilterIndex)
\r
1716 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1717 StringComparison.InvariantCultureIgnoreCase))
\r
1718 if (Properties.Settings.Default.useM4v)
\r
1719 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1721 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1725 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1726 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1732 text_destination.Text = DVD_Save.FileName;
\r
1734 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1735 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1736 SetExtension(".m4v");
\r
1740 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1742 string path = text_destination.Text;
\r
1743 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1744 drop_format.SelectedIndex = 0;
\r
1745 else if (path.EndsWith(".mkv"))
\r
1746 drop_format.SelectedIndex = 1;
\r
1749 // Output Settings
\r
1750 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1752 switch (drop_format.SelectedIndex)
\r
1755 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1756 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1757 SetExtension(".m4v");
\r
1759 SetExtension(".mp4");
\r
1762 SetExtension(".mkv");
\r
1766 AudioSettings.SetContainer(drop_format.Text);
\r
1768 if (drop_format.Text.Contains("MP4"))
\r
1770 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1772 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1773 drp_videoEncoder.SelectedIndex = 1;
\r
1776 else if (drop_format.Text.Contains("MKV"))
\r
1777 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1780 public void SetExtension(string newExtension)
\r
1782 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1783 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1784 Subtitles.RequiresM4V())
\r
1785 newExtension = ".m4v";
\r
1787 newExtension = ".mp4";
\r
1789 if (Path.HasExtension(newExtension))
\r
1790 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1794 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1796 setContainerOpts();
\r
1798 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1799 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1801 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1802 check_turbo.Enabled = true;
\r
1804 tab_advanced.Enabled = true;
\r
1805 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1806 check_iPodAtom.Enabled = true;
\r
1808 check_iPodAtom.Enabled = false;
\r
1812 check_turbo.CheckState = CheckState.Unchecked;
\r
1813 check_turbo.Enabled = false;
\r
1814 tab_advanced.Enabled = false;
\r
1815 x264Panel.X264Query = string.Empty;
\r
1816 check_iPodAtom.Enabled = false;
\r
1817 check_iPodAtom.Checked = false;
\r
1820 // Setup the CQ Slider
\r
1821 switch (drp_videoEncoder.Text)
\r
1823 case "MPEG-4 (FFmpeg)":
\r
1824 if (slider_videoQuality.Value > 31)
\r
1825 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1826 slider_videoQuality.Minimum = 1;
\r
1827 slider_videoQuality.Maximum = 31;
\r
1829 case "H.264 (x264)":
\r
1830 slider_videoQuality.Minimum = 0;
\r
1831 slider_videoQuality.TickFrequency = 1;
\r
1833 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1834 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1835 double multiplier = 1.0 / cqStep;
\r
1836 double value = slider_videoQuality.Value * multiplier;
\r
1838 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1840 if (value < slider_videoQuality.Maximum)
\r
1841 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1844 case "VP3 (Theora)":
\r
1845 if (slider_videoQuality.Value > 63)
\r
1846 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1847 slider_videoQuality.Minimum = 0;
\r
1848 slider_videoQuality.Maximum = 63;
\r
1854 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1856 /// <param name="sender">
\r
1859 /// <param name="e">
\r
1862 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1864 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1866 this.checkMaximumFramerate.Visible = false;
\r
1867 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1871 this.checkMaximumFramerate.Visible = true;
\r
1876 /// Set the container format options
\r
1878 public void setContainerOpts()
\r
1880 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1882 check_largeFile.Enabled = true;
\r
1883 check_optimiseMP4.Enabled = true;
\r
1884 check_iPodAtom.Enabled = true;
\r
1888 check_largeFile.Enabled = false;
\r
1889 check_optimiseMP4.Enabled = false;
\r
1890 check_iPodAtom.Enabled = false;
\r
1891 check_largeFile.Checked = false;
\r
1892 check_optimiseMP4.Checked = false;
\r
1893 check_iPodAtom.Checked = false;
\r
1897 private double cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1900 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1902 public void setQualityFromSlider()
\r
1904 // Work out the current RF value.
\r
1905 double cqStep = this.cachedCqStep;
\r
1906 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1908 // Change the maximum value for the slider
\r
1909 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1911 // Reset the CQ slider to RF0
\r
1912 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1914 // Reset the CQ slider back to the previous value as close as possible
\r
1915 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1916 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1917 while (rfValueCurrent < rfValue)
\r
1919 slider_videoQuality.Value--;
\r
1920 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1923 // Cache the CQ step for the next calculation
\r
1924 this.cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1927 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1929 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1930 switch (drp_videoEncoder.Text)
\r
1932 case "MPEG-4 (FFmpeg)":
\r
1933 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1935 case "H.264 (x264)":
\r
1936 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1937 rfValue = Math.Round(rfValue, 2);
\r
1938 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1940 case "VP3 (Theora)":
\r
1941 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1946 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1948 text_bitrate.Enabled = false;
\r
1949 text_filesize.Enabled = true;
\r
1950 slider_videoQuality.Enabled = false;
\r
1952 check_2PassEncode.Enabled = true;
\r
1955 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1957 text_bitrate.Enabled = true;
\r
1958 text_filesize.Enabled = false;
\r
1959 slider_videoQuality.Enabled = false;
\r
1961 check_2PassEncode.Enabled = true;
\r
1964 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1966 text_bitrate.Enabled = false;
\r
1967 text_filesize.Enabled = false;
\r
1968 slider_videoQuality.Enabled = true;
\r
1970 check_2PassEncode.Enabled = false;
\r
1971 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1974 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1976 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1978 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1979 check_turbo.Enabled = true;
\r
1983 check_turbo.Enabled = false;
\r
1984 check_turbo.CheckState = CheckState.Unchecked;
\r
1988 // Chapter Marker Tab
\r
1989 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1991 if (Check_ChapterMarkers.Checked)
\r
1993 if (drop_format.SelectedIndex != 1)
\r
1994 SetExtension(".m4v");
\r
1995 data_chpt.Enabled = true;
\r
1996 btn_importChapters.Enabled = true;
\r
2000 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
2001 SetExtension(".mp4");
\r
2002 data_chpt.Enabled = false;
\r
2003 btn_importChapters.Enabled = false;
\r
2007 private void btn_importChapters_Click(object sender, EventArgs e)
\r
2009 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
2011 string filename = File_ChapterImport.FileName;
\r
2012 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
2013 if (imported != null)
\r
2014 data_chpt = imported;
\r
2018 private void btn_export_Click(object sender, EventArgs e)
\r
2020 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
2021 saveFileDialog.Filter = "Csv File|*.csv";
\r
2022 saveFileDialog.DefaultExt = "csv";
\r
2023 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
2025 string filename = saveFileDialog.FileName;
\r
2027 Main.SaveChapterMarkersToCsv(this, filename);
\r
2031 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
2033 data_chpt.Rows.Clear();
\r
2034 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
2035 if (chapterGridView != null)
\r
2037 data_chpt = chapterGridView;
\r
2041 // Query Editor Tab
\r
2042 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
2044 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
2047 private void btn_clear_Click(object sender, EventArgs e)
\r
2049 rtf_query.Clear();
\r
2054 // MainWindow Components, Actions and Functions ***********************
\r
2056 #region Source Scan
\r
2059 /// Start the Scan Process
\r
2061 /// <param name="filename">
\r
2064 /// <param name="title">
\r
2067 private void StartScan(string filename, int title)
\r
2069 // Setup the GUI components for the scan.
\r
2070 sourcePath = filename;
\r
2072 this.DisableGUI();
\r
2077 SourceScan.Scan(sourcePath, title);
\r
2078 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
2079 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
2081 catch (Exception exc)
\r
2083 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2088 /// Update the Status label for the scan
\r
2090 /// <param name="sender">
\r
2093 /// <param name="e">
\r
2096 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
2098 UpdateScanStatusLabel();
\r
2102 /// Update the UI after the scan has completed
\r
2104 /// <param name="sender">
\r
2107 /// <param name="e">
\r
2110 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
2112 UpdateGuiAfterScan();
\r
2116 /// Update the Scan Status Label
\r
2118 private void UpdateScanStatusLabel()
\r
2120 if (InvokeRequired)
\r
2122 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
2125 labelSource.Text = SourceScan.ScanStatus;
\r
2129 /// Reset the GUI when the scan has completed
\r
2131 private void UpdateGuiAfterScan()
\r
2133 if (InvokeRequired)
\r
2135 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2141 currentSource = SourceScan.SouceData;
\r
2143 // Setup some GUI components
\r
2144 drp_dvdtitle.Items.Clear();
\r
2145 if (currentSource.Titles.Count != 0)
\r
2146 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2148 foreach (Title title in currentSource.Titles)
\r
2150 if (title.MainTitle)
\r
2152 drp_dvdtitle.SelectedItem = title;
\r
2156 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2158 drp_dvdtitle.SelectedIndex = 0;
\r
2161 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2162 if (drop_chapterStart.Items.Count > 0)
\r
2165 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2166 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2167 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2170 Check_ChapterMarkers.Enabled = false;
\r
2171 Check_ChapterMarkers.Checked = false;
\r
2172 data_chpt.Rows.Clear();
\r
2176 // If no titles were found, Display an error message
\r
2177 if (drp_dvdtitle.Items.Count == 0)
\r
2180 "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
2181 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2182 sourcePath = string.Empty;
\r
2184 UpdateSourceLabel();
\r
2186 // Enable the GUI components and enable any disabled components
\r
2189 catch (Exception exc)
\r
2191 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2192 MessageBoxIcon.Error);
\r
2198 /// Enable the GUI
\r
2200 private void EnableGUI()
\r
2204 if (InvokeRequired)
\r
2205 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2206 foreach (Control ctrl in Controls)
\r
2207 ctrl.Enabled = true;
\r
2208 btn_start.Enabled = true;
\r
2209 btn_showQueue.Enabled = true;
\r
2210 btn_add2Queue.Enabled = true;
\r
2211 tb_preview.Enabled = true;
\r
2212 btn_source.Enabled = true;
\r
2213 mnu_killCLI.Visible = false;
\r
2215 catch (Exception exc)
\r
2217 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2222 /// Disable the GUI
\r
2224 private void DisableGUI()
\r
2226 foreach (Control ctrl in Controls)
\r
2227 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2228 ctrl.Enabled = false;
\r
2230 labelSource.Enabled = true;
\r
2231 labelStaticSource.Enabled = true;
\r
2232 SourceLayoutPanel.Enabled = true;
\r
2233 btn_source.Enabled = false;
\r
2234 btn_start.Enabled = false;
\r
2235 btn_showQueue.Enabled = false;
\r
2236 btn_add2Queue.Enabled = false;
\r
2237 tb_preview.Enabled = false;
\r
2238 mnu_killCLI.Visible = true;
\r
2244 private void KillScan()
\r
2246 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2250 SourceScan.Stop();
\r
2252 labelSource.Text = "Scan Cancelled";
\r
2258 private void ResetGUI()
\r
2260 drp_dvdtitle.Items.Clear();
\r
2261 drop_chapterStart.Items.Clear();
\r
2262 drop_chapterFinish.Items.Clear();
\r
2263 lbl_duration.Text = "Select a Title";
\r
2264 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2265 sourcePath = String.Empty;
\r
2266 text_destination.Text = String.Empty;
\r
2267 selectedTitle = null;
\r
2271 /// Update the Source Label
\r
2273 private void UpdateSourceLabel()
\r
2275 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2279 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2281 /// <param name="job">
\r
2284 public void RecievingJob(Job job)
\r
2286 string query = job.Query;
\r
2287 StartScan(job.Source, job.Title);
\r
2289 if (query != null)
\r
2291 // Ok, Reset all the H264 widgets before changing the preset
\r
2292 x264Panel.Reset2Defaults();
\r
2294 // Send the query from the file to the Query Parser class
\r
2295 QueryParser presetQuery = QueryParser.Parse(query);
\r
2297 // Now load the preset
\r
2298 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2300 // The x264 widgets will need updated, so do this now:
\r
2301 x264Panel.StandardizeOptString();
\r
2302 x264Panel.SetCurrentSettingsInPanel();
\r
2304 // Finally, let this window have a copy of the preset settings.
\r
2305 this.currentlySelectedPreset = null;
\r
2306 PictureSettings.SetPresetCropWarningLabel(null);
\r
2312 #region GUI Functions and Actions
\r
2315 /// Set the GUI to it's finished encoding state.
\r
2317 private void SetEncodeFinished()
\r
2321 if (InvokeRequired)
\r
2323 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2327 lbl_encode.Text = "Encoding Finished";
\r
2328 ProgressBarStatus.Visible = false;
\r
2329 btn_start.Text = "Start";
\r
2330 btn_start.ToolTipText = "Start the encoding process";
\r
2331 btn_start.Image = Properties.Resources.Play;
\r
2333 // If the window is minimized, display the notification in a popup.
\r
2334 if (Properties.Settings.Default.trayIconAlerts)
\r
2335 if (FormWindowState.Minimized == this.WindowState)
\r
2337 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2338 notifyIcon.ShowBalloonTip(500);
\r
2341 catch (Exception exc)
\r
2343 MessageBox.Show(exc.ToString());
\r
2348 /// Set the GUI to it's started encoding state.
\r
2350 private void SetEncodeStarted()
\r
2354 if (InvokeRequired)
\r
2356 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2359 lbl_encode.Visible = true;
\r
2360 ProgressBarStatus.Value = 0;
\r
2361 ProgressBarStatus.Visible = true;
\r
2362 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2363 btn_start.Text = "Stop";
\r
2364 btn_start.ToolTipText = "Stop the encoding process.";
\r
2365 btn_start.Image = Properties.Resources.stop;
\r
2367 catch (Exception exc)
\r
2369 MessageBox.Show(exc.ToString());
\r
2374 /// Display the Encode Status
\r
2376 /// <param name="sender">
\r
2379 /// <param name="e">
\r
2382 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2384 if (this.InvokeRequired)
\r
2386 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2392 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2393 e.PercentComplete,
\r
2394 e.CurrentFrameRate,
\r
2395 e.AverageFrameRate,
\r
2396 e.EstimatedTimeLeft,
\r
2397 encodeQueue.Count);
\r
2399 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2403 /// Set the DVD Drive selection in the "Source" Menu
\r
2405 private void SetDriveSelectionMenuItem()
\r
2409 if (InvokeRequired)
\r
2411 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2415 drives = Main.GetDrives();
\r
2417 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2418 foreach (DriveInformation drive in drives)
\r
2420 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2422 Name = drive.ToString(),
\r
2423 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2424 Image = Resources.disc_small
\r
2426 menuItem.Click += new EventHandler(MnuDvdDriveClick);
\r
2427 menuItems.Add(menuItem);
\r
2430 foreach (ToolStripMenuItem item in menuItems)
\r
2431 btn_source.DropDownItems.Add(item);
\r
2433 catch (Exception exc)
\r
2435 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2440 /// Access the preset Handler and setup the preset panel.
\r
2442 private void LoadPresetPanel()
\r
2444 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2445 if (!Settings.Default.presetNotification)
\r
2446 MessageBox.Show(this,
\r
2447 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2448 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2450 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2451 treeView_presets.Update();
\r
2455 /// Get the title from the selected item in the title dropdown.
\r
2460 private int GetTitle()
\r
2463 if (drp_dvdtitle.SelectedItem != null)
\r
2465 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2466 int.TryParse(titleInfo[0], out title);
\r
2473 /// Handle the Update Check Finishing.
\r
2475 /// <param name="result">
\r
2478 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2480 // Make sure it's running on the calling thread
\r
2481 if (InvokeRequired)
\r
2483 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2486 UpdateCheckInformation info;
\r
2489 // Get the information about the new build, if any, and close the window
\r
2490 info = UpdateService.EndCheckForUpdates(result);
\r
2492 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2494 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
2495 updateWindow.ShowDialog();
\r
2498 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2499 MessageBoxIcon.Information);
\r
2500 lbl_updateCheck.Visible = false;
\r
2503 catch (Exception ex)
\r
2505 if ((bool)result.AsyncState)
\r
2507 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2508 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2517 /// Handle GUI shortcuts
\r
2519 /// <param name="msg">Message</param>
\r
2520 /// <param name="keyData">Keys</param>
\r
2521 /// <returns>Bool</returns>
\r
2522 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2524 if (keyData == (Keys.Control | Keys.S))
\r
2526 btn_start_Click(this, new EventArgs());
\r
2530 if (keyData == (Keys.Control | Keys.Shift | Keys.A))
\r
2532 btn_add2Queue_Click(this, new EventArgs());
\r
2535 return base.ProcessCmdKey(ref msg, keyData);
\r
2539 /// If the queue is being processed, prompt the user to confirm application close.
\r
2541 /// <param name="e">FormClosingEventArgs</param>
\r
2542 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2546 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2547 if (encodeQueue.IsEncoding)
\r
2549 DialogResult result =
\r
2551 "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
2552 "Close HandBrake?",
\r
2553 MessageBoxButtons.YesNo,
\r
2554 MessageBoxIcon.Question);
\r
2556 if (result == DialogResult.No)
\r
2562 encodeQueue.Stop();
\r
2565 if (SourceScan.IsScanning)
\r
2567 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2568 SourceScan.Stop();
\r
2571 catch (Exception exc)
\r
2573 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
2577 base.OnFormClosing(e);
\r
2583 // This is the END of the road ****************************************
\r