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
39 private frmSplashScreen splash = new frmSplashScreen();
\r
41 // Globals: Mainly used for tracking. *********************************
\r
42 public Title selectedTitle;
\r
43 public string sourcePath;
\r
44 private SourceType selectedSourceType;
\r
45 private string dvdDrivePath;
\r
46 private string dvdDriveLabel;
\r
47 private Preset CurrentlySelectedPreset;
\r
48 private DVD currentSource;
\r
49 private IScan SourceScan = new ScanService();
\r
50 private List<DriveInformation> drives;
\r
51 private Thread encodeMonitor;
\r
53 // Delegates **********************************************************
\r
54 private delegate void UpdateWindowHandler();
\r
56 // Applicaiton Startup ************************************************
\r
61 /// Gets SourceName.
\r
63 public string SourceName
\r
67 if (this.selectedSourceType == SourceType.DvdDrive)
\r
69 return this.dvdDriveLabel;
\r
72 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
73 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
75 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
81 #region Application Startup
\r
85 // Load and setup the splash screen in this thread
\r
87 Label lblStatus = new Label { Size = new Size(150, 20), Location = new Point(182, 102) };
\r
88 splash.Controls.Add(lblStatus);
\r
90 InitializeComponent();
\r
92 // Update the users config file with the CLI version data.
\r
93 UpdateSplashStatus(lblStatus, "Checking CLI Version Data ...");
\r
94 Main.SetCliVersionData();
\r
95 Main.CheckForValidCliVersion();
\r
97 if (Settings.Default.hb_version.Contains("svn"))
\r
99 Version v = Assembly.GetExecutingAssembly().GetName().Version;
\r
100 this.Text += " " + v.ToString(4);
\r
103 // Show the form, but leave disabled until preloading is complete then show the main form)
\r
104 this.Enabled = false;
\r
106 Application.DoEvents(); // Forces frmMain to draw
\r
108 // Check for new versions, if update checking is enabled
\r
109 if (Properties.Settings.Default.updateStatus)
\r
111 DateTime now = DateTime.Now;
\r
112 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;
\r
113 TimeSpan elapsed = now.Subtract(lastCheck);
\r
114 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
116 UpdateSplashStatus(lblStatus, "Checking for updates ...");
\r
117 Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);
\r
121 // Clear the log files in the background
\r
122 if (Properties.Settings.Default.clearOldLogs)
\r
124 UpdateSplashStatus(lblStatus, "Clearing Old Log Files ..");
\r
125 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
129 // Setup the GUI components
\r
130 UpdateSplashStatus(lblStatus, "Setting up the GUI ...");
\r
131 LoadPresetPanel(); // Load the Preset Panel
\r
132 treeView_presets.ExpandAll();
\r
133 lbl_encode.Text = string.Empty;
\r
134 drop_mode.SelectedIndex = 0;
\r
135 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
136 if (!Properties.Settings.Default.QueryEditorTab)
\r
137 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
138 if (Properties.Settings.Default.tooltipEnable)
\r
139 ToolTip.Active = true;
\r
141 // Load the user's default settings or Normal Preset
\r
142 if (Properties.Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
144 string query = presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).Query;
\r
147 x264Panel.Reset2Defaults();
\r
149 QueryParser presetQuery = QueryParser.Parse(query);
\r
150 PresetLoader.LoadPreset(this, presetQuery, Properties.Settings.Default.defaultPreset,
\r
151 presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).PictureSettings);
\r
153 x264Panel.X264_StandardizeOptString();
\r
154 x264Panel.X264_SetCurrentSettingsInPanel();
\r
158 loadNormalPreset();
\r
160 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
161 GrowlCommunicator.Register();
\r
163 // Finished Loading
\r
164 UpdateSplashStatus(lblStatus, "Loading Complete.");
\r
167 this.Enabled = true;
\r
169 // Event Handlers and Queue Recovery
\r
174 private void UpdateCheckDone(IAsyncResult result)
\r
176 if (InvokeRequired)
\r
178 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
182 UpdateCheckInformation info;
\r
186 info = Main.EndCheckForUpdates(result);
\r
188 if (info.NewVersionAvailable)
\r
190 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
191 updateWindow.ShowDialog();
\r
194 catch (Exception ex)
\r
196 if ((bool)result.AsyncState)
\r
197 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
201 // Startup Functions
\r
202 private void queueRecovery()
\r
204 if (Main.CheckQueueRecovery())
\r
206 DialogResult result =
\r
208 "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",
\r
209 "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
211 if (result == DialogResult.Yes)
\r
212 encodeQueue.LoadQueueFromFile("hb_queue_recovery.xml"); // Start Recovery
\r
215 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
216 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
217 if (File.Exists(queuePath))
\r
218 File.Delete(queuePath);
\r
223 private void UpdateSplashStatus(Label status, string text)
\r
225 status.Text = text;
\r
226 Application.DoEvents();
\r
233 // Encoding Events for setting up the GUI
\r
234 private void events()
\r
236 // Handle Widget changes when preset is selected.
\r
237 RegisterPresetEventHandler();
\r
239 // Handle Window Resize
\r
240 if (Properties.Settings.Default.MainWindowMinimize)
\r
241 this.Resize += new EventHandler(frmMain_Resize);
\r
243 // Handle Encode Start / Finish / Pause
\r
244 encodeQueue.QueuePauseRequested += new EventHandler(encodePaused);
\r
245 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
246 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
248 // Handle a file being draged onto the GUI.
\r
249 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
250 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
253 // 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
254 private void RegisterPresetEventHandler()
\r
257 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
258 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
259 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
260 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
262 // Picture Settings
\r
263 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
266 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
269 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
270 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
271 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
272 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
273 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
274 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
277 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
280 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
283 private void UnRegisterPresetEventHandler()
\r
285 // Output Settings
\r
286 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
287 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
288 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
289 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
291 // Picture Settings
\r
292 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
295 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
298 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
299 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
300 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
301 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
302 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
303 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
306 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
309 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
312 private void changePresetLabel(object sender, EventArgs e)
\r
314 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
315 CurrentlySelectedPreset = null;
\r
318 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
320 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
321 e.Effect = DragDropEffects.All;
\r
324 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
326 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
327 sourcePath = string.Empty;
\r
329 if (fileList != null)
\r
331 if (!string.IsNullOrEmpty(fileList[0]))
\r
333 this.selectedSourceType = SourceType.VideoFile;
\r
334 StartScan(fileList[0], 0);
\r
337 UpdateSourceLabel();
\r
340 UpdateSourceLabel();
\r
343 private void encodeStarted(object sender, EventArgs e)
\r
345 SetEncodeStarted();
\r
347 // Experimental HBProc Process Monitoring.
\r
348 if (Properties.Settings.Default.enocdeStatusInGui)
\r
350 encodeMonitor = new Thread(EncodeMonitorThread);
\r
351 encodeMonitor.Start();
\r
355 private void encodeEnded(object sender, EventArgs e)
\r
357 SetEncodeFinished();
\r
360 private void encodePaused(object sender, EventArgs e)
\r
362 SetEncodeFinished();
\r
367 // User Interface Menus / Tool Strips *********************************
\r
372 /// Kill The scan menu Item
\r
374 /// <param name="sender">
\r
377 /// <param name="e">
\r
380 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
386 /// Exit the Application Menu Item
\r
388 /// <param name="sender">
\r
391 /// <param name="e">
\r
394 private void mnu_exit_Click(object sender, EventArgs e)
\r
396 Application.Exit();
\r
404 /// Menu - Start Button
\r
406 /// <param name="sender">
\r
409 /// <param name="e">
\r
412 private void mnu_encode_Click(object sender, EventArgs e)
\r
414 queueWindow.Show();
\r
418 /// Menu - Display the Log Window
\r
420 /// <param name="sender">
\r
423 /// <param name="e">
\r
426 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
428 frmActivityWindow dvdInfoWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
429 dvdInfoWindow.Show();
\r
433 /// Menu - Display the Options Window
\r
435 /// <param name="sender">
\r
438 /// <param name="e">
\r
441 private void mnu_options_Click(object sender, EventArgs e)
\r
443 Form options = new frmOptions(this);
\r
444 options.ShowDialog();
\r
449 #region Presets Menu
\r
452 /// Reset the Built in Presets
\r
454 /// <param name="sender">
\r
457 /// <param name="e">
\r
460 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
462 presetHandler.UpdateBuiltInPresets();
\r
464 if (treeView_presets.Nodes.Count == 0)
\r
466 "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
467 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
469 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
471 treeView_presets.ExpandAll();
\r
475 /// Delete the selected preset
\r
477 /// <param name="sender">
\r
480 /// <param name="e">
\r
483 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
485 presetHandler.RemoveBuiltInPresets();
\r
486 LoadPresetPanel(); // Reload the preset panel
\r
490 /// Select the Normal preset
\r
492 /// <param name="sender">
\r
495 /// <param name="e">
\r
498 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
500 loadNormalPreset();
\r
504 /// Import a plist Preset
\r
506 /// <param name="sender">
\r
509 /// <param name="e">
\r
512 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
518 /// Export a Plist Preset
\r
520 /// <param name="sender">
\r
523 /// <param name="e">
\r
526 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
532 /// Create a new Preset
\r
534 /// <param name="sender">
\r
537 /// <param name="e">
\r
540 private void btn_new_preset_Click(object sender, EventArgs e)
\r
542 Form preset = new frmAddPreset(this, QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
544 preset.ShowDialog();
\r
552 /// Menu - Display the User Guide Web Page
\r
554 /// <param name="sender">
\r
557 /// <param name="e">
\r
560 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
562 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
566 /// Menu - Check for Updates
\r
568 /// <param name="sender">
\r
571 /// <param name="e">
\r
574 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
576 lbl_updateCheck.Visible = true;
\r
577 Main.BeginCheckForUpdates(new AsyncCallback(updateCheckDoneMenu), false);
\r
581 /// Menu - Display the About Window
\r
583 /// <param name="sender">
\r
586 /// <param name="e">
\r
589 private void mnu_about_Click(object sender, EventArgs e)
\r
591 using (frmAbout About = new frmAbout())
\r
593 About.ShowDialog();
\r
602 /// RMenu - Expand All
\r
604 /// <param name="sender">
\r
607 /// <param name="e">
\r
610 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
612 treeView_presets.ExpandAll();
\r
616 /// RMenu - Collaspe All
\r
618 /// <param name="sender">
\r
621 /// <param name="e">
\r
624 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
626 treeView_presets.CollapseAll();
\r
630 /// Menu - Import Preset
\r
632 /// <param name="sender">
\r
635 /// <param name="e">
\r
638 private void pmnu_import_Click(object sender, EventArgs e)
\r
644 /// RMenu - Save Changes to Preset
\r
646 /// <param name="sender">
\r
649 /// <param name="e">
\r
652 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
654 DialogResult result =
\r
656 "Do you wish to include picture settings when updating the preset: " +
\r
657 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
658 MessageBoxIcon.Question);
\r
659 if (result == DialogResult.Yes)
\r
660 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
661 QueryGenerator.GenerateTabbedComponentsQuery(this), true);
\r
662 else if (result == DialogResult.No)
\r
663 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
664 QueryGenerator.GenerateTabbedComponentsQuery(this), false);
\r
668 /// RMenu - Delete Preset
\r
670 /// <param name="sender">
\r
673 /// <param name="e">
\r
676 private void pmnu_delete_click(object sender, EventArgs e)
\r
678 if (treeView_presets.SelectedNode != null)
\r
680 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
681 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
683 treeView_presets.Select();
\r
687 /// Preset Menu Is Opening. Setup the Menu
\r
689 /// <param name="sender">
\r
692 /// <param name="e">
\r
695 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
697 // Make sure that the save menu is always disabled by default
\r
698 pmnu_saveChanges.Enabled = false;
\r
700 // Now enable the save menu if the selected preset is a user preset
\r
701 if (treeView_presets.SelectedNode != null)
\r
702 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
703 pmnu_saveChanges.Enabled = true;
\r
705 treeView_presets.Select();
\r
708 // Presets Management
\r
711 /// Button - Add a preset
\r
713 /// <param name="sender">
\r
716 /// <param name="e">
\r
719 private void btn_addPreset_Click(object sender, EventArgs e)
\r
721 Form preset = new frmAddPreset(this, QueryGenerator.GenerateTabbedComponentsQuery(this), presetHandler);
\r
722 preset.ShowDialog();
\r
726 /// Button - remove a Preset
\r
728 /// <param name="sender">
\r
731 /// <param name="e">
\r
734 private void btn_removePreset_Click(object sender, EventArgs e)
\r
736 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
737 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
738 if (result == DialogResult.Yes)
\r
740 if (treeView_presets.SelectedNode != null)
\r
742 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
743 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
746 treeView_presets.Select();
\r
750 /// Button - Set the selected preset as the default
\r
752 /// <param name="sender">
\r
755 /// <param name="e">
\r
758 private void btn_setDefault_Click(object sender, EventArgs e)
\r
760 if (treeView_presets.SelectedNode != null)
\r
762 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
763 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
764 if (result == DialogResult.Yes)
\r
766 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
767 Properties.Settings.Default.Save();
\r
768 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
772 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
776 /// PresetBar Mouse Down event
\r
778 /// <param name="sender">
\r
781 /// <param name="e">
\r
784 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
786 if (e.Button == MouseButtons.Right)
\r
787 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
788 else if (e.Button == MouseButtons.Left)
\r
790 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
792 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
797 treeView_presets.Select();
\r
801 /// Preset Bar after selecting the preset
\r
803 /// <param name="sender">
\r
806 /// <param name="e">
\r
809 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
815 /// Preset Bar - Handle the Delete Key
\r
817 /// <param name="sender">
\r
820 /// <param name="e">
\r
823 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
825 if (e.KeyCode == Keys.Delete)
\r
827 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
828 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
829 if (result == DialogResult.Yes)
\r
831 if (treeView_presets.SelectedNode != null)
\r
832 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
834 // Remember each nodes expanded status so we can reload it
\r
835 List<bool> nodeStatus = new List<bool>();
\r
836 foreach (TreeNode node in treeView_presets.Nodes)
\r
837 nodeStatus.Add(node.IsExpanded);
\r
839 // Now reload the preset panel
\r
842 // And finally, re-expand any of the nodes if required
\r
844 foreach (TreeNode node in treeView_presets.Nodes)
\r
856 /// Select the selected preset and setup the GUI
\r
858 private void selectPreset()
\r
860 if (treeView_presets.SelectedNode != null)
\r
862 // Ok, so, we've selected a preset. Now we want to load it.
\r
863 string presetName = treeView_presets.SelectedNode.Text;
\r
864 Preset preset = presetHandler.GetPreset(presetName);
\r
865 if (preset != null)
\r
867 string query = presetHandler.GetPreset(presetName).Query;
\r
868 bool loadPictureSettings = presetHandler.GetPreset(presetName).PictureSettings;
\r
872 // Ok, Reset all the H264 widgets before changing the preset
\r
873 x264Panel.Reset2Defaults();
\r
875 // Send the query from the file to the Query Parser class
\r
876 QueryParser presetQuery = QueryParser.Parse(query);
\r
878 // Now load the preset
\r
879 PresetLoader.LoadPreset(this, presetQuery, presetName, loadPictureSettings);
\r
881 // The x264 widgets will need updated, so do this now:
\r
882 x264Panel.X264_StandardizeOptString();
\r
883 x264Panel.X264_SetCurrentSettingsInPanel();
\r
885 // Finally, let this window have a copy of the preset settings.
\r
886 CurrentlySelectedPreset = preset;
\r
887 PictureSettings.SetPresetCropWarningLabel(preset);
\r
894 /// Load the Normal Preset
\r
896 private void loadNormalPreset()
\r
898 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
900 foreach (TreeNode node in treenode.Nodes)
\r
902 if (node.Text.Equals("Normal"))
\r
903 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
909 /// Import a plist preset
\r
911 private void ImportPreset()
\r
913 if (openPreset.ShowDialog() == DialogResult.OK)
\r
915 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
916 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
918 DialogResult result =
\r
919 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
920 "Overwrite preset?",
\r
921 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
922 if (result == DialogResult.Yes)
\r
924 PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);
\r
925 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
926 QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
927 parsed.UsesPictureSettings);
\r
932 PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);
\r
933 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
934 QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
935 parsed.UsesPictureSettings))
\r
937 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
939 ForeColor = Color.Black
\r
941 treeView_presets.Nodes.Add(preset_treeview);
\r
948 /// Export a plist Preset
\r
950 private void ExportPreset()
\r
952 MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
955 SaveFileDialog savefiledialog = new SaveFileDialog();
\r
956 savefiledialog.Filter = "plist|*.plist";
\r
958 if (treeView_presets.SelectedNode != null)
\r
961 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
963 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
964 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
974 /// 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
976 /// <param name="sender">
\r
979 /// <param name="e">
\r
982 private void btn_source_Click(object sender, EventArgs e)
\r
984 // Remove old Drive Menu Items.
\r
985 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
986 foreach (var item in btn_source.DropDownItems)
\r
988 if (item.GetType() == typeof(ToolStripMenuItem))
\r
990 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
991 if (menuItem.Name.StartsWith("Drive"))
\r
993 itemsToRemove.Add(menuItem);
\r
998 foreach (ToolStripMenuItem item in itemsToRemove)
\r
999 btn_source.DropDownItems.Remove(item);
\r
1001 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
1002 driveInfoThread.Start();
\r
1006 /// Toolbar - Start The Encode
\r
1008 /// <param name="sender">
\r
1011 /// <param name="e">
\r
1014 private void btn_start_Click(object sender, EventArgs e)
\r
1016 if (btn_start.Text == "Stop")
\r
1018 DialogResult result;
\r
1019 if (Properties.Settings.Default.enocdeStatusInGui &&
\r
1020 !Properties.Settings.Default.showCliForInGuiEncodeStatus)
\r
1022 result = MessageBox.Show(
\r
1023 "Are you sure you wish to cancel the encode?\n\nPlease note, when 'Enable in-GUI encode status' is enabled, stopping this encode will render the file unplayable. ",
\r
1024 "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1028 result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?",
\r
1029 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1032 if (result == DialogResult.Yes)
\r
1034 // Pause The Queue
\r
1035 encodeQueue.Pause();
\r
1037 if (Properties.Settings.Default.enocdeStatusInGui &&
\r
1038 !Properties.Settings.Default.showCliForInGuiEncodeStatus)
\r
1040 encodeQueue.Stop();
\r
1041 if (encodeQueue.HbProcess != null)
\r
1042 encodeQueue.HbProcess.WaitForExit();
\r
1046 encodeQueue.SafelyClose();
\r
1052 if (encodeQueue.Count != 0 ||
\r
1053 (!string.IsNullOrEmpty(sourcePath) && !string.IsNullOrEmpty(text_destination.Text)))
\r
1055 string generatedQuery = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1056 string specifiedQuery = rtf_query.Text != string.Empty
\r
1058 : QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1059 string query = string.Empty;
\r
1061 // Check to make sure the generated query matches the GUI settings
\r
1062 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1063 generatedQuery != specifiedQuery)
\r
1065 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1066 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1067 "priority over the GUI, your recently updated settings will not be taken " +
\r
1068 "into account when encoding this job." +
\r
1069 Environment.NewLine + Environment.NewLine +
\r
1070 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1071 "Manual Query does not Match GUI",
\r
1072 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1073 MessageBoxDefaultButton.Button3);
\r
1077 case DialogResult.Yes:
\r
1078 // Replace the manual query with the generated one
\r
1079 query = generatedQuery;
\r
1080 rtf_query.Text = generatedQuery;
\r
1082 case DialogResult.No:
\r
1083 // Use the manual query
\r
1084 query = specifiedQuery;
\r
1086 case DialogResult.Cancel:
\r
1087 // Don't start the encode
\r
1093 query = specifiedQuery;
\r
1096 DialogResult overwrite = DialogResult.Yes;
\r
1097 if (text_destination.Text != string.Empty)
\r
1098 if (File.Exists(text_destination.Text))
\r
1101 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1102 "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1104 if (overwrite == DialogResult.Yes)
\r
1106 if (encodeQueue.Count == 0)
\r
1107 encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1109 queueWindow.SetQueue();
\r
1110 if (encodeQueue.Count > 1)
\r
1111 queueWindow.Show(false);
\r
1113 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1114 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1119 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1120 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1121 MessageBoxIcon.Warning);
\r
1126 /// Toolbar - Add the current job to the Queue
\r
1128 /// <param name="sender">
\r
1131 /// <param name="e">
\r
1134 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1136 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1137 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1140 if (!Directory.Exists(Path.GetDirectoryName(text_destination.Text)))
\r
1142 MessageBox.Show("Destination Path does not exist.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1146 string query = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1147 if (rtf_query.Text != string.Empty)
\r
1148 query = rtf_query.Text;
\r
1150 if (encodeQueue.CheckForDestinationDuplicate(text_destination.Text))
\r
1152 DialogResult result =
\r
1154 "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
1155 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
1156 if (result == DialogResult.Yes)
\r
1157 encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1160 encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1162 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1164 queueWindow.Show();
\r
1169 /// Toolbar - Show the Queue
\r
1171 /// <param name="sender">
\r
1174 /// <param name="e">
\r
1177 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1179 queueWindow.Show();
\r
1180 queueWindow.Activate();
\r
1184 /// Toolbar - Show the Preview Window
\r
1186 /// <param name="sender">
\r
1189 /// <param name="e">
\r
1192 private void tb_preview_Click(object sender, EventArgs e)
\r
1194 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1195 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1196 MessageBoxIcon.Warning);
\r
1199 if (qtpreview == null)
\r
1201 qtpreview = new frmPreview(this);
\r
1204 else if (qtpreview.IsDisposed)
\r
1206 qtpreview = new frmPreview(this);
\r
1210 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1211 MessageBoxIcon.Warning);
\r
1216 /// Toolbar - Show the Activity log Window
\r
1218 /// <param name="sender">
\r
1221 /// <param name="e">
\r
1224 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1226 if (ActivityWindow == null || !ActivityWindow.IsHandleCreated)
\r
1227 ActivityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1229 ActivityWindow.Show();
\r
1230 ActivityWindow.Activate();
\r
1235 #region System Tray Icon
\r
1238 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1240 /// <param name="sender">
\r
1243 /// <param name="e">
\r
1246 private void frmMain_Resize(object sender, EventArgs e)
\r
1248 if (FormWindowState.Minimized == this.WindowState)
\r
1250 notifyIcon.Visible = true;
\r
1253 else if (FormWindowState.Normal == this.WindowState)
\r
1254 notifyIcon.Visible = false;
\r
1258 /// Double Click the Tray Icon
\r
1260 /// <param name="sender">
\r
1263 /// <param name="e">
\r
1266 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1268 this.Visible = true;
\r
1270 this.WindowState = FormWindowState.Normal;
\r
1271 notifyIcon.Visible = false;
\r
1275 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1277 /// <param name="sender">
\r
1280 /// <param name="e">
\r
1283 private void btn_restore_Click(object sender, EventArgs e)
\r
1285 this.Visible = true;
\r
1287 this.WindowState = FormWindowState.Normal;
\r
1288 notifyIcon.Visible = false;
\r
1293 #region Main Window and Tab Control
\r
1296 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
1298 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1300 this.selectedSourceType = SourceType.Folder;
\r
1301 SelectSource(DVD_Open.SelectedPath);
\r
1304 UpdateSourceLabel();
\r
1307 private void btn_file_source_Click(object sender, EventArgs e)
\r
1309 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1311 this.selectedSourceType = SourceType.VideoFile;
\r
1312 SelectSource(ISO_Open.FileName);
\r
1315 UpdateSourceLabel();
\r
1318 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
1320 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1323 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1325 if (int.TryParse(driveId, out id))
\r
1328 this.dvdDrivePath = drives[id].RootDirectory;
\r
1329 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1331 if (this.dvdDrivePath == null) return;
\r
1332 this.selectedSourceType = SourceType.DvdDrive;
\r
1333 SelectSource(this.dvdDrivePath);
\r
1338 private void SelectSource(string file)
\r
1340 Check_ChapterMarkers.Enabled = true;
\r
1341 sourcePath = string.Empty;
\r
1343 if (file == string.Empty) // Must have a file or path
\r
1345 UpdateSourceLabel();
\r
1349 sourcePath = Path.GetFileName(file);
\r
1350 StartScan(file, 0);
\r
1353 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1355 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1357 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1358 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1361 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1363 UnRegisterPresetEventHandler();
\r
1364 drop_mode.SelectedIndex = 0;
\r
1366 drop_chapterStart.Items.Clear();
\r
1367 drop_chapterFinish.Items.Clear();
\r
1369 // If the dropdown is set to automatic nothing else needs to be done.
\r
1370 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1371 if (drp_dvdtitle.Text != "Automatic")
\r
1373 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1374 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1375 PictureSettings.CurrentlySelectedPreset = CurrentlySelectedPreset;
\r
1376 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1378 // Populate the Angles dropdown
\r
1379 drop_angle.Items.Clear();
\r
1380 if (!Properties.Settings.Default.noDvdNav)
\r
1382 drop_angle.Visible = true;
\r
1383 lbl_angle.Visible = true;
\r
1385 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1386 drop_angle.Items.Add(i.ToString());
\r
1388 if (drop_angle.Items.Count != 0)
\r
1389 drop_angle.SelectedIndex = 0;
\r
1393 drop_angle.Visible = false;
\r
1394 lbl_angle.Visible = false;
\r
1397 // Populate the Start chapter Dropdown
\r
1398 drop_chapterStart.Items.Clear();
\r
1399 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1400 if (drop_chapterStart.Items.Count > 0)
\r
1401 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1403 // Populate the Final Chapter Dropdown
\r
1404 drop_chapterFinish.Items.Clear();
\r
1405 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1406 if (drop_chapterFinish.Items.Count > 0)
\r
1407 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1409 // Populate the Audio Channels Dropdown
\r
1410 AudioSettings.SetTrackList(selectedTitle, CurrentlySelectedPreset);
\r
1412 // Populate the Subtitles dropdown
\r
1413 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1415 // Update the source label if we have multiple streams
\r
1416 if (selectedTitle != null)
\r
1417 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1418 labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1420 // Run the AutoName & ChapterNaming functions
\r
1421 if (Properties.Settings.Default.autoNaming)
\r
1423 string autoPath = Main.AutoName(this);
\r
1424 if (autoPath != null)
\r
1425 text_destination.Text = autoPath;
\r
1428 "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
1429 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1432 data_chpt.Rows.Clear();
\r
1433 if (selectedTitle.Chapters.Count != 1)
\r
1435 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1436 if (chapterGridView != null)
\r
1437 data_chpt = chapterGridView;
\r
1441 Check_ChapterMarkers.Checked = false;
\r
1442 Check_ChapterMarkers.Enabled = false;
\r
1445 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1446 data_chpt.Columns[0].Width = 166;
\r
1447 data_chpt.Columns[0].Width = 165;
\r
1449 RegisterPresetEventHandler();
\r
1452 private void chapersChanged(object sender, EventArgs e)
\r
1454 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1457 Control ctl = (Control)sender;
\r
1458 int chapterStart, chapterEnd;
\r
1459 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1460 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1464 case "drop_chapterStart":
\r
1465 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1466 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1468 if (chapterEnd != 0)
\r
1469 if (chapterStart > chapterEnd)
\r
1470 drop_chapterFinish.Text = chapterStart.ToString();
\r
1472 case "drop_chapterFinish":
\r
1473 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1474 drop_chapterStart.SelectedIndex = 0;
\r
1476 if (chapterStart != 0)
\r
1477 if (chapterEnd < chapterStart)
\r
1478 drop_chapterFinish.Text = chapterStart.ToString();
\r
1480 // Add more rows to the Chapter menu if needed.
\r
1481 if (Check_ChapterMarkers.Checked)
\r
1483 int i = data_chpt.Rows.Count, finish = 0;
\r
1484 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1486 while (i < finish)
\r
1488 int n = data_chpt.Rows.Add();
\r
1489 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1490 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1491 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1492 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1499 // Update the Duration
\r
1500 lbl_duration.Text =
\r
1501 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1504 // Run the Autonaming function
\r
1505 if (Properties.Settings.Default.autoNaming)
\r
1506 text_destination.Text = Main.AutoName(this);
\r
1508 // Disable chapter markers if only 1 chapter is selected.
\r
1509 if (chapterStart == chapterEnd)
\r
1511 Check_ChapterMarkers.Enabled = false;
\r
1512 btn_importChapters.Enabled = false;
\r
1513 data_chpt.Enabled = false;
\r
1517 Check_ChapterMarkers.Enabled = true;
\r
1518 if (Check_ChapterMarkers.Checked)
\r
1520 btn_importChapters.Enabled = true;
\r
1521 data_chpt.Enabled = true;
\r
1526 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1529 int.TryParse(drop_chapterStart.Text, out start);
\r
1530 int.TryParse(drop_chapterFinish.Text, out end);
\r
1531 double duration = end - start;
\r
1533 switch (drop_mode.SelectedIndex)
\r
1536 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1539 if (selectedTitle != null)
\r
1541 duration = duration / selectedTitle.Fps;
\r
1542 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1545 lbl_duration.Text = "--:--:--";
\r
1551 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1554 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1555 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1558 switch (drop_mode.SelectedIndex)
\r
1561 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1562 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1563 if (drop_chapterStart.Items.Count != 0)
\r
1565 drop_chapterStart.SelectedIndex = 0;
\r
1566 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1569 lbl_duration.Text = "--:--:--";
\r
1572 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1573 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1574 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1575 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1576 if (selectedTitle != null)
\r
1578 drop_chapterStart.Text = "0";
\r
1579 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1583 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1584 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1585 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1586 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1587 if (selectedTitle != null)
\r
1589 drop_chapterStart.Text = "0";
\r
1590 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1597 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1599 // This removes the file extension from the filename box on the save file dialog.
\r
1600 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1601 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1603 if (Path.IsPathRooted(text_destination.Text))
\r
1604 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1606 // Show the dialog and set the main form file path
\r
1607 if (drop_format.SelectedIndex.Equals(0))
\r
1608 DVD_Save.FilterIndex = 1;
\r
1609 else if (drop_format.SelectedIndex.Equals(1))
\r
1610 DVD_Save.FilterIndex = 2;
\r
1612 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1614 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1615 switch (DVD_Save.FilterIndex)
\r
1619 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1620 StringComparison.InvariantCultureIgnoreCase))
\r
1621 if (Properties.Settings.Default.useM4v)
\r
1622 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1624 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1628 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1629 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1635 text_destination.Text = DVD_Save.FileName;
\r
1637 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1638 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1639 SetExtension(".m4v");
\r
1643 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1645 string path = text_destination.Text;
\r
1646 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1647 drop_format.SelectedIndex = 0;
\r
1648 else if (path.EndsWith(".mkv"))
\r
1649 drop_format.SelectedIndex = 1;
\r
1652 // Output Settings
\r
1653 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1655 switch (drop_format.SelectedIndex)
\r
1658 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1659 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1660 SetExtension(".m4v");
\r
1662 SetExtension(".mp4");
\r
1665 SetExtension(".mkv");
\r
1669 AudioSettings.SetContainer(drop_format.Text);
\r
1671 if (drop_format.Text.Contains("MP4"))
\r
1673 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1675 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1676 drp_videoEncoder.SelectedIndex = 1;
\r
1679 else if (drop_format.Text.Contains("MKV"))
\r
1680 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1683 public void SetExtension(string newExtension)
\r
1685 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1686 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1687 Subtitles.RequiresM4V())
\r
1688 newExtension = ".m4v";
\r
1690 newExtension = ".mp4";
\r
1692 if (Path.HasExtension(newExtension))
\r
1693 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1697 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1699 setContainerOpts();
\r
1701 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1702 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1704 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1705 check_turbo.Enabled = true;
\r
1707 tab_advanced.Enabled = true;
\r
1708 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1709 check_iPodAtom.Enabled = true;
\r
1711 check_iPodAtom.Enabled = false;
\r
1715 check_turbo.CheckState = CheckState.Unchecked;
\r
1716 check_turbo.Enabled = false;
\r
1717 tab_advanced.Enabled = false;
\r
1718 x264Panel.X264Query = string.Empty;
\r
1719 check_iPodAtom.Enabled = false;
\r
1720 check_iPodAtom.Checked = false;
\r
1723 // Setup the CQ Slider
\r
1724 switch (drp_videoEncoder.Text)
\r
1726 case "MPEG-4 (FFmpeg)":
\r
1727 if (slider_videoQuality.Value > 31)
\r
1728 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1729 slider_videoQuality.Minimum = 1;
\r
1730 slider_videoQuality.Maximum = 31;
\r
1732 case "H.264 (x264)":
\r
1733 slider_videoQuality.Minimum = 0;
\r
1734 slider_videoQuality.TickFrequency = 1;
\r
1736 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1737 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1738 double multiplier = 1.0 / cqStep;
\r
1739 double value = slider_videoQuality.Value * multiplier;
\r
1741 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1743 if (value < slider_videoQuality.Maximum)
\r
1744 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1747 case "VP3 (Theora)":
\r
1748 if (slider_videoQuality.Value > 63)
\r
1749 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1750 slider_videoQuality.Minimum = 0;
\r
1751 slider_videoQuality.Maximum = 63;
\r
1757 /// Set the container format options
\r
1759 public void setContainerOpts()
\r
1761 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1763 check_largeFile.Enabled = true;
\r
1764 check_optimiseMP4.Enabled = true;
\r
1765 check_iPodAtom.Enabled = true;
\r
1769 check_largeFile.Enabled = false;
\r
1770 check_optimiseMP4.Enabled = false;
\r
1771 check_iPodAtom.Enabled = false;
\r
1772 check_largeFile.Checked = false;
\r
1773 check_optimiseMP4.Checked = false;
\r
1774 check_iPodAtom.Checked = false;
\r
1778 private double _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1781 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1783 public void setQualityFromSlider()
\r
1785 // Work out the current RF value.
\r
1786 double cqStep = _cachedCqStep;
\r
1787 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1789 // Change the maximum value for the slider
\r
1790 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1792 // Reset the CQ slider to RF0
\r
1793 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1795 // Reset the CQ slider back to the previous value as close as possible
\r
1796 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1797 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1798 while (rfValueCurrent < rfValue)
\r
1800 slider_videoQuality.Value--;
\r
1801 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1804 // Cache the CQ step for the next calculation
\r
1805 _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1808 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1810 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1811 switch (drp_videoEncoder.Text)
\r
1813 case "MPEG-4 (FFmpeg)":
\r
1814 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1816 case "H.264 (x264)":
\r
1817 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1818 rfValue = Math.Round(rfValue, 2);
\r
1819 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1821 case "VP3 (Theora)":
\r
1822 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1827 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1829 text_bitrate.Enabled = false;
\r
1830 text_filesize.Enabled = true;
\r
1831 slider_videoQuality.Enabled = false;
\r
1833 check_2PassEncode.Enabled = true;
\r
1836 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1838 text_bitrate.Enabled = true;
\r
1839 text_filesize.Enabled = false;
\r
1840 slider_videoQuality.Enabled = false;
\r
1842 check_2PassEncode.Enabled = true;
\r
1845 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1847 text_bitrate.Enabled = false;
\r
1848 text_filesize.Enabled = false;
\r
1849 slider_videoQuality.Enabled = true;
\r
1851 check_2PassEncode.Enabled = false;
\r
1852 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1855 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1857 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1859 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1860 check_turbo.Enabled = true;
\r
1864 check_turbo.Enabled = false;
\r
1865 check_turbo.CheckState = CheckState.Unchecked;
\r
1869 // Chapter Marker Tab
\r
1870 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1872 if (Check_ChapterMarkers.Checked)
\r
1874 if (drop_format.SelectedIndex != 1)
\r
1875 SetExtension(".m4v");
\r
1876 data_chpt.Enabled = true;
\r
1877 btn_importChapters.Enabled = true;
\r
1881 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
1882 SetExtension(".mp4");
\r
1883 data_chpt.Enabled = false;
\r
1884 btn_importChapters.Enabled = false;
\r
1888 private void btn_importChapters_Click(object sender, EventArgs e)
\r
1890 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
1892 string filename = File_ChapterImport.FileName;
\r
1893 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
1894 if (imported != null)
\r
1895 data_chpt = imported;
\r
1899 private void btn_export_Click(object sender, EventArgs e)
\r
1901 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
1902 saveFileDialog.Filter = "Csv File|*.csv";
\r
1903 saveFileDialog.DefaultExt = "csv";
\r
1904 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
1906 string filename = saveFileDialog.FileName;
\r
1908 Main.SaveChapterMarkersToCsv(this, filename);
\r
1912 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
1914 data_chpt.Rows.Clear();
\r
1915 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1916 if (chapterGridView != null)
\r
1918 data_chpt = chapterGridView;
\r
1922 // Query Editor Tab
\r
1923 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1925 rtf_query.Text = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1928 private void btn_clear_Click(object sender, EventArgs e)
\r
1930 rtf_query.Clear();
\r
1935 // MainWindow Components, Actions and Functions ***********************
\r
1937 #region Source Scan
\r
1940 /// Start the Scan Process
\r
1942 /// <param name="filename">
\r
1945 /// <param name="title">
\r
1948 private void StartScan(string filename, int title)
\r
1950 // Setup the GUI components for the scan.
\r
1951 sourcePath = filename;
\r
1953 this.DisableGUI();
\r
1958 SourceScan.Scan(sourcePath, title);
\r
1959 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
1960 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
1962 catch (Exception exc)
\r
1964 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1969 /// Update the Status label for the scan
\r
1971 /// <param name="sender">
\r
1974 /// <param name="e">
\r
1977 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
1979 UpdateScanStatusLabel();
\r
1983 /// Update the UI after the scan has completed
\r
1985 /// <param name="sender">
\r
1988 /// <param name="e">
\r
1991 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
1993 UpdateGuiAfterScan();
\r
1997 /// Update the Scan Status Label
\r
1999 private void UpdateScanStatusLabel()
\r
2001 if (InvokeRequired)
\r
2003 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
2006 lbl_encode.Text = SourceScan.ScanStatus;
\r
2010 /// Reset the GUI when the scan has completed
\r
2012 private void UpdateGuiAfterScan()
\r
2014 if (InvokeRequired)
\r
2016 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2022 currentSource = SourceScan.SouceData;
\r
2024 // Setup some GUI components
\r
2025 drp_dvdtitle.Items.Clear();
\r
2026 if (currentSource.Titles.Count != 0)
\r
2027 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2029 foreach (Title title in currentSource.Titles)
\r
2031 if (title.MainTitle)
\r
2033 drp_dvdtitle.SelectedItem = title;
\r
2037 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2039 drp_dvdtitle.SelectedIndex = 0;
\r
2042 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
2044 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2045 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2047 Check_ChapterMarkers.Enabled = true;
\r
2050 Check_ChapterMarkers.Enabled = false;
\r
2051 Check_ChapterMarkers.Checked = false;
\r
2052 data_chpt.Rows.Clear();
\r
2055 // If no titles were found, Display an error message
\r
2056 if (drp_dvdtitle.Items.Count == 0)
\r
2059 "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
2060 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2061 sourcePath = string.Empty;
\r
2063 UpdateSourceLabel();
\r
2065 // Enable the GUI components and enable any disabled components
\r
2068 catch (Exception exc)
\r
2070 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2071 MessageBoxIcon.Error);
\r
2077 /// Enable the GUI
\r
2079 private void EnableGUI()
\r
2083 if (InvokeRequired)
\r
2084 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2085 lbl_encode.Text = "Scan Completed";
\r
2086 foreach (Control ctrl in Controls)
\r
2087 ctrl.Enabled = true;
\r
2088 btn_start.Enabled = true;
\r
2089 btn_showQueue.Enabled = true;
\r
2090 btn_add2Queue.Enabled = true;
\r
2091 tb_preview.Enabled = true;
\r
2092 btn_source.Enabled = true;
\r
2093 mnu_killCLI.Visible = false;
\r
2095 catch (Exception exc)
\r
2097 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2102 /// Disable the GUI
\r
2104 private void DisableGUI()
\r
2106 foreach (Control ctrl in Controls)
\r
2107 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2108 ctrl.Enabled = false;
\r
2110 lbl_encode.Visible = true;
\r
2111 lbl_encode.Text = "Scanning ...";
\r
2112 btn_source.Enabled = false;
\r
2113 btn_start.Enabled = false;
\r
2114 btn_showQueue.Enabled = false;
\r
2115 btn_add2Queue.Enabled = false;
\r
2116 tb_preview.Enabled = false;
\r
2117 mnu_killCLI.Visible = true;
\r
2123 private void KillScan()
\r
2125 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2129 SourceScan.Stop();
\r
2131 lbl_encode.Text = "Scan Cancelled!";
\r
2137 private void ResetGUI()
\r
2139 drp_dvdtitle.Items.Clear();
\r
2140 drop_chapterStart.Items.Clear();
\r
2141 drop_chapterFinish.Items.Clear();
\r
2142 lbl_duration.Text = "Select a Title";
\r
2143 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2144 sourcePath = String.Empty;
\r
2145 text_destination.Text = String.Empty;
\r
2146 selectedTitle = null;
\r
2150 /// Update the Source Label
\r
2152 private void UpdateSourceLabel()
\r
2154 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2156 if (selectedTitle != null)
\r
2157 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
2158 // If it's one of multiple source files, make sure we don't use the folder name
\r
2159 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
2163 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2165 /// <param name="job">
\r
2168 public void RecievingJob(Job job)
\r
2170 string query = job.Query;
\r
2171 StartScan(job.Source, job.Title);
\r
2173 if (query != null)
\r
2175 // Ok, Reset all the H264 widgets before changing the preset
\r
2176 x264Panel.Reset2Defaults();
\r
2178 // Send the query from the file to the Query Parser class
\r
2179 QueryParser presetQuery = QueryParser.Parse(query);
\r
2181 // Now load the preset
\r
2182 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);
\r
2184 // The x264 widgets will need updated, so do this now:
\r
2185 x264Panel.X264_StandardizeOptString();
\r
2186 x264Panel.X264_SetCurrentSettingsInPanel();
\r
2188 // Finally, let this window have a copy of the preset settings.
\r
2189 CurrentlySelectedPreset = null;
\r
2190 PictureSettings.SetPresetCropWarningLabel(null);
\r
2196 #region GUI Functions and Actions
\r
2199 /// Set the GUI to it's finished encoding state.
\r
2201 private void SetEncodeFinished()
\r
2205 if (InvokeRequired)
\r
2207 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2211 lbl_encode.Text = "Encoding Finished";
\r
2212 ProgressBarStatus.Visible = false;
\r
2213 btn_start.Text = "Start";
\r
2214 btn_start.ToolTipText = "Start the encoding process";
\r
2215 btn_start.Image = Properties.Resources.Play;
\r
2217 // If the window is minimized, display the notification in a popup.
\r
2218 if (Properties.Settings.Default.trayIconAlerts)
\r
2219 if (FormWindowState.Minimized == this.WindowState)
\r
2221 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2222 notifyIcon.ShowBalloonTip(500);
\r
2225 catch (Exception exc)
\r
2227 MessageBox.Show(exc.ToString());
\r
2232 /// Set the GUI to it's started encoding state.
\r
2234 private void SetEncodeStarted()
\r
2238 if (InvokeRequired)
\r
2240 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2243 lbl_encode.Visible = true;
\r
2244 ProgressBarStatus.Value = 0;
\r
2245 ProgressBarStatus.Visible = true;
\r
2246 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2247 btn_start.Text = "Stop";
\r
2248 btn_start.ToolTipText = "Stop the encoding process.";
\r
2249 btn_start.Image = Properties.Resources.stop;
\r
2251 catch (Exception exc)
\r
2253 MessageBox.Show(exc.ToString());
\r
2258 /// Set the DVD Drive selection in the "Source" Menu
\r
2260 private void SetDriveSelectionMenuItem()
\r
2264 if (InvokeRequired)
\r
2266 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2270 drives = Main.GetDrives();
\r
2272 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2273 foreach (DriveInformation drive in drives)
\r
2275 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2277 Name = drive.ToString(),
\r
2278 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2279 Image = Resources.disc_small
\r
2281 menuItem.Click += new EventHandler(mnu_dvd_drive_Click);
\r
2282 menuItems.Add(menuItem);
\r
2285 foreach (ToolStripMenuItem item in menuItems)
\r
2286 btn_source.DropDownItems.Add(item);
\r
2288 catch (Exception exc)
\r
2290 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2295 /// Access the preset Handler and setup the preset panel.
\r
2297 private void LoadPresetPanel()
\r
2299 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2300 if (!Properties.Settings.Default.presetNotification)
\r
2301 MessageBox.Show(splash,
\r
2302 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2303 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2305 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2306 treeView_presets.Update();
\r
2310 /// Get the title from the selected item in the title dropdown.
\r
2315 private int getTitle()
\r
2318 if (drp_dvdtitle.SelectedItem != null)
\r
2320 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2321 int.TryParse(titleInfo[0], out title);
\r
2328 /// Handle the Update Check Finishing.
\r
2330 /// <param name="result">
\r
2333 private void updateCheckDoneMenu(IAsyncResult result)
\r
2335 // Make sure it's running on the calling thread
\r
2336 if (InvokeRequired)
\r
2338 Invoke(new MethodInvoker(() => updateCheckDoneMenu(result)));
\r
2341 UpdateCheckInformation info;
\r
2344 // Get the information about the new build, if any, and close the window
\r
2345 info = Main.EndCheckForUpdates(result);
\r
2347 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2349 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
2350 updateWindow.ShowDialog();
\r
2353 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2354 MessageBoxIcon.Information);
\r
2355 lbl_updateCheck.Visible = false;
\r
2358 catch (Exception ex)
\r
2360 if ((bool)result.AsyncState)
\r
2362 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2363 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2372 /// Handle GUI shortcuts
\r
2374 /// <param name="msg">Message</param>
\r
2375 /// <param name="keyData">Keys</param>
\r
2376 /// <returns>Bool</returns>
\r
2377 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2379 if (keyData == (Keys.Control | Keys.S))
\r
2381 btn_start_Click(this, new EventArgs());
\r
2385 if (keyData == (Keys.Control | Keys.A))
\r
2387 btn_add2Queue_Click(this, new EventArgs());
\r
2390 return base.ProcessCmdKey(ref msg, keyData);
\r
2394 /// If the queue is being processed, prompt the user to confirm application close.
\r
2396 /// <param name="e">FormClosingEventArgs</param>
\r
2397 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2399 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2400 if (encodeQueue.IsEncoding)
\r
2402 DialogResult result =
\r
2404 "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",
\r
2405 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
2407 if (result == DialogResult.No)
\r
2410 // Try to safely close out if we can, or kill the cli if using in-gui status
\r
2411 if (Settings.Default.enocdeStatusInGui)
\r
2412 encodeQueue.Stop();
\r
2414 encodeQueue.SafelyClose();
\r
2417 if (SourceScan.IsScanning)
\r
2419 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2420 SourceScan.Stop();
\r
2422 base.OnFormClosing(e);
\r
2427 #region In-GUI Encode Status
\r
2430 /// Starts a new thread to monitor and process the CLI encode status
\r
2432 private void EncodeMonitorThread()
\r
2436 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);
\r
2437 encode.OnEncodeProgress += EncodeOnEncodeProgress;
\r
2438 while (!encode.EndOfStream)
\r
2439 encode.ReadEncodeStatus();
\r
2441 SetEncodeFinished();
\r
2443 catch (Exception exc)
\r
2445 MessageBox.Show(exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2450 /// Displays the Encode status in the GUI
\r
2452 /// <param name="sender">The sender</param>
\r
2453 /// <param name="currentTask">The current task</param>
\r
2454 /// <param name="taskCount">Number of tasks</param>
\r
2455 /// <param name="percentComplete">Percent complete</param>
\r
2456 /// <param name="currentFps">Current encode speed in fps</param>
\r
2457 /// <param name="av">Avg encode speed</param>
\r
2458 /// <param name="timeRemaining">Time Left</param>
\r
2459 private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float av, TimeSpan timeRemaining)
\r
2461 if (this.InvokeRequired)
\r
2464 new EncodeProgressEventHandler(EncodeOnEncodeProgress),
\r
2465 new[] { sender, currentTask, taskCount, percentComplete, currentFps, av, timeRemaining });
\r
2470 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}",
\r
2476 ProgressBarStatus.Value = (int)Math.Round(percentComplete);
\r
2481 // This is the END of the road ****************************************
\r