2 This file is part of the HandBrake source code.
\r
3 Homepage: <http://handbrake.fr/>.
\r
4 It may be used under the terms of the GNU General Public License. */
\r
9 using System.Collections.Generic;
\r
10 using System.ComponentModel;
\r
11 using System.Diagnostics;
\r
12 using System.Drawing;
\r
13 using System.Globalization;
\r
15 using System.Threading;
\r
16 using System.Windows.Forms;
\r
19 using HandBrake.ApplicationServices.EventArgs;
\r
20 using HandBrake.ApplicationServices.Utilities;
\r
21 using HandBrake.Framework.Model;
\r
22 using HandBrake.Framework.Services;
\r
23 using HandBrake.Framework.Views;
\r
24 using HandBrake.ApplicationServices.Functions;
\r
25 using HandBrake.ApplicationServices.Model;
\r
26 using HandBrake.ApplicationServices.Parsing;
\r
27 using HandBrake.ApplicationServices.Services;
\r
28 using HandBrake.ApplicationServices.Services.Interfaces;
\r
30 using Handbrake.ToolWindows;
\r
36 using Main = Handbrake.Functions.Main;
\r
41 public partial class frmMain : Form
\r
43 // Objects which may be used by one or more other objects *************
\r
44 private IQueueProcessor queueProcessor = new QueueProcessor(Program.InstanceId);
\r
45 private PresetsHandler presetHandler = new PresetsHandler();
\r
47 // Windows ************************************************************
\r
48 private frmQueue queueWindow;
\r
49 private frmPreview qtpreview;
\r
50 private frmActivityWindow activityWindow;
\r
52 // Globals: Mainly used for tracking. *********************************
\r
53 public Title selectedTitle;
\r
54 public string sourcePath;
\r
55 private SourceType selectedSourceType;
\r
56 private string dvdDrivePath;
\r
57 private string dvdDriveLabel;
\r
58 private Preset currentlySelectedPreset;
\r
59 private Source currentSource;
\r
61 private IScan SourceScan;
\r
62 private List<DriveInformation> drives;
\r
63 private QueueTask queueEdit;
\r
65 // Delegates **********************************************************
\r
66 private delegate void UpdateWindowHandler();
\r
68 // Applicaiton Startup ************************************************
\r
73 /// Gets SourceName.
\r
75 public string SourceName
\r
79 if (this.selectedSourceType == SourceType.DvdDrive)
\r
81 return this.dvdDriveLabel;
\r
84 if (selectedTitle != null && !string.IsNullOrEmpty(selectedTitle.SourceName))
\r
86 return Path.GetFileName(selectedTitle.SourceName);
\r
89 // We have a drive, selected as a folder.
\r
90 if (this.sourcePath.EndsWith("\\"))
\r
92 drives = UtilityService.GetDrives();
\r
93 foreach (DriveInformation item in drives)
\r
95 if (item.RootDirectory.Contains(this.sourcePath))
\r
97 return item.VolumeLabel;
\r
102 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")
\r
103 return Path.GetFileNameWithoutExtension(this.sourcePath);
\r
105 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));
\r
111 #region Application Startup
\r
114 /// Initializes a new instance of the <see cref="frmMain"/> class.
\r
116 /// <param name="args">
\r
117 /// The arguments passed in on application startup.
\r
119 public frmMain(string[] args)
\r
121 InitializeComponent();
\r
123 // We can use LibHB, if the library hb.dll exists.
\r
124 this.SourceScan = File.Exists("hb.dll") ? (IScan)new LibScan() : new ScanService();
\r
126 // Update the users config file with the CLI version data.
\r
127 Main.SetCliVersionData();
\r
129 if (Settings.Default.hb_version.Contains("svn"))
\r
131 this.Text += " " + Settings.Default.hb_version;
\r
134 // Check for new versions, if update checking is enabled
\r
135 if (Settings.Default.updateStatus)
\r
137 if (DateTime.Now.Subtract(Settings.Default.lastUpdateCheckDate).TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
139 // Set when the last update was
\r
140 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
141 Settings.Default.Save();
\r
142 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
143 ? Settings.Default.appcast_unstable
\r
144 : Settings.Default.appcast;
\r
145 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\r
149 // Clear the log files in the background
\r
150 if (Settings.Default.clearOldLogs)
\r
152 Thread clearLog = new Thread(() => UtilityService.ClearLogFiles(30));
\r
156 // Setup the GUI components
\r
157 LoadPresetPanel(); // Load the Preset Panel
\r
158 treeView_presets.ExpandAll();
\r
159 lbl_encode.Text = string.Empty;
\r
160 drop_mode.SelectedIndex = 0;
\r
161 queueWindow = new frmQueue(this.queueProcessor, this); // Prepare the Queue
\r
162 if (!Settings.Default.QueryEditorTab)
\r
163 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
164 if (Settings.Default.tooltipEnable)
\r
165 ToolTip.Active = true;
\r
167 // Load the user's default settings or Normal Preset
\r
168 if (Settings.Default.defaultPreset != string.Empty && presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)
\r
170 string query = presetHandler.GetPreset(Settings.Default.defaultPreset).Query;
\r
173 x264Panel.Reset2Defaults();
\r
175 EncodeTask presetQuery = QueryParserUtility.Parse(query);
\r
176 PresetLoader.LoadPreset(this, presetQuery, Settings.Default.defaultPreset);
\r
178 x264Panel.StandardizeOptString();
\r
179 x264Panel.SetCurrentSettingsInPanel();
\r
183 loadNormalPreset();
\r
185 // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)
\r
186 GrowlCommunicator.Register();
\r
188 // Event Handlers and Queue Recovery
\r
190 Main.RecoverQueue(this.queueProcessor);
\r
192 // If have a file passed in via command arguemtents, check it's a file and try scanning it.
\r
193 if (args.Length >= 1 && (File.Exists(args[0]) || Directory.Exists(args[0])))
\r
195 this.StartScan(args[0], 0);
\r
200 /// When the update check is done, process the results.
\r
202 /// <param name="result">IAsyncResult result</param>
\r
203 private void UpdateCheckDone(IAsyncResult result)
\r
205 if (InvokeRequired)
\r
207 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));
\r
213 UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
\r
215 if (info.NewVersionAvailable)
\r
217 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
218 updateWindow.ShowDialog();
\r
221 catch (Exception ex)
\r
223 if ((bool)result.AsyncState)
\r
224 Main.ShowExceptiowWindow("Unable to check for updates, Please try again later.", ex.ToString());
\r
232 // Encoding Events for setting up the GUI
\r
233 private void events()
\r
235 // Handle Widget changes when preset is selected.
\r
236 RegisterPresetEventHandler();
\r
238 // Handle Window Resize
\r
239 if (Settings.Default.MainWindowMinimize)
\r
240 this.Resize += this.frmMain_Resize;
\r
242 // Handle Encode Start / Finish / Pause
\r
243 this.queueProcessor.EncodeService.EncodeStarted += this.encodeStarted;
\r
244 this.queueProcessor.EncodeService.EncodeCompleted += encodeEnded;
\r
246 // Scan Started and Completed Events
\r
247 SourceScan.ScanStatusChanged += this.SourceScanScanStatusChanged;
\r
248 SourceScan.ScanCompleted += this.SourceScanScanCompleted;
\r
250 // Handle a file being draged onto the GUI.
\r
251 this.DragEnter += frmMain_DragEnter;
\r
252 this.DragDrop += this.frmMain_DragDrop;
\r
255 // 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
256 private void RegisterPresetEventHandler()
\r
259 drop_format.SelectedIndexChanged += this.changePresetLabel;
\r
260 check_largeFile.CheckedChanged += this.changePresetLabel;
\r
261 check_iPodAtom.CheckedChanged += this.changePresetLabel;
\r
262 check_optimiseMP4.CheckedChanged += this.changePresetLabel;
\r
264 // Picture Settings
\r
265 PictureSettings.PictureSettingsChanged += this.changePresetLabel;
\r
268 Filters.FilterSettingsChanged += this.changePresetLabel;
\r
271 drp_videoEncoder.SelectedIndexChanged += this.changePresetLabel;
\r
272 check_2PassEncode.CheckedChanged += this.changePresetLabel;
\r
273 check_turbo.CheckedChanged += this.changePresetLabel;
\r
274 text_filesize.TextChanged += this.changePresetLabel;
\r
275 text_bitrate.TextChanged += this.changePresetLabel;
\r
276 slider_videoQuality.ValueChanged += this.changePresetLabel;
\r
279 AudioSettings.AudioListChanged += this.changePresetLabel;
\r
282 x264Panel.rtf_x264Query.TextChanged += this.changePresetLabel;
\r
285 private void UnRegisterPresetEventHandler()
\r
287 // Output Settings
\r
288 drop_format.SelectedIndexChanged -= this.changePresetLabel;
\r
289 check_largeFile.CheckedChanged -= this.changePresetLabel;
\r
290 check_iPodAtom.CheckedChanged -= this.changePresetLabel;
\r
291 check_optimiseMP4.CheckedChanged -= this.changePresetLabel;
\r
293 // Picture Settings
\r
294 PictureSettings.PictureSettingsChanged -= this.changePresetLabel;
\r
297 Filters.FilterSettingsChanged -= this.changePresetLabel;
\r
300 drp_videoEncoder.SelectedIndexChanged -= this.changePresetLabel;
\r
301 check_2PassEncode.CheckedChanged -= this.changePresetLabel;
\r
302 check_turbo.CheckedChanged -= this.changePresetLabel;
\r
303 text_filesize.TextChanged -= this.changePresetLabel;
\r
304 text_bitrate.TextChanged -= this.changePresetLabel;
\r
305 slider_videoQuality.ValueChanged -= this.changePresetLabel;
\r
308 AudioSettings.AudioListChanged -= this.changePresetLabel;
\r
311 x264Panel.rtf_x264Query.TextChanged -= this.changePresetLabel;
\r
314 private void changePresetLabel(object sender, EventArgs e)
\r
316 labelPreset.Text = "Output Settings (Preset: Custom)";
\r
317 this.currentlySelectedPreset = null;
\r
320 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
322 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
323 e.Effect = DragDropEffects.All;
\r
326 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
328 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
329 sourcePath = string.Empty;
\r
331 if (fileList != null)
\r
333 if (!string.IsNullOrEmpty(fileList[0]))
\r
335 this.selectedSourceType = SourceType.VideoFile;
\r
336 StartScan(fileList[0], 0);
\r
339 UpdateSourceLabel();
\r
342 UpdateSourceLabel();
\r
345 private void encodeStarted(object sender, EventArgs e)
\r
347 SetEncodeStarted();
\r
348 this.queueProcessor.EncodeService.EncodeStatusChanged += EncodeQueue_EncodeStatusChanged;
\r
351 private void encodeEnded(object sender, EventArgs e)
\r
353 this.queueProcessor.EncodeService.EncodeStatusChanged -= EncodeQueue_EncodeStatusChanged;
\r
354 SetEncodeFinished();
\r
358 // User Interface Menus / Tool Strips *********************************
\r
363 /// Kill The scan menu Item
\r
365 /// <param name="sender">
\r
368 /// <param name="e">
\r
371 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
377 /// Exit the Application Menu Item
\r
379 /// <param name="sender">
\r
382 /// <param name="e">
\r
385 private void mnu_exit_Click(object sender, EventArgs e)
\r
387 Application.Exit();
\r
395 /// Menu - Start Button
\r
397 /// <param name="sender">
\r
400 /// <param name="e">
\r
403 private void mnu_encode_Click(object sender, EventArgs e)
\r
405 queueWindow.Show();
\r
409 /// Menu - Display the Log Window
\r
411 /// <param name="sender">
\r
414 /// <param name="e">
\r
417 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
419 this.btn_ActivityWindow_Click(this, null);
\r
423 /// Menu - Display the Options Window
\r
425 /// <param name="sender">
\r
428 /// <param name="e">
\r
431 private void mnu_options_Click(object sender, EventArgs e)
\r
433 Form options = new frmOptions(this);
\r
434 options.ShowDialog();
\r
439 #region Presets Menu
\r
442 /// Reset the Built in Presets
\r
444 /// <param name="sender">
\r
447 /// <param name="e">
\r
450 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
452 presetHandler.UpdateBuiltInPresets();
\r
454 if (treeView_presets.Nodes.Count == 0)
\r
456 "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
457 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
459 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
461 treeView_presets.ExpandAll();
\r
465 /// Delete the selected preset
\r
467 /// <param name="sender">
\r
470 /// <param name="e">
\r
473 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
475 presetHandler.RemoveBuiltInPresets();
\r
476 LoadPresetPanel(); // Reload the preset panel
\r
480 /// Select the Normal preset
\r
482 /// <param name="sender">
\r
485 /// <param name="e">
\r
488 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
490 loadNormalPreset();
\r
494 /// Import a plist Preset
\r
496 /// <param name="sender">
\r
499 /// <param name="e">
\r
502 private void mnu_importMacPreset_Click(object sender, EventArgs e)
\r
508 /// Export a Plist Preset
\r
510 /// <param name="sender">
\r
513 /// <param name="e">
\r
516 private void mnu_exportMacPreset_Click(object sender, EventArgs e)
\r
522 /// Create a new Preset
\r
524 /// <param name="sender">
\r
527 /// <param name="e">
\r
530 private void btn_new_preset_Click(object sender, EventArgs e)
\r
532 Form preset = new frmAddPreset(this, presetHandler);
\r
533 if (preset.ShowDialog() == DialogResult.OK)
\r
535 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
536 treeView_presets.Nodes.Add(presetTreeview);
\r
537 presetHandler.LastPresetAdded = null;
\r
546 /// Menu - Display the User Guide Web Page
\r
548 /// <param name="sender">
\r
551 /// <param name="e">
\r
554 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
556 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
560 /// Menu - Check for Updates
\r
562 /// <param name="sender">
\r
565 /// <param name="e">
\r
568 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
570 lbl_updateCheck.Visible = true;
\r
571 Settings.Default.lastUpdateCheckDate = DateTime.Now;
\r
572 Settings.Default.Save();
\r
573 string url = Settings.Default.hb_build.ToString().EndsWith("1")
\r
574 ? Settings.Default.appcast_unstable
\r
575 : Settings.Default.appcast;
\r
576 UpdateService.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDoneMenu), false, url, Settings.Default.hb_build, Settings.Default.skipversion, Settings.Default.hb_version);
\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 // TODO this requires a re-think since the Query Editor has changed.
\r
654 DialogResult result =
\r
656 "Do you wish to include picture settings when updating the preset: " +
\r
657 treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,
\r
658 MessageBoxIcon.Question);
\r
659 if (result == DialogResult.Yes)
\r
660 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
661 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), true);
\r
662 else if (result == DialogResult.No)
\r
663 presetHandler.Update(treeView_presets.SelectedNode.Text,
\r
664 QueryGenerator.GenerateQueryForPreset(this, QueryPictureSettingsMode.SourceMaximum, true, 0, 0), false);
\r
668 /// RMenu - Delete Preset
\r
670 /// <param name="sender">
\r
673 /// <param name="e">
\r
676 private void pmnu_delete_click(object sender, EventArgs e)
\r
678 if (treeView_presets.SelectedNode != null)
\r
680 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
681 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
683 treeView_presets.Select();
\r
687 /// Preset Menu Is Opening. Setup the Menu
\r
689 /// <param name="sender">
\r
692 /// <param name="e">
\r
695 private void presets_menu_Opening(object sender, CancelEventArgs e)
\r
697 // Make sure that the save menu is always disabled by default
\r
698 pmnu_saveChanges.Enabled = false;
\r
700 // Now enable the save menu if the selected preset is a user preset
\r
701 if (treeView_presets.SelectedNode != null)
\r
702 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
703 pmnu_saveChanges.Enabled = true;
\r
705 treeView_presets.Select();
\r
708 // Presets Management
\r
711 /// Button - Add a preset
\r
713 /// <param name="sender">
\r
716 /// <param name="e">
\r
719 private void btn_addPreset_Click(object sender, EventArgs e)
\r
721 Form preset = new frmAddPreset(this, presetHandler);
\r
722 if (preset.ShowDialog() == DialogResult.OK)
\r
724 TreeNode presetTreeview = new TreeNode(presetHandler.LastPresetAdded.Name) { ForeColor = Color.Black };
\r
725 treeView_presets.Nodes.Add(presetTreeview);
\r
726 presetHandler.LastPresetAdded = null;
\r
731 /// Button - remove a Preset
\r
733 /// <param name="sender">
\r
736 /// <param name="e">
\r
739 private void btn_removePreset_Click(object sender, EventArgs e)
\r
741 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
742 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
743 if (result == DialogResult.Yes)
\r
745 if (treeView_presets.SelectedNode != null)
\r
747 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
748 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
751 treeView_presets.Select();
\r
755 /// Button - Set the selected preset as the default
\r
757 /// <param name="sender">
\r
760 /// <param name="e">
\r
763 private void btn_setDefault_Click(object sender, EventArgs e)
\r
765 if (treeView_presets.SelectedNode != null)
\r
767 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",
\r
768 "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
769 if (result == DialogResult.Yes)
\r
771 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
772 Properties.Settings.Default.Save();
\r
773 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
777 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
781 /// PresetBar Mouse Down event
\r
783 /// <param name="sender">
\r
786 /// <param name="e">
\r
789 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
791 if (e.Button == MouseButtons.Right)
\r
792 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
793 else if (e.Button == MouseButtons.Left)
\r
795 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
797 if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
802 treeView_presets.Select();
\r
806 /// Preset Bar after selecting the preset
\r
808 /// <param name="sender">
\r
811 /// <param name="e">
\r
814 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
820 /// When the mouse moves, display a preset
\r
822 /// <param name="sender">The Sender</param>
\r
823 /// <param name="e">the MouseEventArgs</param>
\r
824 private void TreeViewPresetsMouseMove(object sender, MouseEventArgs e)
\r
826 TreeNode theNode = this.treeView_presets.GetNodeAt(e.X, e.Y);
\r
828 if ((theNode != null))
\r
830 // Change the ToolTip only if the pointer moved to a new node.
\r
831 if (theNode.ToolTipText != this.ToolTip.GetToolTip(this.treeView_presets))
\r
833 this.ToolTip.SetToolTip(this.treeView_presets, theNode.ToolTipText);
\r
836 else // Pointer is not over a node so clear the ToolTip.
\r
838 this.ToolTip.SetToolTip(this.treeView_presets, string.Empty);
\r
843 /// Preset Bar - Handle the Delete Key
\r
845 /// <param name="sender">
\r
848 /// <param name="e">
\r
851 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
853 if (e.KeyCode == Keys.Delete)
\r
855 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",
\r
856 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
857 if (result == DialogResult.Yes)
\r
859 if (treeView_presets.SelectedNode != null)
\r
860 presetHandler.Remove(treeView_presets.SelectedNode.Text);
\r
862 // Remember each nodes expanded status so we can reload it
\r
863 List<bool> nodeStatus = new List<bool>();
\r
864 foreach (TreeNode node in treeView_presets.Nodes)
\r
865 nodeStatus.Add(node.IsExpanded);
\r
867 // Now reload the preset panel
\r
870 // And finally, re-expand any of the nodes if required
\r
872 foreach (TreeNode node in treeView_presets.Nodes)
\r
884 /// Select the selected preset and setup the GUI
\r
886 private void selectPreset()
\r
888 if (treeView_presets.SelectedNode != null)
\r
890 // Ok, so, we've selected a preset. Now we want to load it.
\r
891 string presetName = treeView_presets.SelectedNode.Text;
\r
892 Preset preset = presetHandler.GetPreset(presetName);
\r
893 if (preset != null)
\r
895 string query = presetHandler.GetPreset(presetName).Query;
\r
899 // Ok, Reset all the H264 widgets before changing the preset
\r
900 x264Panel.Reset2Defaults();
\r
902 // Send the query from the file to the Query Parser class
\r
903 EncodeTask presetQuery = QueryParserUtility.Parse(query);
\r
905 // Now load the preset
\r
906 PresetLoader.LoadPreset(this, presetQuery, presetName);
\r
908 // The x264 widgets will need updated, so do this now:
\r
909 x264Panel.StandardizeOptString();
\r
910 x264Panel.SetCurrentSettingsInPanel();
\r
912 // Finally, let this window have a copy of the preset settings.
\r
913 this.currentlySelectedPreset = preset;
\r
914 PictureSettings.SetPresetCropWarningLabel(preset);
\r
921 /// Load the Normal Preset
\r
923 private void loadNormalPreset()
\r
925 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
927 foreach (TreeNode node in treenode.Nodes)
\r
929 if (node.Text.Equals("Normal"))
\r
930 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
936 /// Import a plist preset
\r
938 private void ImportPreset()
\r
940 if (openPreset.ShowDialog() == DialogResult.OK)
\r
942 EncodeTask parsed = PlistPresetHandler.Import(openPreset.FileName);
\r
943 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))
\r
945 DialogResult result =
\r
946 MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",
\r
947 "Overwrite preset?",
\r
948 MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
949 if (result == DialogResult.Yes)
\r
951 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
952 presetHandler.Update(parsed.PresetName + " (Imported)",
\r
953 QueryGenerator.GenerateFullQuery(this),
\r
954 parsed.UsesPictureSettings);
\r
959 PresetLoader.LoadPreset(this, parsed, parsed.PresetName);
\r
960 if (presetHandler.Add(parsed.PresetName + " (Imported)",
\r
961 QueryGenerator.GenerateFullQuery(this),
\r
962 parsed.UsesPictureSettings, string.Empty))
\r
964 TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")
\r
966 ForeColor = Color.Black
\r
968 treeView_presets.Nodes.Add(preset_treeview);
\r
975 /// Export a plist Preset
\r
977 private void ExportPreset()
\r
979 SaveFileDialog savefiledialog = new SaveFileDialog { Filter = "plist|*.plist" };
\r
981 if (treeView_presets.SelectedNode != null)
\r
983 if (savefiledialog.ShowDialog() == DialogResult.OK)
\r
985 Preset preset = presetHandler.GetPreset(treeView_presets.SelectedNode.Text);
\r
986 PlistPresetHandler.Export(savefiledialog.FileName, preset);
\r
996 /// 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
998 /// <param name="sender">
\r
1001 /// <param name="e">
\r
1004 private void btn_source_Click(object sender, EventArgs e)
\r
1006 // Remove old Drive Menu Items.
\r
1007 List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();
\r
1008 foreach (var item in btn_source.DropDownItems)
\r
1010 if (item.GetType() == typeof(ToolStripMenuItem))
\r
1012 ToolStripMenuItem menuItem = (ToolStripMenuItem)item;
\r
1013 if (menuItem.Name.StartsWith("Drive"))
\r
1015 itemsToRemove.Add(menuItem);
\r
1020 foreach (ToolStripMenuItem item in itemsToRemove)
\r
1021 btn_source.DropDownItems.Remove(item);
\r
1023 Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);
\r
1024 driveInfoThread.Start();
\r
1028 /// Toolbar - Start The Encode
\r
1030 /// <param name="sender">
\r
1033 /// <param name="e">
\r
1036 private void btn_start_Click(object sender, EventArgs e)
\r
1038 if (btn_start.Text == "Stop")
\r
1040 DialogResult result = !Properties.Settings.Default.showCliForInGuiEncodeStatus
\r
1041 ? MessageBox.Show(
\r
1042 "Are you sure you wish to cancel the encode?\n\nPlease note: Stopping this encode will render the file unplayable. ",
\r
1044 MessageBoxButtons.YesNo,
\r
1045 MessageBoxIcon.Question)
\r
1046 : MessageBox.Show(
\r
1047 "Are you sure you wish to cancel the encode?",
\r
1049 MessageBoxButtons.YesNo,
\r
1050 MessageBoxIcon.Question);
\r
1052 if (result == DialogResult.Yes)
\r
1054 // Pause The Queue
\r
1055 this.queueProcessor.Pause();
\r
1057 if (Settings.Default.showCliForInGuiEncodeStatus)
\r
1058 this.queueProcessor.EncodeService.SafelyStop();
\r
1060 this.queueProcessor.EncodeService.Stop();
\r
1065 // 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
1066 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1067 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1069 if (this.queueProcessor.QueueManager.Count != 0 || (!string.IsNullOrEmpty(jobSourcePath) && !string.IsNullOrEmpty(jobDestination)))
\r
1071 string generatedQuery = QueryGenerator.GenerateFullQuery(this);
\r
1072 string specifiedQuery = rtf_query.Text != string.Empty
\r
1074 : QueryGenerator.GenerateFullQuery(this);
\r
1075 string query = string.Empty;
\r
1077 // Check to make sure the generated query matches the GUI settings
\r
1078 if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&
\r
1079 generatedQuery != specifiedQuery)
\r
1081 DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +
\r
1082 "does not match the current GUI settings.\n\nBecause the manual query takes " +
\r
1083 "priority over the GUI, your recently updated settings will not be taken " +
\r
1084 "into account when encoding this job." +
\r
1085 Environment.NewLine + Environment.NewLine +
\r
1086 "Do you want to replace the manual query with the updated GUI-generated query?",
\r
1087 "Manual Query does not Match GUI",
\r
1088 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,
\r
1089 MessageBoxDefaultButton.Button3);
\r
1093 case DialogResult.Yes:
\r
1094 // Replace the manual query with the generated one
\r
1095 query = generatedQuery;
\r
1096 rtf_query.Text = generatedQuery;
\r
1098 case DialogResult.No:
\r
1099 // Use the manual query
\r
1100 query = specifiedQuery;
\r
1102 case DialogResult.Cancel:
\r
1103 // Don't start the encode
\r
1109 query = specifiedQuery;
\r
1112 DialogResult overwrite = DialogResult.Yes;
\r
1113 if (!string.IsNullOrEmpty(jobDestination) && File.Exists(jobDestination))
\r
1115 overwrite = MessageBox.Show(
\r
1116 "The destination file already exists. Are you sure you want to overwrite it?",
\r
1117 "Overwrite File?",
\r
1118 MessageBoxButtons.YesNo,
\r
1119 MessageBoxIcon.Question);
\r
1122 if (overwrite == DialogResult.Yes)
\r
1124 QueueTask task = new QueueTask(query)
\r
1126 Title = this.GetTitle(),
\r
1127 Source = jobSourcePath,
\r
1128 Destination = jobDestination,
\r
1129 CustomQuery = (this.rtf_query.Text != string.Empty)
\r
1132 if (this.queueProcessor.QueueManager.Count == 0)
\r
1133 this.queueProcessor.QueueManager.Add(task);
\r
1135 queueWindow.SetQueue();
\r
1136 if (this.queueProcessor.QueueManager.Count > 1)
\r
1137 queueWindow.Show(false);
\r
1139 SetEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
1140 this.queueProcessor.Start(); // Start The Queue Encoding Process
\r
1145 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1146 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1147 MessageBoxIcon.Warning);
\r
1152 /// Toolbar - Add the current job to the Queue
\r
1154 /// <param name="sender">
\r
1157 /// <param name="e">
\r
1160 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
1162 // Add the item to the queue.
\r
1163 AddItemToQueue(true);
\r
1164 queueWindow.Show();
\r
1168 /// Add Multiple Items to the Queue at once.
\r
1170 /// <param name="sender">The Sender</param>
\r
1171 /// <param name="e">The EventArgs</param>
\r
1172 private void MnuAddMultiToQueueClick(object sender, EventArgs e)
\r
1174 if (!Settings.Default.autoNaming)
\r
1176 MessageBox.Show("Destination Auto Naming must be enabled in preferences for this feature to work.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1180 if (this.SourceScan.SouceData == null)
\r
1182 MessageBox.Show("You must first scan a source or collection of source to use this feature.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1186 BatchAdd batchAdd = new BatchAdd();
\r
1187 if (batchAdd.ShowDialog() == DialogResult.OK)
\r
1189 int min = batchAdd.Min;
\r
1190 int max = batchAdd.Max;
\r
1191 bool errors = false;
\r
1193 foreach (Title title in this.SourceScan.SouceData.Titles)
\r
1195 if (title.Duration.TotalMinutes > min && title.Duration.TotalMinutes < max)
\r
1198 this.drp_dvdtitle.SelectedItem = title;
\r
1200 if (!this.AddItemToQueue(false))
\r
1210 "One or more items could not be added to the queue. You should check your queue and manually add any missing jobs.",
\r
1212 MessageBoxButtons.OK,
\r
1213 MessageBoxIcon.Warning);
\r
1218 private bool AddItemToQueue(bool showError)
\r
1220 string query = QueryGenerator.GenerateFullQuery(this);
\r
1221 if (!string.IsNullOrEmpty(rtf_query.Text))
\r
1222 query = rtf_query.Text;
\r
1224 // 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
1225 string jobSourcePath = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetSourceFromQuery(rtf_query.Text) : sourcePath;
\r
1226 string jobDestination = !string.IsNullOrEmpty(rtf_query.Text) ? Main.GetDestinationFromQuery(rtf_query.Text) : text_destination.Text;
\r
1228 // Make sure we have a Source and Destination.
\r
1229 if (string.IsNullOrEmpty(jobSourcePath) || string.IsNullOrEmpty(jobDestination))
\r
1232 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1236 // Make sure the destination path exists.
\r
1237 if (!Directory.Exists(Path.GetDirectoryName(jobDestination)))
\r
1240 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
1244 // Make sure we don't have a duplciate on the queue.
\r
1245 if (this.queueProcessor.QueueManager.CheckForDestinationPathDuplicates(jobDestination))
\r
1249 DialogResult result;
\r
1253 "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
1256 MessageBoxButtons.YesNo,
\r
1257 MessageBoxIcon.Warning);
\r
1259 if (result != DialogResult.Yes) return false;
\r
1268 QueueTask task = new QueueTask(query)
\r
1270 Title = this.GetTitle(),
\r
1271 Source = jobSourcePath,
\r
1272 Destination = jobDestination,
\r
1273 CustomQuery = (this.rtf_query.Text != string.Empty)
\r
1275 this.queueProcessor.QueueManager.Add(task);
\r
1277 lbl_encode.Text = this.queueProcessor.QueueManager.Count + " encode(s) pending in the queue";
\r
1283 /// Toolbar - Show the Queue
\r
1285 /// <param name="sender">
\r
1288 /// <param name="e">
\r
1291 private void btn_showQueue_Click(object sender, EventArgs e)
\r
1293 queueWindow.Show();
\r
1294 queueWindow.Activate();
\r
1298 /// Toolbar - Show the Preview Window
\r
1300 /// <param name="sender">
\r
1303 /// <param name="e">
\r
1306 private void tb_preview_Click(object sender, EventArgs e)
\r
1308 if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))
\r
1309 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,
\r
1310 MessageBoxIcon.Warning);
\r
1313 if (qtpreview == null)
\r
1315 qtpreview = new frmPreview(this);
\r
1318 else if (qtpreview.IsDisposed)
\r
1320 qtpreview = new frmPreview(this);
\r
1324 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,
\r
1325 MessageBoxIcon.Warning);
\r
1330 /// Toolbar - Show the Activity log Window
\r
1332 /// <param name="sender">
\r
1335 /// <param name="e">
\r
1338 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
1340 if (this.activityWindow == null || !this.activityWindow.IsHandleCreated)
\r
1341 this.activityWindow = new frmActivityWindow(this.queueProcessor.EncodeService, SourceScan);
\r
1343 this.activityWindow.Show();
\r
1344 this.activityWindow.Activate();
\r
1349 #region System Tray Icon
\r
1352 /// Handle Resizing of the main window when deaing with the Notify Icon
\r
1354 /// <param name="sender">
\r
1357 /// <param name="e">
\r
1360 private void frmMain_Resize(object sender, EventArgs e)
\r
1362 if (FormWindowState.Minimized == this.WindowState)
\r
1364 notifyIcon.Visible = true;
\r
1367 else if (FormWindowState.Normal == this.WindowState)
\r
1368 notifyIcon.Visible = false;
\r
1372 /// Double Click the Tray Icon
\r
1374 /// <param name="sender">
\r
1377 /// <param name="e">
\r
1380 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
1382 this.Visible = true;
\r
1384 this.WindowState = FormWindowState.Normal;
\r
1385 notifyIcon.Visible = false;
\r
1389 /// Tray Icon - Restore Menu Item - Resture the Window
\r
1391 /// <param name="sender">
\r
1394 /// <param name="e">
\r
1397 private void btn_restore_Click(object sender, EventArgs e)
\r
1399 this.Visible = true;
\r
1401 this.WindowState = FormWindowState.Normal;
\r
1402 notifyIcon.Visible = false;
\r
1407 #region Main Window and Tab Control
\r
1410 private void BtnFolderScanClicked(object sender, EventArgs e)
\r
1412 this.btn_source.HideDropDown();
\r
1413 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1415 this.selectedSourceType = SourceType.Folder;
\r
1416 SelectSource(DVD_Open.SelectedPath, 0);
\r
1419 UpdateSourceLabel();
\r
1422 private void BtnFileScanClicked(object sender, EventArgs e)
\r
1424 this.btn_source.HideDropDown();
\r
1425 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1427 this.selectedSourceType = SourceType.VideoFile;
\r
1428 SelectSource(ISO_Open.FileName, 0);
\r
1431 UpdateSourceLabel();
\r
1434 private void MnuDvdDriveClick(object sender, EventArgs e)
\r
1436 ToolStripMenuItem item = sender as ToolStripMenuItem;
\r
1439 string driveId = item.Name.Replace("Drive", string.Empty);
\r
1441 if (int.TryParse(driveId, out id))
\r
1443 this.dvdDrivePath = drives[id].RootDirectory;
\r
1444 this.dvdDriveLabel = drives[id].VolumeLabel;
\r
1446 if (this.dvdDrivePath == null) return;
\r
1447 this.selectedSourceType = SourceType.DvdDrive;
\r
1448 SelectSource(this.dvdDrivePath, 0);
\r
1453 private void VideoTitleSpecificScanClick(object sender, EventArgs e)
\r
1455 this.btn_source.HideDropDown();
\r
1456 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
1458 this.selectedSourceType = SourceType.VideoFile;
\r
1460 int sourceTitle = 0;
\r
1461 TitleSpecificScan title = new TitleSpecificScan();
\r
1462 if (title.ShowDialog() == DialogResult.OK)
\r
1464 sourceTitle = title.Title;
\r
1465 SelectSource(ISO_Open.FileName, sourceTitle);
\r
1469 UpdateSourceLabel();
\r
1472 private void FolderTitleSpecificScanClick(object sender, EventArgs e)
\r
1474 this.btn_source.HideDropDown();
\r
1475 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
1477 this.selectedSourceType = SourceType.Folder;
\r
1479 int sourceTitle = 0;
\r
1480 TitleSpecificScan title = new TitleSpecificScan();
\r
1481 if (title.ShowDialog() == DialogResult.OK)
\r
1483 sourceTitle = title.Title;
\r
1484 SelectSource(DVD_Open.SelectedPath, sourceTitle);
\r
1488 UpdateSourceLabel();
\r
1491 private void SelectSource(string file, int titleSpecific)
\r
1493 Check_ChapterMarkers.Enabled = true;
\r
1494 sourcePath = string.Empty;
\r
1496 if (file == string.Empty) // Must have a file or path
\r
1498 UpdateSourceLabel();
\r
1502 sourcePath = Path.GetFileName(file);
\r
1503 StartScan(file, titleSpecific);
\r
1506 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
1508 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
1510 "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",
\r
1511 "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
1514 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1516 UnRegisterPresetEventHandler();
\r
1517 drop_mode.SelectedIndex = 0;
\r
1519 drop_chapterStart.Items.Clear();
\r
1520 drop_chapterFinish.Items.Clear();
\r
1522 // If the dropdown is set to automatic nothing else needs to be done.
\r
1523 // Otheriwse if its not, title data has to be loaded from parsing.
\r
1524 if (drp_dvdtitle.Text != "Automatic")
\r
1526 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
1527 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
1528 PictureSettings.CurrentlySelectedPreset = this.currentlySelectedPreset;
\r
1529 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control
\r
1531 // Populate the Angles dropdown
\r
1532 drop_angle.Items.Clear();
\r
1533 if (!Properties.Settings.Default.noDvdNav)
\r
1535 drop_angle.Visible = true;
\r
1536 lbl_angle.Visible = true;
\r
1538 for (int i = 1; i <= selectedTitle.AngleCount; i++)
\r
1539 drop_angle.Items.Add(i.ToString());
\r
1541 if (drop_angle.Items.Count == 0)
\r
1543 drop_angle.Visible = false;
\r
1544 lbl_angle.Visible = false;
\r
1547 if (drop_angle.Items.Count != 0)
\r
1548 drop_angle.SelectedIndex = 0;
\r
1552 drop_angle.Visible = false;
\r
1553 lbl_angle.Visible = false;
\r
1556 // Populate the Start chapter Dropdown
\r
1557 drop_chapterStart.Items.Clear();
\r
1558 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1559 if (drop_chapterStart.Items.Count > 0)
\r
1560 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
1562 // Populate the Final Chapter Dropdown
\r
1563 drop_chapterFinish.Items.Clear();
\r
1564 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
1565 if (drop_chapterFinish.Items.Count > 0)
\r
1566 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
1568 // Populate the Audio Channels Dropdown
\r
1569 AudioSettings.SetTrackListFromPreset(selectedTitle, this.currentlySelectedPreset);
\r
1571 // Populate the Subtitles dropdown
\r
1572 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());
\r
1574 // Update the source label if we have multiple streams
\r
1575 if (selectedTitle != null)
\r
1576 if (!string.IsNullOrEmpty(selectedTitle.SourceName))
\r
1577 labelSource.Text = Path.GetFileName(selectedTitle.SourceName);
\r
1579 // Run the AutoName & ChapterNaming functions
\r
1580 if (Properties.Settings.Default.autoNaming)
\r
1582 string autoPath = Main.AutoName(this);
\r
1583 if (autoPath != null)
\r
1584 text_destination.Text = autoPath;
\r
1587 "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
1588 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1591 data_chpt.Rows.Clear();
\r
1592 if (selectedTitle.Chapters.Count != 1)
\r
1594 DataGridView chapterGridView = Main.ChapterNaming(selectedTitle, data_chpt, drop_chapterFinish.Text);
\r
1595 if (chapterGridView != null)
\r
1596 data_chpt = chapterGridView;
\r
1600 Check_ChapterMarkers.Checked = false;
\r
1601 Check_ChapterMarkers.Enabled = false;
\r
1604 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
1605 data_chpt.Columns[0].Width = 166;
\r
1606 data_chpt.Columns[0].Width = 165;
\r
1608 RegisterPresetEventHandler();
\r
1611 private void chapersChanged(object sender, EventArgs e)
\r
1613 if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.
\r
1616 Control ctl = (Control)sender;
\r
1617 int chapterStart, chapterEnd;
\r
1618 int.TryParse(drop_chapterStart.Text, out chapterStart);
\r
1619 int.TryParse(drop_chapterFinish.Text, out chapterEnd);
\r
1623 case "drop_chapterStart":
\r
1624 if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)
\r
1625 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1627 if (chapterEnd != 0)
\r
1628 if (chapterStart > chapterEnd)
\r
1629 drop_chapterFinish.Text = chapterStart.ToString();
\r
1631 case "drop_chapterFinish":
\r
1632 if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)
\r
1633 drop_chapterStart.SelectedIndex = 0;
\r
1635 if (chapterStart != 0)
\r
1636 if (chapterEnd < chapterStart)
\r
1637 drop_chapterFinish.Text = chapterStart.ToString();
\r
1639 // Add more rows to the Chapter menu if needed.
\r
1640 if (Check_ChapterMarkers.Checked)
\r
1642 int i = data_chpt.Rows.Count, finish = 0;
\r
1643 int.TryParse(drop_chapterFinish.Text, out finish);
\r
1645 while (i < finish)
\r
1647 int n = data_chpt.Rows.Add();
\r
1648 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
1649 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
1650 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
1651 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
1658 // Update the Duration
\r
1659 lbl_duration.Text =
\r
1660 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)
\r
1663 // Run the Autonaming function
\r
1664 if (Properties.Settings.Default.autoNaming)
\r
1665 text_destination.Text = Main.AutoName(this);
\r
1667 // Disable chapter markers if only 1 chapter is selected.
\r
1668 if (chapterStart == chapterEnd)
\r
1670 Check_ChapterMarkers.Enabled = false;
\r
1671 btn_importChapters.Enabled = false;
\r
1672 data_chpt.Enabled = false;
\r
1676 Check_ChapterMarkers.Enabled = true;
\r
1677 if (Check_ChapterMarkers.Checked)
\r
1679 btn_importChapters.Enabled = true;
\r
1680 data_chpt.Enabled = true;
\r
1685 private void SecondsOrFramesChanged(object sender, EventArgs e)
\r
1688 int.TryParse(drop_chapterStart.Text, out start);
\r
1689 int.TryParse(drop_chapterFinish.Text, out end);
\r
1690 double duration = end - start;
\r
1692 switch (drop_mode.SelectedIndex)
\r
1695 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1698 if (selectedTitle != null)
\r
1700 duration = duration / selectedTitle.Fps;
\r
1701 lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();
\r
1704 lbl_duration.Text = "--:--:--";
\r
1710 private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)
\r
1713 this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1714 this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);
\r
1717 switch (drop_mode.SelectedIndex)
\r
1720 drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1721 drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;
\r
1722 if (drop_chapterStart.Items.Count != 0)
\r
1724 drop_chapterStart.SelectedIndex = 0;
\r
1725 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
1728 lbl_duration.Text = "--:--:--";
\r
1731 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1732 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1733 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1734 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1735 if (selectedTitle != null)
\r
1737 drop_chapterStart.Text = "0";
\r
1738 drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();
\r
1742 this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1743 this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);
\r
1744 drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;
\r
1745 drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;
\r
1746 if (selectedTitle != null)
\r
1748 drop_chapterStart.Text = "0";
\r
1749 drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();
\r
1756 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
1758 // This removes the file extension from the filename box on the save file dialog.
\r
1759 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
1760 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
1762 if (Path.IsPathRooted(text_destination.Text))
\r
1763 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
1765 // Show the dialog and set the main form file path
\r
1766 if (drop_format.SelectedIndex.Equals(0))
\r
1767 DVD_Save.FilterIndex = 1;
\r
1768 else if (drop_format.SelectedIndex.Equals(1))
\r
1769 DVD_Save.FilterIndex = 2;
\r
1771 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1773 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1774 switch (DVD_Save.FilterIndex)
\r
1778 !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",
\r
1779 StringComparison.InvariantCultureIgnoreCase))
\r
1780 if (Properties.Settings.Default.useM4v)
\r
1781 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");
\r
1783 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");
\r
1787 !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1788 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");
\r
1794 text_destination.Text = DVD_Save.FileName;
\r
1796 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1797 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)
\r
1798 SetExtension(".m4v");
\r
1802 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1804 string path = text_destination.Text;
\r
1805 if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))
\r
1806 drop_format.SelectedIndex = 0;
\r
1807 else if (path.EndsWith(".mkv"))
\r
1808 drop_format.SelectedIndex = 1;
\r
1811 // Output Settings
\r
1812 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1814 switch (drop_format.SelectedIndex)
\r
1817 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||
\r
1818 AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())
\r
1819 SetExtension(".m4v");
\r
1821 SetExtension(".mp4");
\r
1824 SetExtension(".mkv");
\r
1828 AudioSettings.SetContainer(drop_format.Text);
\r
1830 if (drop_format.Text.Contains("MP4"))
\r
1832 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1834 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1835 drp_videoEncoder.SelectedIndex = 1;
\r
1838 else if (drop_format.Text.Contains("MKV"))
\r
1839 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1842 public void SetExtension(string newExtension)
\r
1844 if (newExtension == ".mp4" || newExtension == ".m4v")
\r
1845 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||
\r
1846 Subtitles.RequiresM4V())
\r
1847 newExtension = ".m4v";
\r
1849 newExtension = ".mp4";
\r
1851 if (Path.HasExtension(newExtension))
\r
1852 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);
\r
1856 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1858 setContainerOpts();
\r
1860 // Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1861 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1863 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1864 check_turbo.Enabled = true;
\r
1866 tab_advanced.Enabled = true;
\r
1867 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1868 check_iPodAtom.Enabled = true;
\r
1870 check_iPodAtom.Enabled = false;
\r
1874 check_turbo.CheckState = CheckState.Unchecked;
\r
1875 check_turbo.Enabled = false;
\r
1876 tab_advanced.Enabled = false;
\r
1877 x264Panel.X264Query = string.Empty;
\r
1878 check_iPodAtom.Enabled = false;
\r
1879 check_iPodAtom.Checked = false;
\r
1882 // Setup the CQ Slider
\r
1883 switch (drp_videoEncoder.Text)
\r
1885 case "MPEG-4 (FFmpeg)":
\r
1886 if (slider_videoQuality.Value > 31)
\r
1887 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1888 slider_videoQuality.Minimum = 1;
\r
1889 slider_videoQuality.Maximum = 31;
\r
1891 case "H.264 (x264)":
\r
1892 slider_videoQuality.Minimum = 0;
\r
1893 slider_videoQuality.TickFrequency = 1;
\r
1895 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1896 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1897 double multiplier = 1.0 / cqStep;
\r
1898 double value = slider_videoQuality.Value * multiplier;
\r
1900 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1902 if (value < slider_videoQuality.Maximum)
\r
1903 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1906 case "VP3 (Theora)":
\r
1907 if (slider_videoQuality.Value > 63)
\r
1908 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1909 slider_videoQuality.Minimum = 0;
\r
1910 slider_videoQuality.Maximum = 63;
\r
1916 /// When the FrameRate is not Same As Source, show the Max/Constant Mode dropdown
\r
1918 /// <param name="sender">
\r
1921 /// <param name="e">
\r
1924 private void drp_videoFramerate_SelectedIndexChanged(object sender, EventArgs e)
\r
1926 if (this.drp_videoFramerate.SelectedIndex == 0)
\r
1928 this.checkMaximumFramerate.Visible = false;
\r
1929 this.checkMaximumFramerate.CheckState = CheckState.Unchecked;
\r
1933 this.checkMaximumFramerate.Visible = true;
\r
1938 /// Set the container format options
\r
1940 public void setContainerOpts()
\r
1942 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1944 check_largeFile.Enabled = true;
\r
1945 check_optimiseMP4.Enabled = true;
\r
1946 check_iPodAtom.Enabled = true;
\r
1950 check_largeFile.Enabled = false;
\r
1951 check_optimiseMP4.Enabled = false;
\r
1952 check_iPodAtom.Enabled = false;
\r
1953 check_largeFile.Checked = false;
\r
1954 check_optimiseMP4.Checked = false;
\r
1955 check_iPodAtom.Checked = false;
\r
1959 private double cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1962 /// Update the CQ slider for x264 for a new CQ step. This is set from option
\r
1964 public void setQualityFromSlider()
\r
1966 // Work out the current RF value.
\r
1967 double cqStep = this.cachedCqStep;
\r
1968 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1970 // Change the maximum value for the slider
\r
1971 slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);
\r
1973 // Reset the CQ slider to RF0
\r
1974 slider_videoQuality.Value = slider_videoQuality.Maximum;
\r
1976 // Reset the CQ slider back to the previous value as close as possible
\r
1977 double cqStepNew = Properties.Settings.Default.x264cqstep;
\r
1978 double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1979 while (rfValueCurrent < rfValue)
\r
1981 slider_videoQuality.Value--;
\r
1982 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;
\r
1985 // Cache the CQ step for the next calculation
\r
1986 this.cachedCqStep = Properties.Settings.Default.x264cqstep;
\r
1989 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1991 double cqStep = Properties.Settings.Default.x264cqstep;
\r
1992 switch (drp_videoEncoder.Text)
\r
1994 case "MPEG-4 (FFmpeg)":
\r
1995 lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);
\r
1997 case "H.264 (x264)":
\r
1998 double rfValue = 51.0 - slider_videoQuality.Value * cqStep;
\r
1999 rfValue = Math.Round(rfValue, 2);
\r
2000 lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));
\r
2001 this.lbl_rfwarn.Visible = rfValue == 0;
\r
2003 case "VP3 (Theora)":
\r
2004 lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;
\r
2009 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
2011 text_bitrate.Enabled = false;
\r
2012 text_filesize.Enabled = true;
\r
2013 slider_videoQuality.Enabled = false;
\r
2015 check_2PassEncode.Enabled = true;
\r
2018 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
2020 text_bitrate.Enabled = true;
\r
2021 text_filesize.Enabled = false;
\r
2022 slider_videoQuality.Enabled = false;
\r
2024 check_2PassEncode.Enabled = true;
\r
2027 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
2029 text_bitrate.Enabled = false;
\r
2030 text_filesize.Enabled = false;
\r
2031 slider_videoQuality.Enabled = true;
\r
2033 check_2PassEncode.Enabled = false;
\r
2034 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
2037 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
2039 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
2041 if (drp_videoEncoder.Text.Contains("H.264"))
\r
2042 check_turbo.Enabled = true;
\r
2046 check_turbo.Enabled = false;
\r
2047 check_turbo.CheckState = CheckState.Unchecked;
\r
2051 // Chapter Marker Tab
\r
2052 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
2054 if (Check_ChapterMarkers.Checked)
\r
2056 if (drop_format.SelectedIndex != 1)
\r
2057 SetExtension(".m4v");
\r
2058 data_chpt.Enabled = true;
\r
2059 btn_importChapters.Enabled = true;
\r
2063 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)
\r
2064 SetExtension(".mp4");
\r
2065 data_chpt.Enabled = false;
\r
2066 btn_importChapters.Enabled = false;
\r
2070 private void btn_importChapters_Click(object sender, EventArgs e)
\r
2072 if (File_ChapterImport.ShowDialog() == DialogResult.OK)
\r
2074 string filename = File_ChapterImport.FileName;
\r
2075 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);
\r
2076 if (imported != null)
\r
2077 data_chpt = imported;
\r
2081 private void btn_export_Click(object sender, EventArgs e)
\r
2083 SaveFileDialog saveFileDialog = new SaveFileDialog();
\r
2084 saveFileDialog.Filter = "Csv File|*.csv";
\r
2085 saveFileDialog.DefaultExt = "csv";
\r
2086 if (saveFileDialog.ShowDialog() == DialogResult.OK)
\r
2088 string filename = saveFileDialog.FileName;
\r
2090 Main.SaveChapterMarkersToCsv(this, filename);
\r
2094 private void mnu_resetChapters_Click(object sender, EventArgs e)
\r
2096 data_chpt.Rows.Clear();
\r
2097 DataGridView chapterGridView = Main.ChapterNaming(selectedTitle, data_chpt, drop_chapterFinish.Text);
\r
2098 if (chapterGridView != null)
\r
2100 data_chpt = chapterGridView;
\r
2104 // Query Editor Tab
\r
2105 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
2107 rtf_query.Text = QueryGenerator.GenerateFullQuery(this);
\r
2110 private void btn_clear_Click(object sender, EventArgs e)
\r
2112 rtf_query.Clear();
\r
2117 // MainWindow Components, Actions and Functions ***********************
\r
2119 #region Source Scan
\r
2122 /// Start the Scan Process
\r
2124 /// <param name="filename">
\r
2127 /// <param name="title">
\r
2130 private void StartScan(string filename, int title)
\r
2132 // Setup the GUI components for the scan.
\r
2133 sourcePath = filename;
\r
2135 this.DisableGUI();
\r
2140 SourceScan.Scan(sourcePath, title);
\r
2142 catch (Exception exc)
\r
2144 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2149 /// Update the Status label for the scan
\r
2151 /// <param name="sender">
\r
2154 /// <param name="e">
\r
2157 private void SourceScanScanStatusChanged(object sender, ScanProgressEventArgs e)
\r
2159 if (this.InvokeRequired)
\r
2161 this.BeginInvoke(new ScanProgessStatus(this.SourceScanScanStatusChanged), new[] { sender, e });
\r
2165 labelSource.Text = string.Format("Processing Title: {0} of {1}", e.CurrentTitle, e.Titles);
\r
2169 /// Update the UI after the scan has completed
\r
2171 /// <param name="sender">
\r
2174 /// <param name="e">
\r
2177 private void SourceScanScanCompleted(object sender, EventArgs e)
\r
2179 if (this.InvokeRequired)
\r
2181 this.BeginInvoke(new ScanCompletedStatus(this.SourceScanScanCompleted), new[] { sender, e });
\r
2187 currentSource = SourceScan.SouceData;
\r
2189 // Setup some GUI components
\r
2190 drp_dvdtitle.Items.Clear();
\r
2191 if (currentSource.Titles.Count != 0)
\r
2192 drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());
\r
2194 foreach (Title title in currentSource.Titles)
\r
2196 if (title.MainTitle)
\r
2198 drp_dvdtitle.SelectedItem = title;
\r
2202 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)
\r
2204 drp_dvdtitle.SelectedIndex = 0;
\r
2207 // Enable the creation of chapter markers if the file is an image of a dvd
\r
2208 if (drop_chapterStart.Items.Count > 0)
\r
2211 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);
\r
2212 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);
\r
2213 if (end > start) Check_ChapterMarkers.Enabled = true;
\r
2216 Check_ChapterMarkers.Enabled = false;
\r
2217 Check_ChapterMarkers.Checked = false;
\r
2218 data_chpt.Rows.Clear();
\r
2222 // If no titles were found, Display an error message
\r
2223 if (drp_dvdtitle.Items.Count == 0)
\r
2226 "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
2227 "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
2228 sourcePath = string.Empty;
\r
2230 UpdateSourceLabel();
\r
2232 // This is a bit of a hack to fix the queue editing.
\r
2233 // 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
2234 // When this occures, we want to repopulate their old settings.
\r
2235 if (queueEdit != null)
\r
2238 if (queueEdit.Query != null)
\r
2240 // Send the query from the file to the Query Parser class
\r
2241 EncodeTask presetQuery = QueryParserUtility.Parse(queueEdit.Query);
\r
2243 // Now load the preset
\r
2244 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue");
\r
2246 // Set the destination path
\r
2247 this.text_destination.Text = queueEdit.Destination;
\r
2249 // The x264 widgets will need updated, so do this now:
\r
2250 x264Panel.StandardizeOptString();
\r
2251 x264Panel.SetCurrentSettingsInPanel();
\r
2253 // Set the crop label
\r
2254 PictureSettings.SetPresetCropWarningLabel(null);
\r
2260 // Enable the GUI components and enable any disabled components
\r
2263 catch (Exception exc)
\r
2265 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,
\r
2266 MessageBoxIcon.Error);
\r
2272 /// Enable the GUI
\r
2274 private void EnableGUI()
\r
2278 if (InvokeRequired)
\r
2279 BeginInvoke(new UpdateWindowHandler(EnableGUI));
\r
2280 foreach (Control ctrl in Controls)
\r
2281 ctrl.Enabled = true;
\r
2282 btn_start.Enabled = true;
\r
2283 btn_showQueue.Enabled = true;
\r
2284 btn_add2Queue.Enabled = true;
\r
2285 tb_preview.Enabled = true;
\r
2286 btn_source.Enabled = true;
\r
2287 mnu_killCLI.Visible = false;
\r
2289 catch (Exception exc)
\r
2291 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2296 /// Disable the GUI
\r
2298 private void DisableGUI()
\r
2300 foreach (Control ctrl in Controls)
\r
2301 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
2302 ctrl.Enabled = false;
\r
2304 labelSource.Enabled = true;
\r
2305 labelStaticSource.Enabled = true;
\r
2306 SourceLayoutPanel.Enabled = true;
\r
2307 btn_source.Enabled = false;
\r
2308 btn_start.Enabled = false;
\r
2309 btn_showQueue.Enabled = false;
\r
2310 btn_add2Queue.Enabled = false;
\r
2311 tb_preview.Enabled = false;
\r
2312 mnu_killCLI.Visible = true;
\r
2318 private void KillScan()
\r
2320 SourceScan.ScanCompleted -= this.SourceScanScanCompleted;
\r
2324 SourceScan.Stop();
\r
2326 labelSource.Text = "Scan Cancelled";
\r
2332 private void ResetGUI()
\r
2334 drp_dvdtitle.Items.Clear();
\r
2335 drop_chapterStart.Items.Clear();
\r
2336 drop_chapterFinish.Items.Clear();
\r
2337 lbl_duration.Text = "Select a Title";
\r
2338 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
2339 sourcePath = String.Empty;
\r
2340 text_destination.Text = String.Empty;
\r
2341 selectedTitle = null;
\r
2345 /// Update the Source Label
\r
2347 private void UpdateSourceLabel()
\r
2349 labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;
\r
2353 /// Take a job from the Queue, rescan it, and reload the GUI for that job.
\r
2355 /// <param name="job">
\r
2358 public void RecievingJob(QueueTask job)
\r
2361 this.currentlySelectedPreset = null;
\r
2362 x264Panel.Reset2Defaults();
\r
2365 queueEdit = job; // Nasty but will do for now. TODO
\r
2366 StartScan(job.Source, job.Title);
\r
2371 #region GUI Functions and Actions
\r
2374 /// Set the GUI to it's finished encoding state.
\r
2376 private void SetEncodeFinished()
\r
2380 if (InvokeRequired)
\r
2382 BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));
\r
2386 lbl_encode.Text = "Encoding Finished";
\r
2387 ProgressBarStatus.Visible = false;
\r
2388 btn_start.Text = "Start";
\r
2389 btn_start.ToolTipText = "Start the encoding process";
\r
2390 btn_start.Image = Properties.Resources.Play;
\r
2392 // If the window is minimized, display the notification in a popup.
\r
2393 if (Properties.Settings.Default.trayIconAlerts)
\r
2394 if (FormWindowState.Minimized == this.WindowState)
\r
2396 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
2397 notifyIcon.ShowBalloonTip(500);
\r
2400 catch (Exception exc)
\r
2402 MessageBox.Show(exc.ToString());
\r
2407 /// Set the GUI to it's started encoding state.
\r
2409 private void SetEncodeStarted()
\r
2413 if (InvokeRequired)
\r
2415 BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));
\r
2418 lbl_encode.Visible = true;
\r
2419 ProgressBarStatus.Value = 0;
\r
2420 ProgressBarStatus.Visible = true;
\r
2421 lbl_encode.Text = "Encoding with " + this.queueProcessor.QueueManager.Count + " encode(s) pending";
\r
2422 btn_start.Text = "Stop";
\r
2423 btn_start.ToolTipText = "Stop the encoding process.";
\r
2424 btn_start.Image = Properties.Resources.stop;
\r
2426 catch (Exception exc)
\r
2428 MessageBox.Show(exc.ToString());
\r
2433 /// Display the Encode Status
\r
2435 /// <param name="sender">
\r
2438 /// <param name="e">
\r
2441 private void EncodeQueue_EncodeStatusChanged(object sender, EncodeProgressEventArgs e)
\r
2443 if (this.InvokeRequired)
\r
2445 this.BeginInvoke(new EncodeProgessStatus(EncodeQueue_EncodeStatusChanged), new[] { sender, e });
\r
2451 "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Encode(s) Pending {4}",
\r
2452 e.PercentComplete,
\r
2453 e.CurrentFrameRate,
\r
2454 e.AverageFrameRate,
\r
2455 e.EstimatedTimeLeft,
\r
2456 this.queueProcessor.QueueManager.Count);
\r
2458 ProgressBarStatus.Value = (int)Math.Round(e.PercentComplete);
\r
2462 /// Set the DVD Drive selection in the "Source" Menu
\r
2464 private void SetDriveSelectionMenuItem()
\r
2468 if (InvokeRequired)
\r
2470 BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));
\r
2474 drives = UtilityService.GetDrives();
\r
2476 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
\r
2477 foreach (DriveInformation drive in drives)
\r
2479 ToolStripMenuItem menuItem = new ToolStripMenuItem
\r
2481 Name = drive.ToString(),
\r
2482 Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")",
\r
2483 Image = Resources.disc_small
\r
2485 menuItem.Click += new EventHandler(MnuDvdDriveClick);
\r
2486 menuItems.Add(menuItem);
\r
2489 foreach (ToolStripMenuItem item in menuItems)
\r
2490 btn_source.DropDownItems.Add(item);
\r
2492 catch (Exception exc)
\r
2494 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);
\r
2499 /// Access the preset Handler and setup the preset panel.
\r
2501 private void LoadPresetPanel()
\r
2503 if (presetHandler.CheckIfPresetsAreOutOfDate())
\r
2504 if (!Settings.Default.presetNotification)
\r
2505 MessageBox.Show(this,
\r
2506 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
2507 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
2509 presetHandler.GetPresetPanel(ref treeView_presets);
\r
2510 treeView_presets.Update();
\r
2514 /// Get the title from the selected item in the title dropdown.
\r
2519 private int GetTitle()
\r
2522 if (drp_dvdtitle.SelectedItem != null)
\r
2524 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');
\r
2525 int.TryParse(titleInfo[0], out title);
\r
2532 /// Handle the Update Check Finishing.
\r
2534 /// <param name="result">
\r
2537 private void UpdateCheckDoneMenu(IAsyncResult result)
\r
2539 // Make sure it's running on the calling thread
\r
2540 if (InvokeRequired)
\r
2542 Invoke(new MethodInvoker(() => this.UpdateCheckDoneMenu(result)));
\r
2545 UpdateCheckInformation info;
\r
2548 // Get the information about the new build, if any, and close the window
\r
2549 info = UpdateService.EndCheckForUpdates(result);
\r
2551 if (info.NewVersionAvailable && info.BuildInformation != null)
\r
2553 UpdateInfo updateWindow = new UpdateInfo(info.BuildInformation, Settings.Default.hb_version, Settings.Default.hb_build.ToString());
\r
2554 updateWindow.ShowDialog();
\r
2557 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,
\r
2558 MessageBoxIcon.Information);
\r
2559 lbl_updateCheck.Visible = false;
\r
2562 catch (Exception ex)
\r
2564 if ((bool)result.AsyncState)
\r
2566 "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,
\r
2567 "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
2576 /// Handle GUI shortcuts
\r
2578 /// <param name="msg">Message</param>
\r
2579 /// <param name="keyData">Keys</param>
\r
2580 /// <returns>Bool</returns>
\r
2581 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
\r
2583 if (keyData == (Keys.Control | Keys.S))
\r
2585 btn_start_Click(this, new EventArgs());
\r
2589 if (keyData == (Keys.Control | Keys.Shift | Keys.A))
\r
2591 btn_add2Queue_Click(this, new EventArgs());
\r
2594 return base.ProcessCmdKey(ref msg, keyData);
\r
2598 /// If the queue is being processed, prompt the user to confirm application close.
\r
2600 /// <param name="e">FormClosingEventArgs</param>
\r
2601 protected override void OnFormClosing(FormClosingEventArgs e)
\r
2605 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
2606 if (this.queueProcessor.EncodeService.IsEncoding)
\r
2608 DialogResult result =
\r
2610 "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
2611 "Close HandBrake?",
\r
2612 MessageBoxButtons.YesNo,
\r
2613 MessageBoxIcon.Question);
\r
2615 if (result == DialogResult.No)
\r
2621 this.queueProcessor.Pause();
\r
2622 this.queueProcessor.EncodeService.Stop();
\r
2625 if (SourceScan.IsScanning)
\r
2627 SourceScan.Stop();
\r
2630 SourceScan.ScanCompleted -= this.SourceScanScanCompleted;
\r
2631 SourceScan.ScanStatusChanged -= this.SourceScanScanStatusChanged;
\r
2633 catch (Exception exc)
\r
2635 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
2639 base.OnFormClosing(e);
\r
2645 // This is the END of the road ****************************************
\r