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.ApplicationServices.Functions;
\r
20 using HandBrake.ApplicationServices.Model;
\r
21 using HandBrake.ApplicationServices.Parsing;
\r
22 using HandBrake.ApplicationServices.Services;
\r
23 using HandBrake.ApplicationServices.Services.Interfaces;
\r
29 using Main = Handbrake.Functions.Main;
\r
34 public partial class frmMain : Form
\r
36 // Objects which may be used by one or more other objects *************
\r
37 private IQueue encodeQueue = new Queue();
\r
38 private PresetsHandler presetHandler = new PresetsHandler();
\r
40 // Windows ************************************************************
\r
41 private frmQueue queueWindow;
\r
42 private frmPreview qtpreview;
\r
43 private frmActivityWindow activityWindow;
\r
45 // Globals: Mainly used for tracking. *********************************
\r
46 public Title selectedTitle;
\r
47 public string sourcePath;
\r
48 private SourceType selectedSourceType;
\r
49 private string dvdDrivePath;
\r
50 private string dvdDriveLabel;
\r
51 private Preset currentlySelectedPreset;
\r
52 private DVD currentSource;
\r
53 private IScan SourceScan = new ScanService();
\r
54 private List<DriveInformation> drives;
\r
56 // Delegates **********************************************************
\r
57 private delegate void UpdateWindowHandler();
\r
59 // Applicaiton Startup ************************************************
\r
64 /// Gets SourceName.
\r
66 public string SourceName
\r
70 if (this.selectedSourceType == SourceType.DvdDrive)
\r
72 return this.dvdDriveLabel;
\r
75 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
76 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
78 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
84 #region Application Startup
\r
87 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
89 /// <param name="args">
\r
90 /// The arguments passed in on application startup.
\r
92 public frmMain(string[] args)
\r
94 InitializeComponent();
\r
96 // Update the users config file with the CLI version data.
\r
97 Main.SetCliVersionData();
\r
98 Main.CheckForValidCliVersion();
\r
100 if (Settings.Default.hb_version.Contains("svn"))
\r
102 this.Text += " " + Settings.Default.hb_version;
\r
105 // Check for new versions, if update checking is enabled
\r
106 if (Settings.Default.updateStatus)
\r
108 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
110 Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);
\r
114 // Clear the log files in the background
\r
115 if (Settings.Default.clearOldLogs)
\r
117 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
121 // Setup the GUI components
\r
122 LoadPresetPanel(); // Load the Preset Panel
\r
123 treeView_presets.ExpandAll();
\r
124 lbl_encode.Text = string.Empty;
\r
125 drop_mode.SelectedIndex = 0;
\r
126 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
127 if (!Settings.Default.QueryEditorTab)
\r
128 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
129 if (Settings.Default.tooltipEnable)
\r
130 ToolTip.Active = true;
\r
132 // Load the user's default settings or Normal Preset
\r
133 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
135 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
138 x264Panel.Reset2Defaults();
\r
140 QueryParser presetQuery = QueryParser.Parse(query);
\r
141 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
143 x264Panel.StandardizeOptString();
\r
144 x264Panel.SetCurrentSettingsInPanel();
\r
148 loadNormalPreset();
\r
150 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
151 GrowlCommunicator.Register();
\r
153 // Event Handlers and Queue Recovery
\r
155 Main.RecoverQueue(encodeQueue);
\r
157 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
158 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
160 this.StartScan(args[0], 0);
\r
165 /// When the update check is done, process the results.
\r
167 /// <param name="result">IAsyncResult result</param>
\r
168 private void UpdateCheckDone(IAsyncResult result)
\r
170 if (InvokeRequired)
\r
172 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
176 UpdateCheckInformation info;
\r
180 info = Main.EndCheckForUpdates(result);
\r
182 if (info.NewVersionAvailable)
\r
184 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
185 updateWindow.ShowDialog();
\r
188 catch (Exception ex)
\r
190 if ((bool)result.AsyncState)
\r
191 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
199 // Encoding Events for setting up the GUI
\r
200 private void events()
\r
202 // Handle Widget changes when preset is selected.
\r
203 RegisterPresetEventHandler();
\r
205 // Handle Window Resize
\r
206 if (Properties.Settings.Default.MainWindowMinimize)
\r
207 this.Resize += new EventHandler(frmMain_Resize);
\r
209 // Handle Encode Start / Finish / Pause
\r
210 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
211 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
213 // Handle a file being draged onto the GUI.
\r
214 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
215 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
218 // 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
219 private void RegisterPresetEventHandler()
\r
222 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
223 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
224 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
225 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
227 // Picture Settings
\r
228 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
231 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
234 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
235 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
236 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
237 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
238 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
239 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
242 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
245 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
248 private void UnRegisterPresetEventHandler()
\r
250 // Output Settings
\r
251 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
252 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
253 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
254 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
256 // Picture Settings
\r
257 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
260 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
263 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
264 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
265 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
266 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
267 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
268 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
271 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
274 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
277 private void changePresetLabel(object sender, EventArgs e)
\r
279 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
280 this.currentlySelectedPreset = null;
\r
283 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
285 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
286 e.Effect = DragDropEffects.All;
\r
289 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
291 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
292 sourcePath = string.Empty;
\r
294 if (fileList != null)
\r
296 if (!string.IsNullOrEmpty(fileList[0]))
\r
298 this.selectedSourceType = SourceType.VideoFile;
\r
299 StartScan(fileList[0], 0);
\r
302 UpdateSourceLabel();
\r
305 UpdateSourceLabel();
\r
308 private void encodeStarted(object sender, EventArgs e)
\r
310 SetEncodeStarted();
\r
311 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
314 private void encodeEnded(object sender, EventArgs e)
\r
316 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
317 SetEncodeFinished();
\r
321 // User Interface Menus / Tool Strips *********************************
\r
326 /// Kill The scan menu Item
\r
328 /// <param name="sender">
\r
331 /// <param name="e">
\r
334 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
340 /// Exit the Application Menu Item
\r
342 /// <param name="sender">
\r
345 /// <param name="e">
\r
348 private void mnu_exit_Click(object sender, EventArgs e)
\r
350 Application.Exit();
\r
358 /// Menu - Start Button
\r
360 /// <param name="sender">
\r
363 /// <param name="e">
\r
366 private void mnu_encode_Click(object sender, EventArgs e)
\r
368 queueWindow.Show();
\r
372 /// Menu - Display the Log Window
\r
374 /// <param name="sender">
\r
377 /// <param name="e">
\r
380 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
382 this.btn_ActivityWindow_Click(this, null);
\r
386 /// Menu - Display the Options Window
\r
388 /// <param name="sender">
\r
391 /// <param name="e">
\r
394 private void mnu_options_Click(object sender, EventArgs e)
\r
396 Form options = new frmOptions(this);
\r
397 options.ShowDialog();
\r
402 #region Presets Menu
\r
405 /// Reset the Built in Presets
\r
407 /// <param name="sender">
\r
410 /// <param name="e">
\r
413 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
415 presetHandler.UpdateBuiltInPresets();
\r
417 if (treeView_presets.Nodes.Count == 0)
\r
419 "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
420 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
422 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
424 treeView_presets.ExpandAll();
\r
428 /// Delete the selected preset
\r
430 /// <param name="sender">
\r
433 /// <param name="e">
\r
436 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
438 presetHandler.RemoveBuiltInPresets();
\r
439 LoadPresetPanel(); // Reload the preset panel
\r
443 /// Select the Normal preset
\r
445 /// <param name="sender">
\r
448 /// <param name="e">
\r
451 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
453 loadNormalPreset();
\r
457 /// Import a plist Preset
\r
459 /// <param name="sender">
\r
462 /// <param name="e">
\r
465 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
471 /// Export a Plist Preset
\r
473 /// <param name="sender">
\r
476 /// <param name="e">
\r
479 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
485 /// Create a new Preset
\r
487 /// <param name="sender">
\r
490 /// <param name="e">
\r
493 private void btn_new_preset_Click(object sender, EventArgs e)
\r
495 Form preset = new frmAddPreset(this, presetHandler);
\r
496 if (preset.ShowDialog() == DialogResult.OK)
\r
498 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
499 treeView_presets.Nodes.Add(presetTreeview);
\r
500 presetHandler.LastPresetAdded = null;
\r
509 /// Menu - Display the User Guide Web Page
\r
511 /// <param name="sender">
\r
514 /// <param name="e">
\r
517 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
519 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
523 /// Menu - Check for Updates
\r
525 /// <param name="sender">
\r
528 /// <param name="e">
\r
531 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
533 lbl_updateCheck.Visible = true;
\r
534 Main.BeginCheckForUpdates(new AsyncCallback(this.UpdateCheckDoneMenu), false);
\r
538 /// Menu - Display the About Window
\r
540 /// <param name="sender">
\r
543 /// <param name="e">
\r
546 private void mnu_about_Click(object sender, EventArgs e)
\r
548 using (frmAbout About = new frmAbout())
\r
550 About.ShowDialog();
\r
559 /// RMenu - Expand All
\r
561 /// <param name="sender">
\r
564 /// <param name="e">
\r
567 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
569 treeView_presets.ExpandAll();
\r
573 /// RMenu - Collaspe All
\r
575 /// <param name="sender">
\r
578 /// <param name="e">
\r
581 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
583 treeView_presets.CollapseAll();
\r
587 /// Menu - Import Preset
\r
589 /// <param name="sender">
\r
592 /// <param name="e">
\r
595 private void pmnu_import_Click(object sender, EventArgs e)
\r
601 /// RMenu - Save Changes to Preset
\r
603 /// <param name="sender">
\r
606 /// <param name="e">
\r
609 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
611 // TODO this requires a re-think since the Query Editor has changed.
\r
612 DialogResult result =
\r
614 "Do you wish to include picture settings when updating the preset: " +
\r
615 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
616 MessageBoxIcon.Question);
\r
617 if (result == DialogResult.Yes)
\r
618 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
619 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
620 else if (result == DialogResult.No)
\r
621 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
622 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
626 /// RMenu - Delete Preset
\r
628 /// <param name="sender">
\r
631 /// <param name="e">
\r
634 private void pmnu_delete_click(object sender, EventArgs e)
\r
636 if (treeView_presets.SelectedNode != null)
\r
638 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
639 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
641 treeView_presets.Select();
\r
645 /// Preset Menu Is Opening. Setup the Menu
\r
647 /// <param name="sender">
\r
650 /// <param name="e">
\r
653 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
655 // Make sure that the save menu is always disabled by default
\r
656 pmnu_saveChanges.Enabled = false;
\r
658 // Now enable the save menu if the selected preset is a user preset
\r
659 if (treeView_presets.SelectedNode != null)
\r
660 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
661 pmnu_saveChanges.Enabled = true;
\r
663 treeView_presets.Select();
\r
666 // Presets Management
\r
669 /// Button - Add a preset
\r
671 /// <param name="sender">
\r
674 /// <param name="e">
\r
677 private void btn_addPreset_Click(object sender, EventArgs e)
\r
679 Form preset = new frmAddPreset(this, presetHandler);
\r
680 if (preset.ShowDialog() == DialogResult.OK)
\r
682 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
683 treeView_presets.Nodes.Add(presetTreeview);
\r
684 presetHandler.LastPresetAdded = null;
\r
689 /// Button - remove a Preset
\r
691 /// <param name="sender">
\r
694 /// <param name="e">
\r
697 private void btn_removePreset_Click(object sender, EventArgs e)
\r
699 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
700 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
701 if (result == DialogResult.Yes)
\r
703 if (treeView_presets.SelectedNode != null)
\r
705 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
706 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
709 treeView_presets.Select();
\r
713 /// Button - Set the selected preset as the default
\r
715 /// <param name="sender">
\r
718 /// <param name="e">
\r
721 private void btn_setDefault_Click(object sender, EventArgs e)
\r
723 if (treeView_presets.SelectedNode != null)
\r
725 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
726 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
727 if (result == DialogResult.Yes)
\r
729 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
730 Properties.Settings.Default.Save();
\r
731 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
735 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
739 /// PresetBar Mouse Down event
\r
741 /// <param name="sender">
\r
744 /// <param name="e">
\r
747 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
749 if (e.Button == MouseButtons.Right)
\r
750 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
751 else if (e.Button == MouseButtons.Left)
\r
753 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
755 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
760 treeView_presets.Select();
\r
764 /// Preset Bar after selecting the preset
\r
766 /// <param name="sender">
\r
769 /// <param name="e">
\r
772 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
778 /// Preset Bar - Handle the Delete Key
\r
780 /// <param name="sender">
\r
783 /// <param name="e">
\r
786 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
788 if (e.KeyCode == Keys.Delete)
\r
790 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
791 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
792 if (result == DialogResult.Yes)
\r
794 if (treeView_presets.SelectedNode != null)
\r
795 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
797 // Remember each nodes expanded status so we can reload it
\r
798 List<bool> nodeStatus = new List<bool>();
\r
799 foreach (TreeNode node in treeView_presets.Nodes)
\r
800 nodeStatus.Add(node.IsExpanded);
\r
802 // Now reload the preset panel
\r
805 // And finally, re-expand any of the nodes if required
\r
807 foreach (TreeNode node in treeView_presets.Nodes)
\r
819 /// Select the selected preset and setup the GUI
\r
821 private void selectPreset()
\r
823 if (treeView_presets.SelectedNode != null)
\r
825 // Ok, so, we've selected a preset. Now we want to load it.
\r
826 string presetName = treeView_presets.SelectedNode.Text;
\r
827 Preset preset = presetHandler.GetPreset(presetName);
\r
828 if (preset != null)
\r
830 string query = presetHandler.GetPreset(presetName).Query;
\r
834 // Ok, Reset all the H264 widgets before changing the preset
\r
835 x264Panel.Reset2Defaults();
\r
837 // Send the query from the file to the Query Parser class
\r
838 QueryParser presetQuery = QueryParser.Parse(query);
\r
840 // Now load the preset
\r
841 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
843 // The x264 widgets will need updated, so do this now:
\r
844 x264Panel.StandardizeOptString();
\r
845 x264Panel.SetCurrentSettingsInPanel();
\r
847 // Finally, let this window have a copy of the preset settings.
\r
848 this.currentlySelectedPreset = preset;
\r
849 PictureSettings.SetPresetCropWarningLabel(preset);
\r
856 /// Load the Normal Preset
\r
858 private void loadNormalPreset()
\r
860 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
862 foreach (TreeNode node in treenode.Nodes)
\r
864 if (node.Text.Equals("Normal"))
\r
865 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
871 /// Import a plist preset
\r
873 private void ImportPreset()
\r
875 if (openPreset.ShowDialog() == DialogResult.OK)
\r
877 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
878 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
880 DialogResult result =
\r
881 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
882 "Overwrite preset?",
\r
883 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
884 if (result == DialogResult.Yes)
\r
886 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
887 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
888 QueryGenerator.GenerateFullQuery(this),
\r
889 parsed.UsesPictureSettings);
\r
894 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
895 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
896 QueryGenerator.GenerateFullQuery(this),
\r
897 parsed.UsesPictureSettings))
\r
899 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
901 ForeColor = Color.Black
\r
903 treeView_presets.Nodes.Add(preset_treeview);
\r
910 /// Export a plist Preset
\r
912 private void ExportPreset()
\r
914 MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
917 /*SaveFileDialog savefiledialog = new SaveFileDialog();
\r
918 savefiledialog.Filter = "plist|*.plist";
\r
920 if (treeView_presets.SelectedNode != null)
\r
923 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
925 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
926 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
936 /// 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
938 /// <param name="sender">
\r
941 /// <param name="e">
\r
944 private void btn_source_Click(object sender, EventArgs e)
\r
946 // Remove old Drive Menu Items.
\r
947 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
948 foreach (var item in btn_source.DropDownItems)
\r
950 if (item.GetType() == typeof(ToolStripMenuItem))
\r
952 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
953 if (menuItem.Name.StartsWith("Drive"))
\r
955 itemsToRemove.Add(menuItem);
\r
960 foreach (ToolStripMenuItem item in itemsToRemove)
\r
961 btn_source.DropDownItems.Remove(item);
\r
963 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
964 driveInfoThread.Start();
\r
968 /// Toolbar - Start The Encode
\r
970 /// <param name="sender">
\r
973 /// <param name="e">
\r
976 private void btn_start_Click(object sender, EventArgs e)
\r
978 if (btn_start.Text == "Stop")
\r
980 DialogResult result = !Properties.Settings.Default.showCliForInGuiEncodeStatus
\r
982 "Are you sure you wish to cancel the encode?\n\nPlease note: Stopping this encode will render the file unplayable. ",
\r
984 MessageBoxButtons.YesNo,
\r
985 MessageBoxIcon.Question)
\r
987 "Are you sure you wish to cancel the encode?",
\r
989 MessageBoxButtons.YesNo,
\r
990 MessageBoxIcon.Question);
\r
992 if (result == DialogResult.Yes)
\r
995 encodeQueue.Pause();
\r
997 if (Settings.Default.showCliForInGuiEncodeStatus)
\r
998 encodeQueue.SafelyClose();
\r
1000 encodeQueue.Stop();
\r
1005 // 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
1006 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1007 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1009 if (encodeQueue.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))
\r
1011 string generatedQuery = QueryGenerator.GenerateFullQuery(this);
\r
1012 string specifiedQuery = rtf_query.Text != string.Empty
\r
1014 : QueryGenerator.GenerateFullQuery(this);
\r
1015 string query = string.Empty;
\r
1017 // Check to make sure the generated query matches the GUI settings
\r
1018 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1019 generatedQuery != specifiedQuery)
\r
1021 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1022 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1023 "priority over the GUI, your recently updated settings will not be taken " +
\r
1024 "into account when encoding this job." +
\r
1025 Environment.NewLine + Environment.NewLine +
\r
1026 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1027 "Manual Query does not Match GUI",
\r
1028 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1029 MessageBoxDefaultButton.Button3);
\r
1033 case DialogResult.Yes:
\r
1034 // Replace the manual query with the generated one
\r
1035 query = generatedQuery;
\r
1036 rtf_query.Text = generatedQuery;
\r
1038 case DialogResult.No:
\r
1039 // Use the manual query
\r
1040 query = specifiedQuery;
\r
1042 case DialogResult.Cancel:
\r
1043 // Don't start the encode
\r
1049 query = specifiedQuery;
\r
1052 DialogResult overwrite = DialogResult.Yes;
\r
1053 if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))
\r
1055 overwrite = MessageBox.Show(
\r
1056 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1057 "Overwrite File?",
\r
1058 MessageBoxButtons.YesNo,
\r
1059 MessageBoxIcon.Question);
\r
1062 if (overwrite == DialogResult.Yes)
\r
1064 if (encodeQueue.Count == 0)
\r
1065 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1067 queueWindow.SetQueue();
\r
1068 if (encodeQueue.Count > 1)
\r
1069 queueWindow.Show(false);
\r
1071 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1072 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1077 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1078 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1079 MessageBoxIcon.Warning);
\r
1084 /// Toolbar - Add the current job to the Queue
\r
1086 /// <param name="sender">
\r
1089 /// <param name="e">
\r
1092 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1094 // Get the CLI query or use the query editor if it's not empty.
\r
1095 string query = QueryGenerator.GenerateFullQuery(this);
\r
1096 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1097 query = rtf_query.Text;
\r
1099 // 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
1100 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1101 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1103 // Make sure we have a Source and Destination.
\r
1104 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1106 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1110 // Make sure the destination path exists.
\r
1111 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1113 MessageBox.Show("Destination Path does not exist.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1117 // Make sure we don't have a duplciate on the queue.
\r
1118 if (encodeQueue.CheckForDestinationDuplicate(jobDestination))
\r
1120 DialogResult result =
\r
1122 "There is already a queue item for this destination path. \n\n If you continue, the encode will be overwritten. Do you wish to continue?",
\r
1123 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
1124 if (result == DialogResult.Yes)
\r
1125 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1128 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1130 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1132 queueWindow.Show();
\r
1136 /// Toolbar - Show the Queue
\r
1138 /// <param name="sender">
\r
1141 /// <param name="e">
\r
1144 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1146 queueWindow.Show();
\r
1147 queueWindow.Activate();
\r
1151 /// Toolbar - Show the Preview Window
\r
1153 /// <param name="sender">
\r
1156 /// <param name="e">
\r
1159 private void tb_preview_Click(object sender, EventArgs e)
\r
1161 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1162 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1163 MessageBoxIcon.Warning);
\r
1166 if (qtpreview == null)
\r
1168 qtpreview = new frmPreview(this);
\r
1171 else if (qtpreview.IsDisposed)
\r
1173 qtpreview = new frmPreview(this);
\r
1177 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1178 MessageBoxIcon.Warning);
\r
1183 /// Toolbar - Show the Activity log Window
\r
1185 /// <param name="sender">
\r
1188 /// <param name="e">
\r
1191 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1193 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1194 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1196 this.activityWindow.Show();
\r
1197 this.activityWindow.Activate();
\r
1202 #region System Tray Icon
\r
1205 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1207 /// <param name="sender">
\r
1210 /// <param name="e">
\r
1213 private void frmMain_Resize(object sender, EventArgs e)
\r
1215 if (FormWindowState.Minimized == this.WindowState)
\r
1217 notifyIcon.Visible = true;
\r
1220 else if (FormWindowState.Normal == this.WindowState)
\r
1221 notifyIcon.Visible = false;
\r
1225 /// Double Click the Tray Icon
\r
1227 /// <param name="sender">
\r
1230 /// <param name="e">
\r
1233 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1235 this.Visible = true;
\r
1237 this.WindowState = FormWindowState.Normal;
\r
1238 notifyIcon.Visible = false;
\r
1242 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1244 /// <param name="sender">
\r
1247 /// <param name="e">
\r
1250 private void btn_restore_Click(object sender, EventArgs e)
\r
1252 this.Visible = true;
\r
1254 this.WindowState = FormWindowState.Normal;
\r
1255 notifyIcon.Visible = false;
\r
1260 #region Main Window and Tab Control
\r
1263 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
1265 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1267 this.selectedSourceType = SourceType.Folder;
\r
1268 SelectSource(DVD_Open.SelectedPath);
\r
1271 UpdateSourceLabel();
\r
1274 private void btn_file_source_Click(object sender, EventArgs e)
\r
1276 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1278 this.selectedSourceType = SourceType.VideoFile;
\r
1279 SelectSource(ISO_Open.FileName);
\r
1282 UpdateSourceLabel();
\r
1285 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
1287 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1290 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1292 if (int.TryParse(driveId, out id))
\r
1294 this.dvdDrivePath = drives[id].RootDirectory;
\r
1295 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1297 if (this.dvdDrivePath == null) return;
\r
1298 this.selectedSourceType = SourceType.DvdDrive;
\r
1299 SelectSource(this.dvdDrivePath);
\r
1304 private void SelectSource(string file)
\r
1306 Check_ChapterMarkers.Enabled = true;
\r
1307 sourcePath = string.Empty;
\r
1309 if (file == string.Empty) // Must have a file or path
\r
1311 UpdateSourceLabel();
\r
1315 sourcePath = Path.GetFileName(file);
\r
1316 StartScan(file, 0);
\r
1319 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1321 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1323 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1324 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1327 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1329 UnRegisterPresetEventHandler();
\r
1330 drop_mode.SelectedIndex = 0;
\r
1332 drop_chapterStart.Items.Clear();
\r
1333 drop_chapterFinish.Items.Clear();
\r
1335 // If the dropdown is set to automatic nothing else needs to be done.
\r
1336 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1337 if (drp_dvdtitle.Text != "Automatic")
\r
1339 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1340 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1341 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1342 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1344 // Populate the Angles dropdown
\r
1345 drop_angle.Items.Clear();
\r
1346 if (!Properties.Settings.Default.noDvdNav)
\r
1348 drop_angle.Visible = true;
\r
1349 lbl_angle.Visible = true;
\r
1351 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1352 drop_angle.Items.Add(i.ToString());
\r
1354 if (drop_angle.Items.Count != 0)
\r
1355 drop_angle.SelectedIndex = 0;
\r
1359 drop_angle.Visible = false;
\r
1360 lbl_angle.Visible = false;
\r
1363 // Populate the Start chapter Dropdown
\r
1364 drop_chapterStart.Items.Clear();
\r
1365 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1366 if (drop_chapterStart.Items.Count > 0)
\r
1367 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1369 // Populate the Final Chapter Dropdown
\r
1370 drop_chapterFinish.Items.Clear();
\r
1371 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1372 if (drop_chapterFinish.Items.Count > 0)
\r
1373 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1375 // Populate the Audio Channels Dropdown
\r
1376 AudioSettings.SetTrackList(selectedTitle, this.currentlySelectedPreset);
\r
1378 // Populate the Subtitles dropdown
\r
1379 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1381 // Update the source label if we have multiple streams
\r
1382 if (selectedTitle != null)
\r
1383 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1384 labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1386 // Run the AutoName & ChapterNaming functions
\r
1387 if (Properties.Settings.Default.autoNaming)
\r
1389 string autoPath = Main.AutoName(this);
\r
1390 if (autoPath != null)
\r
1391 text_destination.Text = autoPath;
\r
1394 "You currently have \"Automatically name output files\" enabled for the destination file box, but you do not have a default directory set.\n\nYou should set a \"Default Path\" in HandBrakes preferences. (See 'Tools' menu -> 'Options' -> 'General' Tab -> 'Default Path')",
\r
1395 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1398 data_chpt.Rows.Clear();
\r
1399 if (selectedTitle.Chapters.Count != 1)
\r
1401 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1402 if (chapterGridView != null)
\r
1403 data_chpt = chapterGridView;
\r
1407 Check_ChapterMarkers.Checked = false;
\r
1408 Check_ChapterMarkers.Enabled = false;
\r
1411 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1412 data_chpt.Columns[0].Width = 166;
\r
1413 data_chpt.Columns[0].Width = 165;
\r
1415 RegisterPresetEventHandler();
\r
1418 private void chapersChanged(object sender, EventArgs e)
\r
1420 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1423 Control ctl = (Control)sender;
\r
1424 int chapterStart, chapterEnd;
\r
1425 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1426 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1430 case "drop_chapterStart":
\r
1431 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1432 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1434 if (chapterEnd != 0)
\r
1435 if (chapterStart > chapterEnd)
\r
1436 drop_chapterFinish.Text = chapterStart.ToString();
\r
1438 case "drop_chapterFinish":
\r
1439 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1440 drop_chapterStart.SelectedIndex = 0;
\r
1442 if (chapterStart != 0)
\r
1443 if (chapterEnd < chapterStart)
\r
1444 drop_chapterFinish.Text = chapterStart.ToString();
\r
1446 // Add more rows to the Chapter menu if needed.
\r
1447 if (Check_ChapterMarkers.Checked)
\r
1449 int i = data_chpt.Rows.Count, finish = 0;
\r
1450 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1452 while (i < finish)
\r
1454 int n = data_chpt.Rows.Add();
\r
1455 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1456 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1457 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1458 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1465 // Update the Duration
\r
1466 lbl_duration.Text =
\r
1467 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1470 // Run the Autonaming function
\r
1471 if (Properties.Settings.Default.autoNaming)
\r
1472 text_destination.Text = Main.AutoName(this);
\r
1474 // Disable chapter markers if only 1 chapter is selected.
\r
1475 if (chapterStart == chapterEnd)
\r
1477 Check_ChapterMarkers.Enabled = false;
\r
1478 btn_importChapters.Enabled = false;
\r
1479 data_chpt.Enabled = false;
\r
1483 Check_ChapterMarkers.Enabled = true;
\r
1484 if (Check_ChapterMarkers.Checked)
\r
1486 btn_importChapters.Enabled = true;
\r
1487 data_chpt.Enabled = true;
\r
1492 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1495 int.TryParse(drop_chapterStart.Text, out start);
\r
1496 int.TryParse(drop_chapterFinish.Text, out end);
\r
1497 double duration = end - start;
\r
1499 switch (drop_mode.SelectedIndex)
\r
1502 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1505 if (selectedTitle != null)
\r
1507 duration = duration / selectedTitle.Fps;
\r
1508 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1511 lbl_duration.Text = "--:--:--";
\r
1517 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1520 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1521 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1524 switch (drop_mode.SelectedIndex)
\r
1527 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1528 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1529 if (drop_chapterStart.Items.Count != 0)
\r
1531 drop_chapterStart.SelectedIndex = 0;
\r
1532 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1535 lbl_duration.Text = "--:--:--";
\r
1538 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1539 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1540 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1541 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1542 if (selectedTitle != null)
\r
1544 drop_chapterStart.Text = "0";
\r
1545 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1549 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1550 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1551 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1552 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1553 if (selectedTitle != null)
\r
1555 drop_chapterStart.Text = "0";
\r
1556 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1563 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1565 // This removes the file extension from the filename box on the save file dialog.
\r
1566 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1567 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1569 if (Path.IsPathRooted(text_destination.Text))
\r
1570 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1572 // Show the dialog and set the main form file path
\r
1573 if (drop_format.SelectedIndex.Equals(0))
\r
1574 DVD_Save.FilterIndex = 1;
\r
1575 else if (drop_format.SelectedIndex.Equals(1))
\r
1576 DVD_Save.FilterIndex = 2;
\r
1578 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1580 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1581 switch (DVD_Save.FilterIndex)
\r
1585 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1586 StringComparison.InvariantCultureIgnoreCase))
\r
1587 if (Properties.Settings.Default.useM4v)
\r
1588 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1590 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1594 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1595 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1601 text_destination.Text = DVD_Save.FileName;
\r
1603 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1604 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1605 SetExtension(".m4v");
\r
1609 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1611 string path = text_destination.Text;
\r
1612 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1613 drop_format.SelectedIndex = 0;
\r
1614 else if (path.EndsWith(".mkv"))
\r
1615 drop_format.SelectedIndex = 1;
\r
1618 // Output Settings
\r
1619 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1621 switch (drop_format.SelectedIndex)
\r
1624 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1625 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1626 SetExtension(".m4v");
\r
1628 SetExtension(".mp4");
\r
1631 SetExtension(".mkv");
\r
1635 AudioSettings.SetContainer(drop_format.Text);
\r
1637 if (drop_format.Text.Contains("MP4"))
\r
1639 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1641 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1642 drp_videoEncoder.SelectedIndex = 1;
\r
1645 else if (drop_format.Text.Contains("MKV"))
\r
1646 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1649 public void SetExtension(string newExtension)
\r
1651 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1652 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1653 Subtitles.RequiresM4V())
\r
1654 newExtension = ".m4v";
\r
1656 newExtension = ".mp4";
\r
1658 if (Path.HasExtension(newExtension))
\r
1659 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1663 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1665 setContainerOpts();
\r
1667 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1668 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1670 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1671 check_turbo.Enabled = true;
\r
1673 tab_advanced.Enabled = true;
\r
1674 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1675 check_iPodAtom.Enabled = true;
\r
1677 check_iPodAtom.Enabled = false;
\r
1681 check_turbo.CheckState = CheckState.Unchecked;
\r
1682 check_turbo.Enabled = false;
\r
1683 tab_advanced.Enabled = false;
\r
1684 x264Panel.X264Query = string.Empty;
\r
1685 check_iPodAtom.Enabled = false;
\r
1686 check_iPodAtom.Checked = false;
\r
1689 // Setup the CQ Slider
\r
1690 switch (drp_videoEncoder.Text)
\r
1692 case "MPEG-4 (FFmpeg)":
\r
1693 if (slider_videoQuality.Value > 31)
\r
1694 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1695 slider_videoQuality.Minimum = 1;
\r
1696 slider_videoQuality.Maximum = 31;
\r
1698 case "H.264 (x264)":
\r
1699 slider_videoQuality.Minimum = 0;
\r
1700 slider_videoQuality.TickFrequency = 1;
\r
1702 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1703 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1704 double multiplier = 1.0 / cqStep;
\r
1705 double value = slider_videoQuality.Value * multiplier;
\r
1707 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1709 if (value < slider_videoQuality.Maximum)
\r
1710 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1713 case "VP3 (Theora)":
\r
1714 if (slider_videoQuality.Value > 63)
\r
1715 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1716 slider_videoQuality.Minimum = 0;
\r
1717 slider_videoQuality.Maximum = 63;
\r
1723 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1725 /// <param name="sender">
\r
1728 /// <param name="e">
\r
1731 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1733 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1735 this.checkMaximumFramerate.Visible = false;
\r
1736 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1740 this.checkMaximumFramerate.Visible = true;
\r
1745 /// Set the container format options
\r
1747 public void setContainerOpts()
\r
1749 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1751 check_largeFile.Enabled = true;
\r
1752 check_optimiseMP4.Enabled = true;
\r
1753 check_iPodAtom.Enabled = true;
\r
1757 check_largeFile.Enabled = false;
\r
1758 check_optimiseMP4.Enabled = false;
\r
1759 check_iPodAtom.Enabled = false;
\r
1760 check_largeFile.Checked = false;
\r
1761 check_optimiseMP4.Checked = false;
\r
1762 check_iPodAtom.Checked = false;
\r
1766 private double cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1769 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1771 public void setQualityFromSlider()
\r
1773 // Work out the current RF value.
\r
1774 double cqStep = this.cachedCqStep;
\r
1775 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1777 // Change the maximum value for the slider
\r
1778 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1780 // Reset the CQ slider to RF0
\r
1781 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1783 // Reset the CQ slider back to the previous value as close as possible
\r
1784 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1785 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1786 while (rfValueCurrent < rfValue)
\r
1788 slider_videoQuality.Value--;
\r
1789 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1792 // Cache the CQ step for the next calculation
\r
1793 this.cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1796 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1798 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1799 switch (drp_videoEncoder.Text)
\r
1801 case "MPEG-4 (FFmpeg)":
\r
1802 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1804 case "H.264 (x264)":
\r
1805 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1806 rfValue = Math.Round(rfValue, 2);
\r
1807 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1809 case "VP3 (Theora)":
\r
1810 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1815 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1817 text_bitrate.Enabled = false;
\r
1818 text_filesize.Enabled = true;
\r
1819 slider_videoQuality.Enabled = false;
\r
1821 check_2PassEncode.Enabled = true;
\r
1824 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1826 text_bitrate.Enabled = true;
\r
1827 text_filesize.Enabled = false;
\r
1828 slider_videoQuality.Enabled = false;
\r
1830 check_2PassEncode.Enabled = true;
\r
1833 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1835 text_bitrate.Enabled = false;
\r
1836 text_filesize.Enabled = false;
\r
1837 slider_videoQuality.Enabled = true;
\r
1839 check_2PassEncode.Enabled = false;
\r
1840 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1843 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1845 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1847 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1848 check_turbo.Enabled = true;
\r
1852 check_turbo.Enabled = false;
\r
1853 check_turbo.CheckState = CheckState.Unchecked;
\r
1857 // Chapter Marker Tab
\r
1858 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1860 if (Check_ChapterMarkers.Checked)
\r
1862 if (drop_format.SelectedIndex != 1)
\r
1863 SetExtension(".m4v");
\r
1864 data_chpt.Enabled = true;
\r
1865 btn_importChapters.Enabled = true;
\r
1869 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
1870 SetExtension(".mp4");
\r
1871 data_chpt.Enabled = false;
\r
1872 btn_importChapters.Enabled = false;
\r
1876 private void btn_importChapters_Click(object sender, EventArgs e)
\r
1878 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
1880 string filename = File_ChapterImport.FileName;
\r
1881 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
1882 if (imported != null)
\r
1883 data_chpt = imported;
\r
1887 private void btn_export_Click(object sender, EventArgs e)
\r
1889 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
1890 saveFileDialog.Filter = "Csv File|*.csv";
\r
1891 saveFileDialog.DefaultExt = "csv";
\r
1892 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
1894 string filename = saveFileDialog.FileName;
\r
1896 Main.SaveChapterMarkersToCsv(this, filename);
\r
1900 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
1902 data_chpt.Rows.Clear();
\r
1903 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1904 if (chapterGridView != null)
\r
1906 data_chpt = chapterGridView;
\r
1910 // Query Editor Tab
\r
1911 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1913 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
1916 private void btn_clear_Click(object sender, EventArgs e)
\r
1918 rtf_query.Clear();
\r
1923 // MainWindow Components, Actions and Functions ***********************
\r
1925 #region Source Scan
\r
1928 /// Start the Scan Process
\r
1930 /// <param name="filename">
\r
1933 /// <param name="title">
\r
1936 private void StartScan(string filename, int title)
\r
1938 // Setup the GUI components for the scan.
\r
1939 sourcePath = filename;
\r
1941 this.DisableGUI();
\r
1946 SourceScan.Scan(sourcePath, title);
\r
1947 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
1948 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
1950 catch (Exception exc)
\r
1952 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1957 /// Update the Status label for the scan
\r
1959 /// <param name="sender">
\r
1962 /// <param name="e">
\r
1965 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
1967 UpdateScanStatusLabel();
\r
1971 /// Update the UI after the scan has completed
\r
1973 /// <param name="sender">
\r
1976 /// <param name="e">
\r
1979 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
1981 UpdateGuiAfterScan();
\r
1985 /// Update the Scan Status Label
\r
1987 private void UpdateScanStatusLabel()
\r
1989 if (InvokeRequired)
\r
1991 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
1994 lbl_encode.Text = SourceScan.ScanStatus;
\r
1998 /// Reset the GUI when the scan has completed
\r
2000 private void UpdateGuiAfterScan()
\r
2002 if (InvokeRequired)
\r
2004 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2010 currentSource = SourceScan.SouceData;
\r
2012 // Setup some GUI components
\r
2013 drp_dvdtitle.Items.Clear();
\r
2014 if (currentSource.Titles.Count != 0)
\r
2015 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2017 foreach (Title title in currentSource.Titles)
\r
2019 if (title.MainTitle)
\r
2021 drp_dvdtitle.SelectedItem = title;
\r
2025 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2027 drp_dvdtitle.SelectedIndex = 0;
\r
2030 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2031 if (drop_chapterStart.Items.Count > 0)
\r
2034 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2035 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2036 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2039 Check_ChapterMarkers.Enabled = false;
\r
2040 Check_ChapterMarkers.Checked = false;
\r
2041 data_chpt.Rows.Clear();
\r
2045 // If no titles were found, Display an error message
\r
2046 if (drp_dvdtitle.Items.Count == 0)
\r
2049 "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
2050 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2051 sourcePath = string.Empty;
\r
2053 UpdateSourceLabel();
\r
2055 // Enable the GUI components and enable any disabled components
\r
2058 catch (Exception exc)
\r
2060 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2061 MessageBoxIcon.Error);
\r
2067 /// Enable the GUI
\r
2069 private void EnableGUI()
\r
2073 if (InvokeRequired)
\r
2074 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2075 lbl_encode.Text = "Scan Completed";
\r
2076 foreach (Control ctrl in Controls)
\r
2077 ctrl.Enabled = true;
\r
2078 btn_start.Enabled = true;
\r
2079 btn_showQueue.Enabled = true;
\r
2080 btn_add2Queue.Enabled = true;
\r
2081 tb_preview.Enabled = true;
\r
2082 btn_source.Enabled = true;
\r
2083 mnu_killCLI.Visible = false;
\r
2085 catch (Exception exc)
\r
2087 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2092 /// Disable the GUI
\r
2094 private void DisableGUI()
\r
2096 foreach (Control ctrl in Controls)
\r
2097 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2098 ctrl.Enabled = false;
\r
2100 lbl_encode.Visible = true;
\r
2101 lbl_encode.Text = "Scanning ...";
\r
2102 btn_source.Enabled = false;
\r
2103 btn_start.Enabled = false;
\r
2104 btn_showQueue.Enabled = false;
\r
2105 btn_add2Queue.Enabled = false;
\r
2106 tb_preview.Enabled = false;
\r
2107 mnu_killCLI.Visible = true;
\r
2113 private void KillScan()
\r
2115 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2119 SourceScan.Stop();
\r
2121 lbl_encode.Text = "Scan Cancelled!";
\r
2127 private void ResetGUI()
\r
2129 drp_dvdtitle.Items.Clear();
\r
2130 drop_chapterStart.Items.Clear();
\r
2131 drop_chapterFinish.Items.Clear();
\r
2132 lbl_duration.Text = "Select a Title";
\r
2133 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2134 sourcePath = String.Empty;
\r
2135 text_destination.Text = String.Empty;
\r
2136 selectedTitle = null;
\r
2140 /// Update the Source Label
\r
2142 private void UpdateSourceLabel()
\r
2144 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2146 if (selectedTitle != null)
\r
2147 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
2148 // If it's one of multiple source files, make sure we don't use the folder name
\r
2149 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
2153 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2155 /// <param name="job">
\r
2158 public void RecievingJob(Job job)
\r
2160 string query = job.Query;
\r
2161 StartScan(job.Source, job.Title);
\r
2163 if (query != null)
\r
2165 // Ok, Reset all the H264 widgets before changing the preset
\r
2166 x264Panel.Reset2Defaults();
\r
2168 // Send the query from the file to the Query Parser class
\r
2169 QueryParser presetQuery = QueryParser.Parse(query);
\r
2171 // Now load the preset
\r
2172 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2174 // The x264 widgets will need updated, so do this now:
\r
2175 x264Panel.StandardizeOptString();
\r
2176 x264Panel.SetCurrentSettingsInPanel();
\r
2178 // Finally, let this window have a copy of the preset settings.
\r
2179 this.currentlySelectedPreset = null;
\r
2180 PictureSettings.SetPresetCropWarningLabel(null);
\r
2186 #region GUI Functions and Actions
\r
2189 /// Set the GUI to it's finished encoding state.
\r
2191 private void SetEncodeFinished()
\r
2195 if (InvokeRequired)
\r
2197 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2201 lbl_encode.Text = "Encoding Finished";
\r
2202 ProgressBarStatus.Visible = false;
\r
2203 btn_start.Text = "Start";
\r
2204 btn_start.ToolTipText = "Start the encoding process";
\r
2205 btn_start.Image = Properties.Resources.Play;
\r
2207 // If the window is minimized, display the notification in a popup.
\r
2208 if (Properties.Settings.Default.trayIconAlerts)
\r
2209 if (FormWindowState.Minimized == this.WindowState)
\r
2211 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2212 notifyIcon.ShowBalloonTip(500);
\r
2215 catch (Exception exc)
\r
2217 MessageBox.Show(exc.ToString());
\r
2222 /// Set the GUI to it's started encoding state.
\r
2224 private void SetEncodeStarted()
\r
2228 if (InvokeRequired)
\r
2230 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2233 lbl_encode.Visible = true;
\r
2234 ProgressBarStatus.Value = 0;
\r
2235 ProgressBarStatus.Visible = true;
\r
2236 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2237 btn_start.Text = "Stop";
\r
2238 btn_start.ToolTipText = "Stop the encoding process.";
\r
2239 btn_start.Image = Properties.Resources.stop;
\r
2241 catch (Exception exc)
\r
2243 MessageBox.Show(exc.ToString());
\r
2248 /// Display the Encode Status
\r
2250 /// <param name="sender">
\r
2253 /// <param name="e">
\r
2256 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2258 if (this.InvokeRequired)
\r
2260 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2266 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2267 e.PercentComplete,
\r
2268 e.CurrentFrameRate,
\r
2269 e.AverageFrameRate,
\r
2270 e.EstimatedTimeLeft,
\r
2271 encodeQueue.Count);
\r
2273 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2277 /// Set the DVD Drive selection in the "Source" Menu
\r
2279 private void SetDriveSelectionMenuItem()
\r
2283 if (InvokeRequired)
\r
2285 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2289 drives = Main.GetDrives();
\r
2291 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2292 foreach (DriveInformation drive in drives)
\r
2294 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2296 Name = drive.ToString(),
\r
2297 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2298 Image = Resources.disc_small
\r
2300 menuItem.Click += new EventHandler(mnu_dvd_drive_Click);
\r
2301 menuItems.Add(menuItem);
\r
2304 foreach (ToolStripMenuItem item in menuItems)
\r
2305 btn_source.DropDownItems.Add(item);
\r
2307 catch (Exception exc)
\r
2309 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2314 /// Access the preset Handler and setup the preset panel.
\r
2316 private void LoadPresetPanel()
\r
2318 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2319 if (!Settings.Default.presetNotification)
\r
2320 MessageBox.Show(this,
\r
2321 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2322 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2324 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2325 treeView_presets.Update();
\r
2329 /// Get the title from the selected item in the title dropdown.
\r
2334 private int GetTitle()
\r
2337 if (drp_dvdtitle.SelectedItem != null)
\r
2339 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2340 int.TryParse(titleInfo[0], out title);
\r
2347 /// Handle the Update Check Finishing.
\r
2349 /// <param name="result">
\r
2352 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2354 // Make sure it's running on the calling thread
\r
2355 if (InvokeRequired)
\r
2357 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2360 UpdateCheckInformation info;
\r
2363 // Get the information about the new build, if any, and close the window
\r
2364 info = Main.EndCheckForUpdates(result);
\r
2366 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2368 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
2369 updateWindow.ShowDialog();
\r
2372 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2373 MessageBoxIcon.Information);
\r
2374 lbl_updateCheck.Visible = false;
\r
2377 catch (Exception ex)
\r
2379 if ((bool)result.AsyncState)
\r
2381 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2382 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2391 /// Handle GUI shortcuts
\r
2393 /// <param name="msg">Message</param>
\r
2394 /// <param name="keyData">Keys</param>
\r
2395 /// <returns>Bool</returns>
\r
2396 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2398 if (keyData == (Keys.Control | Keys.S))
\r
2400 btn_start_Click(this, new EventArgs());
\r
2404 if (keyData == (Keys.Control | Keys.A))
\r
2406 btn_add2Queue_Click(this, new EventArgs());
\r
2409 return base.ProcessCmdKey(ref msg, keyData);
\r
2413 /// If the queue is being processed, prompt the user to confirm application close.
\r
2415 /// <param name="e">FormClosingEventArgs</param>
\r
2416 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2420 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2421 if (encodeQueue.IsEncoding)
\r
2423 DialogResult result =
\r
2425 "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
2426 "Close HandBrake?",
\r
2427 MessageBoxButtons.YesNo,
\r
2428 MessageBoxIcon.Question);
\r
2430 if (result == DialogResult.No)
\r
2436 encodeQueue.Stop();
\r
2439 if (SourceScan.IsScanning)
\r
2441 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2442 SourceScan.Stop();
\r
2445 catch (Exception exc)
\r
2447 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
2451 base.OnFormClosing(e);
\r
2457 // This is the END of the road ****************************************
\r