2 This file is part of the HandBrake source code.
\r
3 Homepage: <http://handbrake.fr/>.
\r
4 It may be used under the terms of the GNU General Public License. */
\r
9 using System.Collections.Generic;
\r
10 using System.ComponentModel;
\r
11 using System.Diagnostics;
\r
12 using System.Drawing;
\r
13 using System.Globalization;
\r
15 using System.Threading;
\r
16 using System.Windows.Forms;
\r
19 using HandBrake.Framework.Model;
\r
20 using HandBrake.Framework.Services;
\r
21 using HandBrake.Framework.Views;
\r
22 using HandBrake.ApplicationServices.Functions;
\r
23 using HandBrake.ApplicationServices.Model;
\r
24 using HandBrake.ApplicationServices.Parsing;
\r
25 using HandBrake.ApplicationServices.Services;
\r
26 using HandBrake.ApplicationServices.Services.Interfaces;
\r
28 using Handbrake.ToolWindows;
\r
34 using Main = Handbrake.Functions.Main;
\r
39 public partial class frmMain : Form
\r
41 // Objects which may be used by one or more other objects *************
\r
42 private IQueue encodeQueue = new Queue();
\r
43 private PresetsHandler presetHandler = new PresetsHandler();
\r
45 // Windows ************************************************************
\r
46 private frmQueue queueWindow;
\r
47 private frmPreview qtpreview;
\r
48 private frmActivityWindow activityWindow;
\r
50 // Globals: Mainly used for tracking. *********************************
\r
51 public Title selectedTitle;
\r
52 public string sourcePath;
\r
53 private SourceType selectedSourceType;
\r
54 private string dvdDrivePath;
\r
55 private string dvdDriveLabel;
\r
56 private Preset currentlySelectedPreset;
\r
57 private DVD currentSource;
\r
58 private IScan SourceScan = new ScanService();
\r
59 private List<DriveInformation> drives;
\r
60 private Job queueEdit;
\r
62 // Delegates **********************************************************
\r
63 private delegate void UpdateWindowHandler();
\r
65 // Applicaiton Startup ************************************************
\r
70 /// Gets SourceName.
\r
72 public string SourceName
\r
76 if (this.selectedSourceType == SourceType.DvdDrive)
\r
78 return this.dvdDriveLabel;
\r
81 if (selectedTitle != null && !string.IsNullOrEmpty(selectedTitle.SourceName))
\r
83 return Path.GetFileName(selectedTitle.SourceName);
\r
86 // We have a drive, selected as a folder.
\r
87 if (this.sourcePath.EndsWith("\\"))
\r
89 drives = Main.GetDrives();
\r
90 foreach (DriveInformation item in drives)
\r
92 if (item.RootDirectory.Contains(this.sourcePath))
\r
94 return item.VolumeLabel;
\r
99 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
100 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
102 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
108 #region Application Startup
\r
111 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
113 /// <param name="args">
\r
114 /// The arguments passed in on application startup.
\r
116 public frmMain(string[] args)
\r
118 InitializeComponent();
\r
120 // Update the users config file with the CLI version data.
\r
121 Main.SetCliVersionData();
\r
123 if (Settings.Default.hb_version.Contains("svn"))
\r
125 this.Text += " " + Settings.Default.hb_version;
\r
128 // Check for new versions, if update checking is enabled
\r
129 if (Settings.Default.updateStatus)
\r
131 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
133 // Set when the last update was
\r
134 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
135 Settings.Default.Save();
\r
136 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
137 ? Settings.Default.appcast_unstable
\r
138 : Settings.Default.appcast;
\r
139 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
143 // Clear the log files in the background
\r
144 if (Settings.Default.clearOldLogs)
\r
146 Thread clearLog = new Thread(Main.ClearOldLogs);
\r
150 // Setup the GUI components
\r
151 LoadPresetPanel(); // Load the Preset Panel
\r
152 treeView_presets.ExpandAll();
\r
153 lbl_encode.Text = string.Empty;
\r
154 drop_mode.SelectedIndex = 0;
\r
155 queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue
\r
156 if (!Settings.Default.QueryEditorTab)
\r
157 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
158 if (Settings.Default.tooltipEnable)
\r
159 ToolTip.Active = true;
\r
161 // Load the user's default settings or Normal Preset
\r
162 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
164 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
167 x264Panel.Reset2Defaults();
\r
169 QueryParser presetQuery = QueryParser.Parse(query);
\r
170 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
172 x264Panel.StandardizeOptString();
\r
173 x264Panel.SetCurrentSettingsInPanel();
\r
177 loadNormalPreset();
\r
179 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
180 GrowlCommunicator.Register();
\r
182 // Event Handlers and Queue Recovery
\r
184 Main.RecoverQueue(encodeQueue);
\r
186 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
187 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
189 this.StartScan(args[0], 0);
\r
194 /// When the update check is done, process the results.
\r
196 /// <param name="result">IAsyncResult result</param>
\r
197 private void UpdateCheckDone(IAsyncResult result)
\r
199 if (InvokeRequired)
\r
201 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
207 UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
\r
209 if (info.NewVersionAvailable)
\r
211 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
212 updateWindow.ShowDialog();
\r
215 catch (Exception ex)
\r
217 if ((bool)result.AsyncState)
\r
218 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
226 // Encoding Events for setting up the GUI
\r
227 private void events()
\r
229 // Handle Widget changes when preset is selected.
\r
230 RegisterPresetEventHandler();
\r
232 // Handle Window Resize
\r
233 if (Properties.Settings.Default.MainWindowMinimize)
\r
234 this.Resize += new EventHandler(frmMain_Resize);
\r
236 // Handle Encode Start / Finish / Pause
\r
237 encodeQueue.EncodeStarted += new EventHandler(encodeStarted);
\r
238 encodeQueue.EncodeEnded += new EventHandler(encodeEnded);
\r
240 // Scan Started and Completed Events
\r
241 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);
\r
242 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);
\r
244 // Handle a file being draged onto the GUI.
\r
245 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
246 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
249 // 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
250 private void RegisterPresetEventHandler()
\r
253 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
254 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
255 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
256 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
258 // Picture Settings
\r
259 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
262 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
265 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
266 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
267 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
268 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
269 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
270 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
273 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
276 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
279 private void UnRegisterPresetEventHandler()
\r
281 // Output Settings
\r
282 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
283 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
284 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
285 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
287 // Picture Settings
\r
288 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
291 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
294 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
295 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
296 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
297 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
298 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
299 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
302 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
305 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
308 private void changePresetLabel(object sender, EventArgs e)
\r
310 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
311 this.currentlySelectedPreset = null;
\r
314 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
316 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
317 e.Effect = DragDropEffects.All;
\r
320 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
322 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
323 sourcePath = string.Empty;
\r
325 if (fileList != null)
\r
327 if (!string.IsNullOrEmpty(fileList[0]))
\r
329 this.selectedSourceType = SourceType.VideoFile;
\r
330 StartScan(fileList[0], 0);
\r
333 UpdateSourceLabel();
\r
336 UpdateSourceLabel();
\r
339 private void encodeStarted(object sender, EventArgs e)
\r
341 SetEncodeStarted();
\r
342 encodeQueue.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
345 private void encodeEnded(object sender, EventArgs e)
\r
347 encodeQueue.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
348 SetEncodeFinished();
\r
352 // User Interface Menus / Tool Strips *********************************
\r
357 /// Kill The scan menu Item
\r
359 /// <param name="sender">
\r
362 /// <param name="e">
\r
365 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
371 /// Exit the Application Menu Item
\r
373 /// <param name="sender">
\r
376 /// <param name="e">
\r
379 private void mnu_exit_Click(object sender, EventArgs e)
\r
381 Application.Exit();
\r
389 /// Menu - Start Button
\r
391 /// <param name="sender">
\r
394 /// <param name="e">
\r
397 private void mnu_encode_Click(object sender, EventArgs e)
\r
399 queueWindow.Show();
\r
403 /// Menu - Display the Log Window
\r
405 /// <param name="sender">
\r
408 /// <param name="e">
\r
411 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
413 this.btn_ActivityWindow_Click(this, null);
\r
417 /// Menu - Display the Options Window
\r
419 /// <param name="sender">
\r
422 /// <param name="e">
\r
425 private void mnu_options_Click(object sender, EventArgs e)
\r
427 Form options = new frmOptions(this);
\r
428 options.ShowDialog();
\r
433 #region Presets Menu
\r
436 /// Reset the Built in Presets
\r
438 /// <param name="sender">
\r
441 /// <param name="e">
\r
444 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
446 presetHandler.UpdateBuiltInPresets();
\r
448 if (treeView_presets.Nodes.Count == 0)
\r
450 "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
451 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
453 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
455 treeView_presets.ExpandAll();
\r
459 /// Delete the selected preset
\r
461 /// <param name="sender">
\r
464 /// <param name="e">
\r
467 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
469 presetHandler.RemoveBuiltInPresets();
\r
470 LoadPresetPanel(); // Reload the preset panel
\r
474 /// Select the Normal preset
\r
476 /// <param name="sender">
\r
479 /// <param name="e">
\r
482 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
484 loadNormalPreset();
\r
488 /// Import a plist Preset
\r
490 /// <param name="sender">
\r
493 /// <param name="e">
\r
496 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
502 /// Export a Plist Preset
\r
504 /// <param name="sender">
\r
507 /// <param name="e">
\r
510 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
516 /// Create a new Preset
\r
518 /// <param name="sender">
\r
521 /// <param name="e">
\r
524 private void btn_new_preset_Click(object sender, EventArgs e)
\r
526 Form preset = new frmAddPreset(this, presetHandler);
\r
527 if (preset.ShowDialog() == DialogResult.OK)
\r
529 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
530 treeView_presets.Nodes.Add(presetTreeview);
\r
531 presetHandler.LastPresetAdded = null;
\r
540 /// Menu - Display the User Guide Web Page
\r
542 /// <param name="sender">
\r
545 /// <param name="e">
\r
548 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
550 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
554 /// Menu - Check for Updates
\r
556 /// <param name="sender">
\r
559 /// <param name="e">
\r
562 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
564 lbl_updateCheck.Visible = true;
\r
565 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
566 Settings.Default.Save();
\r
567 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
568 ? Settings.Default.appcast_unstable
\r
569 : Settings.Default.appcast;
\r
570 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDoneMenu), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
574 /// Menu - Display the About Window
\r
576 /// <param name="sender">
\r
579 /// <param name="e">
\r
582 private void mnu_about_Click(object sender, EventArgs e)
\r
584 using (frmAbout About = new frmAbout())
\r
586 About.ShowDialog();
\r
595 /// RMenu - Expand All
\r
597 /// <param name="sender">
\r
600 /// <param name="e">
\r
603 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
605 treeView_presets.ExpandAll();
\r
609 /// RMenu - Collaspe All
\r
611 /// <param name="sender">
\r
614 /// <param name="e">
\r
617 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
619 treeView_presets.CollapseAll();
\r
623 /// Menu - Import Preset
\r
625 /// <param name="sender">
\r
628 /// <param name="e">
\r
631 private void pmnu_import_Click(object sender, EventArgs e)
\r
637 /// RMenu - Save Changes to Preset
\r
639 /// <param name="sender">
\r
642 /// <param name="e">
\r
645 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
647 // TODO this requires a re-think since the Query Editor has changed.
\r
648 DialogResult result =
\r
650 "Do you wish to include picture settings when updating the preset: " +
\r
651 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
652 MessageBoxIcon.Question);
\r
653 if (result == DialogResult.Yes)
\r
654 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
655 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
656 else if (result == DialogResult.No)
\r
657 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
658 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
662 /// RMenu - Delete Preset
\r
664 /// <param name="sender">
\r
667 /// <param name="e">
\r
670 private void pmnu_delete_click(object sender, EventArgs e)
\r
672 if (treeView_presets.SelectedNode != null)
\r
674 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
675 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
677 treeView_presets.Select();
\r
681 /// Preset Menu Is Opening. Setup the Menu
\r
683 /// <param name="sender">
\r
686 /// <param name="e">
\r
689 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
691 // Make sure that the save menu is always disabled by default
\r
692 pmnu_saveChanges.Enabled = false;
\r
694 // Now enable the save menu if the selected preset is a user preset
\r
695 if (treeView_presets.SelectedNode != null)
\r
696 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
697 pmnu_saveChanges.Enabled = true;
\r
699 treeView_presets.Select();
\r
702 // Presets Management
\r
705 /// Button - Add a preset
\r
707 /// <param name="sender">
\r
710 /// <param name="e">
\r
713 private void btn_addPreset_Click(object sender, EventArgs e)
\r
715 Form preset = new frmAddPreset(this, presetHandler);
\r
716 if (preset.ShowDialog() == DialogResult.OK)
\r
718 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
719 treeView_presets.Nodes.Add(presetTreeview);
\r
720 presetHandler.LastPresetAdded = null;
\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 /// When the mouse moves, display a preset
\r
816 /// <param name="sender">The Sender</param>
\r
817 /// <param name="e">the MouseEventArgs</param>
\r
818 private void TreeViewPresetsMouseMove(object sender, MouseEventArgs e)
\r
820 TreeNode theNode = this.treeView_presets.GetNodeAt(e.X, e.Y);
\r
822 if ((theNode != null))
\r
824 // Change the ToolTip only if the pointer moved to a new node.
\r
825 if (theNode.ToolTipText != this.ToolTip.GetToolTip(this.treeView_presets))
\r
827 this.ToolTip.SetToolTip(this.treeView_presets, theNode.ToolTipText);
\r
830 else // Pointer is not over a node so clear the ToolTip.
\r
832 this.ToolTip.SetToolTip(this.treeView_presets, string.Empty);
\r
837 /// Preset Bar - Handle the Delete Key
\r
839 /// <param name="sender">
\r
842 /// <param name="e">
\r
845 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
847 if (e.KeyCode == Keys.Delete)
\r
849 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
850 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
851 if (result == DialogResult.Yes)
\r
853 if (treeView_presets.SelectedNode != null)
\r
854 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
856 // Remember each nodes expanded status so we can reload it
\r
857 List<bool> nodeStatus = new List<bool>();
\r
858 foreach (TreeNode node in treeView_presets.Nodes)
\r
859 nodeStatus.Add(node.IsExpanded);
\r
861 // Now reload the preset panel
\r
864 // And finally, re-expand any of the nodes if required
\r
866 foreach (TreeNode node in treeView_presets.Nodes)
\r
878 /// Select the selected preset and setup the GUI
\r
880 private void selectPreset()
\r
882 if (treeView_presets.SelectedNode != null)
\r
884 // Ok, so, we've selected a preset. Now we want to load it.
\r
885 string presetName = treeView_presets.SelectedNode.Text;
\r
886 Preset preset = presetHandler.GetPreset(presetName);
\r
887 if (preset != null)
\r
889 string query = presetHandler.GetPreset(presetName).Query;
\r
893 // Ok, Reset all the H264 widgets before changing the preset
\r
894 x264Panel.Reset2Defaults();
\r
896 // Send the query from the file to the Query Parser class
\r
897 QueryParser presetQuery = QueryParser.Parse(query);
\r
899 // Now load the preset
\r
900 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
902 // The x264 widgets will need updated, so do this now:
\r
903 x264Panel.StandardizeOptString();
\r
904 x264Panel.SetCurrentSettingsInPanel();
\r
906 // Finally, let this window have a copy of the preset settings.
\r
907 this.currentlySelectedPreset = preset;
\r
908 PictureSettings.SetPresetCropWarningLabel(preset);
\r
915 /// Load the Normal Preset
\r
917 private void loadNormalPreset()
\r
919 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
921 foreach (TreeNode node in treenode.Nodes)
\r
923 if (node.Text.Equals("Normal"))
\r
924 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
930 /// Import a plist preset
\r
932 private void ImportPreset()
\r
934 if (openPreset.ShowDialog() == DialogResult.OK)
\r
936 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
937 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
939 DialogResult result =
\r
940 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
941 "Overwrite preset?",
\r
942 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
943 if (result == DialogResult.Yes)
\r
945 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
946 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
947 QueryGenerator.GenerateFullQuery(this),
\r
948 parsed.UsesPictureSettings);
\r
953 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
954 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
955 QueryGenerator.GenerateFullQuery(this),
\r
956 parsed.UsesPictureSettings, string.Empty))
\r
958 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
960 ForeColor = Color.Black
\r
962 treeView_presets.Nodes.Add(preset_treeview);
\r
969 /// Export a plist Preset
\r
971 private void ExportPreset()
\r
973 SaveFileDialog savefiledialog = new SaveFileDialog { Filter = "plist|*.plist" };
\r
975 if (treeView_presets.SelectedNode != null)
\r
977 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
979 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
980 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
990 /// 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
992 /// <param name="sender">
\r
995 /// <param name="e">
\r
998 private void btn_source_Click(object sender, EventArgs e)
\r
1000 // Remove old Drive Menu Items.
\r
1001 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
1002 foreach (var item in btn_source.DropDownItems)
\r
1004 if (item.GetType() == typeof(ToolStripMenuItem))
\r
1006 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
1007 if (menuItem.Name.StartsWith("Drive"))
\r
1009 itemsToRemove.Add(menuItem);
\r
1014 foreach (ToolStripMenuItem item in itemsToRemove)
\r
1015 btn_source.DropDownItems.Remove(item);
\r
1017 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
1018 driveInfoThread.Start();
\r
1022 /// Toolbar - Start The Encode
\r
1024 /// <param name="sender">
\r
1027 /// <param name="e">
\r
1030 private void btn_start_Click(object sender, EventArgs e)
\r
1032 if (btn_start.Text == "Stop")
\r
1034 DialogResult result = !Properties.Settings.Default.showCliForInGuiEncodeStatus
\r
1035 ? MessageBox.Show(
\r
1036 "Are you sure you wish to cancel the encode?\n\nPlease note: Stopping this encode will render the file unplayable. ",
\r
1038 MessageBoxButtons.YesNo,
\r
1039 MessageBoxIcon.Question)
\r
1040 : MessageBox.Show(
\r
1041 "Are you sure you wish to cancel the encode?",
\r
1043 MessageBoxButtons.YesNo,
\r
1044 MessageBoxIcon.Question);
\r
1046 if (result == DialogResult.Yes)
\r
1048 // Pause The Queue
\r
1049 encodeQueue.Pause();
\r
1051 if (Settings.Default.showCliForInGuiEncodeStatus)
\r
1052 encodeQueue.SafelyClose();
\r
1054 encodeQueue.Stop();
\r
1059 // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.
\r
1060 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1061 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1063 if (encodeQueue.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))
\r
1065 string generatedQuery = QueryGenerator.GenerateFullQuery(this);
\r
1066 string specifiedQuery = rtf_query.Text != string.Empty
\r
1068 : QueryGenerator.GenerateFullQuery(this);
\r
1069 string query = string.Empty;
\r
1071 // Check to make sure the generated query matches the GUI settings
\r
1072 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1073 generatedQuery != specifiedQuery)
\r
1075 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1076 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1077 "priority over the GUI, your recently updated settings will not be taken " +
\r
1078 "into account when encoding this job." +
\r
1079 Environment.NewLine + Environment.NewLine +
\r
1080 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1081 "Manual Query does not Match GUI",
\r
1082 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1083 MessageBoxDefaultButton.Button3);
\r
1087 case DialogResult.Yes:
\r
1088 // Replace the manual query with the generated one
\r
1089 query = generatedQuery;
\r
1090 rtf_query.Text = generatedQuery;
\r
1092 case DialogResult.No:
\r
1093 // Use the manual query
\r
1094 query = specifiedQuery;
\r
1096 case DialogResult.Cancel:
\r
1097 // Don't start the encode
\r
1103 query = specifiedQuery;
\r
1106 DialogResult overwrite = DialogResult.Yes;
\r
1107 if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))
\r
1109 overwrite = MessageBox.Show(
\r
1110 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1111 "Overwrite File?",
\r
1112 MessageBoxButtons.YesNo,
\r
1113 MessageBoxIcon.Question);
\r
1116 if (overwrite == DialogResult.Yes)
\r
1118 if (encodeQueue.Count == 0)
\r
1119 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1121 queueWindow.SetQueue();
\r
1122 if (encodeQueue.Count > 1)
\r
1123 queueWindow.Show(false);
\r
1125 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1126 encodeQueue.Start(); // Start The Queue Encoding Process
\r
1131 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1132 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1133 MessageBoxIcon.Warning);
\r
1138 /// Toolbar - Add the current job to the Queue
\r
1140 /// <param name="sender">
\r
1143 /// <param name="e">
\r
1146 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1148 // Add the item to the queue.
\r
1149 AddItemToQueue(true);
\r
1150 queueWindow.Show();
\r
1154 /// Add Multiple Items to the Queue at once.
\r
1156 /// <param name="sender">The Sender</param>
\r
1157 /// <param name="e">The EventArgs</param>
\r
1158 private void MnuAddMultiToQueueClick(object sender, EventArgs e)
\r
1160 if (!Settings.Default.autoNaming)
\r
1162 MessageBox.Show("Destination Auto Naming must be enabled in preferences for this feature to work.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1166 if (this.SourceScan.SouceData == null)
\r
1168 MessageBox.Show("You must first scan a source or collection of source to use this feature.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1172 BatchAdd batchAdd = new BatchAdd();
\r
1173 if (batchAdd.ShowDialog() == DialogResult.OK)
\r
1175 int min = batchAdd.Min;
\r
1176 int max = batchAdd.Max;
\r
1177 bool errors = false;
\r
1179 foreach (Title title in this.SourceScan.SouceData.Titles)
\r
1181 if (title.Duration.TotalMinutes > min && title.Duration.TotalMinutes < max)
\r
1184 this.drp_dvdtitle.SelectedItem = title;
\r
1186 if (!this.AddItemToQueue(false))
\r
1196 "One or more items could not be added to the queue. You should check your queue and manually add any missing jobs.",
\r
1198 MessageBoxButtons.OK,
\r
1199 MessageBoxIcon.Warning);
\r
1204 private bool AddItemToQueue(bool showError)
\r
1206 string query = QueryGenerator.GenerateFullQuery(this);
\r
1207 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1208 query = rtf_query.Text;
\r
1210 // If we have a custom query, then we'll want to figure out what the new source and destination is, otherwise we'll just use the gui components.
\r
1211 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1212 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1214 // Make sure we have a Source and Destination.
\r
1215 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1218 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1222 // Make sure the destination path exists.
\r
1223 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1226 MessageBox.Show(string.Format("Destination Path does not exist.\nPath: {0}\n\nThis item was not added to the Queue.", Path.GetDirectoryName(jobDestination)), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1230 // Make sure we don't have a duplciate on the queue.
\r
1231 if (encodeQueue.CheckForDestinationDuplicate(jobDestination))
\r
1235 DialogResult result;
\r
1239 "There is already a queue item for this destination path.\nDestination Path: {0} \n\nIf you continue, the encode will be overwritten. Do you wish to continue?",
\r
1242 MessageBoxButtons.YesNo,
\r
1243 MessageBoxIcon.Warning);
\r
1245 if (result != DialogResult.Yes) return false;
\r
1254 encodeQueue.Add(query, this.GetTitle(), jobSourcePath, jobDestination, (rtf_query.Text != string.Empty));
\r
1256 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";
\r
1262 /// Toolbar - Show the Queue
\r
1264 /// <param name="sender">
\r
1267 /// <param name="e">
\r
1270 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1272 queueWindow.Show();
\r
1273 queueWindow.Activate();
\r
1277 /// Toolbar - Show the Preview Window
\r
1279 /// <param name="sender">
\r
1282 /// <param name="e">
\r
1285 private void tb_preview_Click(object sender, EventArgs e)
\r
1287 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1288 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1289 MessageBoxIcon.Warning);
\r
1292 if (qtpreview == null)
\r
1294 qtpreview = new frmPreview(this);
\r
1297 else if (qtpreview.IsDisposed)
\r
1299 qtpreview = new frmPreview(this);
\r
1303 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1304 MessageBoxIcon.Warning);
\r
1309 /// Toolbar - Show the Activity log Window
\r
1311 /// <param name="sender">
\r
1314 /// <param name="e">
\r
1317 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1319 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1320 this.activityWindow = new frmActivityWindow(encodeQueue, SourceScan);
\r
1322 this.activityWindow.Show();
\r
1323 this.activityWindow.Activate();
\r
1328 #region System Tray Icon
\r
1331 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1333 /// <param name="sender">
\r
1336 /// <param name="e">
\r
1339 private void frmMain_Resize(object sender, EventArgs e)
\r
1341 if (FormWindowState.Minimized == this.WindowState)
\r
1343 notifyIcon.Visible = true;
\r
1346 else if (FormWindowState.Normal == this.WindowState)
\r
1347 notifyIcon.Visible = false;
\r
1351 /// Double Click the Tray Icon
\r
1353 /// <param name="sender">
\r
1356 /// <param name="e">
\r
1359 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1361 this.Visible = true;
\r
1363 this.WindowState = FormWindowState.Normal;
\r
1364 notifyIcon.Visible = false;
\r
1368 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1370 /// <param name="sender">
\r
1373 /// <param name="e">
\r
1376 private void btn_restore_Click(object sender, EventArgs e)
\r
1378 this.Visible = true;
\r
1380 this.WindowState = FormWindowState.Normal;
\r
1381 notifyIcon.Visible = false;
\r
1386 #region Main Window and Tab Control
\r
1389 private void BtnFolderScanClicked(object sender, EventArgs e)
\r
1391 this.btn_source.HideDropDown();
\r
1392 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1394 this.selectedSourceType = SourceType.Folder;
\r
1395 SelectSource(DVD_Open.SelectedPath, 0);
\r
1398 UpdateSourceLabel();
\r
1401 private void BtnFileScanClicked(object sender, EventArgs e)
\r
1403 this.btn_source.HideDropDown();
\r
1404 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1406 this.selectedSourceType = SourceType.VideoFile;
\r
1407 SelectSource(ISO_Open.FileName, 0);
\r
1410 UpdateSourceLabel();
\r
1413 private void MnuDvdDriveClick(object sender, EventArgs e)
\r
1415 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1418 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1420 if (int.TryParse(driveId, out id))
\r
1422 this.dvdDrivePath = drives[id].RootDirectory;
\r
1423 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1425 if (this.dvdDrivePath == null) return;
\r
1426 this.selectedSourceType = SourceType.DvdDrive;
\r
1427 SelectSource(this.dvdDrivePath, 0);
\r
1432 private void VideoTitleSpecificScanClick(object sender, EventArgs e)
\r
1434 this.btn_source.HideDropDown();
\r
1435 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1437 this.selectedSourceType = SourceType.VideoFile;
\r
1439 int sourceTitle = 0;
\r
1440 TitleSpecificScan title = new TitleSpecificScan();
\r
1441 if (title.ShowDialog() == DialogResult.OK)
\r
1443 sourceTitle = title.Title;
\r
1444 SelectSource(ISO_Open.FileName, sourceTitle);
\r
1448 UpdateSourceLabel();
\r
1451 private void FolderTitleSpecificScanClick(object sender, EventArgs e)
\r
1453 this.btn_source.HideDropDown();
\r
1454 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1456 this.selectedSourceType = SourceType.Folder;
\r
1458 int sourceTitle = 0;
\r
1459 TitleSpecificScan title = new TitleSpecificScan();
\r
1460 if (title.ShowDialog() == DialogResult.OK)
\r
1462 sourceTitle = title.Title;
\r
1463 SelectSource(DVD_Open.SelectedPath, sourceTitle);
\r
1467 UpdateSourceLabel();
\r
1470 private void SelectSource(string file, int titleSpecific)
\r
1472 Check_ChapterMarkers.Enabled = true;
\r
1473 sourcePath = string.Empty;
\r
1475 if (file == string.Empty) // Must have a file or path
\r
1477 UpdateSourceLabel();
\r
1481 sourcePath = Path.GetFileName(file);
\r
1482 StartScan(file, titleSpecific);
\r
1485 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1487 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1489 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1490 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1493 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1495 UnRegisterPresetEventHandler();
\r
1496 drop_mode.SelectedIndex = 0;
\r
1498 drop_chapterStart.Items.Clear();
\r
1499 drop_chapterFinish.Items.Clear();
\r
1501 // If the dropdown is set to automatic nothing else needs to be done.
\r
1502 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1503 if (drp_dvdtitle.Text != "Automatic")
\r
1505 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1506 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1507 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1508 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1510 // Populate the Angles dropdown
\r
1511 drop_angle.Items.Clear();
\r
1512 if (!Properties.Settings.Default.noDvdNav)
\r
1514 drop_angle.Visible = true;
\r
1515 lbl_angle.Visible = true;
\r
1517 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1518 drop_angle.Items.Add(i.ToString());
\r
1520 if (drop_angle.Items.Count == 0)
\r
1522 drop_angle.Visible = false;
\r
1523 lbl_angle.Visible = false;
\r
1526 if (drop_angle.Items.Count != 0)
\r
1527 drop_angle.SelectedIndex = 0;
\r
1531 drop_angle.Visible = false;
\r
1532 lbl_angle.Visible = false;
\r
1535 // Populate the Start chapter Dropdown
\r
1536 drop_chapterStart.Items.Clear();
\r
1537 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1538 if (drop_chapterStart.Items.Count > 0)
\r
1539 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1541 // Populate the Final Chapter Dropdown
\r
1542 drop_chapterFinish.Items.Clear();
\r
1543 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1544 if (drop_chapterFinish.Items.Count > 0)
\r
1545 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1547 // Populate the Audio Channels Dropdown
\r
1548 AudioSettings.SetTrackListFromPreset(selectedTitle, this.currentlySelectedPreset);
\r
1550 // Populate the Subtitles dropdown
\r
1551 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1553 // Update the source label if we have multiple streams
\r
1554 if (selectedTitle != null)
\r
1555 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1556 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1558 // Run the AutoName & ChapterNaming functions
\r
1559 if (Properties.Settings.Default.autoNaming)
\r
1561 string autoPath = Main.AutoName(this);
\r
1562 if (autoPath != null)
\r
1563 text_destination.Text = autoPath;
\r
1566 "You currently have \"Automatically name output files\" enabled for the destination file box, but you do not have a valid default directory set.\n\nYou should set a \"Default Path\" in HandBrakes preferences. (See 'Tools' menu -> 'Options' -> 'General' Tab -> 'Default Path')",
\r
1567 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1570 data_chpt.Rows.Clear();
\r
1571 if (selectedTitle.Chapters.Count != 1)
\r
1573 DataGridView chapterGridView = Main.ChapterNaming(selectedTitle, data_chpt, drop_chapterFinish.Text);
\r
1574 if (chapterGridView != null)
\r
1575 data_chpt = chapterGridView;
\r
1579 Check_ChapterMarkers.Checked = false;
\r
1580 Check_ChapterMarkers.Enabled = false;
\r
1583 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1584 data_chpt.Columns[0].Width = 166;
\r
1585 data_chpt.Columns[0].Width = 165;
\r
1587 RegisterPresetEventHandler();
\r
1590 private void chapersChanged(object sender, EventArgs e)
\r
1592 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1595 Control ctl = (Control)sender;
\r
1596 int chapterStart, chapterEnd;
\r
1597 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1598 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1602 case "drop_chapterStart":
\r
1603 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1604 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1606 if (chapterEnd != 0)
\r
1607 if (chapterStart > chapterEnd)
\r
1608 drop_chapterFinish.Text = chapterStart.ToString();
\r
1610 case "drop_chapterFinish":
\r
1611 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1612 drop_chapterStart.SelectedIndex = 0;
\r
1614 if (chapterStart != 0)
\r
1615 if (chapterEnd < chapterStart)
\r
1616 drop_chapterFinish.Text = chapterStart.ToString();
\r
1618 // Add more rows to the Chapter menu if needed.
\r
1619 if (Check_ChapterMarkers.Checked)
\r
1621 int i = data_chpt.Rows.Count, finish = 0;
\r
1622 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1624 while (i < finish)
\r
1626 int n = data_chpt.Rows.Add();
\r
1627 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1628 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1629 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1630 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1637 // Update the Duration
\r
1638 lbl_duration.Text =
\r
1639 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1642 // Run the Autonaming function
\r
1643 if (Properties.Settings.Default.autoNaming)
\r
1644 text_destination.Text = Main.AutoName(this);
\r
1646 // Disable chapter markers if only 1 chapter is selected.
\r
1647 if (chapterStart == chapterEnd)
\r
1649 Check_ChapterMarkers.Enabled = false;
\r
1650 btn_importChapters.Enabled = false;
\r
1651 data_chpt.Enabled = false;
\r
1655 Check_ChapterMarkers.Enabled = true;
\r
1656 if (Check_ChapterMarkers.Checked)
\r
1658 btn_importChapters.Enabled = true;
\r
1659 data_chpt.Enabled = true;
\r
1664 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1667 int.TryParse(drop_chapterStart.Text, out start);
\r
1668 int.TryParse(drop_chapterFinish.Text, out end);
\r
1669 double duration = end - start;
\r
1671 switch (drop_mode.SelectedIndex)
\r
1674 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1677 if (selectedTitle != null)
\r
1679 duration = duration / selectedTitle.Fps;
\r
1680 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1683 lbl_duration.Text = "--:--:--";
\r
1689 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1692 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1693 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1696 switch (drop_mode.SelectedIndex)
\r
1699 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1700 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1701 if (drop_chapterStart.Items.Count != 0)
\r
1703 drop_chapterStart.SelectedIndex = 0;
\r
1704 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1707 lbl_duration.Text = "--:--:--";
\r
1710 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1711 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1712 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1713 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1714 if (selectedTitle != null)
\r
1716 drop_chapterStart.Text = "0";
\r
1717 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1721 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1722 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1723 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1724 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1725 if (selectedTitle != null)
\r
1727 drop_chapterStart.Text = "0";
\r
1728 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1735 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1737 // This removes the file extension from the filename box on the save file dialog.
\r
1738 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1739 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1741 if (Path.IsPathRooted(text_destination.Text))
\r
1742 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1744 // Show the dialog and set the main form file path
\r
1745 if (drop_format.SelectedIndex.Equals(0))
\r
1746 DVD_Save.FilterIndex = 1;
\r
1747 else if (drop_format.SelectedIndex.Equals(1))
\r
1748 DVD_Save.FilterIndex = 2;
\r
1750 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1752 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1753 switch (DVD_Save.FilterIndex)
\r
1757 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1758 StringComparison.InvariantCultureIgnoreCase))
\r
1759 if (Properties.Settings.Default.useM4v)
\r
1760 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1762 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1766 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1767 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1773 text_destination.Text = DVD_Save.FileName;
\r
1775 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1776 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1777 SetExtension(".m4v");
\r
1781 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1783 string path = text_destination.Text;
\r
1784 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1785 drop_format.SelectedIndex = 0;
\r
1786 else if (path.EndsWith(".mkv"))
\r
1787 drop_format.SelectedIndex = 1;
\r
1790 // Output Settings
\r
1791 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1793 switch (drop_format.SelectedIndex)
\r
1796 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1797 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1798 SetExtension(".m4v");
\r
1800 SetExtension(".mp4");
\r
1803 SetExtension(".mkv");
\r
1807 AudioSettings.SetContainer(drop_format.Text);
\r
1809 if (drop_format.Text.Contains("MP4"))
\r
1811 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1813 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1814 drp_videoEncoder.SelectedIndex = 1;
\r
1817 else if (drop_format.Text.Contains("MKV"))
\r
1818 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1821 public void SetExtension(string newExtension)
\r
1823 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1824 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1825 Subtitles.RequiresM4V())
\r
1826 newExtension = ".m4v";
\r
1828 newExtension = ".mp4";
\r
1830 if (Path.HasExtension(newExtension))
\r
1831 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1835 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1837 setContainerOpts();
\r
1839 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1840 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1842 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1843 check_turbo.Enabled = true;
\r
1845 tab_advanced.Enabled = true;
\r
1846 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1847 check_iPodAtom.Enabled = true;
\r
1849 check_iPodAtom.Enabled = false;
\r
1853 check_turbo.CheckState = CheckState.Unchecked;
\r
1854 check_turbo.Enabled = false;
\r
1855 tab_advanced.Enabled = false;
\r
1856 x264Panel.X264Query = string.Empty;
\r
1857 check_iPodAtom.Enabled = false;
\r
1858 check_iPodAtom.Checked = false;
\r
1861 // Setup the CQ Slider
\r
1862 switch (drp_videoEncoder.Text)
\r
1864 case "MPEG-4 (FFmpeg)":
\r
1865 if (slider_videoQuality.Value > 31)
\r
1866 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1867 slider_videoQuality.Minimum = 1;
\r
1868 slider_videoQuality.Maximum = 31;
\r
1870 case "H.264 (x264)":
\r
1871 slider_videoQuality.Minimum = 0;
\r
1872 slider_videoQuality.TickFrequency = 1;
\r
1874 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1875 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1876 double multiplier = 1.0 / cqStep;
\r
1877 double value = slider_videoQuality.Value * multiplier;
\r
1879 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1881 if (value < slider_videoQuality.Maximum)
\r
1882 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1885 case "VP3 (Theora)":
\r
1886 if (slider_videoQuality.Value > 63)
\r
1887 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1888 slider_videoQuality.Minimum = 0;
\r
1889 slider_videoQuality.Maximum = 63;
\r
1895 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1897 /// <param name="sender">
\r
1900 /// <param name="e">
\r
1903 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1905 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1907 this.checkMaximumFramerate.Visible = false;
\r
1908 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1912 this.checkMaximumFramerate.Visible = true;
\r
1917 /// Set the container format options
\r
1919 public void setContainerOpts()
\r
1921 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1923 check_largeFile.Enabled = true;
\r
1924 check_optimiseMP4.Enabled = true;
\r
1925 check_iPodAtom.Enabled = true;
\r
1929 check_largeFile.Enabled = false;
\r
1930 check_optimiseMP4.Enabled = false;
\r
1931 check_iPodAtom.Enabled = false;
\r
1932 check_largeFile.Checked = false;
\r
1933 check_optimiseMP4.Checked = false;
\r
1934 check_iPodAtom.Checked = false;
\r
1938 private double cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1941 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1943 public void setQualityFromSlider()
\r
1945 // Work out the current RF value.
\r
1946 double cqStep = this.cachedCqStep;
\r
1947 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1949 // Change the maximum value for the slider
\r
1950 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1952 // Reset the CQ slider to RF0
\r
1953 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1955 // Reset the CQ slider back to the previous value as close as possible
\r
1956 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1957 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1958 while (rfValueCurrent < rfValue)
\r
1960 slider_videoQuality.Value--;
\r
1961 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1964 // Cache the CQ step for the next calculation
\r
1965 this.cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1968 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1970 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1971 switch (drp_videoEncoder.Text)
\r
1973 case "MPEG-4 (FFmpeg)":
\r
1974 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1976 case "H.264 (x264)":
\r
1977 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1978 rfValue = Math.Round(rfValue, 2);
\r
1979 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
1980 this.lbl_rfwarn.Visible = rfValue == 0;
\r
1982 case "VP3 (Theora)":
\r
1983 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
1988 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1990 text_bitrate.Enabled = false;
\r
1991 text_filesize.Enabled = true;
\r
1992 slider_videoQuality.Enabled = false;
\r
1994 check_2PassEncode.Enabled = true;
\r
1997 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1999 text_bitrate.Enabled = true;
\r
2000 text_filesize.Enabled = false;
\r
2001 slider_videoQuality.Enabled = false;
\r
2003 check_2PassEncode.Enabled = true;
\r
2006 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
2008 text_bitrate.Enabled = false;
\r
2009 text_filesize.Enabled = false;
\r
2010 slider_videoQuality.Enabled = true;
\r
2012 check_2PassEncode.Enabled = false;
\r
2013 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
2016 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
2018 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
2020 if (drp_videoEncoder.Text.Contains("H.264"))
\r
2021 check_turbo.Enabled = true;
\r
2025 check_turbo.Enabled = false;
\r
2026 check_turbo.CheckState = CheckState.Unchecked;
\r
2030 // Chapter Marker Tab
\r
2031 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
2033 if (Check_ChapterMarkers.Checked)
\r
2035 if (drop_format.SelectedIndex != 1)
\r
2036 SetExtension(".m4v");
\r
2037 data_chpt.Enabled = true;
\r
2038 btn_importChapters.Enabled = true;
\r
2042 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
2043 SetExtension(".mp4");
\r
2044 data_chpt.Enabled = false;
\r
2045 btn_importChapters.Enabled = false;
\r
2049 private void btn_importChapters_Click(object sender, EventArgs e)
\r
2051 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
2053 string filename = File_ChapterImport.FileName;
\r
2054 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
2055 if (imported != null)
\r
2056 data_chpt = imported;
\r
2060 private void btn_export_Click(object sender, EventArgs e)
\r
2062 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
2063 saveFileDialog.Filter = "Csv File|*.csv";
\r
2064 saveFileDialog.DefaultExt = "csv";
\r
2065 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
2067 string filename = saveFileDialog.FileName;
\r
2069 Main.SaveChapterMarkersToCsv(this, filename);
\r
2073 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
2075 data_chpt.Rows.Clear();
\r
2076 DataGridView chapterGridView = Main.ChapterNaming(selectedTitle, data_chpt, drop_chapterFinish.Text);
\r
2077 if (chapterGridView != null)
\r
2079 data_chpt = chapterGridView;
\r
2083 // Query Editor Tab
\r
2084 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
2086 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
2089 private void btn_clear_Click(object sender, EventArgs e)
\r
2091 rtf_query.Clear();
\r
2096 // MainWindow Components, Actions and Functions ***********************
\r
2098 #region Source Scan
\r
2101 /// Start the Scan Process
\r
2103 /// <param name="filename">
\r
2106 /// <param name="title">
\r
2109 private void StartScan(string filename, int title)
\r
2111 // Setup the GUI components for the scan.
\r
2112 sourcePath = filename;
\r
2114 this.DisableGUI();
\r
2119 SourceScan.Scan(sourcePath, title);
\r
2121 catch (Exception exc)
\r
2123 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2128 /// Update the Status label for the scan
\r
2130 /// <param name="sender">
\r
2133 /// <param name="e">
\r
2136 private void SourceScan_ScanStatusChanged(object sender, EventArgs e)
\r
2138 UpdateScanStatusLabel();
\r
2142 /// Update the UI after the scan has completed
\r
2144 /// <param name="sender">
\r
2147 /// <param name="e">
\r
2150 private void SourceScan_ScanCompleted(object sender, EventArgs e)
\r
2152 UpdateGuiAfterScan();
\r
2156 /// Update the Scan Status Label
\r
2158 private void UpdateScanStatusLabel()
\r
2160 if (InvokeRequired)
\r
2162 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));
\r
2165 labelSource.Text = SourceScan.ScanStatus;
\r
2169 /// Reset the GUI when the scan has completed
\r
2171 private void UpdateGuiAfterScan()
\r
2173 if (InvokeRequired)
\r
2175 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));
\r
2181 currentSource = SourceScan.SouceData;
\r
2183 // Setup some GUI components
\r
2184 drp_dvdtitle.Items.Clear();
\r
2185 if (currentSource.Titles.Count != 0)
\r
2186 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2188 foreach (Title title in currentSource.Titles)
\r
2190 if (title.MainTitle)
\r
2192 drp_dvdtitle.SelectedItem = title;
\r
2196 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2198 drp_dvdtitle.SelectedIndex = 0;
\r
2201 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2202 if (drop_chapterStart.Items.Count > 0)
\r
2205 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2206 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2207 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2210 Check_ChapterMarkers.Enabled = false;
\r
2211 Check_ChapterMarkers.Checked = false;
\r
2212 data_chpt.Rows.Clear();
\r
2216 // If no titles were found, Display an error message
\r
2217 if (drp_dvdtitle.Items.Count == 0)
\r
2220 "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
2221 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2222 sourcePath = string.Empty;
\r
2224 UpdateSourceLabel();
\r
2226 // This is a bit of a hack to fix the queue editing.
\r
2227 // If afte the scan, we find a job sitting in queueEdit, then the user has rescaned the source from the queue by clicking edit.
\r
2228 // When this occures, we want to repopulate their old settings.
\r
2229 if (queueEdit != null)
\r
2232 if (queueEdit.Query != null)
\r
2234 // Send the query from the file to the Query Parser class
\r
2235 QueryParser presetQuery = QueryParser.Parse(queueEdit.Query);
\r
2237 // Now load the preset
\r
2238 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2240 // Set the destination path
\r
2241 this.text_destination.Text = queueEdit.Destination;
\r
2243 // The x264 widgets will need updated, so do this now:
\r
2244 x264Panel.StandardizeOptString();
\r
2245 x264Panel.SetCurrentSettingsInPanel();
\r
2247 // Set the crop label
\r
2248 PictureSettings.SetPresetCropWarningLabel(null);
\r
2254 // Enable the GUI components and enable any disabled components
\r
2257 catch (Exception exc)
\r
2259 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2260 MessageBoxIcon.Error);
\r
2266 /// Enable the GUI
\r
2268 private void EnableGUI()
\r
2272 if (InvokeRequired)
\r
2273 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2274 foreach (Control ctrl in Controls)
\r
2275 ctrl.Enabled = true;
\r
2276 btn_start.Enabled = true;
\r
2277 btn_showQueue.Enabled = true;
\r
2278 btn_add2Queue.Enabled = true;
\r
2279 tb_preview.Enabled = true;
\r
2280 btn_source.Enabled = true;
\r
2281 mnu_killCLI.Visible = false;
\r
2283 catch (Exception exc)
\r
2285 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2290 /// Disable the GUI
\r
2292 private void DisableGUI()
\r
2294 foreach (Control ctrl in Controls)
\r
2295 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2296 ctrl.Enabled = false;
\r
2298 labelSource.Enabled = true;
\r
2299 labelStaticSource.Enabled = true;
\r
2300 SourceLayoutPanel.Enabled = true;
\r
2301 btn_source.Enabled = false;
\r
2302 btn_start.Enabled = false;
\r
2303 btn_showQueue.Enabled = false;
\r
2304 btn_add2Queue.Enabled = false;
\r
2305 tb_preview.Enabled = false;
\r
2306 mnu_killCLI.Visible = true;
\r
2312 private void KillScan()
\r
2314 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2318 SourceScan.Stop();
\r
2320 labelSource.Text = "Scan Cancelled";
\r
2326 private void ResetGUI()
\r
2328 drp_dvdtitle.Items.Clear();
\r
2329 drop_chapterStart.Items.Clear();
\r
2330 drop_chapterFinish.Items.Clear();
\r
2331 lbl_duration.Text = "Select a Title";
\r
2332 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2333 sourcePath = String.Empty;
\r
2334 text_destination.Text = String.Empty;
\r
2335 selectedTitle = null;
\r
2339 /// Update the Source Label
\r
2341 private void UpdateSourceLabel()
\r
2343 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2347 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2349 /// <param name="job">
\r
2352 public void RecievingJob(Job job)
\r
2355 this.currentlySelectedPreset = null;
\r
2356 x264Panel.Reset2Defaults();
\r
2359 queueEdit = job; // Nasty but will do for now. TODO
\r
2360 StartScan(job.Source, job.Title);
\r
2365 #region GUI Functions and Actions
\r
2368 /// Set the GUI to it's finished encoding state.
\r
2370 private void SetEncodeFinished()
\r
2374 if (InvokeRequired)
\r
2376 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2380 lbl_encode.Text = "Encoding Finished";
\r
2381 ProgressBarStatus.Visible = false;
\r
2382 btn_start.Text = "Start";
\r
2383 btn_start.ToolTipText = "Start the encoding process";
\r
2384 btn_start.Image = Properties.Resources.Play;
\r
2386 // If the window is minimized, display the notification in a popup.
\r
2387 if (Properties.Settings.Default.trayIconAlerts)
\r
2388 if (FormWindowState.Minimized == this.WindowState)
\r
2390 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2391 notifyIcon.ShowBalloonTip(500);
\r
2394 catch (Exception exc)
\r
2396 MessageBox.Show(exc.ToString());
\r
2401 /// Set the GUI to it's started encoding state.
\r
2403 private void SetEncodeStarted()
\r
2407 if (InvokeRequired)
\r
2409 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2412 lbl_encode.Visible = true;
\r
2413 ProgressBarStatus.Value = 0;
\r
2414 ProgressBarStatus.Visible = true;
\r
2415 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";
\r
2416 btn_start.Text = "Stop";
\r
2417 btn_start.ToolTipText = "Stop the encoding process.";
\r
2418 btn_start.Image = Properties.Resources.stop;
\r
2420 catch (Exception exc)
\r
2422 MessageBox.Show(exc.ToString());
\r
2427 /// Display the Encode Status
\r
2429 /// <param name="sender">
\r
2432 /// <param name="e">
\r
2435 private void EncodeQueue_EncodeStatusChanged(object sender, HandBrake.ApplicationServices.EncodeProgressEventArgs e)
\r
2437 if (this.InvokeRequired)
\r
2439 this.BeginInvoke(new Encode.EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2445 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2446 e.PercentComplete,
\r
2447 e.CurrentFrameRate,
\r
2448 e.AverageFrameRate,
\r
2449 e.EstimatedTimeLeft,
\r
2450 encodeQueue.Count);
\r
2452 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2456 /// Set the DVD Drive selection in the "Source" Menu
\r
2458 private void SetDriveSelectionMenuItem()
\r
2462 if (InvokeRequired)
\r
2464 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2468 drives = Main.GetDrives();
\r
2470 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2471 foreach (DriveInformation drive in drives)
\r
2473 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2475 Name = drive.ToString(),
\r
2476 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2477 Image = Resources.disc_small
\r
2479 menuItem.Click += new EventHandler(MnuDvdDriveClick);
\r
2480 menuItems.Add(menuItem);
\r
2483 foreach (ToolStripMenuItem item in menuItems)
\r
2484 btn_source.DropDownItems.Add(item);
\r
2486 catch (Exception exc)
\r
2488 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2493 /// Access the preset Handler and setup the preset panel.
\r
2495 private void LoadPresetPanel()
\r
2497 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2498 if (!Settings.Default.presetNotification)
\r
2499 MessageBox.Show(this,
\r
2500 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2501 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2503 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2504 treeView_presets.Update();
\r
2508 /// Get the title from the selected item in the title dropdown.
\r
2513 private int GetTitle()
\r
2516 if (drp_dvdtitle.SelectedItem != null)
\r
2518 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2519 int.TryParse(titleInfo[0], out title);
\r
2526 /// Handle the Update Check Finishing.
\r
2528 /// <param name="result">
\r
2531 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2533 // Make sure it's running on the calling thread
\r
2534 if (InvokeRequired)
\r
2536 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2539 UpdateCheckInformation info;
\r
2542 // Get the information about the new build, if any, and close the window
\r
2543 info = UpdateService.EndCheckForUpdates(result);
\r
2545 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2547 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
2548 updateWindow.ShowDialog();
\r
2551 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2552 MessageBoxIcon.Information);
\r
2553 lbl_updateCheck.Visible = false;
\r
2556 catch (Exception ex)
\r
2558 if ((bool)result.AsyncState)
\r
2560 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2561 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2570 /// Handle GUI shortcuts
\r
2572 /// <param name="msg">Message</param>
\r
2573 /// <param name="keyData">Keys</param>
\r
2574 /// <returns>Bool</returns>
\r
2575 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2577 if (keyData == (Keys.Control | Keys.S))
\r
2579 btn_start_Click(this, new EventArgs());
\r
2583 if (keyData == (Keys.Control | Keys.Shift | Keys.A))
\r
2585 btn_add2Queue_Click(this, new EventArgs());
\r
2588 return base.ProcessCmdKey(ref msg, keyData);
\r
2592 /// If the queue is being processed, prompt the user to confirm application close.
\r
2594 /// <param name="e">FormClosingEventArgs</param>
\r
2595 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2599 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2600 if (encodeQueue.IsEncoding)
\r
2602 DialogResult result =
\r
2604 "HandBrake is currently encoding. Closing HandBrake will stop the current encode and will result in an unplayable file.\n\nDo you want to close HandBrake?",
\r
2605 "Close HandBrake?",
\r
2606 MessageBoxButtons.YesNo,
\r
2607 MessageBoxIcon.Question);
\r
2609 if (result == DialogResult.No)
\r
2615 encodeQueue.Stop();
\r
2618 if (SourceScan.IsScanning)
\r
2620 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);
\r
2621 SourceScan.Stop();
\r
2624 catch (Exception exc)
\r
2626 Main.ShowExceptiowWindow("HandBrake was not able to shutdown properly. You may need to forcefully quit HandBrake CLI from TaskManager if it's still running.", exc.ToString());
\r
2630 base.OnFormClosing(e);
\r
2636 // This is the END of the road ****************************************
\r