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.Reflection;
\r
16 using System.Threading;
\r
17 using System.Windows.Forms;
\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 public partial class frmMain : Form
\r
31 // Objects which may be used by one or more other objects *************
\r
32 private IQueue encodeQueue = new Queue();
\r
33 private PresetsHandler presetHandler = new PresetsHandler();
\r
35 // Windows ************************************************************
\r
36 private frmQueue queueWindow;
\r
37 private frmPreview qtpreview;
\r
38 private frmActivityWindow activityWindow;
\r
40 // Globals: Mainly used for tracking. *********************************
\r
41 public Title selectedTitle;
\r
42 public string sourcePath;
\r
43 private SourceType selectedSourceType;
\r
44 private string dvdDrivePath;
\r
45 private string dvdDriveLabel;
\r
46 private Preset currentlySelectedPreset;
\r
47 private DVD currentSource;
\r
48 private IScan SourceScan = new ScanService();
\r
49 private List<DriveInformation> drives;
\r
51 // Delegates **********************************************************
\r
52 private delegate void UpdateWindowHandler();
\r
54 // Applicaiton Startup ************************************************
\r
59 /// Gets SourceName.
\r
61 public string SourceName
\r
65 if (this.selectedSourceType == SourceType.DvdDrive)
\r
67 return this.dvdDriveLabel;
\r
70 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
71 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
73 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
79 #region Application Startup
\r
82 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
84 /// <param name="args">
\r
85 /// The arguments passed in on application startup.
\r
87 public frmMain(string[] args)
\r
89 InitializeComponent();
\r
91 // Update the users config file with the CLI version data.
\r
92 Main.SetCliVersionData();
\r
93 Main.CheckForValidCliVersion();
\r
95 if (Settings.Default.hb_version.Contains("svn"))
\r
97 Version v = Assembly.GetExecutingAssembly().GetName().Version;
\r
98 this.Text += " " + v.ToString(4);
\r
101 // Check for new versions, if update checking is enabled
\r
102 if (Settings.Default.updateStatus)
\r
104 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
106 Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);
\r
110 // Clear the log files in the background
\r
111 if (Settings.Default.clearOldLogs)
\r
113 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
117 // Setup the GUI components
\r
118 LoadPresetPanel(); // Load the Preset Panel
\r
119 treeView_presets.ExpandAll();
\r
120 lbl_encode.Text = string.Empty;
\r
121 drop_mode.SelectedIndex = 0;
\r
122 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
123 if (!Settings.Default.QueryEditorTab)
\r
124 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
125 if (Settings.Default.tooltipEnable)
\r
126 ToolTip.Active = true;
\r
128 // Load the user's default settings or Normal Preset
\r
129 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
131 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
134 x264Panel.Reset2Defaults();
\r
136 QueryParser presetQuery = QueryParser.Parse(query);
\r
137 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
139 x264Panel.StandardizeOptString();
\r
140 x264Panel.SetCurrentSettingsInPanel();
\r
144 loadNormalPreset();
\r
146 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
147 GrowlCommunicator.Register();
\r
149 // Event Handlers and Queue Recovery
\r
151 Main.RecoverQueue(encodeQueue);
\r
153 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
154 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
156 this.StartScan(args[0], 0);
\r
161 /// When the update check is done, process the results.
\r
163 /// <param name="result">IAsyncResult result</param>
\r
164 private void UpdateCheckDone(IAsyncResult result)
\r
166 if (InvokeRequired)
\r
168 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
172 UpdateCheckInformation info;
\r
176 info = Main.EndCheckForUpdates(result);
\r
178 if (info.NewVersionAvailable)
\r
180 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
181 updateWindow.ShowDialog();
\r
184 catch (Exception ex)
\r
186 if ((bool)result.AsyncState)
\r
187 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
195 // Encoding Events for setting up the GUI
\r
196 private void events()
\r
198 // Handle Widget changes when preset is selected.
\r
199 RegisterPresetEventHandler();
\r
201 // Handle Window Resize
\r
202 if (Properties.Settings.Default.MainWindowMinimize)
\r
203 this.Resize += new EventHandler(frmMain_Resize);
\r
205 // Handle Encode Start / Finish / Pause
\r
206 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
207 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
209 // Handle a file being draged onto the GUI.
\r
210 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
211 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
214 // 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
215 private void RegisterPresetEventHandler()
\r
218 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
219 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
220 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
221 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
223 // Picture Settings
\r
224 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
227 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
230 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
231 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
232 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
233 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
234 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
235 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
238 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
241 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
244 private void UnRegisterPresetEventHandler()
\r
246 // Output Settings
\r
247 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
248 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
249 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
250 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
252 // Picture Settings
\r
253 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
256 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
259 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
260 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
261 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
262 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
263 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
264 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
267 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
270 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
273 private void changePresetLabel(object sender, EventArgs e)
\r
275 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
276 this.currentlySelectedPreset = null;
\r
279 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
281 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
282 e.Effect = DragDropEffects.All;
\r
285 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
287 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
288 sourcePath = string.Empty;
\r
290 if (fileList != null)
\r
292 if (!string.IsNullOrEmpty(fileList[0]))
\r
294 this.selectedSourceType = SourceType.VideoFile;
\r
295 StartScan(fileList[0], 0);
\r
298 UpdateSourceLabel();
\r
301 UpdateSourceLabel();
\r
304 private void encodeStarted(object sender, EventArgs e)
\r
306 SetEncodeStarted();
\r
307 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
310 private void encodeEnded(object sender, EventArgs e)
\r
312 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
313 SetEncodeFinished();
\r
317 // User Interface Menus / Tool Strips *********************************
\r
322 /// Kill The scan menu Item
\r
324 /// <param name="sender">
\r
327 /// <param name="e">
\r
330 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
336 /// Exit the Application Menu Item
\r
338 /// <param name="sender">
\r
341 /// <param name="e">
\r
344 private void mnu_exit_Click(object sender, EventArgs e)
\r
346 Application.Exit();
\r
354 /// Menu - Start Button
\r
356 /// <param name="sender">
\r
359 /// <param name="e">
\r
362 private void mnu_encode_Click(object sender, EventArgs e)
\r
364 queueWindow.Show();
\r
368 /// Menu - Display the Log Window
\r
370 /// <param name="sender">
\r
373 /// <param name="e">
\r
376 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
378 this.btn_ActivityWindow_Click(this, null);
\r
382 /// Menu - Display the Options Window
\r
384 /// <param name="sender">
\r
387 /// <param name="e">
\r
390 private void mnu_options_Click(object sender, EventArgs e)
\r
392 Form options = new frmOptions(this);
\r
393 options.ShowDialog();
\r
398 #region Presets Menu
\r
401 /// Reset the Built in Presets
\r
403 /// <param name="sender">
\r
406 /// <param name="e">
\r
409 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
411 presetHandler.UpdateBuiltInPresets();
\r
413 if (treeView_presets.Nodes.Count == 0)
\r
415 "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
416 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
418 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
420 treeView_presets.ExpandAll();
\r
424 /// Delete the selected preset
\r
426 /// <param name="sender">
\r
429 /// <param name="e">
\r
432 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
434 presetHandler.RemoveBuiltInPresets();
\r
435 LoadPresetPanel(); // Reload the preset panel
\r
439 /// Select the Normal preset
\r
441 /// <param name="sender">
\r
444 /// <param name="e">
\r
447 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
449 loadNormalPreset();
\r
453 /// Import a plist Preset
\r
455 /// <param name="sender">
\r
458 /// <param name="e">
\r
461 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
467 /// Export a Plist Preset
\r
469 /// <param name="sender">
\r
472 /// <param name="e">
\r
475 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
481 /// Create a new Preset
\r
483 /// <param name="sender">
\r
486 /// <param name="e">
\r
489 private void btn_new_preset_Click(object sender, EventArgs e)
\r
491 Form preset = new frmAddPreset(this, presetHandler);
\r
492 if (preset.ShowDialog() == DialogResult.OK)
\r
494 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
495 treeView_presets.Nodes.Add(presetTreeview);
\r
496 presetHandler.LastPresetAdded = null;
\r
505 /// Menu - Display the User Guide Web Page
\r
507 /// <param name="sender">
\r
510 /// <param name="e">
\r
513 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
515 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
519 /// Menu - Check for Updates
\r
521 /// <param name="sender">
\r
524 /// <param name="e">
\r
527 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
529 lbl_updateCheck.Visible = true;
\r
530 Main.BeginCheckForUpdates(new AsyncCallback(this.UpdateCheckDoneMenu), false);
\r
534 /// Menu - Display the About Window
\r
536 /// <param name="sender">
\r
539 /// <param name="e">
\r
542 private void mnu_about_Click(object sender, EventArgs e)
\r
544 using (frmAbout About = new frmAbout())
\r
546 About.ShowDialog();
\r
555 /// RMenu - Expand All
\r
557 /// <param name="sender">
\r
560 /// <param name="e">
\r
563 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
565 treeView_presets.ExpandAll();
\r
569 /// RMenu - Collaspe All
\r
571 /// <param name="sender">
\r
574 /// <param name="e">
\r
577 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
579 treeView_presets.CollapseAll();
\r
583 /// Menu - Import Preset
\r
585 /// <param name="sender">
\r
588 /// <param name="e">
\r
591 private void pmnu_import_Click(object sender, EventArgs e)
\r
597 /// RMenu - Save Changes to Preset
\r
599 /// <param name="sender">
\r
602 /// <param name="e">
\r
605 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
607 // TODO this requires a re-think since the Query Editor has changed.
\r
608 DialogResult result =
\r
610 "Do you wish to include picture settings when updating the preset: " +
\r
611 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
612 MessageBoxIcon.Question);
\r
613 if (result == DialogResult.Yes)
\r
614 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
615 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
616 else if (result == DialogResult.No)
\r
617 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
618 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
622 /// RMenu - Delete Preset
\r
624 /// <param name="sender">
\r
627 /// <param name="e">
\r
630 private void pmnu_delete_click(object sender, EventArgs e)
\r
632 if (treeView_presets.SelectedNode != null)
\r
634 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
635 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
637 treeView_presets.Select();
\r
641 /// Preset Menu Is Opening. Setup the Menu
\r
643 /// <param name="sender">
\r
646 /// <param name="e">
\r
649 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
651 // Make sure that the save menu is always disabled by default
\r
652 pmnu_saveChanges.Enabled = false;
\r
654 // Now enable the save menu if the selected preset is a user preset
\r
655 if (treeView_presets.SelectedNode != null)
\r
656 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
657 pmnu_saveChanges.Enabled = true;
\r
659 treeView_presets.Select();
\r
662 // Presets Management
\r
665 /// Button - Add a preset
\r
667 /// <param name="sender">
\r
670 /// <param name="e">
\r
673 private void btn_addPreset_Click(object sender, EventArgs e)
\r
675 Form preset = new frmAddPreset(this, presetHandler);
\r
676 if (preset.ShowDialog() == DialogResult.OK)
\r
678 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
679 treeView_presets.Nodes.Add(presetTreeview);
\r
680 presetHandler.LastPresetAdded = null;
\r
685 /// Button - remove a Preset
\r
687 /// <param name="sender">
\r
690 /// <param name="e">
\r
693 private void btn_removePreset_Click(object sender, EventArgs e)
\r
695 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
696 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
697 if (result == DialogResult.Yes)
\r
699 if (treeView_presets.SelectedNode != null)
\r
701 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
702 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
705 treeView_presets.Select();
\r
709 /// Button - Set the selected preset as the default
\r
711 /// <param name="sender">
\r
714 /// <param name="e">
\r
717 private void btn_setDefault_Click(object sender, EventArgs e)
\r
719 if (treeView_presets.SelectedNode != null)
\r
721 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
722 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
723 if (result == DialogResult.Yes)
\r
725 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
726 Properties.Settings.Default.Save();
\r
727 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
731 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
735 /// PresetBar Mouse Down event
\r
737 /// <param name="sender">
\r
740 /// <param name="e">
\r
743 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
745 if (e.Button == MouseButtons.Right)
\r
746 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
747 else if (e.Button == MouseButtons.Left)
\r
749 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
751 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
756 treeView_presets.Select();
\r
760 /// Preset Bar after selecting the preset
\r
762 /// <param name="sender">
\r
765 /// <param name="e">
\r
768 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
774 /// Preset Bar - Handle the Delete Key
\r
776 /// <param name="sender">
\r
779 /// <param name="e">
\r
782 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
784 if (e.KeyCode == Keys.Delete)
\r
786 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
787 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
788 if (result == DialogResult.Yes)
\r
790 if (treeView_presets.SelectedNode != null)
\r
791 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
793 // Remember each nodes expanded status so we can reload it
\r
794 List<bool> nodeStatus = new List<bool>();
\r
795 foreach (TreeNode node in treeView_presets.Nodes)
\r
796 nodeStatus.Add(node.IsExpanded);
\r
798 // Now reload the preset panel
\r
801 // And finally, re-expand any of the nodes if required
\r
803 foreach (TreeNode node in treeView_presets.Nodes)
\r
815 /// Select the selected preset and setup the GUI
\r
817 private void selectPreset()
\r
819 if (treeView_presets.SelectedNode != null)
\r
821 // Ok, so, we've selected a preset. Now we want to load it.
\r
822 string presetName = treeView_presets.SelectedNode.Text;
\r
823 Preset preset = presetHandler.GetPreset(presetName);
\r
824 if (preset != null)
\r
826 string query = presetHandler.GetPreset(presetName).Query;
\r
830 // Ok, Reset all the H264 widgets before changing the preset
\r
831 x264Panel.Reset2Defaults();
\r
833 // Send the query from the file to the Query Parser class
\r
834 QueryParser presetQuery = QueryParser.Parse(query);
\r
836 // Now load the preset
\r
837 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
839 // The x264 widgets will need updated, so do this now:
\r
840 x264Panel.StandardizeOptString();
\r
841 x264Panel.SetCurrentSettingsInPanel();
\r
843 // Finally, let this window have a copy of the preset settings.
\r
844 this.currentlySelectedPreset = preset;
\r
845 PictureSettings.SetPresetCropWarningLabel(preset);
\r
852 /// Load the Normal Preset
\r
854 private void loadNormalPreset()
\r
856 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
858 foreach (TreeNode node in treenode.Nodes)
\r
860 if (node.Text.Equals("Normal"))
\r
861 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
867 /// Import a plist preset
\r
869 private void ImportPreset()
\r
871 if (openPreset.ShowDialog() == DialogResult.OK)
\r
873 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
874 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
876 DialogResult result =
\r
877 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
878 "Overwrite preset?",
\r
879 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
880 if (result == DialogResult.Yes)
\r
882 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
883 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
884 QueryGenerator.GenerateFullQuery(this),
\r
885 parsed.UsesPictureSettings);
\r
890 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
891 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
892 QueryGenerator.GenerateFullQuery(this),
\r
893 parsed.UsesPictureSettings))
\r
895 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
897 ForeColor = Color.Black
\r
899 treeView_presets.Nodes.Add(preset_treeview);
\r
906 /// Export a plist Preset
\r
908 private void ExportPreset()
\r
910 MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
913 SaveFileDialog savefiledialog = new SaveFileDialog();
\r
914 savefiledialog.Filter = "plist|*.plist";
\r
916 if (treeView_presets.SelectedNode != null)
\r
919 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
921 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
922 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
932 /// 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
934 /// <param name="sender">
\r
937 /// <param name="e">
\r
940 private void btn_source_Click(object sender, EventArgs e)
\r
942 // Remove old Drive Menu Items.
\r
943 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
944 foreach (var item in btn_source.DropDownItems)
\r
946 if (item.GetType() == typeof(ToolStripMenuItem))
\r
948 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
949 if (menuItem.Name.StartsWith("Drive"))
\r
951 itemsToRemove.Add(menuItem);
\r
956 foreach (ToolStripMenuItem item in itemsToRemove)
\r
957 btn_source.DropDownItems.Remove(item);
\r
959 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
960 driveInfoThread.Start();
\r
964 /// Toolbar - Start The Encode
\r
966 /// <param name="sender">
\r
969 /// <param name="e">
\r
972 private void btn_start_Click(object sender, EventArgs e)
\r
974 if (btn_start.Text == "Stop")
\r
976 DialogResult result = !Properties.Settings.Default.showCliForInGuiEncodeStatus
\r
978 "Are you sure you wish to cancel the encode?\n\nPlease note: Stopping this encode will render the file unplayable. ",
\r
980 MessageBoxButtons.YesNo,
\r
981 MessageBoxIcon.Question)
\r
983 "Are you sure you wish to cancel the encode?",
\r
985 MessageBoxButtons.YesNo,
\r
986 MessageBoxIcon.Question);
\r
988 if (result == DialogResult.Yes)
\r
991 encodeQueue.Pause();
\r
993 if (Settings.Default.showCliForInGuiEncodeStatus)
\r
994 encodeQueue.SafelyClose();
\r
996 encodeQueue.Stop();
\r
1001 // 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
1002 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1003 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1005 if (encodeQueue.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))
\r
1007 string generatedQuery = QueryGenerator.GenerateFullQuery(this);
\r
1008 string specifiedQuery = rtf_query.Text != string.Empty
\r
1010 : QueryGenerator.GenerateFullQuery(this);
\r
1011 string query = string.Empty;
\r
1013 // Check to make sure the generated query matches the GUI settings
\r
1014 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1015 generatedQuery != specifiedQuery)
\r
1017 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1018 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1019 "priority over the GUI, your recently updated settings will not be taken " +
\r
1020 "into account when encoding this job." +
\r
1021 Environment.NewLine + Environment.NewLine +
\r
1022 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1023 "Manual Query does not Match GUI",
\r
1024 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1025 MessageBoxDefaultButton.Button3);
\r
1029 case DialogResult.Yes:
\r
1030 // Replace the manual query with the generated one
\r
1031 query = generatedQuery;
\r
1032 rtf_query.Text = generatedQuery;
\r
1034 case DialogResult.No:
\r
1035 // Use the manual query
\r
1036 query = specifiedQuery;
\r
1038 case DialogResult.Cancel:
\r
1039 // Don't start the encode
\r
1045 query = specifiedQuery;
\r
1048 DialogResult overwrite = DialogResult.Yes;
\r
1049 if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))
\r
1051 overwrite = MessageBox.Show(
\r
1052 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1053 "Overwrite File?",
\r
1054 MessageBoxButtons.YesNo,
\r
1055 MessageBoxIcon.Question);
\r
1058 if (overwrite == DialogResult.Yes)
\r
1060 if (encodeQueue.Count == 0)
\r
1061 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1063 queueWindow.SetQueue();
\r
1064 if (encodeQueue.Count > 1)
\r
1065 queueWindow.Show(false);
\r
1067 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1068 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1073 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1074 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1075 MessageBoxIcon.Warning);
\r
1080 /// Toolbar - Add the current job to the Queue
\r
1082 /// <param name="sender">
\r
1085 /// <param name="e">
\r
1088 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1090 // Get the CLI query or use the query editor if it's not empty.
\r
1091 string query = QueryGenerator.GenerateFullQuery(this);
\r
1092 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1093 query = rtf_query.Text;
\r
1095 // 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
1096 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1097 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1099 // Make sure we have a Source and Destination.
\r
1100 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1102 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1106 // Make sure the destination path exists.
\r
1107 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1109 MessageBox.Show("Destination Path does not exist.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1113 // Make sure we don't have a duplciate on the queue.
\r
1114 if (encodeQueue.CheckForDestinationDuplicate(jobDestination))
\r
1116 DialogResult result =
\r
1118 "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
1119 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
1120 if (result == DialogResult.Yes)
\r
1121 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1124 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1126 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1128 queueWindow.Show();
\r
1133 /// Toolbar - Show the Queue
\r
1135 /// <param name="sender">
\r
1138 /// <param name="e">
\r
1141 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1143 queueWindow.Show();
\r
1144 queueWindow.Activate();
\r
1148 /// Toolbar - Show the Preview Window
\r
1150 /// <param name="sender">
\r
1153 /// <param name="e">
\r
1156 private void tb_preview_Click(object sender, EventArgs e)
\r
1158 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1159 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1160 MessageBoxIcon.Warning);
\r
1163 if (qtpreview == null)
\r
1165 qtpreview = new frmPreview(this);
\r
1168 else if (qtpreview.IsDisposed)
\r
1170 qtpreview = new frmPreview(this);
\r
1174 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1175 MessageBoxIcon.Warning);
\r
1180 /// Toolbar - Show the Activity log Window
\r
1182 /// <param name="sender">
\r
1185 /// <param name="e">
\r
1188 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1190 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1191 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1193 this.activityWindow.Show();
\r
1194 this.activityWindow.Activate();
\r
1199 #region System Tray Icon
\r
1202 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1204 /// <param name="sender">
\r
1207 /// <param name="e">
\r
1210 private void frmMain_Resize(object sender, EventArgs e)
\r
1212 if (FormWindowState.Minimized == this.WindowState)
\r
1214 notifyIcon.Visible = true;
\r
1217 else if (FormWindowState.Normal == this.WindowState)
\r
1218 notifyIcon.Visible = false;
\r
1222 /// Double Click the Tray Icon
\r
1224 /// <param name="sender">
\r
1227 /// <param name="e">
\r
1230 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1232 this.Visible = true;
\r
1234 this.WindowState = FormWindowState.Normal;
\r
1235 notifyIcon.Visible = false;
\r
1239 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1241 /// <param name="sender">
\r
1244 /// <param name="e">
\r
1247 private void btn_restore_Click(object sender, EventArgs e)
\r
1249 this.Visible = true;
\r
1251 this.WindowState = FormWindowState.Normal;
\r
1252 notifyIcon.Visible = false;
\r
1257 #region Main Window and Tab Control
\r
1260 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
1262 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1264 this.selectedSourceType = SourceType.Folder;
\r
1265 SelectSource(DVD_Open.SelectedPath);
\r
1268 UpdateSourceLabel();
\r
1271 private void btn_file_source_Click(object sender, EventArgs e)
\r
1273 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1275 this.selectedSourceType = SourceType.VideoFile;
\r
1276 SelectSource(ISO_Open.FileName);
\r
1279 UpdateSourceLabel();
\r
1282 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
1284 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1287 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1289 if (int.TryParse(driveId, out id))
\r
1292 this.dvdDrivePath = drives[id].RootDirectory;
\r
1293 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1295 if (this.dvdDrivePath == null) return;
\r
1296 this.selectedSourceType = SourceType.DvdDrive;
\r
1297 SelectSource(this.dvdDrivePath);
\r
1302 private void SelectSource(string file)
\r
1304 Check_ChapterMarkers.Enabled = true;
\r
1305 sourcePath = string.Empty;
\r
1307 if (file == string.Empty) // Must have a file or path
\r
1309 UpdateSourceLabel();
\r
1313 sourcePath = Path.GetFileName(file);
\r
1314 StartScan(file, 0);
\r
1317 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1319 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1321 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1322 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1325 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1327 UnRegisterPresetEventHandler();
\r
1328 drop_mode.SelectedIndex = 0;
\r
1330 drop_chapterStart.Items.Clear();
\r
1331 drop_chapterFinish.Items.Clear();
\r
1333 // If the dropdown is set to automatic nothing else needs to be done.
\r
1334 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1335 if (drp_dvdtitle.Text != "Automatic")
\r
1337 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1338 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1339 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1340 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1342 // Populate the Angles dropdown
\r
1343 drop_angle.Items.Clear();
\r
1344 if (!Properties.Settings.Default.noDvdNav)
\r
1346 drop_angle.Visible = true;
\r
1347 lbl_angle.Visible = true;
\r
1349 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1350 drop_angle.Items.Add(i.ToString());
\r
1352 if (drop_angle.Items.Count != 0)
\r
1353 drop_angle.SelectedIndex = 0;
\r
1357 drop_angle.Visible = false;
\r
1358 lbl_angle.Visible = false;
\r
1361 // Populate the Start chapter Dropdown
\r
1362 drop_chapterStart.Items.Clear();
\r
1363 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1364 if (drop_chapterStart.Items.Count > 0)
\r
1365 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1367 // Populate the Final Chapter Dropdown
\r
1368 drop_chapterFinish.Items.Clear();
\r
1369 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1370 if (drop_chapterFinish.Items.Count > 0)
\r
1371 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1373 // Populate the Audio Channels Dropdown
\r
1374 AudioSettings.SetTrackList(selectedTitle, this.currentlySelectedPreset);
\r
1376 // Populate the Subtitles dropdown
\r
1377 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1379 // Update the source label if we have multiple streams
\r
1380 if (selectedTitle != null)
\r
1381 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1382 labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1384 // Run the AutoName & ChapterNaming functions
\r
1385 if (Properties.Settings.Default.autoNaming)
\r
1387 string autoPath = Main.AutoName(this);
\r
1388 if (autoPath != null)
\r
1389 text_destination.Text = autoPath;
\r
1392 "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
1393 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1396 data_chpt.Rows.Clear();
\r
1397 if (selectedTitle.Chapters.Count != 1)
\r
1399 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1400 if (chapterGridView != null)
\r
1401 data_chpt = chapterGridView;
\r
1405 Check_ChapterMarkers.Checked = false;
\r
1406 Check_ChapterMarkers.Enabled = false;
\r
1409 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1410 data_chpt.Columns[0].Width = 166;
\r
1411 data_chpt.Columns[0].Width = 165;
\r
1413 RegisterPresetEventHandler();
\r
1416 private void chapersChanged(object sender, EventArgs e)
\r
1418 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1421 Control ctl = (Control)sender;
\r
1422 int chapterStart, chapterEnd;
\r
1423 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1424 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1428 case "drop_chapterStart":
\r
1429 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1430 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1432 if (chapterEnd != 0)
\r
1433 if (chapterStart > chapterEnd)
\r
1434 drop_chapterFinish.Text = chapterStart.ToString();
\r
1436 case "drop_chapterFinish":
\r
1437 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1438 drop_chapterStart.SelectedIndex = 0;
\r
1440 if (chapterStart != 0)
\r
1441 if (chapterEnd < chapterStart)
\r
1442 drop_chapterFinish.Text = chapterStart.ToString();
\r
1444 // Add more rows to the Chapter menu if needed.
\r
1445 if (Check_ChapterMarkers.Checked)
\r
1447 int i = data_chpt.Rows.Count, finish = 0;
\r
1448 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1450 while (i < finish)
\r
1452 int n = data_chpt.Rows.Add();
\r
1453 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1454 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1455 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1456 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1463 // Update the Duration
\r
1464 lbl_duration.Text =
\r
1465 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1468 // Run the Autonaming function
\r
1469 if (Properties.Settings.Default.autoNaming)
\r
1470 text_destination.Text = Main.AutoName(this);
\r
1472 // Disable chapter markers if only 1 chapter is selected.
\r
1473 if (chapterStart == chapterEnd)
\r
1475 Check_ChapterMarkers.Enabled = false;
\r
1476 btn_importChapters.Enabled = false;
\r
1477 data_chpt.Enabled = false;
\r
1481 Check_ChapterMarkers.Enabled = true;
\r
1482 if (Check_ChapterMarkers.Checked)
\r
1484 btn_importChapters.Enabled = true;
\r
1485 data_chpt.Enabled = true;
\r
1490 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1493 int.TryParse(drop_chapterStart.Text, out start);
\r
1494 int.TryParse(drop_chapterFinish.Text, out end);
\r
1495 double duration = end - start;
\r
1497 switch (drop_mode.SelectedIndex)
\r
1500 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1503 if (selectedTitle != null)
\r
1505 duration = duration / selectedTitle.Fps;
\r
1506 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1509 lbl_duration.Text = "--:--:--";
\r
1515 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1518 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1519 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1522 switch (drop_mode.SelectedIndex)
\r
1525 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1526 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1527 if (drop_chapterStart.Items.Count != 0)
\r
1529 drop_chapterStart.SelectedIndex = 0;
\r
1530 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1533 lbl_duration.Text = "--:--:--";
\r
1536 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1537 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1538 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1539 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1540 if (selectedTitle != null)
\r
1542 drop_chapterStart.Text = "0";
\r
1543 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1547 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1548 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1549 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1550 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1551 if (selectedTitle != null)
\r
1553 drop_chapterStart.Text = "0";
\r
1554 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1561 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1563 // This removes the file extension from the filename box on the save file dialog.
\r
1564 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1565 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1567 if (Path.IsPathRooted(text_destination.Text))
\r
1568 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1570 // Show the dialog and set the main form file path
\r
1571 if (drop_format.SelectedIndex.Equals(0))
\r
1572 DVD_Save.FilterIndex = 1;
\r
1573 else if (drop_format.SelectedIndex.Equals(1))
\r
1574 DVD_Save.FilterIndex = 2;
\r
1576 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1578 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1579 switch (DVD_Save.FilterIndex)
\r
1583 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1584 StringComparison.InvariantCultureIgnoreCase))
\r
1585 if (Properties.Settings.Default.useM4v)
\r
1586 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1588 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1592 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1593 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1599 text_destination.Text = DVD_Save.FileName;
\r
1601 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1602 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1603 SetExtension(".m4v");
\r
1607 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1609 string path = text_destination.Text;
\r
1610 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1611 drop_format.SelectedIndex = 0;
\r
1612 else if (path.EndsWith(".mkv"))
\r
1613 drop_format.SelectedIndex = 1;
\r
1616 // Output Settings
\r
1617 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1619 switch (drop_format.SelectedIndex)
\r
1622 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1623 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1624 SetExtension(".m4v");
\r
1626 SetExtension(".mp4");
\r
1629 SetExtension(".mkv");
\r
1633 AudioSettings.SetContainer(drop_format.Text);
\r
1635 if (drop_format.Text.Contains("MP4"))
\r
1637 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1639 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1640 drp_videoEncoder.SelectedIndex = 1;
\r
1643 else if (drop_format.Text.Contains("MKV"))
\r
1644 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1647 public void SetExtension(string newExtension)
\r
1649 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1650 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1651 Subtitles.RequiresM4V())
\r
1652 newExtension = ".m4v";
\r
1654 newExtension = ".mp4";
\r
1656 if (Path.HasExtension(newExtension))
\r
1657 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1661 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1663 setContainerOpts();
\r
1665 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1666 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1668 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1669 check_turbo.Enabled = true;
\r
1671 tab_advanced.Enabled = true;
\r
1672 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1673 check_iPodAtom.Enabled = true;
\r
1675 check_iPodAtom.Enabled = false;
\r
1679 check_turbo.CheckState = CheckState.Unchecked;
\r
1680 check_turbo.Enabled = false;
\r
1681 tab_advanced.Enabled = false;
\r
1682 x264Panel.X264Query = string.Empty;
\r
1683 check_iPodAtom.Enabled = false;
\r
1684 check_iPodAtom.Checked = false;
\r
1687 // Setup the CQ Slider
\r
1688 switch (drp_videoEncoder.Text)
\r
1690 case "MPEG-4 (FFmpeg)":
\r
1691 if (slider_videoQuality.Value > 31)
\r
1692 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1693 slider_videoQuality.Minimum = 1;
\r
1694 slider_videoQuality.Maximum = 31;
\r
1696 case "H.264 (x264)":
\r
1697 slider_videoQuality.Minimum = 0;
\r
1698 slider_videoQuality.TickFrequency = 1;
\r
1700 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1701 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1702 double multiplier = 1.0 / cqStep;
\r
1703 double value = slider_videoQuality.Value * multiplier;
\r
1705 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1707 if (value < slider_videoQuality.Maximum)
\r
1708 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1711 case "VP3 (Theora)":
\r
1712 if (slider_videoQuality.Value > 63)
\r
1713 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1714 slider_videoQuality.Minimum = 0;
\r
1715 slider_videoQuality.Maximum = 63;
\r
1721 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1723 /// <param name="sender">
\r
1726 /// <param name="e">
\r
1729 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1731 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1733 this.checkMaximumFramerate.Visible = false;
\r
1734 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1738 this.checkMaximumFramerate.Visible = true;
\r
1743 /// Set the container format options
\r
1745 public void setContainerOpts()
\r
1747 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1749 check_largeFile.Enabled = true;
\r
1750 check_optimiseMP4.Enabled = true;
\r
1751 check_iPodAtom.Enabled = true;
\r
1755 check_largeFile.Enabled = false;
\r
1756 check_optimiseMP4.Enabled = false;
\r
1757 check_iPodAtom.Enabled = false;
\r
1758 check_largeFile.Checked = false;
\r
1759 check_optimiseMP4.Checked = false;
\r
1760 check_iPodAtom.Checked = false;
\r
1764 private double _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1767 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1769 public void setQualityFromSlider()
\r
1771 // Work out the current RF value.
\r
1772 double cqStep = _cachedCqStep;
\r
1773 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1775 // Change the maximum value for the slider
\r
1776 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1778 // Reset the CQ slider to RF0
\r
1779 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1781 // Reset the CQ slider back to the previous value as close as possible
\r
1782 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1783 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1784 while (rfValueCurrent < rfValue)
\r
1786 slider_videoQuality.Value--;
\r
1787 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1790 // Cache the CQ step for the next calculation
\r
1791 _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1794 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1796 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1797 switch (drp_videoEncoder.Text)
\r
1799 case "MPEG-4 (FFmpeg)":
\r
1800 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1802 case "H.264 (x264)":
\r
1803 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1804 rfValue = Math.Round(rfValue, 2);
\r
1805 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1807 case "VP3 (Theora)":
\r
1808 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1813 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1815 text_bitrate.Enabled = false;
\r
1816 text_filesize.Enabled = true;
\r
1817 slider_videoQuality.Enabled = false;
\r
1819 check_2PassEncode.Enabled = true;
\r
1822 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1824 text_bitrate.Enabled = true;
\r
1825 text_filesize.Enabled = false;
\r
1826 slider_videoQuality.Enabled = false;
\r
1828 check_2PassEncode.Enabled = true;
\r
1831 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1833 text_bitrate.Enabled = false;
\r
1834 text_filesize.Enabled = false;
\r
1835 slider_videoQuality.Enabled = true;
\r
1837 check_2PassEncode.Enabled = false;
\r
1838 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1841 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1843 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1845 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1846 check_turbo.Enabled = true;
\r
1850 check_turbo.Enabled = false;
\r
1851 check_turbo.CheckState = CheckState.Unchecked;
\r
1855 // Chapter Marker Tab
\r
1856 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1858 if (Check_ChapterMarkers.Checked)
\r
1860 if (drop_format.SelectedIndex != 1)
\r
1861 SetExtension(".m4v");
\r
1862 data_chpt.Enabled = true;
\r
1863 btn_importChapters.Enabled = true;
\r
1867 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
1868 SetExtension(".mp4");
\r
1869 data_chpt.Enabled = false;
\r
1870 btn_importChapters.Enabled = false;
\r
1874 private void btn_importChapters_Click(object sender, EventArgs e)
\r
1876 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
1878 string filename = File_ChapterImport.FileName;
\r
1879 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
1880 if (imported != null)
\r
1881 data_chpt = imported;
\r
1885 private void btn_export_Click(object sender, EventArgs e)
\r
1887 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
1888 saveFileDialog.Filter = "Csv File|*.csv";
\r
1889 saveFileDialog.DefaultExt = "csv";
\r
1890 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
1892 string filename = saveFileDialog.FileName;
\r
1894 Main.SaveChapterMarkersToCsv(this, filename);
\r
1898 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
1900 data_chpt.Rows.Clear();
\r
1901 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1902 if (chapterGridView != null)
\r
1904 data_chpt = chapterGridView;
\r
1908 // Query Editor Tab
\r
1909 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1911 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
1914 private void btn_clear_Click(object sender, EventArgs e)
\r
1916 rtf_query.Clear();
\r
1921 // MainWindow Components, Actions and Functions ***********************
\r
1923 #region Source Scan
\r
1926 /// Start the Scan Process
\r
1928 /// <param name="filename">
\r
1931 /// <param name="title">
\r
1934 private void StartScan(string filename, int title)
\r
1936 // Setup the GUI components for the scan.
\r
1937 sourcePath = filename;
\r
1939 this.DisableGUI();
\r
1944 SourceScan.Scan(sourcePath, title);
\r
1945 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
1946 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
1948 catch (Exception exc)
\r
1950 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1955 /// Update the Status label for the scan
\r
1957 /// <param name="sender">
\r
1960 /// <param name="e">
\r
1963 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
1965 UpdateScanStatusLabel();
\r
1969 /// Update the UI after the scan has completed
\r
1971 /// <param name="sender">
\r
1974 /// <param name="e">
\r
1977 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
1979 UpdateGuiAfterScan();
\r
1983 /// Update the Scan Status Label
\r
1985 private void UpdateScanStatusLabel()
\r
1987 if (InvokeRequired)
\r
1989 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
1992 lbl_encode.Text = SourceScan.ScanStatus;
\r
1996 /// Reset the GUI when the scan has completed
\r
1998 private void UpdateGuiAfterScan()
\r
2000 if (InvokeRequired)
\r
2002 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2008 currentSource = SourceScan.SouceData;
\r
2010 // Setup some GUI components
\r
2011 drp_dvdtitle.Items.Clear();
\r
2012 if (currentSource.Titles.Count != 0)
\r
2013 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2015 foreach (Title title in currentSource.Titles)
\r
2017 if (title.MainTitle)
\r
2019 drp_dvdtitle.SelectedItem = title;
\r
2023 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2025 drp_dvdtitle.SelectedIndex = 0;
\r
2028 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2029 if (drop_chapterStart.Items.Count > 0)
\r
2032 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2033 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2034 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2037 Check_ChapterMarkers.Enabled = false;
\r
2038 Check_ChapterMarkers.Checked = false;
\r
2039 data_chpt.Rows.Clear();
\r
2043 // If no titles were found, Display an error message
\r
2044 if (drp_dvdtitle.Items.Count == 0)
\r
2047 "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
2048 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2049 sourcePath = string.Empty;
\r
2051 UpdateSourceLabel();
\r
2053 // Enable the GUI components and enable any disabled components
\r
2056 catch (Exception exc)
\r
2058 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2059 MessageBoxIcon.Error);
\r
2065 /// Enable the GUI
\r
2067 private void EnableGUI()
\r
2071 if (InvokeRequired)
\r
2072 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2073 lbl_encode.Text = "Scan Completed";
\r
2074 foreach (Control ctrl in Controls)
\r
2075 ctrl.Enabled = true;
\r
2076 btn_start.Enabled = true;
\r
2077 btn_showQueue.Enabled = true;
\r
2078 btn_add2Queue.Enabled = true;
\r
2079 tb_preview.Enabled = true;
\r
2080 btn_source.Enabled = true;
\r
2081 mnu_killCLI.Visible = false;
\r
2083 catch (Exception exc)
\r
2085 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2090 /// Disable the GUI
\r
2092 private void DisableGUI()
\r
2094 foreach (Control ctrl in Controls)
\r
2095 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2096 ctrl.Enabled = false;
\r
2098 lbl_encode.Visible = true;
\r
2099 lbl_encode.Text = "Scanning ...";
\r
2100 btn_source.Enabled = false;
\r
2101 btn_start.Enabled = false;
\r
2102 btn_showQueue.Enabled = false;
\r
2103 btn_add2Queue.Enabled = false;
\r
2104 tb_preview.Enabled = false;
\r
2105 mnu_killCLI.Visible = true;
\r
2111 private void KillScan()
\r
2113 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2117 SourceScan.Stop();
\r
2119 lbl_encode.Text = "Scan Cancelled!";
\r
2125 private void ResetGUI()
\r
2127 drp_dvdtitle.Items.Clear();
\r
2128 drop_chapterStart.Items.Clear();
\r
2129 drop_chapterFinish.Items.Clear();
\r
2130 lbl_duration.Text = "Select a Title";
\r
2131 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2132 sourcePath = String.Empty;
\r
2133 text_destination.Text = String.Empty;
\r
2134 selectedTitle = null;
\r
2138 /// Update the Source Label
\r
2140 private void UpdateSourceLabel()
\r
2142 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2144 if (selectedTitle != null)
\r
2145 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
2146 // If it's one of multiple source files, make sure we don't use the folder name
\r
2147 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
2151 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2153 /// <param name="job">
\r
2156 public void RecievingJob(Job job)
\r
2158 string query = job.Query;
\r
2159 StartScan(job.Source, job.Title);
\r
2161 if (query != null)
\r
2163 // Ok, Reset all the H264 widgets before changing the preset
\r
2164 x264Panel.Reset2Defaults();
\r
2166 // Send the query from the file to the Query Parser class
\r
2167 QueryParser presetQuery = QueryParser.Parse(query);
\r
2169 // Now load the preset
\r
2170 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2172 // The x264 widgets will need updated, so do this now:
\r
2173 x264Panel.StandardizeOptString();
\r
2174 x264Panel.SetCurrentSettingsInPanel();
\r
2176 // Finally, let this window have a copy of the preset settings.
\r
2177 this.currentlySelectedPreset = null;
\r
2178 PictureSettings.SetPresetCropWarningLabel(null);
\r
2184 #region GUI Functions and Actions
\r
2187 /// Set the GUI to it's finished encoding state.
\r
2189 private void SetEncodeFinished()
\r
2193 if (InvokeRequired)
\r
2195 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2199 lbl_encode.Text = "Encoding Finished";
\r
2200 ProgressBarStatus.Visible = false;
\r
2201 btn_start.Text = "Start";
\r
2202 btn_start.ToolTipText = "Start the encoding process";
\r
2203 btn_start.Image = Properties.Resources.Play;
\r
2205 // If the window is minimized, display the notification in a popup.
\r
2206 if (Properties.Settings.Default.trayIconAlerts)
\r
2207 if (FormWindowState.Minimized == this.WindowState)
\r
2209 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2210 notifyIcon.ShowBalloonTip(500);
\r
2213 catch (Exception exc)
\r
2215 MessageBox.Show(exc.ToString());
\r
2220 /// Set the GUI to it's started encoding state.
\r
2222 private void SetEncodeStarted()
\r
2226 if (InvokeRequired)
\r
2228 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2231 lbl_encode.Visible = true;
\r
2232 ProgressBarStatus.Value = 0;
\r
2233 ProgressBarStatus.Visible = true;
\r
2234 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2235 btn_start.Text = "Stop";
\r
2236 btn_start.ToolTipText = "Stop the encoding process.";
\r
2237 btn_start.Image = Properties.Resources.stop;
\r
2239 catch (Exception exc)
\r
2241 MessageBox.Show(exc.ToString());
\r
2246 /// Display the Encode Status
\r
2248 /// <param name="sender">
\r
2251 /// <param name="e">
\r
2254 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2256 if (this.InvokeRequired)
\r
2258 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2264 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2265 e.PercentComplete,
\r
2266 e.CurrentFrameRate,
\r
2267 e.AverageFrameRate,
\r
2268 e.EstimatedTimeLeft,
\r
2269 encodeQueue.Count);
\r
2271 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2275 /// Set the DVD Drive selection in the "Source" Menu
\r
2277 private void SetDriveSelectionMenuItem()
\r
2281 if (InvokeRequired)
\r
2283 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2287 drives = Main.GetDrives();
\r
2289 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2290 foreach (DriveInformation drive in drives)
\r
2292 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2294 Name = drive.ToString(),
\r
2295 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2296 Image = Resources.disc_small
\r
2298 menuItem.Click += new EventHandler(mnu_dvd_drive_Click);
\r
2299 menuItems.Add(menuItem);
\r
2302 foreach (ToolStripMenuItem item in menuItems)
\r
2303 btn_source.DropDownItems.Add(item);
\r
2305 catch (Exception exc)
\r
2307 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2312 /// Access the preset Handler and setup the preset panel.
\r
2314 private void LoadPresetPanel()
\r
2316 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2317 if (!Settings.Default.presetNotification)
\r
2318 MessageBox.Show(this,
\r
2319 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2320 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2322 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2323 treeView_presets.Update();
\r
2327 /// Get the title from the selected item in the title dropdown.
\r
2332 private int GetTitle()
\r
2335 if (drp_dvdtitle.SelectedItem != null)
\r
2337 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2338 int.TryParse(titleInfo[0], out title);
\r
2345 /// Handle the Update Check Finishing.
\r
2347 /// <param name="result">
\r
2350 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2352 // Make sure it's running on the calling thread
\r
2353 if (InvokeRequired)
\r
2355 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2358 UpdateCheckInformation info;
\r
2361 // Get the information about the new build, if any, and close the window
\r
2362 info = Main.EndCheckForUpdates(result);
\r
2364 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2366 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
2367 updateWindow.ShowDialog();
\r
2370 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2371 MessageBoxIcon.Information);
\r
2372 lbl_updateCheck.Visible = false;
\r
2375 catch (Exception ex)
\r
2377 if ((bool)result.AsyncState)
\r
2379 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2380 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2389 /// Handle GUI shortcuts
\r
2391 /// <param name="msg">Message</param>
\r
2392 /// <param name="keyData">Keys</param>
\r
2393 /// <returns>Bool</returns>
\r
2394 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2396 if (keyData == (Keys.Control | Keys.S))
\r
2398 btn_start_Click(this, new EventArgs());
\r
2402 if (keyData == (Keys.Control | Keys.A))
\r
2404 btn_add2Queue_Click(this, new EventArgs());
\r
2407 return base.ProcessCmdKey(ref msg, keyData);
\r
2411 /// If the queue is being processed, prompt the user to confirm application close.
\r
2413 /// <param name="e">FormClosingEventArgs</param>
\r
2414 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2418 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2419 if (encodeQueue.IsEncoding)
\r
2421 DialogResult result =
\r
2423 "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
2424 "Close HandBrake?",
\r
2425 MessageBoxButtons.YesNo,
\r
2426 MessageBoxIcon.Question);
\r
2428 if (result == DialogResult.No)
\r
2434 encodeQueue.Stop();
\r
2437 if (SourceScan.IsScanning)
\r
2439 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2440 SourceScan.Stop();
\r
2443 catch (Exception exc)
\r
2445 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
2449 base.OnFormClosing(e);
\r
2455 // This is the END of the road ****************************************
\r