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
52 // Delegates **********************************************************
\r
53 private delegate void UpdateWindowHandler();
\r
55 // Applicaiton Startup ************************************************
\r
60 /// Gets SourceName.
\r
62 public string SourceName
\r
66 if (this.selectedSourceType == SourceType.DvdDrive)
\r
68 return this.dvdDriveLabel;
\r
71 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
72 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
74 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
80 #region Application Startup
\r
83 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
85 /// <param name="args">
\r
86 /// The arguments passed in on application startup.
\r
88 public frmMain(string[] args)
\r
90 // Load and setup the splash screen in this thread
\r
92 Label lblStatus = new Label { Size = new Size(150, 20), Location = new Point(182, 102) };
\r
93 splash.Controls.Add(lblStatus);
\r
95 InitializeComponent();
\r
97 // Update the users config file with the CLI version data.
\r
98 UpdateSplashStatus(lblStatus, "Checking CLI Version Data ...");
\r
99 Main.SetCliVersionData();
\r
100 Main.CheckForValidCliVersion();
\r
102 if (Settings.Default.hb_version.Contains("svn"))
\r
104 Version v = Assembly.GetExecutingAssembly().GetName().Version;
\r
105 this.Text += " " + v.ToString(4);
\r
108 // Show the form, but leave disabled until preloading is complete then show the main form)
\r
109 this.Enabled = false;
\r
111 Application.DoEvents(); // Forces frmMain to draw
\r
113 // Check for new versions, if update checking is enabled
\r
114 if (Properties.Settings.Default.updateStatus)
\r
116 DateTime now = DateTime.Now;
\r
117 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;
\r
118 TimeSpan elapsed = now.Subtract(lastCheck);
\r
119 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
121 UpdateSplashStatus(lblStatus, "Checking for updates ...");
\r
122 Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);
\r
126 // Clear the log files in the background
\r
127 if (Properties.Settings.Default.clearOldLogs)
\r
129 UpdateSplashStatus(lblStatus, "Clearing Old Log Files ..");
\r
130 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
134 // Setup the GUI components
\r
135 UpdateSplashStatus(lblStatus, "Setting up the GUI ...");
\r
136 LoadPresetPanel(); // Load the Preset Panel
\r
137 treeView_presets.ExpandAll();
\r
138 lbl_encode.Text = string.Empty;
\r
139 drop_mode.SelectedIndex = 0;
\r
140 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
141 if (!Properties.Settings.Default.QueryEditorTab)
\r
142 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
143 if (Properties.Settings.Default.tooltipEnable)
\r
144 ToolTip.Active = true;
\r
146 // Load the user's default settings or Normal Preset
\r
147 if (Properties.Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
149 string query = presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).Query;
\r
152 x264Panel.Reset2Defaults();
\r
154 QueryParser presetQuery = QueryParser.Parse(query);
\r
155 PresetLoader.LoadPreset(this, presetQuery, Properties.Settings.Default.defaultPreset,
\r
156 presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).PictureSettings);
\r
158 x264Panel.StandardizeOptString();
\r
159 x264Panel.SetCurrentSettingsInPanel();
\r
163 loadNormalPreset();
\r
165 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
166 GrowlCommunicator.Register();
\r
168 // Finished Loading
\r
169 UpdateSplashStatus(lblStatus, "Loading Complete.");
\r
172 this.Enabled = true;
\r
174 // Event Handlers and Queue Recovery
\r
178 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
179 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
181 this.StartScan(args[0], 0);
\r
185 private void UpdateCheckDone(IAsyncResult result)
\r
187 if (InvokeRequired)
\r
189 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
193 UpdateCheckInformation info;
\r
197 info = Main.EndCheckForUpdates(result);
\r
199 if (info.NewVersionAvailable)
\r
201 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
202 updateWindow.ShowDialog();
\r
205 catch (Exception ex)
\r
207 if ((bool)result.AsyncState)
\r
208 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
212 // Startup Functions
\r
213 private void queueRecovery()
\r
215 if (Main.CheckQueueRecovery())
\r
217 DialogResult result =
\r
219 "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",
\r
220 "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
222 if (result == DialogResult.Yes)
\r
223 encodeQueue.LoadQueueFromFile("hb_queue_recovery.xml"); // Start Recovery
\r
226 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
227 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
228 if (File.Exists(queuePath))
\r
229 File.Delete(queuePath);
\r
234 private void UpdateSplashStatus(Label status, string text)
\r
236 status.Text = text;
\r
237 Application.DoEvents();
\r
244 // Encoding Events for setting up the GUI
\r
245 private void events()
\r
247 // Handle Widget changes when preset is selected.
\r
248 RegisterPresetEventHandler();
\r
250 // Handle Window Resize
\r
251 if (Properties.Settings.Default.MainWindowMinimize)
\r
252 this.Resize += new EventHandler(frmMain_Resize);
\r
254 // Handle Encode Start / Finish / Pause
\r
255 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
256 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
258 // Handle a file being draged onto the GUI.
\r
259 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
260 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
263 // 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
264 private void RegisterPresetEventHandler()
\r
267 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
268 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
269 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
270 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
272 // Picture Settings
\r
273 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
276 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
279 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
280 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
281 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
282 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
283 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
284 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
287 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
290 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
293 private void UnRegisterPresetEventHandler()
\r
295 // Output Settings
\r
296 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
297 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
298 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
299 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
301 // Picture Settings
\r
302 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
305 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
308 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
309 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
310 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
311 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
312 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
313 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
316 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
319 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
322 private void changePresetLabel(object sender, EventArgs e)
\r
324 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
325 CurrentlySelectedPreset = null;
\r
328 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
330 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
331 e.Effect = DragDropEffects.All;
\r
334 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
336 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
337 sourcePath = string.Empty;
\r
339 if (fileList != null)
\r
341 if (!string.IsNullOrEmpty(fileList[0]))
\r
343 this.selectedSourceType = SourceType.VideoFile;
\r
344 StartScan(fileList[0], 0);
\r
347 UpdateSourceLabel();
\r
350 UpdateSourceLabel();
\r
353 private void encodeStarted(object sender, EventArgs e)
\r
355 SetEncodeStarted();
\r
356 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
359 private void encodeEnded(object sender, EventArgs e)
\r
361 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
362 SetEncodeFinished();
\r
366 // User Interface Menus / Tool Strips *********************************
\r
371 /// Kill The scan menu Item
\r
373 /// <param name="sender">
\r
376 /// <param name="e">
\r
379 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
385 /// Exit the Application Menu Item
\r
387 /// <param name="sender">
\r
390 /// <param name="e">
\r
393 private void mnu_exit_Click(object sender, EventArgs e)
\r
395 Application.Exit();
\r
403 /// Menu - Start Button
\r
405 /// <param name="sender">
\r
408 /// <param name="e">
\r
411 private void mnu_encode_Click(object sender, EventArgs e)
\r
413 queueWindow.Show();
\r
417 /// Menu - Display the Log Window
\r
419 /// <param name="sender">
\r
422 /// <param name="e">
\r
425 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
427 frmActivityWindow dvdInfoWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
428 dvdInfoWindow.Show();
\r
432 /// Menu - Display the Options Window
\r
434 /// <param name="sender">
\r
437 /// <param name="e">
\r
440 private void mnu_options_Click(object sender, EventArgs e)
\r
442 Form options = new frmOptions(this);
\r
443 options.ShowDialog();
\r
448 #region Presets Menu
\r
451 /// Reset the Built in Presets
\r
453 /// <param name="sender">
\r
456 /// <param name="e">
\r
459 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
461 presetHandler.UpdateBuiltInPresets();
\r
463 if (treeView_presets.Nodes.Count == 0)
\r
465 "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
466 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
468 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
470 treeView_presets.ExpandAll();
\r
474 /// Delete the selected preset
\r
476 /// <param name="sender">
\r
479 /// <param name="e">
\r
482 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
484 presetHandler.RemoveBuiltInPresets();
\r
485 LoadPresetPanel(); // Reload the preset panel
\r
489 /// Select the Normal preset
\r
491 /// <param name="sender">
\r
494 /// <param name="e">
\r
497 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
499 loadNormalPreset();
\r
503 /// Import a plist Preset
\r
505 /// <param name="sender">
\r
508 /// <param name="e">
\r
511 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
517 /// Export a Plist Preset
\r
519 /// <param name="sender">
\r
522 /// <param name="e">
\r
525 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
531 /// Create a new Preset
\r
533 /// <param name="sender">
\r
536 /// <param name="e">
\r
539 private void btn_new_preset_Click(object sender, EventArgs e)
\r
541 Form preset = new frmAddPreset(this, QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
543 preset.ShowDialog();
\r
551 /// Menu - Display the User Guide Web Page
\r
553 /// <param name="sender">
\r
556 /// <param name="e">
\r
559 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
561 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
565 /// Menu - Check for Updates
\r
567 /// <param name="sender">
\r
570 /// <param name="e">
\r
573 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
575 lbl_updateCheck.Visible = true;
\r
576 Main.BeginCheckForUpdates(new AsyncCallback(this.UpdateCheckDoneMenu), false);
\r
580 /// Menu - Display the About Window
\r
582 /// <param name="sender">
\r
585 /// <param name="e">
\r
588 private void mnu_about_Click(object sender, EventArgs e)
\r
590 using (frmAbout About = new frmAbout())
\r
592 About.ShowDialog();
\r
601 /// RMenu - Expand All
\r
603 /// <param name="sender">
\r
606 /// <param name="e">
\r
609 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
611 treeView_presets.ExpandAll();
\r
615 /// RMenu - Collaspe All
\r
617 /// <param name="sender">
\r
620 /// <param name="e">
\r
623 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
625 treeView_presets.CollapseAll();
\r
629 /// Menu - Import Preset
\r
631 /// <param name="sender">
\r
634 /// <param name="e">
\r
637 private void pmnu_import_Click(object sender, EventArgs e)
\r
643 /// RMenu - Save Changes to Preset
\r
645 /// <param name="sender">
\r
648 /// <param name="e">
\r
651 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
653 DialogResult result =
\r
655 "Do you wish to include picture settings when updating the preset: " +
\r
656 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
657 MessageBoxIcon.Question);
\r
658 if (result == DialogResult.Yes)
\r
659 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
660 QueryGenerator.GenerateTabbedComponentsQuery(this), true);
\r
661 else if (result == DialogResult.No)
\r
662 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
663 QueryGenerator.GenerateTabbedComponentsQuery(this), false);
\r
667 /// RMenu - Delete Preset
\r
669 /// <param name="sender">
\r
672 /// <param name="e">
\r
675 private void pmnu_delete_click(object sender, EventArgs e)
\r
677 if (treeView_presets.SelectedNode != null)
\r
679 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
680 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
682 treeView_presets.Select();
\r
686 /// Preset Menu Is Opening. Setup the Menu
\r
688 /// <param name="sender">
\r
691 /// <param name="e">
\r
694 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
696 // Make sure that the save menu is always disabled by default
\r
697 pmnu_saveChanges.Enabled = false;
\r
699 // Now enable the save menu if the selected preset is a user preset
\r
700 if (treeView_presets.SelectedNode != null)
\r
701 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
702 pmnu_saveChanges.Enabled = true;
\r
704 treeView_presets.Select();
\r
707 // Presets Management
\r
710 /// Button - Add a preset
\r
712 /// <param name="sender">
\r
715 /// <param name="e">
\r
718 private void btn_addPreset_Click(object sender, EventArgs e)
\r
720 Form preset = new frmAddPreset(this, QueryGenerator.GenerateTabbedComponentsQuery(this), presetHandler);
\r
721 preset.ShowDialog();
\r
725 /// Button - remove a Preset
\r
727 /// <param name="sender">
\r
730 /// <param name="e">
\r
733 private void btn_removePreset_Click(object sender, EventArgs e)
\r
735 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
736 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
737 if (result == DialogResult.Yes)
\r
739 if (treeView_presets.SelectedNode != null)
\r
741 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
742 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
745 treeView_presets.Select();
\r
749 /// Button - Set the selected preset as the default
\r
751 /// <param name="sender">
\r
754 /// <param name="e">
\r
757 private void btn_setDefault_Click(object sender, EventArgs e)
\r
759 if (treeView_presets.SelectedNode != null)
\r
761 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
762 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
763 if (result == DialogResult.Yes)
\r
765 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
766 Properties.Settings.Default.Save();
\r
767 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
771 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
775 /// PresetBar Mouse Down event
\r
777 /// <param name="sender">
\r
780 /// <param name="e">
\r
783 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
785 if (e.Button == MouseButtons.Right)
\r
786 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
787 else if (e.Button == MouseButtons.Left)
\r
789 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
791 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
796 treeView_presets.Select();
\r
800 /// Preset Bar after selecting the preset
\r
802 /// <param name="sender">
\r
805 /// <param name="e">
\r
808 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
814 /// Preset Bar - Handle the Delete Key
\r
816 /// <param name="sender">
\r
819 /// <param name="e">
\r
822 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
824 if (e.KeyCode == Keys.Delete)
\r
826 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
827 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
828 if (result == DialogResult.Yes)
\r
830 if (treeView_presets.SelectedNode != null)
\r
831 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
833 // Remember each nodes expanded status so we can reload it
\r
834 List<bool> nodeStatus = new List<bool>();
\r
835 foreach (TreeNode node in treeView_presets.Nodes)
\r
836 nodeStatus.Add(node.IsExpanded);
\r
838 // Now reload the preset panel
\r
841 // And finally, re-expand any of the nodes if required
\r
843 foreach (TreeNode node in treeView_presets.Nodes)
\r
855 /// Select the selected preset and setup the GUI
\r
857 private void selectPreset()
\r
859 if (treeView_presets.SelectedNode != null)
\r
861 // Ok, so, we've selected a preset. Now we want to load it.
\r
862 string presetName = treeView_presets.SelectedNode.Text;
\r
863 Preset preset = presetHandler.GetPreset(presetName);
\r
864 if (preset != null)
\r
866 string query = presetHandler.GetPreset(presetName).Query;
\r
867 bool loadPictureSettings = presetHandler.GetPreset(presetName).PictureSettings;
\r
871 // Ok, Reset all the H264 widgets before changing the preset
\r
872 x264Panel.Reset2Defaults();
\r
874 // Send the query from the file to the Query Parser class
\r
875 QueryParser presetQuery = QueryParser.Parse(query);
\r
877 // Now load the preset
\r
878 PresetLoader.LoadPreset(this, presetQuery, presetName, loadPictureSettings);
\r
880 // The x264 widgets will need updated, so do this now:
\r
881 x264Panel.StandardizeOptString();
\r
882 x264Panel.SetCurrentSettingsInPanel();
\r
884 // Finally, let this window have a copy of the preset settings.
\r
885 CurrentlySelectedPreset = preset;
\r
886 PictureSettings.SetPresetCropWarningLabel(preset);
\r
893 /// Load the Normal Preset
\r
895 private void loadNormalPreset()
\r
897 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
899 foreach (TreeNode node in treenode.Nodes)
\r
901 if (node.Text.Equals("Normal"))
\r
902 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
908 /// Import a plist preset
\r
910 private void ImportPreset()
\r
912 if (openPreset.ShowDialog() == DialogResult.OK)
\r
914 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
915 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
917 DialogResult result =
\r
918 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
919 "Overwrite preset?",
\r
920 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
921 if (result == DialogResult.Yes)
\r
923 PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);
\r
924 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
925 QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
926 parsed.UsesPictureSettings);
\r
931 PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);
\r
932 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
933 QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),
\r
934 parsed.UsesPictureSettings))
\r
936 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
938 ForeColor = Color.Black
\r
940 treeView_presets.Nodes.Add(preset_treeview);
\r
947 /// Export a plist Preset
\r
949 private void ExportPreset()
\r
951 MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
954 SaveFileDialog savefiledialog = new SaveFileDialog();
\r
955 savefiledialog.Filter = "plist|*.plist";
\r
957 if (treeView_presets.SelectedNode != null)
\r
960 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
962 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
963 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
973 /// 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
975 /// <param name="sender">
\r
978 /// <param name="e">
\r
981 private void btn_source_Click(object sender, EventArgs e)
\r
983 // Remove old Drive Menu Items.
\r
984 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
985 foreach (var item in btn_source.DropDownItems)
\r
987 if (item.GetType() == typeof(ToolStripMenuItem))
\r
989 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
990 if (menuItem.Name.StartsWith("Drive"))
\r
992 itemsToRemove.Add(menuItem);
\r
997 foreach (ToolStripMenuItem item in itemsToRemove)
\r
998 btn_source.DropDownItems.Remove(item);
\r
1000 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
1001 driveInfoThread.Start();
\r
1005 /// Toolbar - Start The Encode
\r
1007 /// <param name="sender">
\r
1010 /// <param name="e">
\r
1013 private void btn_start_Click(object sender, EventArgs e)
\r
1015 if (btn_start.Text == "Stop")
\r
1017 DialogResult result;
\r
1018 if (Properties.Settings.Default.enocdeStatusInGui &&
\r
1019 !Properties.Settings.Default.showCliForInGuiEncodeStatus)
\r
1021 result = MessageBox.Show(
\r
1022 "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
1023 "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1027 result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?",
\r
1028 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1031 if (result == DialogResult.Yes)
\r
1033 // Pause The Queue
\r
1034 encodeQueue.Pause();
\r
1036 if (Properties.Settings.Default.enocdeStatusInGui &&
\r
1037 !Properties.Settings.Default.showCliForInGuiEncodeStatus)
\r
1039 encodeQueue.Stop();
\r
1043 encodeQueue.SafelyClose();
\r
1049 if (encodeQueue.Count != 0 ||
\r
1050 (!string.IsNullOrEmpty(sourcePath) && !string.IsNullOrEmpty(text_destination.Text)))
\r
1052 string generatedQuery = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1053 string specifiedQuery = rtf_query.Text != string.Empty
\r
1055 : QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1056 string query = string.Empty;
\r
1058 // Check to make sure the generated query matches the GUI settings
\r
1059 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1060 generatedQuery != specifiedQuery)
\r
1062 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1063 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1064 "priority over the GUI, your recently updated settings will not be taken " +
\r
1065 "into account when encoding this job." +
\r
1066 Environment.NewLine + Environment.NewLine +
\r
1067 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1068 "Manual Query does not Match GUI",
\r
1069 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1070 MessageBoxDefaultButton.Button3);
\r
1074 case DialogResult.Yes:
\r
1075 // Replace the manual query with the generated one
\r
1076 query = generatedQuery;
\r
1077 rtf_query.Text = generatedQuery;
\r
1079 case DialogResult.No:
\r
1080 // Use the manual query
\r
1081 query = specifiedQuery;
\r
1083 case DialogResult.Cancel:
\r
1084 // Don't start the encode
\r
1090 query = specifiedQuery;
\r
1093 DialogResult overwrite = DialogResult.Yes;
\r
1094 if (text_destination.Text != string.Empty)
\r
1095 if (File.Exists(text_destination.Text))
\r
1098 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1099 "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1101 if (overwrite == DialogResult.Yes)
\r
1103 if (encodeQueue.Count == 0)
\r
1104 encodeQueue.Add(query, this.GetTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1106 queueWindow.SetQueue();
\r
1107 if (encodeQueue.Count > 1)
\r
1108 queueWindow.Show(false);
\r
1110 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1111 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1116 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1117 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1118 MessageBoxIcon.Warning);
\r
1123 /// Toolbar - Add the current job to the Queue
\r
1125 /// <param name="sender">
\r
1128 /// <param name="e">
\r
1131 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1133 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1134 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1137 if (!Directory.Exists(Path.GetDirectoryName(text_destination.Text)))
\r
1139 MessageBox.Show("Destination Path does not exist.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1143 string query = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1144 if (rtf_query.Text != string.Empty)
\r
1145 query = rtf_query.Text;
\r
1147 if (encodeQueue.CheckForDestinationDuplicate(text_destination.Text))
\r
1149 DialogResult result =
\r
1151 "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
1152 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
1153 if (result == DialogResult.Yes)
\r
1154 encodeQueue.Add(query, this.GetTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1157 encodeQueue.Add(query, this.GetTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));
\r
1159 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1161 queueWindow.Show();
\r
1166 /// Toolbar - Show the Queue
\r
1168 /// <param name="sender">
\r
1171 /// <param name="e">
\r
1174 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1176 queueWindow.Show();
\r
1177 queueWindow.Activate();
\r
1181 /// Toolbar - Show the Preview Window
\r
1183 /// <param name="sender">
\r
1186 /// <param name="e">
\r
1189 private void tb_preview_Click(object sender, EventArgs e)
\r
1191 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1192 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1193 MessageBoxIcon.Warning);
\r
1196 if (qtpreview == null)
\r
1198 qtpreview = new frmPreview(this);
\r
1201 else if (qtpreview.IsDisposed)
\r
1203 qtpreview = new frmPreview(this);
\r
1207 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1208 MessageBoxIcon.Warning);
\r
1213 /// Toolbar - Show the Activity log Window
\r
1215 /// <param name="sender">
\r
1218 /// <param name="e">
\r
1221 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1223 if (ActivityWindow == null || !ActivityWindow.IsHandleCreated)
\r
1224 ActivityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1226 ActivityWindow.Show();
\r
1227 ActivityWindow.Activate();
\r
1232 #region System Tray Icon
\r
1235 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1237 /// <param name="sender">
\r
1240 /// <param name="e">
\r
1243 private void frmMain_Resize(object sender, EventArgs e)
\r
1245 if (FormWindowState.Minimized == this.WindowState)
\r
1247 notifyIcon.Visible = true;
\r
1250 else if (FormWindowState.Normal == this.WindowState)
\r
1251 notifyIcon.Visible = false;
\r
1255 /// Double Click the Tray Icon
\r
1257 /// <param name="sender">
\r
1260 /// <param name="e">
\r
1263 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1265 this.Visible = true;
\r
1267 this.WindowState = FormWindowState.Normal;
\r
1268 notifyIcon.Visible = false;
\r
1272 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1274 /// <param name="sender">
\r
1277 /// <param name="e">
\r
1280 private void btn_restore_Click(object sender, EventArgs e)
\r
1282 this.Visible = true;
\r
1284 this.WindowState = FormWindowState.Normal;
\r
1285 notifyIcon.Visible = false;
\r
1290 #region Main Window and Tab Control
\r
1293 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
1295 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1297 this.selectedSourceType = SourceType.Folder;
\r
1298 SelectSource(DVD_Open.SelectedPath);
\r
1301 UpdateSourceLabel();
\r
1304 private void btn_file_source_Click(object sender, EventArgs e)
\r
1306 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1308 this.selectedSourceType = SourceType.VideoFile;
\r
1309 SelectSource(ISO_Open.FileName);
\r
1312 UpdateSourceLabel();
\r
1315 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
1317 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1320 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1322 if (int.TryParse(driveId, out id))
\r
1325 this.dvdDrivePath = drives[id].RootDirectory;
\r
1326 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1328 if (this.dvdDrivePath == null) return;
\r
1329 this.selectedSourceType = SourceType.DvdDrive;
\r
1330 SelectSource(this.dvdDrivePath);
\r
1335 private void SelectSource(string file)
\r
1337 Check_ChapterMarkers.Enabled = true;
\r
1338 sourcePath = string.Empty;
\r
1340 if (file == string.Empty) // Must have a file or path
\r
1342 UpdateSourceLabel();
\r
1346 sourcePath = Path.GetFileName(file);
\r
1347 StartScan(file, 0);
\r
1350 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1352 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1354 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1355 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1358 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1360 UnRegisterPresetEventHandler();
\r
1361 drop_mode.SelectedIndex = 0;
\r
1363 drop_chapterStart.Items.Clear();
\r
1364 drop_chapterFinish.Items.Clear();
\r
1366 // If the dropdown is set to automatic nothing else needs to be done.
\r
1367 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1368 if (drp_dvdtitle.Text != "Automatic")
\r
1370 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1371 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1372 PictureSettings.CurrentlySelectedPreset = CurrentlySelectedPreset;
\r
1373 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1375 // Populate the Angles dropdown
\r
1376 drop_angle.Items.Clear();
\r
1377 if (!Properties.Settings.Default.noDvdNav)
\r
1379 drop_angle.Visible = true;
\r
1380 lbl_angle.Visible = true;
\r
1382 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1383 drop_angle.Items.Add(i.ToString());
\r
1385 if (drop_angle.Items.Count != 0)
\r
1386 drop_angle.SelectedIndex = 0;
\r
1390 drop_angle.Visible = false;
\r
1391 lbl_angle.Visible = false;
\r
1394 // Populate the Start chapter Dropdown
\r
1395 drop_chapterStart.Items.Clear();
\r
1396 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1397 if (drop_chapterStart.Items.Count > 0)
\r
1398 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1400 // Populate the Final Chapter Dropdown
\r
1401 drop_chapterFinish.Items.Clear();
\r
1402 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1403 if (drop_chapterFinish.Items.Count > 0)
\r
1404 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1406 // Populate the Audio Channels Dropdown
\r
1407 AudioSettings.SetTrackList(selectedTitle, CurrentlySelectedPreset);
\r
1409 // Populate the Subtitles dropdown
\r
1410 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1412 // Update the source label if we have multiple streams
\r
1413 if (selectedTitle != null)
\r
1414 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1415 labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1417 // Run the AutoName & ChapterNaming functions
\r
1418 if (Properties.Settings.Default.autoNaming)
\r
1420 string autoPath = Main.AutoName(this);
\r
1421 if (autoPath != null)
\r
1422 text_destination.Text = autoPath;
\r
1425 "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
1426 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1429 data_chpt.Rows.Clear();
\r
1430 if (selectedTitle.Chapters.Count != 1)
\r
1432 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1433 if (chapterGridView != null)
\r
1434 data_chpt = chapterGridView;
\r
1438 Check_ChapterMarkers.Checked = false;
\r
1439 Check_ChapterMarkers.Enabled = false;
\r
1442 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1443 data_chpt.Columns[0].Width = 166;
\r
1444 data_chpt.Columns[0].Width = 165;
\r
1446 RegisterPresetEventHandler();
\r
1449 private void chapersChanged(object sender, EventArgs e)
\r
1451 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1454 Control ctl = (Control)sender;
\r
1455 int chapterStart, chapterEnd;
\r
1456 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1457 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1461 case "drop_chapterStart":
\r
1462 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1463 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1465 if (chapterEnd != 0)
\r
1466 if (chapterStart > chapterEnd)
\r
1467 drop_chapterFinish.Text = chapterStart.ToString();
\r
1469 case "drop_chapterFinish":
\r
1470 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1471 drop_chapterStart.SelectedIndex = 0;
\r
1473 if (chapterStart != 0)
\r
1474 if (chapterEnd < chapterStart)
\r
1475 drop_chapterFinish.Text = chapterStart.ToString();
\r
1477 // Add more rows to the Chapter menu if needed.
\r
1478 if (Check_ChapterMarkers.Checked)
\r
1480 int i = data_chpt.Rows.Count, finish = 0;
\r
1481 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1483 while (i < finish)
\r
1485 int n = data_chpt.Rows.Add();
\r
1486 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1487 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1488 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1489 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1496 // Update the Duration
\r
1497 lbl_duration.Text =
\r
1498 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1501 // Run the Autonaming function
\r
1502 if (Properties.Settings.Default.autoNaming)
\r
1503 text_destination.Text = Main.AutoName(this);
\r
1505 // Disable chapter markers if only 1 chapter is selected.
\r
1506 if (chapterStart == chapterEnd)
\r
1508 Check_ChapterMarkers.Enabled = false;
\r
1509 btn_importChapters.Enabled = false;
\r
1510 data_chpt.Enabled = false;
\r
1514 Check_ChapterMarkers.Enabled = true;
\r
1515 if (Check_ChapterMarkers.Checked)
\r
1517 btn_importChapters.Enabled = true;
\r
1518 data_chpt.Enabled = true;
\r
1523 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1526 int.TryParse(drop_chapterStart.Text, out start);
\r
1527 int.TryParse(drop_chapterFinish.Text, out end);
\r
1528 double duration = end - start;
\r
1530 switch (drop_mode.SelectedIndex)
\r
1533 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1536 if (selectedTitle != null)
\r
1538 duration = duration / selectedTitle.Fps;
\r
1539 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1542 lbl_duration.Text = "--:--:--";
\r
1548 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1551 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1552 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1555 switch (drop_mode.SelectedIndex)
\r
1558 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1559 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1560 if (drop_chapterStart.Items.Count != 0)
\r
1562 drop_chapterStart.SelectedIndex = 0;
\r
1563 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1566 lbl_duration.Text = "--:--:--";
\r
1569 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1570 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1571 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1572 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1573 if (selectedTitle != null)
\r
1575 drop_chapterStart.Text = "0";
\r
1576 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1580 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1581 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1582 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1583 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1584 if (selectedTitle != null)
\r
1586 drop_chapterStart.Text = "0";
\r
1587 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1594 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1596 // This removes the file extension from the filename box on the save file dialog.
\r
1597 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1598 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1600 if (Path.IsPathRooted(text_destination.Text))
\r
1601 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1603 // Show the dialog and set the main form file path
\r
1604 if (drop_format.SelectedIndex.Equals(0))
\r
1605 DVD_Save.FilterIndex = 1;
\r
1606 else if (drop_format.SelectedIndex.Equals(1))
\r
1607 DVD_Save.FilterIndex = 2;
\r
1609 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1611 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1612 switch (DVD_Save.FilterIndex)
\r
1616 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1617 StringComparison.InvariantCultureIgnoreCase))
\r
1618 if (Properties.Settings.Default.useM4v)
\r
1619 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1621 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1625 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1626 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1632 text_destination.Text = DVD_Save.FileName;
\r
1634 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1635 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1636 SetExtension(".m4v");
\r
1640 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1642 string path = text_destination.Text;
\r
1643 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1644 drop_format.SelectedIndex = 0;
\r
1645 else if (path.EndsWith(".mkv"))
\r
1646 drop_format.SelectedIndex = 1;
\r
1649 // Output Settings
\r
1650 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1652 switch (drop_format.SelectedIndex)
\r
1655 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1656 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1657 SetExtension(".m4v");
\r
1659 SetExtension(".mp4");
\r
1662 SetExtension(".mkv");
\r
1666 AudioSettings.SetContainer(drop_format.Text);
\r
1668 if (drop_format.Text.Contains("MP4"))
\r
1670 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1672 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1673 drp_videoEncoder.SelectedIndex = 1;
\r
1676 else if (drop_format.Text.Contains("MKV"))
\r
1677 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1680 public void SetExtension(string newExtension)
\r
1682 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1683 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1684 Subtitles.RequiresM4V())
\r
1685 newExtension = ".m4v";
\r
1687 newExtension = ".mp4";
\r
1689 if (Path.HasExtension(newExtension))
\r
1690 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1694 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1696 setContainerOpts();
\r
1698 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1699 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1701 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1702 check_turbo.Enabled = true;
\r
1704 tab_advanced.Enabled = true;
\r
1705 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1706 check_iPodAtom.Enabled = true;
\r
1708 check_iPodAtom.Enabled = false;
\r
1712 check_turbo.CheckState = CheckState.Unchecked;
\r
1713 check_turbo.Enabled = false;
\r
1714 tab_advanced.Enabled = false;
\r
1715 x264Panel.X264Query = string.Empty;
\r
1716 check_iPodAtom.Enabled = false;
\r
1717 check_iPodAtom.Checked = false;
\r
1720 // Setup the CQ Slider
\r
1721 switch (drp_videoEncoder.Text)
\r
1723 case "MPEG-4 (FFmpeg)":
\r
1724 if (slider_videoQuality.Value > 31)
\r
1725 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1726 slider_videoQuality.Minimum = 1;
\r
1727 slider_videoQuality.Maximum = 31;
\r
1729 case "H.264 (x264)":
\r
1730 slider_videoQuality.Minimum = 0;
\r
1731 slider_videoQuality.TickFrequency = 1;
\r
1733 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1734 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1735 double multiplier = 1.0 / cqStep;
\r
1736 double value = slider_videoQuality.Value * multiplier;
\r
1738 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1740 if (value < slider_videoQuality.Maximum)
\r
1741 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1744 case "VP3 (Theora)":
\r
1745 if (slider_videoQuality.Value > 63)
\r
1746 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1747 slider_videoQuality.Minimum = 0;
\r
1748 slider_videoQuality.Maximum = 63;
\r
1754 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1756 /// <param name="sender">
\r
1759 /// <param name="e">
\r
1762 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1764 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1766 this.checkMaximumFramerate.Visible = false;
\r
1767 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1771 this.checkMaximumFramerate.Visible = true;
\r
1776 /// Set the container format options
\r
1778 public void setContainerOpts()
\r
1780 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1782 check_largeFile.Enabled = true;
\r
1783 check_optimiseMP4.Enabled = true;
\r
1784 check_iPodAtom.Enabled = true;
\r
1788 check_largeFile.Enabled = false;
\r
1789 check_optimiseMP4.Enabled = false;
\r
1790 check_iPodAtom.Enabled = false;
\r
1791 check_largeFile.Checked = false;
\r
1792 check_optimiseMP4.Checked = false;
\r
1793 check_iPodAtom.Checked = false;
\r
1797 private double _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1800 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1802 public void setQualityFromSlider()
\r
1804 // Work out the current RF value.
\r
1805 double cqStep = _cachedCqStep;
\r
1806 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1808 // Change the maximum value for the slider
\r
1809 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1811 // Reset the CQ slider to RF0
\r
1812 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1814 // Reset the CQ slider back to the previous value as close as possible
\r
1815 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1816 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1817 while (rfValueCurrent < rfValue)
\r
1819 slider_videoQuality.Value--;
\r
1820 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1823 // Cache the CQ step for the next calculation
\r
1824 _cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1827 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1829 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1830 switch (drp_videoEncoder.Text)
\r
1832 case "MPEG-4 (FFmpeg)":
\r
1833 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1835 case "H.264 (x264)":
\r
1836 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1837 rfValue = Math.Round(rfValue, 2);
\r
1838 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1840 case "VP3 (Theora)":
\r
1841 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1846 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1848 text_bitrate.Enabled = false;
\r
1849 text_filesize.Enabled = true;
\r
1850 slider_videoQuality.Enabled = false;
\r
1852 check_2PassEncode.Enabled = true;
\r
1855 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1857 text_bitrate.Enabled = true;
\r
1858 text_filesize.Enabled = false;
\r
1859 slider_videoQuality.Enabled = false;
\r
1861 check_2PassEncode.Enabled = true;
\r
1864 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1866 text_bitrate.Enabled = false;
\r
1867 text_filesize.Enabled = false;
\r
1868 slider_videoQuality.Enabled = true;
\r
1870 check_2PassEncode.Enabled = false;
\r
1871 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1874 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1876 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1878 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1879 check_turbo.Enabled = true;
\r
1883 check_turbo.Enabled = false;
\r
1884 check_turbo.CheckState = CheckState.Unchecked;
\r
1888 // Chapter Marker Tab
\r
1889 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1891 if (Check_ChapterMarkers.Checked)
\r
1893 if (drop_format.SelectedIndex != 1)
\r
1894 SetExtension(".m4v");
\r
1895 data_chpt.Enabled = true;
\r
1896 btn_importChapters.Enabled = true;
\r
1900 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
1901 SetExtension(".mp4");
\r
1902 data_chpt.Enabled = false;
\r
1903 btn_importChapters.Enabled = false;
\r
1907 private void btn_importChapters_Click(object sender, EventArgs e)
\r
1909 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
1911 string filename = File_ChapterImport.FileName;
\r
1912 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
1913 if (imported != null)
\r
1914 data_chpt = imported;
\r
1918 private void btn_export_Click(object sender, EventArgs e)
\r
1920 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
1921 saveFileDialog.Filter = "Csv File|*.csv";
\r
1922 saveFileDialog.DefaultExt = "csv";
\r
1923 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
1925 string filename = saveFileDialog.FileName;
\r
1927 Main.SaveChapterMarkersToCsv(this, filename);
\r
1931 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
1933 data_chpt.Rows.Clear();
\r
1934 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1935 if (chapterGridView != null)
\r
1937 data_chpt = chapterGridView;
\r
1941 // Query Editor Tab
\r
1942 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1944 rtf_query.Text = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);
\r
1947 private void btn_clear_Click(object sender, EventArgs e)
\r
1949 rtf_query.Clear();
\r
1954 // MainWindow Components, Actions and Functions ***********************
\r
1956 #region Source Scan
\r
1959 /// Start the Scan Process
\r
1961 /// <param name="filename">
\r
1964 /// <param name="title">
\r
1967 private void StartScan(string filename, int title)
\r
1969 // Setup the GUI components for the scan.
\r
1970 sourcePath = filename;
\r
1972 this.DisableGUI();
\r
1977 SourceScan.Scan(sourcePath, title);
\r
1978 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
1979 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
1981 catch (Exception exc)
\r
1983 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1988 /// Update the Status label for the scan
\r
1990 /// <param name="sender">
\r
1993 /// <param name="e">
\r
1996 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
1998 UpdateScanStatusLabel();
\r
2002 /// Update the UI after the scan has completed
\r
2004 /// <param name="sender">
\r
2007 /// <param name="e">
\r
2010 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
2012 UpdateGuiAfterScan();
\r
2016 /// Update the Scan Status Label
\r
2018 private void UpdateScanStatusLabel()
\r
2020 if (InvokeRequired)
\r
2022 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
2025 lbl_encode.Text = SourceScan.ScanStatus;
\r
2029 /// Reset the GUI when the scan has completed
\r
2031 private void UpdateGuiAfterScan()
\r
2033 if (InvokeRequired)
\r
2035 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2041 currentSource = SourceScan.SouceData;
\r
2043 // Setup some GUI components
\r
2044 drp_dvdtitle.Items.Clear();
\r
2045 if (currentSource.Titles.Count != 0)
\r
2046 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2048 foreach (Title title in currentSource.Titles)
\r
2050 if (title.MainTitle)
\r
2052 drp_dvdtitle.SelectedItem = title;
\r
2056 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2058 drp_dvdtitle.SelectedIndex = 0;
\r
2061 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2062 if (drop_chapterStart.Items.Count > 0)
\r
2065 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2066 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2067 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2070 Check_ChapterMarkers.Enabled = false;
\r
2071 Check_ChapterMarkers.Checked = false;
\r
2072 data_chpt.Rows.Clear();
\r
2076 // If no titles were found, Display an error message
\r
2077 if (drp_dvdtitle.Items.Count == 0)
\r
2080 "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
2081 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2082 sourcePath = string.Empty;
\r
2084 UpdateSourceLabel();
\r
2086 // Enable the GUI components and enable any disabled components
\r
2089 catch (Exception exc)
\r
2091 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2092 MessageBoxIcon.Error);
\r
2098 /// Enable the GUI
\r
2100 private void EnableGUI()
\r
2104 if (InvokeRequired)
\r
2105 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2106 lbl_encode.Text = "Scan Completed";
\r
2107 foreach (Control ctrl in Controls)
\r
2108 ctrl.Enabled = true;
\r
2109 btn_start.Enabled = true;
\r
2110 btn_showQueue.Enabled = true;
\r
2111 btn_add2Queue.Enabled = true;
\r
2112 tb_preview.Enabled = true;
\r
2113 btn_source.Enabled = true;
\r
2114 mnu_killCLI.Visible = false;
\r
2116 catch (Exception exc)
\r
2118 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2123 /// Disable the GUI
\r
2125 private void DisableGUI()
\r
2127 foreach (Control ctrl in Controls)
\r
2128 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2129 ctrl.Enabled = false;
\r
2131 lbl_encode.Visible = true;
\r
2132 lbl_encode.Text = "Scanning ...";
\r
2133 btn_source.Enabled = false;
\r
2134 btn_start.Enabled = false;
\r
2135 btn_showQueue.Enabled = false;
\r
2136 btn_add2Queue.Enabled = false;
\r
2137 tb_preview.Enabled = false;
\r
2138 mnu_killCLI.Visible = true;
\r
2144 private void KillScan()
\r
2146 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2150 SourceScan.Stop();
\r
2152 lbl_encode.Text = "Scan Cancelled!";
\r
2158 private void ResetGUI()
\r
2160 drp_dvdtitle.Items.Clear();
\r
2161 drop_chapterStart.Items.Clear();
\r
2162 drop_chapterFinish.Items.Clear();
\r
2163 lbl_duration.Text = "Select a Title";
\r
2164 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2165 sourcePath = String.Empty;
\r
2166 text_destination.Text = String.Empty;
\r
2167 selectedTitle = null;
\r
2171 /// Update the Source Label
\r
2173 private void UpdateSourceLabel()
\r
2175 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2177 if (selectedTitle != null)
\r
2178 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
2179 // If it's one of multiple source files, make sure we don't use the folder name
\r
2180 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
2184 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2186 /// <param name="job">
\r
2189 public void RecievingJob(Job job)
\r
2191 string query = job.Query;
\r
2192 StartScan(job.Source, job.Title);
\r
2194 if (query != null)
\r
2196 // Ok, Reset all the H264 widgets before changing the preset
\r
2197 x264Panel.Reset2Defaults();
\r
2199 // Send the query from the file to the Query Parser class
\r
2200 QueryParser presetQuery = QueryParser.Parse(query);
\r
2202 // Now load the preset
\r
2203 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);
\r
2205 // The x264 widgets will need updated, so do this now:
\r
2206 x264Panel.StandardizeOptString();
\r
2207 x264Panel.SetCurrentSettingsInPanel();
\r
2209 // Finally, let this window have a copy of the preset settings.
\r
2210 CurrentlySelectedPreset = null;
\r
2211 PictureSettings.SetPresetCropWarningLabel(null);
\r
2217 #region GUI Functions and Actions
\r
2220 /// Set the GUI to it's finished encoding state.
\r
2222 private void SetEncodeFinished()
\r
2226 if (InvokeRequired)
\r
2228 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2232 lbl_encode.Text = "Encoding Finished";
\r
2233 ProgressBarStatus.Visible = false;
\r
2234 btn_start.Text = "Start";
\r
2235 btn_start.ToolTipText = "Start the encoding process";
\r
2236 btn_start.Image = Properties.Resources.Play;
\r
2238 // If the window is minimized, display the notification in a popup.
\r
2239 if (Properties.Settings.Default.trayIconAlerts)
\r
2240 if (FormWindowState.Minimized == this.WindowState)
\r
2242 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2243 notifyIcon.ShowBalloonTip(500);
\r
2246 catch (Exception exc)
\r
2248 MessageBox.Show(exc.ToString());
\r
2253 /// Set the GUI to it's started encoding state.
\r
2255 private void SetEncodeStarted()
\r
2259 if (InvokeRequired)
\r
2261 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2264 lbl_encode.Visible = true;
\r
2265 ProgressBarStatus.Value = 0;
\r
2266 ProgressBarStatus.Visible = true;
\r
2267 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2268 btn_start.Text = "Stop";
\r
2269 btn_start.ToolTipText = "Stop the encoding process.";
\r
2270 btn_start.Image = Properties.Resources.stop;
\r
2272 catch (Exception exc)
\r
2274 MessageBox.Show(exc.ToString());
\r
2279 /// Display the Encode Status
\r
2281 /// <param name="sender">
\r
2284 /// <param name="e">
\r
2287 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2289 if (this.InvokeRequired)
\r
2291 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2297 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}",
\r
2298 e.PercentComplete,
\r
2299 e.CurrentFrameRate,
\r
2300 e.AverageFrameRate,
\r
2301 e.EstimatedTimeLeft);
\r
2303 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2307 /// Set the DVD Drive selection in the "Source" Menu
\r
2309 private void SetDriveSelectionMenuItem()
\r
2313 if (InvokeRequired)
\r
2315 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2319 drives = Main.GetDrives();
\r
2321 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2322 foreach (DriveInformation drive in drives)
\r
2324 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2326 Name = drive.ToString(),
\r
2327 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2328 Image = Resources.disc_small
\r
2330 menuItem.Click += new EventHandler(mnu_dvd_drive_Click);
\r
2331 menuItems.Add(menuItem);
\r
2334 foreach (ToolStripMenuItem item in menuItems)
\r
2335 btn_source.DropDownItems.Add(item);
\r
2337 catch (Exception exc)
\r
2339 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2344 /// Access the preset Handler and setup the preset panel.
\r
2346 private void LoadPresetPanel()
\r
2348 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2349 if (!Properties.Settings.Default.presetNotification)
\r
2350 MessageBox.Show(splash,
\r
2351 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2352 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2354 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2355 treeView_presets.Update();
\r
2359 /// Get the title from the selected item in the title dropdown.
\r
2364 private int GetTitle()
\r
2367 if (drp_dvdtitle.SelectedItem != null)
\r
2369 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2370 int.TryParse(titleInfo[0], out title);
\r
2377 /// Handle the Update Check Finishing.
\r
2379 /// <param name="result">
\r
2382 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2384 // Make sure it's running on the calling thread
\r
2385 if (InvokeRequired)
\r
2387 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2390 UpdateCheckInformation info;
\r
2393 // Get the information about the new build, if any, and close the window
\r
2394 info = Main.EndCheckForUpdates(result);
\r
2396 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2398 frmUpdater updateWindow = new frmUpdater(info.BuildInformation);
\r
2399 updateWindow.ShowDialog();
\r
2402 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2403 MessageBoxIcon.Information);
\r
2404 lbl_updateCheck.Visible = false;
\r
2407 catch (Exception ex)
\r
2409 if ((bool)result.AsyncState)
\r
2411 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2412 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2421 /// Handle GUI shortcuts
\r
2423 /// <param name="msg">Message</param>
\r
2424 /// <param name="keyData">Keys</param>
\r
2425 /// <returns>Bool</returns>
\r
2426 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2428 if (keyData == (Keys.Control | Keys.S))
\r
2430 btn_start_Click(this, new EventArgs());
\r
2434 if (keyData == (Keys.Control | Keys.A))
\r
2436 btn_add2Queue_Click(this, new EventArgs());
\r
2439 return base.ProcessCmdKey(ref msg, keyData);
\r
2443 /// If the queue is being processed, prompt the user to confirm application close.
\r
2445 /// <param name="e">FormClosingEventArgs</param>
\r
2446 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2448 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2449 if (encodeQueue.IsEncoding)
\r
2451 DialogResult result =
\r
2453 "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",
\r
2454 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
2456 if (result == DialogResult.No)
\r
2462 // Try to safely close out if we can, or kill the cli if using in-gui status
\r
2463 if (Settings.Default.enocdeStatusInGui)
\r
2464 encodeQueue.Stop();
\r
2466 encodeQueue.SafelyClose();
\r
2469 if (SourceScan.IsScanning)
\r
2471 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2472 SourceScan.Stop();
\r
2474 base.OnFormClosing(e);
\r
2479 // This is the END of the road ****************************************
\r