3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr/>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Collections.Generic;
\r
9 using System.Drawing;
\r
10 using System.Globalization;
\r
11 using System.Windows.Forms;
\r
13 using System.Diagnostics;
\r
14 using System.Threading;
\r
15 using Handbrake.EncodeQueue;
\r
16 using Handbrake.Functions;
\r
17 using Handbrake.Presets;
\r
18 using Handbrake.Parsing;
\r
22 public partial class frmMain : Form
\r
24 // Objects which may be used by one or more other objects *************
\r
25 QueueHandler encodeQueue = new QueueHandler();
\r
26 PresetsHandler presetHandler = new PresetsHandler();
\r
27 QueryGenerator queryGen = new QueryGenerator();
\r
29 // Globals: Mainly used for tracking. *********************************
\r
30 public Title selectedTitle;
\r
31 private DVD thisDVD;
\r
32 private frmQueue queueWindow;
\r
33 private frmPreview qtpreview;
\r
34 private Form splash;
\r
35 public string sourcePath;
\r
37 // Delegates **********************************************************
\r
38 private delegate void UpdateWindowHandler();
\r
39 private delegate void UpdateStatusChanger();
\r
41 // Applicaiton Startup ************************************************
\r
43 #region Application Startup
\r
46 // Load and setup the splash screen in this thread
\r
47 splash = new frmSplashScreen();
\r
49 Label lblStatus = new Label { Size = new Size(150, 20), Location = new Point(182, 102) };
\r
50 splash.Controls.Add(lblStatus);
\r
52 InitializeComponent();
\r
54 // Update the users config file with the CLI version data.
\r
55 lblStatus.Text = "Setting Version Data ...";
\r
56 Application.DoEvents();
\r
57 Main.setCliVersionData();
\r
59 // Show the form, but leave disabled until preloading is complete then show the main form
\r
60 this.Enabled = false;
\r
62 Application.DoEvents(); // Forces frmMain to draw
\r
64 // Check for new versions, if update checking is enabled
\r
65 if (Properties.Settings.Default.updateStatus)
\r
67 DateTime now = DateTime.Now;
\r
68 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;
\r
69 TimeSpan elapsed = now.Subtract(lastCheck);
\r
70 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
72 lblStatus.Text = "Checking for updates ...";
\r
73 Application.DoEvents();
\r
75 Thread updateCheckThread = new Thread(startupUpdateCheck);
\r
76 updateCheckThread.Start();
\r
80 // Setup the GUI components
\r
81 lblStatus.Text = "Setting up the GUI ...";
\r
82 Application.DoEvents();
\r
83 loadPresetPanel(); // Load the Preset Panel
\r
84 treeView_presets.ExpandAll();
\r
85 lbl_encode.Text = "";
\r
86 queueWindow = new frmQueue(encodeQueue); // Prepare the Queue
\r
87 if (!Properties.Settings.Default.QueryEditorTab)
\r
88 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
90 // Load the user's default settings or Normal Preset
\r
91 if (Properties.Settings.Default.defaultSettings && Properties.Settings.Default.defaultPreset != "")
\r
93 if (presetHandler.getPreset(Properties.Settings.Default.defaultPreset) != null)
\r
95 string query = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).Query;
\r
96 Boolean loadPictureSettings = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).PictureSettings;
\r
100 //Ok, Reset all the H264 widgets before changing the preset
\r
101 x264Panel.reset2Defaults();
\r
103 // Send the query from the file to the Query Parser class, then load the preset
\r
104 QueryParser presetQuery = QueryParser.Parse(query);
\r
105 PresetLoader.presetLoader(this, presetQuery, Properties.Settings.Default.defaultPreset, loadPictureSettings);
\r
107 // The x264 widgets will need updated, so do this now:
\r
108 x264Panel.X264_StandardizeOptString();
\r
109 x264Panel.X264_SetCurrentSettingsInPanel();
\r
113 loadNormalPreset();
\r
116 loadNormalPreset();
\r
118 // Enabled GUI tooltip's if Required
\r
119 if (Properties.Settings.Default.tooltipEnable)
\r
120 ToolTip.Active = true;
\r
123 lblStatus.Text = "Loading Complete!";
\r
124 Application.DoEvents();
\r
127 this.Enabled = true;
\r
129 // Event Handlers and Queue Recovery
\r
134 // Startup Functions
\r
135 private void startupUpdateCheck()
\r
139 if (InvokeRequired)
\r
141 BeginInvoke(new UpdateStatusChanger(startupUpdateCheck));
\r
145 Boolean update = Main.updateCheck(false);
\r
148 frmUpdater updateWindow = new frmUpdater();
\r
149 updateWindow.Show();
\r
152 catch (Exception exc)
\r
154 MessageBox.Show(splash, "Unable to perform update check. If this problem persists, you can turn of update checking in the program options. \nError Information: \n\n" + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
157 private void queueRecovery()
\r
159 if (Main.check_queue_recovery())
\r
161 DialogResult result = MessageBox.Show("HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?", "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
163 if (result == DialogResult.Yes)
\r
164 encodeQueue.recoverQueue("hb_queue_recovery.xml"); // Start Recovery
\r
167 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
168 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
169 if (File.Exists(queuePath))
\r
170 File.Delete(queuePath);
\r
177 // Encoding Events for setting up the GUI
\r
178 private void events()
\r
180 // Handle Widget changes when preset is selected.
\r
181 registerPresetEventHandler();
\r
183 // Handle Window Resize
\r
184 if (Properties.Settings.Default.MainWindowMinimize)
\r
185 this.Resize += new EventHandler(frmMain_Resize);
\r
187 // Handle Encode Start / Finish / Pause
\r
188 encodeQueue.OnEncodeEnded += new EventHandler(encodeEnded);
\r
189 encodeQueue.OnPaused += new EventHandler(encodePaused);
\r
190 encodeQueue.OnEncodeStart += new EventHandler(encodeStarted);
\r
192 // Handle a file being draged onto the GUI.
\r
193 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
194 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
197 // 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
198 public void registerPresetEventHandler()
\r
201 drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
202 check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);
\r
203 check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);
\r
204 check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);
\r
206 // Picture Settings
\r
207 PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);
\r
210 Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);
\r
213 drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);
\r
214 check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);
\r
215 check_turbo.CheckedChanged += new EventHandler(changePresetLabel);
\r
216 text_filesize.TextChanged += new EventHandler(changePresetLabel);
\r
217 text_bitrate.TextChanged += new EventHandler(changePresetLabel);
\r
218 slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);
\r
221 AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);
\r
224 x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);
\r
226 public void unRegisterPresetEventHandler()
\r
228 // Output Settings
\r
229 drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
230 check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);
\r
231 check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);
\r
232 check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);
\r
234 // Picture Settings
\r
235 PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);
\r
238 Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);
\r
241 drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);
\r
242 check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);
\r
243 check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);
\r
244 text_filesize.TextChanged -= new EventHandler(changePresetLabel);
\r
245 text_bitrate.TextChanged -= new EventHandler(changePresetLabel);
\r
246 slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);
\r
249 AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);
\r
252 x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);
\r
254 private void changePresetLabel(object sender, EventArgs e)
\r
256 groupBox_output.Text = "Output Settings (Preset: Custom)";
\r
259 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
261 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
262 e.Effect = DragDropEffects.All;
\r
264 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
266 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
267 if (fileList != null)
\r
269 if (fileList[0].StartsWith("\\"))
\r
270 MessageBox.Show("Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
273 if (fileList[0] != "")
\r
275 setupGUIforScan(fileList[0]);
\r
276 startScan(fileList[0]);
\r
279 lbl_source.Text = "Click 'Source' to continue";
\r
283 private void encodeStarted(object sender, EventArgs e)
\r
285 lastAction = "encode";
\r
286 setEncodeStarted();
\r
288 // Experimental HBProc Process Monitoring.
\r
289 if (Properties.Settings.Default.enocdeStatusInGui)
\r
291 Thread encodeMon = new Thread(encodeMonitorThread);
\r
295 private void encodeEnded(object sender, EventArgs e)
\r
297 setEncodeFinished();
\r
299 private void encodePaused(object sender, EventArgs e)
\r
301 setEncodeFinished();
\r
305 // User Interface Menus / Tool Strips *********************************
\r
308 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
312 private void mnu_exit_Click(object sender, EventArgs e)
\r
314 Application.Exit();
\r
319 private void mnu_encode_Click(object sender, EventArgs e)
\r
321 queueWindow.Show();
\r
323 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
325 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
327 frmActivityWindow dvdInfoWindow = new frmActivityWindow(file, encodeQueue, this);
\r
328 dvdInfoWindow.Show();
\r
330 private void mnu_options_Click(object sender, EventArgs e)
\r
332 Form options = new frmOptions();
\r
333 options.ShowDialog();
\r
337 #region Presets Menu
\r
338 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
340 presetHandler.updateBuiltInPresets();
\r
342 if (treeView_presets.Nodes.Count == 0)
\r
343 MessageBox.Show("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!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
345 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
347 treeView_presets.ExpandAll();
\r
349 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
351 // Empty the preset file
\r
352 string presetsFile = Application.StartupPath + "\\presets.xml";
\r
353 if (File.Exists(presetsFile))
\r
354 File.Delete(presetsFile);
\r
358 FileStream strm = new FileStream(presetsFile, FileMode.Create, FileAccess.Write);
\r
362 catch (Exception exc)
\r
364 MessageBox.Show("An error has occured during the preset removal process.\n If you are using Windows Vista, you may need to run under Administrator Mode to complete this task. \n" + exc);
\r
367 // Reload the preset panel
\r
370 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
372 loadNormalPreset();
\r
374 private void btn_new_preset_Click(object sender, EventArgs e)
\r
376 Form preset = new frmAddPreset(this, queryGen.generateTheQuery(this), presetHandler);
\r
377 preset.ShowDialog();
\r
382 private void mnu_handbrake_forums_Click(object sender, EventArgs e)
\r
384 Process.Start("http://forum.handbrake.fr/");
\r
386 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
388 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
390 private void mnu_handbrake_home_Click(object sender, EventArgs e)
\r
392 Process.Start("http://handbrake.fr");
\r
394 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
396 Boolean update = Main.updateCheck(true);
\r
399 frmUpdater updateWindow = new frmUpdater();
\r
400 updateWindow.Show();
\r
403 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
405 private void mnu_about_Click(object sender, EventArgs e)
\r
407 Form About = new frmAbout();
\r
408 About.ShowDialog();
\r
413 // Right Click Menu Code
\r
414 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
416 treeView_presets.ExpandAll();
\r
418 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
420 treeView_presets.CollapseAll();
\r
422 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
424 DialogResult result = MessageBox.Show("Do you wish to include picture settings when updating the preset: " + treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
\r
425 if (result == DialogResult.Yes)
\r
426 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), true);
\r
427 else if (result == DialogResult.No)
\r
428 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), false);
\r
430 private void pmnu_delete_click(object sender, EventArgs e)
\r
432 if (treeView_presets.SelectedNode != null)
\r
434 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
435 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
437 treeView_presets.Select();
\r
439 private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
\r
441 // Make sure that the save menu is always disabled by default
\r
442 pmnu_saveChanges.Enabled = false;
\r
444 // Now enable the save menu if the selected preset is a user preset
\r
445 if (treeView_presets.SelectedNode != null)
\r
446 if (presetHandler.checkIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
447 pmnu_saveChanges.Enabled = true;
\r
449 treeView_presets.Select();
\r
452 // Presets Management
\r
453 private void btn_addPreset_Click(object sender, EventArgs e)
\r
455 Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);
\r
456 preset.ShowDialog();
\r
458 private void btn_removePreset_Click(object sender, EventArgs e)
\r
460 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
461 if (result == DialogResult.Yes)
\r
463 if (treeView_presets.SelectedNode != null)
\r
465 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
466 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
469 treeView_presets.Select();
\r
471 private void btn_setDefault_Click(object sender, EventArgs e)
\r
473 if (treeView_presets.SelectedNode != null)
\r
475 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
476 if (result == DialogResult.Yes)
\r
478 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
479 Properties.Settings.Default.Save();
\r
480 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
484 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
486 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
488 if (e.Button == MouseButtons.Right)
\r
489 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
490 else if (e.Button == MouseButtons.Left)
\r
492 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
494 if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
499 treeView_presets.Select();
\r
501 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
505 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
507 if (e.KeyCode == Keys.Delete)
\r
509 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
510 if (result == DialogResult.Yes)
\r
512 if (treeView_presets.SelectedNode != null)
\r
513 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
515 // Remember each nodes expanded status so we can reload it
\r
516 List<Boolean> nodeStatus = new List<Boolean>();
\r
517 foreach (TreeNode node in treeView_presets.Nodes)
\r
518 nodeStatus.Add(node.IsExpanded);
\r
520 // Now reload the preset panel
\r
523 // And finally, re-expand any of the nodes if required
\r
525 foreach (TreeNode node in treeView_presets.Nodes)
\r
535 private void selectPreset()
\r
537 if (treeView_presets.SelectedNode != null)
\r
539 // Ok, so, we've selected a preset. Now we want to load it.
\r
540 string presetName = treeView_presets.SelectedNode.Text;
\r
541 if (presetHandler.getPreset(presetName) != null)
\r
543 string query = presetHandler.getPreset(presetName).Query;
\r
544 Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;
\r
548 //Ok, Reset all the H264 widgets before changing the preset
\r
549 x264Panel.reset2Defaults();
\r
551 // Send the query from the file to the Query Parser class
\r
552 QueryParser presetQuery = QueryParser.Parse(query);
\r
554 // Now load the preset
\r
555 PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);
\r
557 // The x264 widgets will need updated, so do this now:
\r
558 x264Panel.X264_StandardizeOptString();
\r
559 x264Panel.X264_SetCurrentSettingsInPanel();
\r
564 private void loadNormalPreset()
\r
566 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
568 foreach (TreeNode node in treenode.Nodes)
\r
570 if (node.Text.Equals("Normal"))
\r
571 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
578 private void btn_source_Click(object sender, EventArgs e)
\r
580 if (Properties.Settings.Default.drive_detection)
\r
582 mnu_dvd_drive.Visible = true;
\r
583 Thread driveInfoThread = new Thread(getDriveInfoThread);
\r
584 driveInfoThread.Start();
\r
587 mnu_dvd_drive.Visible = false;
\r
589 private void btn_start_Click(object sender, EventArgs e)
\r
591 if (btn_start.Text == "Stop")
\r
593 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
595 if (result == DialogResult.Yes)
\r
598 encodeQueue.pauseEncodeQueue();
\r
600 // Allow the CLI to exit cleanly
\r
601 Win32.SetForegroundWindow((int)encodeQueue.encodeHandler.processHandle);
\r
602 SendKeys.Send("^C");
\r
605 setEncodeFinished();
\r
610 if (encodeQueue.count() != 0 || (lbl_source.Text != string.Empty && lbl_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))
\r
612 String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.generateTheQuery(this);
\r
614 DialogResult overwrite = DialogResult.Yes;
\r
615 if (text_destination.Text != "")
\r
616 if (File.Exists(text_destination.Text))
\r
617 overwrite = MessageBox.Show("The destination file already exists. Are you sure you want to overwrite it?", "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
619 if (overwrite == DialogResult.Yes)
\r
621 if (encodeQueue.count() == 0)
\r
622 encodeQueue.add(query, lbl_source.Text, text_destination.Text);
\r
624 queueWindow.setQueue();
\r
625 if (encodeQueue.count() > 1)
\r
626 queueWindow.Show(false);
\r
628 setEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
629 encodeQueue.startEncode(); // Start The Queue Encoding Process
\r
630 lastAction = "encode"; // Set the last action to encode - Used for activity window.
\r
634 else if (lbl_source.Text == string.Empty || lbl_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
635 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
638 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
641 if (lbl_source.Text == string.Empty || lbl_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
642 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
645 String query = queryGen.generateTheQuery(this);
\r
646 if (rtf_query.Text != "")
\r
647 query = rtf_query.Text;
\r
649 if (encodeQueue.checkDestinationPath(text_destination.Text))
\r
651 DialogResult result = MessageBox.Show("There is already a queue item for this destination path. \n\n If you continue, the encode will be overwritten. Do you wish to continue?",
\r
652 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
653 if (result == DialogResult.Yes)
\r
654 encodeQueue.add(query, lbl_source.Text, text_destination.Text);
\r
658 encodeQueue.add(query, lbl_source.Text, text_destination.Text);
\r
660 queueWindow.Show();
\r
663 private void btn_showQueue_Click(object sender, EventArgs e)
\r
665 queueWindow.Show();
\r
667 private void tb_preview_Click(object sender, EventArgs e)
\r
669 if (lbl_source.Text == "" || lbl_source.Text == "Click 'Source' to continue" || text_destination.Text == "")
\r
670 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
673 if (qtpreview == null)
\r
675 qtpreview = new frmPreview(this);
\r
678 else if (qtpreview.IsDisposed)
\r
680 qtpreview = new frmPreview(this);
\r
684 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
687 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
689 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
691 frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);
\r
692 ActivityWindow.Show();
\r
696 #region System Tray Icon
\r
697 private void frmMain_Resize(object sender, EventArgs e)
\r
699 if (FormWindowState.Minimized == this.WindowState)
\r
701 notifyIcon.Visible = true;
\r
704 else if (FormWindowState.Normal == this.WindowState)
\r
705 notifyIcon.Visible = false;
\r
707 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
709 this.Visible = true;
\r
711 this.WindowState = FormWindowState.Normal;
\r
712 notifyIcon.Visible = false;
\r
714 private void btn_restore_Click(object sender, EventArgs e)
\r
716 this.Visible = true;
\r
718 this.WindowState = FormWindowState.Normal;
\r
719 notifyIcon.Visible = false;
\r
723 #region Tab Control
\r
726 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
728 // Enable the creation of chapter markers.
\r
729 Check_ChapterMarkers.Enabled = true;
\r
731 // Set the last action to scan.
\r
732 // This is used for tracking which file to load in the activity window
\r
733 lastAction = "scan";
\r
734 lbl_source.Text = "";
\r
736 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
738 String filename = DVD_Open.SelectedPath;
\r
740 if (filename.StartsWith("\\"))
\r
741 MessageBox.Show("Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
744 if (filename != "")
\r
746 lbl_source.Text = Path.GetFullPath(filename);
\r
747 setupGUIforScan(filename);
\r
748 startScan(filename);
\r
751 lbl_source.Text = "Click 'Source' to continue";
\r
755 lbl_source.Text = "Click 'Source' to continue";
\r
757 private void btn_file_source_Click(object sender, EventArgs e)
\r
759 // Set the last action to scan.
\r
760 // This is used for tracking which file to load in the activity window
\r
761 lastAction = "scan";
\r
762 lbl_source.Text = "";
\r
764 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
766 String filename = ISO_Open.FileName;
\r
767 if (filename.StartsWith("\\"))
\r
769 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
770 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
773 if (filename != "")
\r
775 lbl_source.Text = Path.GetFileName(filename);
\r
776 setupGUIforScan(filename);
\r
777 startScan(filename);
\r
780 lbl_source.Text = "Click 'Source' to continue";
\r
784 lbl_source.Text = "Click 'Source' to continue";
\r
787 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
789 // Enable the creation of chapter markers.
\r
790 Check_ChapterMarkers.Enabled = true;
\r
792 // Set the last action to scan.
\r
793 // This is used for tracking which file to load in the activity window
\r
794 lastAction = "scan";
\r
796 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
798 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
799 String filename = path[0];
\r
800 lbl_source.Text = Path.GetFullPath(filename);
\r
801 setupGUIforScan(filename);
\r
802 startScan(filename);
\r
805 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
806 if (drp_dvdtitle.Items.Count == 0)
\r
807 MessageBox.Show("No Title(s) found. Please make sure you have selected a valid, non-copy protected source.\nYour Source may be copy protected, badly mastered or a format which HandBrake does not support. \nPlease refer to the Documentation and FAQ (see Help Menu).", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
809 lbl_encode.Text = "";
\r
811 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
813 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
814 MessageBox.Show("There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
\r
816 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
818 unRegisterPresetEventHandler();
\r
819 // Reset some values on the form
\r
820 PictureSettings.lbl_Aspect.Text = "Select a Title";
\r
821 //lbl_RecomendedCrop.Text = "Select a Title";
\r
822 drop_chapterStart.Items.Clear();
\r
823 drop_chapterFinish.Items.Clear();
\r
825 // If the dropdown is set to automatic nothing else needs to be done.
\r
826 // Otheriwse if its not, title data has to be loased from parsing.
\r
827 if (drp_dvdtitle.Text != "Automatic")
\r
829 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
830 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
831 PictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
833 // Populate the Angles dropdown
\r
834 drop_angle.Items.Clear();
\r
835 if (Properties.Settings.Default.dvdnav)
\r
837 drop_angle.Visible = true;
\r
838 lbl_angle.Visible = true;
\r
839 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
840 if (drop_angle.Items.Count != 0)
\r
841 drop_angle.SelectedIndex = 0;
\r
845 drop_angle.Visible = false;
\r
846 lbl_angle.Visible = false;
\r
849 // Populate the Start chapter Dropdown
\r
850 drop_chapterStart.Items.Clear();
\r
851 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
852 if (drop_chapterStart.Items.Count > 0)
\r
853 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
855 // Populate the Final Chapter Dropdown
\r
856 drop_chapterFinish.Items.Clear();
\r
857 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
858 if (drop_chapterFinish.Items.Count > 0)
\r
859 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
861 // Populate the Audio Channels Dropdown
\r
862 AudioSettings.setTrackList(selectedTitle);
\r
864 // Populate the Subtitles dropdown
\r
865 Subtitles.drp_subtitleTracks.Items.Clear();
\r
866 Subtitles.drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
867 Subtitles.drp_subtitleTracks.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
868 Subtitles.drp_subtitleTracks.SelectedIndex = 0;
\r
871 // Run the autoName & chapterNaming functions
\r
872 if (Properties.Settings.Default.autoNaming)
\r
874 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, lbl_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
875 if (autoPath != null)
\r
876 text_destination.Text = autoPath;
\r
878 MessageBox.Show("You currently have automatic file naming enabled for the destination box, but you do not have a default direcotry set. You should set this in the program options (see Tools Menu)", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
881 data_chpt.Rows.Clear();
\r
882 if (selectedTitle.Chapters.Count != 1)
\r
884 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
885 if (chapterGridView != null)
\r
886 data_chpt = chapterGridView;
\r
890 Check_ChapterMarkers.Checked = false;
\r
891 Check_ChapterMarkers.Enabled = false;
\r
894 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
895 data_chpt.Columns[0].Width = 166;
\r
896 data_chpt.Columns[0].Width = 165;
\r
898 registerPresetEventHandler();
\r
900 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
902 int c_start, c_end;
\r
904 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
905 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
907 int.TryParse(drop_chapterStart.Text, out c_start);
\r
908 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
912 if (c_start > c_end)
\r
913 drop_chapterFinish.Text = c_start.ToString();
\r
916 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
918 // Run the Autonaming function
\r
919 if (Properties.Settings.Default.autoNaming)
\r
920 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, lbl_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
922 // Disable chapter markers if only 1 chapter is selected.
\r
923 if (c_start == c_end)
\r
925 Check_ChapterMarkers.Checked = false;
\r
926 Check_ChapterMarkers.Enabled = false;
\r
929 Check_ChapterMarkers.Enabled = true;
\r
931 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
933 int c_start, c_end;
\r
935 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
936 drop_chapterStart.SelectedIndex = 1;
\r
938 int.TryParse(drop_chapterStart.Text, out c_start);
\r
939 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
943 if (c_end < c_start)
\r
944 drop_chapterFinish.Text = c_start.ToString();
\r
947 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
949 // Run the Autonaming function
\r
950 if (Properties.Settings.Default.autoNaming)
\r
951 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, lbl_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
953 // Add more rows to the Chapter menu if needed.
\r
954 if (Check_ChapterMarkers.Checked)
\r
956 int i = data_chpt.Rows.Count, finish = 0;
\r
958 if (drop_chapterFinish.Text != "Auto")
\r
959 int.TryParse(drop_chapterFinish.Text, out finish);
\r
963 int n = data_chpt.Rows.Add();
\r
964 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
965 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
966 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
967 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
972 // Disable chapter markers if only 1 chapter is selected.
\r
973 if (c_start == c_end)
\r
975 Check_ChapterMarkers.Checked = false;
\r
976 Check_ChapterMarkers.Enabled = false;
\r
979 Check_ChapterMarkers.Enabled = true;
\r
983 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
985 // This removes the file extension from the filename box on the save file dialog.
\r
986 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
987 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
989 if (Path.IsPathRooted(text_destination.Text))
\r
990 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
992 // Show the dialog and set the main form file path
\r
993 if (drop_format.SelectedIndex.Equals(0))
\r
994 DVD_Save.FilterIndex = 1;
\r
995 else if (drop_format.SelectedIndex.Equals(1))
\r
996 DVD_Save.FilterIndex = 2;
\r
997 else if (drop_format.SelectedIndex.Equals(2))
\r
998 DVD_Save.FilterIndex = 3;
\r
1000 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
1002 if (DVD_Save.FileName.StartsWith("\\"))
\r
1003 MessageBox.Show("Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
1006 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
1007 switch (DVD_Save.FilterIndex)
\r
1010 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
1011 DVD_Save.FileName += ".mp4";
\r
1014 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
1015 DVD_Save.FileName += ".m4v";
\r
1018 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1019 DVD_Save.FileName += ".mkv";
\r
1025 text_destination.Text = DVD_Save.FileName;
\r
1027 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1028 if (Check_ChapterMarkers.Checked)
\r
1029 drop_format.SelectedIndex = 1;
\r
1033 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1035 string path = text_destination.Text;
\r
1036 if (path.EndsWith(".mp4"))
\r
1037 drop_format.SelectedIndex = 0;
\r
1038 else if (path.EndsWith(".m4v"))
\r
1039 drop_format.SelectedIndex = 1;
\r
1040 else if (path.EndsWith(".mkv"))
\r
1041 drop_format.SelectedIndex = 2;
\r
1044 // Output Settings
\r
1045 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1047 switch (drop_format.SelectedIndex)
\r
1050 setExtension(".mp4");
\r
1053 setExtension(".m4v");
\r
1056 setExtension(".mkv");
\r
1060 AudioSettings.setAudioByContainer(drop_format.Text);
\r
1061 Subtitles.setContainer(drop_format.SelectedIndex);
\r
1063 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1065 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))
\r
1067 drp_videoEncoder.Items.Remove("VP3 (Theora)");
\r
1068 drp_videoEncoder.SelectedIndex = 1;
\r
1071 else if (drop_format.Text.Contains("MKV"))
\r
1072 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1074 private void setExtension(string newExtension)
\r
1076 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1077 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1078 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1082 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1084 setContainerOpts();
\r
1086 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1087 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1089 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1090 check_turbo.Enabled = true;
\r
1092 tab_advanced.Enabled = true;
\r
1093 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1094 check_iPodAtom.Enabled = true;
\r
1096 check_iPodAtom.Enabled = false;
\r
1100 check_turbo.CheckState = CheckState.Unchecked;
\r
1101 check_turbo.Enabled = false;
\r
1102 tab_advanced.Enabled = false;
\r
1103 x264Panel.x264Query = "";
\r
1104 check_iPodAtom.Enabled = false;
\r
1105 check_iPodAtom.Checked = false;
\r
1108 // Setup the CQ Slider
\r
1109 switch (drp_videoEncoder.Text)
\r
1111 case "MPEG-4 (FFmpeg)":
\r
1112 if (slider_videoQuality.Value > 31)
\r
1113 slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.
\r
1114 slider_videoQuality.Minimum = 1;
\r
1115 slider_videoQuality.Maximum = 31;
\r
1117 case "H.264 (x264)":
\r
1118 slider_videoQuality.Minimum = 0;
\r
1119 slider_videoQuality.TickFrequency = 1;
\r
1121 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
\r
1122 double multiplier = 1.0 / Properties.Settings.Default.x264cqstep;
\r
1123 double value = slider_videoQuality.Value*multiplier;
\r
1125 switch (Properties.Settings.Default.x264cqstep.ToString(culture))
\r
1128 slider_videoQuality.Maximum = 255;
\r
1131 slider_videoQuality.Maximum = 204;
\r
1134 slider_videoQuality.Maximum = 40;
\r
1137 slider_videoQuality.Maximum = 51;
\r
1140 slider_videoQuality.Maximum = 51;
\r
1143 if (value < slider_videoQuality.Maximum)
\r
1144 slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;
\r
1147 case "VP3 (Theora)":
\r
1148 if (slider_videoQuality.Value > 63)
\r
1149 slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.
\r
1150 slider_videoQuality.Minimum = 0;
\r
1151 slider_videoQuality.Maximum = 63;
\r
1156 /// Set the container format options
\r
1158 public void setContainerOpts()
\r
1160 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1162 check_largeFile.Enabled = true;
\r
1163 check_optimiseMP4.Enabled = true;
\r
1164 check_iPodAtom.Enabled = true;
\r
1168 check_largeFile.Enabled = false;
\r
1169 check_optimiseMP4.Enabled = false;
\r
1170 check_iPodAtom.Enabled = false;
\r
1171 check_largeFile.Checked = false;
\r
1172 check_optimiseMP4.Checked = false;
\r
1173 check_iPodAtom.Checked = false;
\r
1176 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1178 switch (drp_videoEncoder.Text)
\r
1180 case "MPEG-4 (FFmpeg)":
\r
1181 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1182 double max = slider_videoQuality.Maximum;
\r
1183 double min = slider_videoQuality.Minimum;
\r
1184 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1185 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1187 case "H.264 (x264)":
\r
1188 rfValue = 51.0 - slider_videoQuality.Value * Properties.Settings.Default.x264cqstep;
\r
1189 max = slider_videoQuality.Maximum * Properties.Settings.Default.x264cqstep;
\r
1190 min = slider_videoQuality.Minimum;
\r
1191 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1192 rfValue = Math.Round(rfValue, 2);
\r
1193 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1195 case "VP3 (Theora)":
\r
1196 rfValue = slider_videoQuality.Value;
\r
1197 double value = rfValue / 63;
\r
1198 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1202 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1204 text_bitrate.Enabled = false;
\r
1205 text_filesize.Enabled = true;
\r
1206 slider_videoQuality.Enabled = false;
\r
1208 check_2PassEncode.Enabled = true;
\r
1210 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1212 text_bitrate.Enabled = true;
\r
1213 text_filesize.Enabled = false;
\r
1214 slider_videoQuality.Enabled = false;
\r
1216 check_2PassEncode.Enabled = true;
\r
1218 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1220 text_bitrate.Enabled = false;
\r
1221 text_filesize.Enabled = false;
\r
1222 slider_videoQuality.Enabled = true;
\r
1224 check_2PassEncode.Enabled = false;
\r
1225 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1227 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1229 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1231 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1232 check_turbo.Enabled = true;
\r
1236 check_turbo.Enabled = false;
\r
1237 check_turbo.CheckState = CheckState.Unchecked;
\r
1241 // Chapter Marker Tab
\r
1242 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1244 if (Check_ChapterMarkers.Checked)
\r
1246 if (drop_format.SelectedIndex != 2)
\r
1247 drop_format.SelectedIndex = 1;
\r
1248 data_chpt.Rows.Clear();
\r
1249 data_chpt.Enabled = true;
\r
1250 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1251 if (chapterGridView != null)
\r
1252 data_chpt = chapterGridView;
\r
1256 if (drop_format.SelectedIndex != 2)
\r
1257 drop_format.SelectedIndex = 0;
\r
1258 data_chpt.Rows.Clear();
\r
1259 data_chpt.Enabled = false;
\r
1263 // Query Editor Tab
\r
1264 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1266 rtf_query.Text = queryGen.generateTheQuery(this);
\r
1268 private void btn_clear_Click(object sender, EventArgs e)
\r
1270 rtf_query.Clear();
\r
1274 // MainWindow Components, Actions and Functions ***********************
\r
1276 #region Source Scan
\r
1277 public Boolean isScanning { get; set; }
\r
1278 private static int scanProcessID { get; set; }
\r
1279 private void setupGUIforScan(String filename)
\r
1281 sourcePath = filename;
\r
1282 foreach (Control ctrl in Controls)
\r
1284 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1285 ctrl.Enabled = false;
\r
1287 lbl_encode.Visible = true;
\r
1288 lbl_encode.Text = "Scanning ...";
\r
1289 //gb_source.Text = "Source: Scanning ...";
\r
1290 btn_source.Enabled = false;
\r
1291 btn_start.Enabled = false;
\r
1292 btn_showQueue.Enabled = false;
\r
1293 btn_add2Queue.Enabled = false;
\r
1294 tb_preview.Enabled = false;
\r
1295 mnu_killCLI.Visible = true;
\r
1297 private void startScan(String filename)
\r
1301 lbl_encode.Visible = true;
\r
1302 lbl_encode.Text = "Scanning...";
\r
1303 isScanning = true;
\r
1304 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1306 catch (Exception exc)
\r
1308 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1311 private void scanProcess(object state)
\r
1315 string inputFile = (string)state;
\r
1316 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1317 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1318 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1320 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1321 if (File.Exists(dvdInfoPath))
\r
1322 File.Delete(dvdInfoPath);
\r
1324 String dvdnav = string.Empty;
\r
1325 if (Properties.Settings.Default.dvdnav)
\r
1326 dvdnav = " --dvdnav";
\r
1327 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1329 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1331 Boolean cleanExit = true;
\r
1332 using (hbproc = Process.Start(hbParseDvd))
\r
1334 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1335 scanProcessID = Main.getCliProcess(before);
\r
1336 hbproc.WaitForExit();
\r
1337 if (hbproc.ExitCode != 0)
\r
1338 cleanExit = false;
\r
1341 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1343 if (!File.Exists(dvdInfoPath))
\r
1345 throw new Exception(
\r
1346 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1350 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1352 thisDVD = DVD.Parse(sr);
\r
1357 updateUIafterScan();
\r
1360 catch (Exception exc)
\r
1362 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1366 private void updateUIafterScan()
\r
1370 if (InvokeRequired)
\r
1372 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1376 // Setup some GUI components
\r
1377 drp_dvdtitle.Items.Clear();
\r
1378 if (thisDVD.Titles.Count != 0)
\r
1379 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1380 drp_dvdtitle.Text = "Automatic";
\r
1381 drop_chapterFinish.Text = "Auto";
\r
1382 drop_chapterStart.Text = "Auto";
\r
1384 // Now select the longest title
\r
1385 if (thisDVD.Titles.Count != 0)
\r
1386 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1388 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1389 if (lbl_source.Text.ToLower().Contains(".iso") || lbl_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1390 Check_ChapterMarkers.Enabled = true;
\r
1393 Check_ChapterMarkers.Enabled = false;
\r
1394 Check_ChapterMarkers.Checked = false;
\r
1395 data_chpt.Rows.Clear();
\r
1398 // If no titles were found, Display an error message
\r
1399 if (drp_dvdtitle.Items.Count == 0)
\r
1400 MessageBox.Show("No Title(s) found. \n\nYour Source may be copy protected, badly mastered or a format which HandBrake does not support. \nPlease refer to the Documentation and FAQ (see Help Menu).", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
\r
1402 // Enable the GUI components and enable any disabled components
\r
1405 catch (Exception exc)
\r
1407 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1411 private void enableGUI()
\r
1415 if (InvokeRequired)
\r
1416 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1417 lbl_encode.Text = "Scan Completed";
\r
1418 //gb_source.Text = "Source";
\r
1419 foreach (Control ctrl in Controls)
\r
1420 ctrl.Enabled = true;
\r
1421 btn_start.Enabled = true;
\r
1422 btn_showQueue.Enabled = true;
\r
1423 btn_add2Queue.Enabled = true;
\r
1424 tb_preview.Enabled = true;
\r
1425 btn_source.Enabled = true;
\r
1426 mnu_killCLI.Visible = false;
\r
1428 catch (Exception exc)
\r
1430 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1433 private void killScan()
\r
1440 Process[] prs = Process.GetProcesses();
\r
1441 foreach (Process process in prs)
\r
1443 if (process.Id == scanProcessID)
\r
1445 process.Refresh();
\r
1446 if (!process.HasExited)
\r
1451 catch (Exception ex)
\r
1453 MessageBox.Show("Unable to kill HandBrakeCLI.exe \nYou may need to manually kill HandBrakeCLI.exe using the Windows Task Manager if it does not close automatically within the next few minutes. \n\nError Information: \n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1456 private void resetGUI()
\r
1458 drp_dvdtitle.Items.Clear();
\r
1459 drp_dvdtitle.Text = "Automatic";
\r
1460 drop_chapterStart.Items.Clear();
\r
1461 drop_chapterStart.Text = "Auto";
\r
1462 drop_chapterFinish.Items.Clear();
\r
1463 drop_chapterFinish.Text = "Auto";
\r
1464 lbl_duration.Text = "Select a Title";
\r
1465 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
1466 PictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1467 lbl_source.Text = "Click 'Source' to continue";
\r
1468 text_destination.Text = "";
\r
1470 selectedTitle = null;
\r
1471 isScanning = false;
\r
1477 /// Set the GUI to it's finished encoding state.
\r
1479 private void setEncodeFinished()
\r
1483 if (InvokeRequired)
\r
1485 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1489 lbl_encode.Text = "Encoding Finished";
\r
1490 btn_start.Text = "Start";
\r
1491 btn_start.ToolTipText = "Start the encoding process";
\r
1492 btn_start.Image = Properties.Resources.Play;
\r
1494 // If the window is minimized, display the notification in a popup.
\r
1495 if (Properties.Settings.Default.trayIconAlerts)
\r
1496 if (FormWindowState.Minimized == this.WindowState)
\r
1498 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1499 notifyIcon.ShowBalloonTip(500);
\r
1502 catch (Exception exc)
\r
1504 MessageBox.Show(exc.ToString());
\r
1509 /// Set the GUI to it's started encoding state.
\r
1511 private void setEncodeStarted()
\r
1515 if (InvokeRequired)
\r
1517 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1521 lbl_encode.Visible = true;
\r
1522 lbl_encode.Text = "Encoding in Progress";
\r
1523 btn_start.Text = "Stop";
\r
1524 btn_start.ToolTipText = "Stop the encoding process.";
\r
1525 btn_start.Image = Properties.Resources.stop;
\r
1527 catch (Exception exc)
\r
1529 MessageBox.Show(exc.ToString());
\r
1534 #region DVD Drive Detection
\r
1535 private delegate void ProgressUpdateHandler();
\r
1536 private void getDriveInfoThread()
\r
1540 if (InvokeRequired)
\r
1542 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1546 Boolean foundDrive = false;
\r
1547 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1548 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1550 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1552 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1554 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1555 foundDrive = true;
\r
1561 if (foundDrive == false)
\r
1562 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1566 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1571 #region Public Methods
\r
1573 /// Access the preset Handler and setup the preset panel.
\r
1575 public void loadPresetPanel()
\r
1577 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1578 if (!Properties.Settings.Default.presetNotification)
\r
1579 MessageBox.Show(splash,
\r
1580 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1581 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1583 presetHandler.getPresetPanel(ref treeView_presets);
\r
1584 treeView_presets.Update();
\r
1588 /// Either Encode or Scan was last performed.
\r
1590 public string lastAction { get; set; }
\r
1595 /// If the queue is being processed, prompt the user to confirm application close.
\r
1597 /// <param name="e"></param>
\r
1598 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1600 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1601 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1603 DialogResult result = MessageBox.Show("HandBrake has queue items to process. Closing HandBrake will not stop the current encoding, but will stop processing the queue.\n\nDo you want to close HandBrake?",
\r
1604 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1605 if (result == DialogResult.No)
\r
1608 base.OnFormClosing(e);
\r
1612 #region In-GUI Encode Status (Experimental)
\r
1614 private void encodeMonitorThread()
\r
1618 Parser encode = new Parser(encodeQueue.encodeHandler.hbProcess.StandardOutput.BaseStream);
\r
1619 encode.OnEncodeProgress += encodeOnEncodeProgress;
\r
1620 while (!encode.EndOfStream)
\r
1622 encode.readEncodeStatus();
\r
1625 catch (Exception exc)
\r
1627 MessageBox.Show(exc.ToString());
\r
1630 private void encodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1632 if (this.InvokeRequired)
\r
1634 this.BeginInvoke(new EncodeProgressEventHandler(encodeOnEncodeProgress),
\r
1635 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1638 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1642 // This is the END of the road ****************************************
\r