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.Windows.Forms;
\r
12 using System.Diagnostics;
\r
13 using System.Threading;
\r
14 using Handbrake.EncodeQueue;
\r
15 using Handbrake.Functions;
\r
16 using Handbrake.Presets;
\r
17 using Handbrake.Parsing;
\r
21 public partial class frmMain : Form
\r
23 // Objects which may be used by one or more other objects
\r
24 QueueHandler encodeQueue = new QueueHandler();
\r
25 PresetsHandler presetHandler = new PresetsHandler();
\r
26 QueryGenerator queryGen = new QueryGenerator();
\r
28 // Globals: Mainly used for tracking.
\r
29 Title selectedTitle;
\r
31 private frmQueue queueWindow;
\r
32 private frmPreview qtpreview;
\r
33 private Form splash;
\r
34 public int maxWidth;
\r
35 public int maxHeight;
\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(250, 20), Location = new Point(10, 280) };
\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 == "Checked")
\r
67 lblStatus.Text = "Checking for updates ...";
\r
68 Application.DoEvents();
\r
70 Thread updateCheckThread = new Thread(startupUpdateCheck);
\r
71 updateCheckThread.Start();
\r
74 // Setup the GUI components
\r
75 lblStatus.Text = "Setting up the GUI ...";
\r
76 Application.DoEvents();
\r
77 loadPresetPanel(); // Load the Preset Panel
\r
78 treeView_presets.ExpandAll();
\r
79 lbl_encode.Text = "";
\r
80 queueWindow = new frmQueue(encodeQueue); // Prepare the Queue
\r
81 if (Properties.Settings.Default.QueryEditorTab != "Checked")
\r
82 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
84 // Load the user's default settings or Normal Preset
\r
85 if (Properties.Settings.Default.defaultSettings == "Checked" && Properties.Settings.Default.defaultPreset != "")
\r
87 if (presetHandler.getPreset(Properties.Settings.Default.defaultPreset) != null)
\r
89 string query = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).Query;
\r
90 Boolean loadPictureSettings = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).PictureSettings;
\r
94 //Ok, Reset all the H264 widgets before changing the preset
\r
95 x264Panel.reset2Defaults();
\r
97 // Send the query from the file to the Query Parser class, then load the preset
\r
98 QueryParser presetQuery = QueryParser.Parse(query);
\r
99 PresetLoader.presetLoader(this, presetQuery, Properties.Settings.Default.defaultPreset, loadPictureSettings);
\r
101 // The x264 widgets will need updated, so do this now:
\r
102 x264Panel.X264_StandardizeOptString();
\r
103 x264Panel.X264_SetCurrentSettingsInPanel();
\r
107 loadNormalPreset();
\r
110 loadNormalPreset();
\r
112 // Enabled GUI tooltip's if Required
\r
113 if (Properties.Settings.Default.tooltipEnable == "Checked")
\r
114 ToolTip.Active = true;
\r
117 lblStatus.Text = "Loading Complete!";
\r
118 Application.DoEvents();
\r
121 this.Enabled = true;
\r
123 // Event Handlers and Queue Recovery
\r
128 // Startup Functions
\r
129 private void startupUpdateCheck()
\r
133 if (InvokeRequired)
\r
135 BeginInvoke(new UpdateStatusChanger(startupUpdateCheck));
\r
139 Boolean update = Main.updateCheck(false);
\r
142 frmUpdater updateWindow = new frmUpdater();
\r
143 updateWindow.Show();
\r
146 catch (Exception exc)
\r
148 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
151 private void queueRecovery()
\r
153 if (Main.check_queue_recovery())
\r
155 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
157 if (result == DialogResult.Yes)
\r
158 encodeQueue.recoverQueue("hb_queue_recovery.xml"); // Start Recovery
\r
161 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
162 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
163 if (File.Exists(queuePath))
\r
164 File.Delete(queuePath);
\r
171 // Encoding Events for setting up the GUI
\r
172 private void events()
\r
174 // Handle Window Resize
\r
175 if (Properties.Settings.Default.MainWindowMinimize == "Checked")
\r
176 this.Resize += new EventHandler(frmMain_Resize);
\r
178 // Handle Encode Start / Finish / Pause
\r
179 encodeQueue.OnEncodeEnded += new EventHandler(encodeEnded);
\r
180 encodeQueue.OnPaused += new EventHandler(encodePaused);
\r
181 encodeQueue.OnEncodeStart += new EventHandler(encodeStarted);
\r
183 // Handle a file being draged onto the GUI.
\r
184 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
185 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
188 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
190 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
191 e.Effect = DragDropEffects.All;
\r
193 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
195 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
196 if (fileList != null)
\r
198 if (fileList[0].StartsWith("\\"))
\r
199 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
202 if (fileList[0] != "")
\r
204 setupGUIforScan(fileList[0]);
\r
205 startScan(fileList[0]);
\r
208 text_source.Text = "Click 'Source' to continue";
\r
212 private void encodeStarted(object sender, EventArgs e)
\r
214 lastAction = "encode";
\r
215 setEncodeStarted();
\r
217 // Experimental HBProc Process Monitoring.
\r
218 if (Properties.Settings.Default.enocdeStatusInGui == "Checked")
\r
220 HBProcess = encodeQueue.encodeProcess.hbProcProcess;
\r
221 Thread EncodeMon = new Thread(encodeMonitorThread);
\r
225 private void encodeEnded(object sender, EventArgs e)
\r
227 setEncodeFinished();
\r
229 private void encodePaused(object sender, EventArgs e)
\r
231 setEncodeFinished();
\r
235 // User Interface Menus / Tool Strips *********************************
\r
238 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
242 private void mnu_exit_Click(object sender, EventArgs e)
\r
244 Application.Exit();
\r
249 private void mnu_encode_Click(object sender, EventArgs e)
\r
251 queueWindow.Show();
\r
253 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
255 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
257 frmActivityWindow dvdInfoWindow = new frmActivityWindow(file, encodeQueue, this);
\r
258 dvdInfoWindow.Show();
\r
260 private void mnu_options_Click(object sender, EventArgs e)
\r
262 Form Options = new frmOptions();
\r
263 Options.ShowDialog();
\r
267 #region Presets Menu
\r
268 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
270 presetHandler.updateBuiltInPresets();
\r
272 if (treeView_presets.Nodes.Count == 0)
\r
273 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
275 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
277 treeView_presets.ExpandAll();
\r
279 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
281 // Empty the preset file
\r
282 string presetsFile = Application.StartupPath + "\\presets.xml";
\r
283 if (File.Exists(presetsFile))
\r
284 File.Delete(presetsFile);
\r
288 FileStream strm = new FileStream(presetsFile, FileMode.Create, FileAccess.Write);
\r
292 catch (Exception exc)
\r
294 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
297 // Reload the preset panel
\r
300 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
302 loadNormalPreset();
\r
304 private void btn_new_preset_Click(object sender, EventArgs e)
\r
306 // Remember each nodes expanded status so we can reload it
\r
307 List<Boolean> nodeStatus = saveTreeViewState();
\r
308 nodeStatus.Add(true);
\r
310 Form preset = new frmAddPreset(this, queryGen.GenerateTheQuery(this), presetHandler);
\r
311 preset.ShowDialog();
\r
313 // Now reload the TreeView states
\r
314 loadTreeViewStates(nodeStatus);
\r
319 private void mnu_handbrake_forums_Click(object sender, EventArgs e)
\r
321 Process.Start("http://forum.handbrake.fr/");
\r
323 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
325 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
327 private void mnu_handbrake_home_Click(object sender, EventArgs e)
\r
329 Process.Start("http://handbrake.fr");
\r
331 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
333 Boolean update = Main.updateCheck(true);
\r
336 frmUpdater updateWindow = new frmUpdater();
\r
337 updateWindow.Show();
\r
340 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
342 private void mnu_about_Click(object sender, EventArgs e)
\r
344 Form About = new frmAbout();
\r
345 About.ShowDialog();
\r
350 private void mnu_qptest_Click(object sender, EventArgs e)
\r
352 QueryParserTester qptest = new QueryParserTester();
\r
358 // Right Click Menu Code
\r
359 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
361 treeView_presets.ExpandAll();
\r
363 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
365 treeView_presets.CollapseAll();
\r
367 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
369 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
370 if (result == DialogResult.Yes)
\r
371 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), true);
\r
372 else if (result == DialogResult.No)
\r
373 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), false);
\r
375 private void pmnu_delete_click(object sender, EventArgs e)
\r
377 if (treeView_presets.SelectedNode != null)
\r
379 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
380 List<Boolean> nodeStatus = saveTreeViewState(); // Remember each nodes expanded status so we can reload it
\r
382 loadTreeViewStates(nodeStatus); // Now reload the TreeView states
\r
384 treeView_presets.Select();
\r
386 private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
\r
388 // Make sure that the save menu is always disabled by default
\r
389 pmnu_saveChanges.Enabled = false;
\r
391 // Now enable the save menu if the selected preset is a user preset
\r
392 if (treeView_presets.SelectedNode != null)
\r
393 if (presetHandler.checkIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
394 pmnu_saveChanges.Enabled = true;
\r
396 treeView_presets.Select();
\r
399 // Presets Management
\r
400 private void btn_addPreset_Click(object sender, EventArgs e)
\r
402 // Remember each nodes expanded status so we can reload it
\r
403 List<Boolean> nodeStatus = saveTreeViewState();
\r
404 nodeStatus.Add(true);
\r
406 // Now add the new preset
\r
407 Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);
\r
408 preset.ShowDialog();
\r
410 // Now reload the TreeView states
\r
411 loadTreeViewStates(nodeStatus);
\r
413 private void btn_removePreset_Click(object sender, EventArgs e)
\r
415 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
416 if (result == DialogResult.Yes)
\r
418 if (treeView_presets.SelectedNode != null)
\r
419 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
421 List<Boolean> nodeStatus = saveTreeViewState(); // Remember each nodes expanded status so we can reload it
\r
423 loadTreeViewStates(nodeStatus); // Now reload the TreeView states
\r
425 treeView_presets.Select();
\r
427 private void btn_setDefault_Click(object sender, EventArgs e)
\r
429 if (treeView_presets.SelectedNode != null)
\r
431 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
432 if (result == DialogResult.Yes)
\r
434 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
435 Properties.Settings.Default.Save();
\r
436 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
440 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
442 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
444 if (e.Button == MouseButtons.Right)
\r
445 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
446 else if (e.Button == MouseButtons.Left)
\r
448 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
450 if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
455 treeView_presets.Select();
\r
457 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
461 private void selectPreset()
\r
463 if (treeView_presets.SelectedNode != null)
\r
465 // Ok, so, we've selected a preset. Now we want to load it.
\r
466 string presetName = treeView_presets.SelectedNode.Text;
\r
467 if (presetHandler.getPreset(presetName) != null)
\r
469 string query = presetHandler.getPreset(presetName).Query;
\r
470 Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;
\r
474 //Ok, Reset all the H264 widgets before changing the preset
\r
475 x264Panel.reset2Defaults();
\r
477 // Send the query from the file to the Query Parser class
\r
478 QueryParser presetQuery = QueryParser.Parse(query);
\r
480 // Now load the preset
\r
481 PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);
\r
483 // The x264 widgets will need updated, so do this now:
\r
484 x264Panel.X264_StandardizeOptString();
\r
485 x264Panel.X264_SetCurrentSettingsInPanel();
\r
487 pictureSettings.setMax();
\r
492 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
494 if (e.KeyCode == Keys.Delete)
\r
496 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
497 if (result == DialogResult.Yes)
\r
499 if (treeView_presets.SelectedNode != null)
\r
500 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
502 // Remember each nodes expanded status so we can reload it
\r
503 List<Boolean> nodeStatus = new List<Boolean>();
\r
504 foreach (TreeNode node in treeView_presets.Nodes)
\r
505 nodeStatus.Add(node.IsExpanded);
\r
507 // Now reload the preset panel
\r
510 // And finally, re-expand any of the nodes if required
\r
512 foreach (TreeNode node in treeView_presets.Nodes)
\r
522 private List<Boolean> saveTreeViewState()
\r
524 // Remember each nodes expanded status so we can reload it
\r
525 List<Boolean> nodeStatus = new List<Boolean>();
\r
526 foreach (TreeNode node in treeView_presets.Nodes)
\r
528 nodeStatus.Add(node.IsExpanded);
\r
529 foreach (TreeNode subNode in node.Nodes)
\r
530 nodeStatus.Add(node.IsExpanded);
\r
534 private void loadTreeViewStates(List<Boolean> nodeStatus)
\r
536 // And finally, re-expand any of the nodes if required
\r
538 foreach (TreeNode node in treeView_presets.Nodes)
\r
543 foreach (TreeNode subNode in node.Nodes)
\r
552 private void loadNormalPreset()
\r
554 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
556 foreach (TreeNode node in treenode.Nodes)
\r
558 if (node.Text.Equals("Normal"))
\r
559 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
566 private void btn_source_Click(object sender, EventArgs e)
\r
568 if (Properties.Settings.Default.drive_detection == "Checked")
\r
570 mnu_dvd_drive.Visible = true;
\r
571 Thread driveInfoThread = new Thread(getDriveInfoThread);
\r
572 driveInfoThread.Start();
\r
575 mnu_dvd_drive.Visible = false;
\r
577 private void btn_start_Click(object sender, EventArgs e)
\r
579 if (btn_start.Text == "Stop")
\r
581 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
583 if (result == DialogResult.Yes)
\r
586 encodeQueue.pauseEncodeQueue();
\r
588 // Allow the CLI to exit cleanly
\r
589 Win32.SetForegroundWindow(encodeQueue.encodeProcess.processHandle);
\r
590 SendKeys.Send("^C");
\r
593 setEncodeFinished();
\r
598 if (encodeQueue.count() != 0 || (text_source.Text != string.Empty && text_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))
\r
600 // Set the last action to encode.
\r
601 // This is used for tracking which file to load in the activity window
\r
602 lastAction = "encode";
\r
604 String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.GenerateTheQuery(this);
\r
606 if (encodeQueue.count() == 0)
\r
608 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
609 encodeQueue.write2disk("hb_queue_recovery.xml");
\r
611 queueWindow.setQueue();
\r
612 if (encodeQueue.count() > 1)
\r
613 queueWindow.Show(false);
\r
615 setEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
616 encodeQueue.startEncode(); // Start The Queue Encoding Process
\r
619 else if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
620 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
623 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
626 if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
627 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
630 String query = queryGen.GenerateTheQuery(this);
\r
631 if (rtf_query.Text != "")
\r
632 query = rtf_query.Text;
\r
634 if (encodeQueue.checkDestinationPath(text_destination.Text))
\r
636 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
637 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
638 if (result == DialogResult.Yes)
\r
639 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
643 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
645 encodeQueue.write2disk("hb_queue_recovery.xml"); // Writes the queue to the recovery file, just incase the GUI crashes.
\r
646 queueWindow.Show();
\r
649 private void btn_showQueue_Click(object sender, EventArgs e)
\r
651 queueWindow.Show();
\r
653 private void tb_preview_Click(object sender, EventArgs e)
\r
655 if (text_source.Text == "" || text_source.Text == "Click 'Source' to continue" || text_destination.Text == "")
\r
656 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
659 if (qtpreview == null)
\r
661 qtpreview = new frmPreview(this);
\r
664 else if (qtpreview.IsDisposed)
\r
666 qtpreview = new frmPreview(this);
\r
670 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
673 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
675 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
677 frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);
\r
678 ActivityWindow.Show();
\r
682 #region System Tray Icon
\r
683 private void frmMain_Resize(object sender, EventArgs e)
\r
685 if (FormWindowState.Minimized == this.WindowState)
\r
687 notifyIcon.Visible = true;
\r
688 if (!encodeQueue.isEncoding)
\r
690 notifyIcon.BalloonTipText = lbl_encode.Text != "" ? lbl_encode.Text : "Not Encoding";
\r
691 if (Properties.Settings.Default.trayIconAlerts == "Checked")
\r
692 notifyIcon.ShowBalloonTip(500);
\r
696 else if (FormWindowState.Normal == this.WindowState)
\r
697 notifyIcon.Visible = false;
\r
699 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
701 this.Visible = true;
\r
703 this.WindowState = FormWindowState.Normal;
\r
704 notifyIcon.Visible = false;
\r
706 private void btn_restore_Click(object sender, EventArgs e)
\r
708 this.Visible = true;
\r
710 this.WindowState = FormWindowState.Normal;
\r
711 notifyIcon.Visible = false;
\r
715 #region Tab Control
\r
718 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
720 // Enable the creation of chapter markers.
\r
721 Check_ChapterMarkers.Enabled = true;
\r
723 // Set the last action to scan.
\r
724 // This is used for tracking which file to load in the activity window
\r
725 lastAction = "scan";
\r
726 text_source.Text = "";
\r
728 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
730 String filename = DVD_Open.SelectedPath;
\r
732 if (filename.StartsWith("\\"))
\r
733 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
736 if (filename != "")
\r
738 setupGUIforScan(filename);
\r
739 startScan(filename);
\r
742 text_source.Text = "Click 'Source' to continue";
\r
746 text_source.Text = "Click 'Source' to continue";
\r
748 private void btn_file_source_Click(object sender, EventArgs e)
\r
750 // Set the last action to scan.
\r
751 // This is used for tracking which file to load in the activity window
\r
752 lastAction = "scan";
\r
753 text_source.Text = "";
\r
755 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
757 String filename = ISO_Open.FileName;
\r
758 if (filename.StartsWith("\\"))
\r
760 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
761 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
764 if (filename != "")
\r
766 setupGUIforScan(filename);
\r
767 startScan(filename);
\r
770 text_source.Text = "Click 'Source' to continue";
\r
774 text_source.Text = "Click 'Source' to continue";
\r
776 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
778 // Enable the creation of chapter markers.
\r
779 Check_ChapterMarkers.Enabled = true;
\r
781 // Set the last action to scan.
\r
782 // This is used for tracking which file to load in the activity window
\r
783 lastAction = "scan";
\r
785 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
787 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
788 String filename = path[0];
\r
789 setupGUIforScan(filename);
\r
790 startScan(filename);
\r
793 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
794 if (drp_dvdtitle.Items.Count == 0)
\r
795 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
797 lbl_encode.Text = "";
\r
799 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
801 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
802 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
804 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
806 // Reset some values on the form
\r
807 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
808 //lbl_RecomendedCrop.Text = "Select a Title";
\r
809 drop_chapterStart.Items.Clear();
\r
810 drop_chapterFinish.Items.Clear();
\r
812 // If the dropdown is set to automatic nothing else needs to be done.
\r
813 // Otheriwse if its not, title data has to be loased from parsing.
\r
814 if (drp_dvdtitle.Text != "Automatic")
\r
816 selectedTitle = drp_dvdtitle.SelectedItem as Parsing.Title;
\r
817 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
818 pictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
820 // Populate the Angles dropdown
\r
821 drop_angle.Items.Clear();
\r
822 if (Properties.Settings.Default.dvdnav == "Checked")
\r
824 drop_angle.Visible = true;
\r
825 lbl_angle.Visible = true;
\r
826 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
827 if (drop_angle.Items.Count != 0)
\r
828 drop_angle.SelectedIndex = 0;
\r
832 drop_angle.Visible = false;
\r
833 lbl_angle.Visible = false;
\r
836 // Populate the Start chapter Dropdown
\r
837 drop_chapterStart.Items.Clear();
\r
838 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
839 if (drop_chapterStart.Items.Count > 0)
\r
840 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
842 // Populate the Final Chapter Dropdown
\r
843 drop_chapterFinish.Items.Clear();
\r
844 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
845 if (drop_chapterFinish.Items.Count > 0)
\r
846 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
848 // Populate the Audio Channels Dropdown
\r
849 audioPanel.setTrackList(selectedTitle);
\r
851 // Populate the Subtitles dropdown
\r
852 drp_subtitle.Items.Clear();
\r
853 drp_subtitle.Items.Add("None");
\r
854 drp_subtitle.Items.Add("Autoselect");
\r
855 drp_subtitle.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
856 if (drp_subtitle.Items.Count > 0)
\r
857 drp_subtitle.Text = drp_subtitle.Items[0].ToString();
\r
861 // Run the autoName & chapterNaming functions
\r
862 if (Properties.Settings.Default.autoNaming == "Checked")
\r
864 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
865 if (autoPath != null)
\r
866 text_destination.Text = autoPath;
\r
868 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
871 data_chpt.Rows.Clear();
\r
872 if (selectedTitle.Chapters.Count != 1)
\r
874 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
875 if (chapterGridView != null)
\r
876 data_chpt = chapterGridView;
\r
880 Check_ChapterMarkers.Checked = false;
\r
881 Check_ChapterMarkers.Enabled = false;
\r
884 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
885 data_chpt.Columns[0].Width = 166;
\r
886 data_chpt.Columns[0].Width = 165;
\r
888 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
890 int c_start, c_end;
\r
892 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
893 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
895 int.TryParse(drop_chapterStart.Text, out c_start);
\r
896 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
900 if (c_start > c_end)
\r
901 drop_chapterFinish.Text = c_start.ToString();
\r
904 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
906 // Run the Autonaming function
\r
907 if (Properties.Settings.Default.autoNaming == "Checked")
\r
908 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
910 // Disable chapter markers if only 1 chapter is selected.
\r
911 if (c_start == c_end)
\r
913 Check_ChapterMarkers.Checked = false;
\r
914 Check_ChapterMarkers.Enabled = false;
\r
917 Check_ChapterMarkers.Enabled = true;
\r
919 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
921 int c_start, c_end;
\r
923 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
924 drop_chapterStart.SelectedIndex = 1;
\r
926 int.TryParse(drop_chapterStart.Text, out c_start);
\r
927 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
931 if (c_end < c_start)
\r
932 drop_chapterFinish.Text = c_start.ToString();
\r
935 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
937 // Run the Autonaming function
\r
938 if (Properties.Settings.Default.autoNaming == "Checked")
\r
939 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
941 // Add more rows to the Chapter menu if needed.
\r
942 if (Check_ChapterMarkers.Checked)
\r
944 int i = data_chpt.Rows.Count, finish = 0;
\r
946 if (drop_chapterFinish.Text != "Auto")
\r
947 int.TryParse(drop_chapterFinish.Text, out finish);
\r
951 int n = data_chpt.Rows.Add();
\r
952 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
953 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
954 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
955 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
960 // Disable chapter markers if only 1 chapter is selected.
\r
961 if (c_start == c_end)
\r
963 Check_ChapterMarkers.Checked = false;
\r
964 Check_ChapterMarkers.Enabled = false;
\r
967 Check_ChapterMarkers.Enabled = true;
\r
971 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
973 // This removes the file extension from the filename box on the save file dialog.
\r
974 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
975 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
977 if (Path.IsPathRooted(text_destination.Text))
\r
978 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
980 // Show the dialog and set the main form file path
\r
981 if (drop_format.SelectedIndex.Equals(0))
\r
982 DVD_Save.FilterIndex = 1;
\r
983 else if (drop_format.SelectedIndex.Equals(1))
\r
984 DVD_Save.FilterIndex = 2;
\r
985 else if (drop_format.SelectedIndex.Equals(2))
\r
986 DVD_Save.FilterIndex = 3;
\r
988 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
990 if (DVD_Save.FileName.StartsWith("\\"))
\r
991 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
994 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
995 switch (DVD_Save.FilterIndex)
\r
998 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
999 DVD_Save.FileName += ".mp4";
\r
1002 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
1003 DVD_Save.FileName += ".m4v";
\r
1006 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1007 DVD_Save.FileName += ".mkv";
\r
1013 text_destination.Text = DVD_Save.FileName;
\r
1015 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1016 if (Check_ChapterMarkers.Checked)
\r
1017 drop_format.SelectedIndex = 1;
\r
1021 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1023 string path = text_destination.Text;
\r
1024 if (path.EndsWith(".mp4"))
\r
1025 drop_format.SelectedIndex = 0;
\r
1026 else if (path.EndsWith(".m4v"))
\r
1027 drop_format.SelectedIndex = 1;
\r
1028 else if (path.EndsWith(".mkv"))
\r
1029 drop_format.SelectedIndex = 2;
\r
1032 // Output Settings
\r
1033 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1035 if (drop_format.SelectedIndex == 0)
\r
1036 setExtension(".mp4");
\r
1037 else if (drop_format.SelectedIndex == 1)
\r
1038 setExtension(".m4v");
\r
1039 else if (drop_format.SelectedIndex == 2)
\r
1040 setExtension(".mkv");
\r
1042 audioPanel.setAudioByContainer(drop_format.Text);
\r
1045 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1047 oldval = drp_videoEncoder.Text;
\r
1048 drp_videoEncoder.Items.Clear();
\r
1049 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1050 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1051 if (oldval == "VP3 (Theora)")
\r
1052 drp_videoEncoder.SelectedIndex = 1;
\r
1054 drp_videoEncoder.Text = oldval;
\r
1056 else if (drop_format.Text.Contains("MKV"))
\r
1058 oldval = drp_videoEncoder.Text;
\r
1059 drp_videoEncoder.Items.Clear();
\r
1060 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1061 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1062 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1063 drp_videoEncoder.Text = oldval;
\r
1066 private void setExtension(string newExtension)
\r
1068 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1069 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1070 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1074 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1076 setContainerOpts();
\r
1078 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1079 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1081 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1082 check_turbo.Enabled = true;
\r
1084 tab_advanced.Enabled = true;
\r
1085 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1086 check_iPodAtom.Enabled = true;
\r
1088 check_iPodAtom.Enabled = false;
\r
1092 check_turbo.CheckState = CheckState.Unchecked;
\r
1093 check_turbo.Enabled = false;
\r
1094 tab_advanced.Enabled = false;
\r
1095 x264Panel.x264Query = "";
\r
1096 check_iPodAtom.Enabled = false;
\r
1097 check_iPodAtom.Checked = false;
\r
1100 // Setup the CQ Slider
\r
1101 switch (drp_videoEncoder.Text)
\r
1103 case "MPEG-4 (FFmpeg)":
\r
1104 slider_videoQuality.Minimum = 1;
\r
1105 slider_videoQuality.Maximum = 31;
\r
1106 slider_videoQuality.Value = 1;
\r
1107 SliderValue.Text = "0% QP: 31.00";
\r
1109 case "H.264 (x264)":
\r
1110 slider_videoQuality.Minimum = 0;
\r
1111 slider_videoQuality.Value = 0;
\r
1112 slider_videoQuality.TickFrequency = 1;
\r
1113 SliderValue.Text = "0% RF: 51.00";
\r
1114 String step = Properties.Settings.Default.x264cqstep;
\r
1118 slider_videoQuality.Maximum = 255;
\r
1121 slider_videoQuality.Maximum = 204;
\r
1124 slider_videoQuality.Maximum = 155;
\r
1127 slider_videoQuality.Maximum = 102;
\r
1130 slider_videoQuality.Maximum = 51;
\r
1133 slider_videoQuality.Maximum = 51;
\r
1137 case "VP3 (Theora)":
\r
1138 slider_videoQuality.Minimum = 0;
\r
1139 slider_videoQuality.Maximum = 63;
\r
1140 slider_videoQuality.Value = 0;
\r
1141 SliderValue.Text = "0% QP: 0.00";
\r
1146 /// Set the container format options
\r
1148 public void setContainerOpts()
\r
1150 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1152 check_largeFile.Enabled = true;
\r
1153 check_optimiseMP4.Enabled = true;
\r
1154 check_iPodAtom.Enabled = true;
\r
1158 check_largeFile.Enabled = false;
\r
1159 check_optimiseMP4.Enabled = false;
\r
1160 check_iPodAtom.Enabled = false;
\r
1161 check_largeFile.Checked = false;
\r
1162 check_optimiseMP4.Checked = false;
\r
1163 check_iPodAtom.Checked = false;
\r
1166 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1168 switch (drp_videoEncoder.Text)
\r
1170 case "MPEG-4 (FFmpeg)":
\r
1171 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1172 double max = slider_videoQuality.Maximum;
\r
1173 double min = slider_videoQuality.Minimum;
\r
1174 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1175 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1177 case "H.264 (x264)":
\r
1179 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
\r
1180 double.TryParse(Properties.Settings.Default.x264cqstep,
\r
1181 System.Globalization.NumberStyles.Number,
\r
1184 rfValue = 51.0 - slider_videoQuality.Value * divided;
\r
1185 max = slider_videoQuality.Maximum * divided;
\r
1186 min = slider_videoQuality.Minimum;
\r
1187 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1188 rfValue = Math.Round(rfValue, 2);
\r
1189 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1191 case "VP3 (Theora)":
\r
1192 rfValue = slider_videoQuality.Value;
\r
1193 double value = rfValue / 63;
\r
1194 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1198 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1200 text_bitrate.Enabled = false;
\r
1201 text_filesize.Enabled = true;
\r
1202 slider_videoQuality.Enabled = false;
\r
1204 check_2PassEncode.Enabled = true;
\r
1206 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1208 text_bitrate.Enabled = true;
\r
1209 text_filesize.Enabled = false;
\r
1210 slider_videoQuality.Enabled = false;
\r
1212 check_2PassEncode.Enabled = true;
\r
1214 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1216 text_bitrate.Enabled = false;
\r
1217 text_filesize.Enabled = false;
\r
1218 slider_videoQuality.Enabled = true;
\r
1220 check_2PassEncode.Enabled = false;
\r
1221 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1223 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1225 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1227 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1228 check_turbo.Enabled = true;
\r
1232 check_turbo.Enabled = false;
\r
1233 check_turbo.CheckState = CheckState.Unchecked;
\r
1238 private void ctl_decomb_changed(object sender, EventArgs e)
\r
1240 if (ctl_decomb.getDropValue != "Off")
\r
1241 if (ctl_deinterlace.getDropValue != "None")
\r
1242 ctl_deinterlace.setOption("None");
\r
1244 private void ctl_deinterlace_changed(object sender, EventArgs e)
\r
1246 if (ctl_detelecine.getDropValue != "None")
\r
1247 if (ctl_decomb.getDropValue != "Off")
\r
1248 ctl_decomb.setOption("Off");
\r
1250 private void slider_deblock_Scroll(object sender, EventArgs e)
\r
1252 lbl_deblockVal.Text = slider_deblock.Value == 4 ? "Off" : slider_deblock.Value.ToString();
\r
1256 private void drp_subtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1258 if (drp_subtitle.Text.Contains("None"))
\r
1260 check_forced.Enabled = false;
\r
1261 check_forced.Checked = false;
\r
1264 check_forced.Enabled = true;
\r
1267 // Chapter Marker Tab
\r
1268 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1270 if (Check_ChapterMarkers.Checked)
\r
1272 drop_format.SelectedIndex = 1;
\r
1273 data_chpt.Rows.Clear();
\r
1274 data_chpt.Enabled = true;
\r
1275 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1276 if (chapterGridView != null)
\r
1277 data_chpt = chapterGridView;
\r
1281 drop_format.SelectedIndex = 0;
\r
1282 data_chpt.Rows.Clear();
\r
1283 data_chpt.Enabled = false;
\r
1287 // Query Editor Tab
\r
1288 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1290 rtf_query.Text = queryGen.GenerateTheQuery(this);
\r
1292 private void btn_clear_Click(object sender, EventArgs e)
\r
1294 rtf_query.Clear();
\r
1298 // MainWindow Components, Actions and Functions ***********************
\r
1300 #region Source Scan
\r
1301 public Boolean isScanning { get; set; }
\r
1302 private static int scanProcessID { get; set; }
\r
1303 private void setupGUIforScan(String filename)
\r
1305 text_source.Text = filename;
\r
1307 foreach (Control ctrl in Controls)
\r
1309 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1310 ctrl.Enabled = false;
\r
1312 lbl_encode.Visible = true;
\r
1313 lbl_encode.Text = "Scanning ...";
\r
1314 gb_source.Text = "Source: Scanning ...";
\r
1315 btn_source.Enabled = false;
\r
1316 btn_start.Enabled = false;
\r
1317 btn_showQueue.Enabled = false;
\r
1318 btn_add2Queue.Enabled = false;
\r
1319 tb_preview.Enabled = false;
\r
1320 mnu_killCLI.Visible = true;
\r
1322 private void startScan(String filename)
\r
1326 lbl_encode.Visible = true;
\r
1327 lbl_encode.Text = "Scanning...";
\r
1328 isScanning = true;
\r
1329 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1331 catch (Exception exc)
\r
1333 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1336 private void scanProcess(object state)
\r
1340 string inputFile = (string)state;
\r
1341 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1342 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1343 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1345 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1346 if (File.Exists(dvdInfoPath))
\r
1347 File.Delete(dvdInfoPath);
\r
1349 String dvdnav = string.Empty;
\r
1350 if (Properties.Settings.Default.dvdnav == "Checked")
\r
1351 dvdnav = " --dvdnav";
\r
1352 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1354 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1356 Boolean cleanExit = true;
\r
1357 using (hbproc = Process.Start(hbParseDvd))
\r
1359 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1360 scanProcessID = Main.getCliProcess(before);
\r
1361 hbproc.WaitForExit();
\r
1362 if (hbproc.ExitCode != 0)
\r
1363 cleanExit = false;
\r
1366 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1368 if (!File.Exists(dvdInfoPath))
\r
1370 throw new Exception(
\r
1371 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1375 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1377 thisDVD = DVD.Parse(sr);
\r
1382 updateUIafterScan();
\r
1385 catch (Exception exc)
\r
1387 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1391 private void updateUIafterScan()
\r
1395 if (InvokeRequired)
\r
1397 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1401 // Setup some GUI components
\r
1402 drp_dvdtitle.Items.Clear();
\r
1403 if (thisDVD.Titles.Count != 0)
\r
1404 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1405 drp_dvdtitle.Text = "Automatic";
\r
1406 drop_chapterFinish.Text = "Auto";
\r
1407 drop_chapterStart.Text = "Auto";
\r
1409 // Now select the longest title
\r
1410 if (thisDVD.Titles.Count != 0)
\r
1411 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1413 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1414 if (text_source.Text.ToLower().Contains(".iso") || text_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1415 Check_ChapterMarkers.Enabled = true;
\r
1418 Check_ChapterMarkers.Enabled = false;
\r
1419 Check_ChapterMarkers.Checked = false;
\r
1420 data_chpt.Rows.Clear();
\r
1423 // If no titles were found, Display an error message
\r
1424 if (drp_dvdtitle.Items.Count == 0)
\r
1425 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
1427 // Enable the GUI components and enable any disabled components
\r
1430 catch (Exception exc)
\r
1432 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1436 private void enableGUI()
\r
1440 if (InvokeRequired)
\r
1441 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1442 lbl_encode.Text = "Scan Completed";
\r
1443 gb_source.Text = "Source";
\r
1444 foreach (Control ctrl in Controls)
\r
1445 ctrl.Enabled = true;
\r
1446 btn_start.Enabled = true;
\r
1447 btn_showQueue.Enabled = true;
\r
1448 btn_add2Queue.Enabled = true;
\r
1449 tb_preview.Enabled = true;
\r
1450 btn_source.Enabled = true;
\r
1451 mnu_killCLI.Visible = false;
\r
1453 catch (Exception exc)
\r
1455 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1458 private void killScan()
\r
1465 Process[] prs = Process.GetProcesses();
\r
1466 foreach (Process process in prs)
\r
1468 if (process.Id == scanProcessID)
\r
1470 process.Refresh();
\r
1471 if (!process.HasExited)
\r
1476 catch (Exception ex)
\r
1478 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
1481 private void resetGUI()
\r
1483 drp_dvdtitle.Items.Clear();
\r
1484 drp_dvdtitle.Text = "Automatic";
\r
1485 drop_chapterStart.Items.Clear();
\r
1486 drop_chapterStart.Text = "Auto";
\r
1487 drop_chapterFinish.Items.Clear();
\r
1488 drop_chapterFinish.Text = "Auto";
\r
1489 lbl_duration.Text = "Select a Title";
\r
1490 pictureSettings.lbl_src_res.Text = "Select a Title";
\r
1491 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1492 text_source.Text = "Click 'Source' to continue";
\r
1493 text_destination.Text = "";
\r
1495 selectedTitle = null;
\r
1496 isScanning = false;
\r
1502 /// Set the GUI to it's finished encoding state.
\r
1504 private void setEncodeFinished()
\r
1508 if (InvokeRequired)
\r
1510 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1514 lbl_encode.Text = "Encoding Finished";
\r
1515 btn_start.Text = "Start";
\r
1516 btn_start.ToolTipText = "Start the encoding process";
\r
1517 btn_start.Image = Properties.Resources.Play;
\r
1519 // If the window is minimized, display the notification in a popup.
\r
1520 if (FormWindowState.Minimized == this.WindowState)
\r
1522 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1523 notifyIcon.ShowBalloonTip(500);
\r
1526 catch (Exception exc)
\r
1528 MessageBox.Show(exc.ToString());
\r
1533 /// Set the GUI to it's started encoding state.
\r
1535 private void setEncodeStarted()
\r
1539 if (InvokeRequired)
\r
1541 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1545 lbl_encode.Visible = true;
\r
1546 lbl_encode.Text = "Encoding in Progress";
\r
1547 btn_start.Text = "Stop";
\r
1548 btn_start.ToolTipText = "Stop the encoding process. \nWarning: This may break your file. Press ctrl-c in the CLI window if you wish it to exit cleanly.";
\r
1549 btn_start.Image = Properties.Resources.stop;
\r
1551 catch (Exception exc)
\r
1553 MessageBox.Show(exc.ToString());
\r
1558 #region DVD Drive Detection
\r
1559 private delegate void ProgressUpdateHandler();
\r
1560 private void getDriveInfoThread()
\r
1564 if (InvokeRequired)
\r
1566 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1570 Boolean foundDrive = false;
\r
1571 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1572 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1574 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1576 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1578 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1579 foundDrive = true;
\r
1585 if (foundDrive == false)
\r
1586 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1590 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1595 #region Public Methods
\r
1597 /// Access the preset Handler and setup the preset panel.
\r
1599 public void loadPresetPanel()
\r
1601 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1602 if (Properties.Settings.Default.presetNotification == "Unchecked")
\r
1604 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1605 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1607 presetHandler.getPresetPanel(ref treeView_presets);
\r
1608 treeView_presets.Update();
\r
1612 /// Either Encode or Scan was last performed.
\r
1614 public string lastAction { get; set; }
\r
1619 /// If the queue is being processed, prompt the user to confirm application close.
\r
1621 /// <param name="e"></param>
\r
1622 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1624 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1625 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1627 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
1628 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1629 if (result == DialogResult.No)
\r
1632 base.OnFormClosing(e);
\r
1636 #region In-GUI Encode Status (Experimental)
\r
1637 private Process HBProcess { get; set; }
\r
1639 private void encodeMonitorThread()
\r
1643 Parser encode = new Parser(HBProcess.StandardOutput.BaseStream);
\r
1644 encode.OnEncodeProgress += encode_OnEncodeProgress;
\r
1645 while (!encode.EndOfStream)
\r
1647 encode.readEncodeStatus();
\r
1650 catch (Exception exc)
\r
1652 MessageBox.Show(exc.ToString());
\r
1656 private void encode_OnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1658 if (this.InvokeRequired)
\r
1660 this.BeginInvoke(new EncodeProgressEventHandler(encode_OnEncodeProgress),
\r
1661 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1664 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1668 // This is the END of the road ****************************************
\r