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
35 // Delegates **********************************************************
\r
36 private delegate void UpdateWindowHandler();
\r
37 private delegate void UpdateStatusChanger();
\r
39 // Applicaiton Startup ************************************************
\r
41 #region Application Startup
\r
44 // Load and setup the splash screen in this thread
\r
45 splash = new frmSplashScreen();
\r
47 Label lblStatus = new Label { Size = new Size(250, 20), Location = new Point(10, 280) };
\r
48 splash.Controls.Add(lblStatus);
\r
50 InitializeComponent();
\r
52 // Update the users config file with the CLI version data.
\r
53 lblStatus.Text = "Setting Version Data ...";
\r
54 Application.DoEvents();
\r
55 Main.setCliVersionData();
\r
57 // Show the form, but leave disabled until preloading is complete then show the main form
\r
58 this.Enabled = false;
\r
60 Application.DoEvents(); // Forces frmMain to draw
\r
62 // Check for new versions, if update checking is enabled
\r
63 if (Properties.Settings.Default.updateStatus == "Checked")
\r
65 lblStatus.Text = "Checking for updates ...";
\r
66 Application.DoEvents();
\r
68 Thread updateCheckThread = new Thread(startupUpdateCheck);
\r
69 updateCheckThread.Start();
\r
72 // Setup the GUI components
\r
73 lblStatus.Text = "Setting up the GUI ...";
\r
74 Application.DoEvents();
\r
75 loadPresetPanel(); // Load the Preset Panel
\r
76 treeView_presets.ExpandAll();
\r
77 lbl_encode.Text = "";
\r
78 queueWindow = new frmQueue(encodeQueue); // Prepare the Queue
\r
79 if (Properties.Settings.Default.QueryEditorTab != "Checked")
\r
80 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
82 // Load the user's default settings or Normal Preset
\r
83 if (Properties.Settings.Default.defaultSettings == "Checked" && Properties.Settings.Default.defaultPreset != "")
\r
85 if (presetHandler.getPreset(Properties.Settings.Default.defaultPreset) != null)
\r
87 string query = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).Query;
\r
88 Boolean loadPictureSettings = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).PictureSettings;
\r
92 //Ok, Reset all the H264 widgets before changing the preset
\r
93 x264Panel.reset2Defaults();
\r
95 // Send the query from the file to the Query Parser class, then load the preset
\r
96 QueryParser presetQuery = QueryParser.Parse(query);
\r
97 PresetLoader.presetLoader(this, presetQuery, Properties.Settings.Default.defaultPreset, loadPictureSettings);
\r
99 // The x264 widgets will need updated, so do this now:
\r
100 x264Panel.X264_StandardizeOptString();
\r
101 x264Panel.X264_SetCurrentSettingsInPanel();
\r
105 loadNormalPreset();
\r
108 loadNormalPreset();
\r
110 // Enabled GUI tooltip's if Required
\r
111 if (Properties.Settings.Default.tooltipEnable == "Checked")
\r
112 ToolTip.Active = true;
\r
115 lblStatus.Text = "Loading Complete!";
\r
116 Application.DoEvents();
\r
119 this.Enabled = true;
\r
121 // Event Handlers and Queue Recovery
\r
126 // Startup Functions
\r
127 private void startupUpdateCheck()
\r
131 if (InvokeRequired)
\r
133 BeginInvoke(new UpdateStatusChanger(startupUpdateCheck));
\r
137 Boolean update = Main.updateCheck(false);
\r
140 frmUpdater updateWindow = new frmUpdater();
\r
141 updateWindow.Show();
\r
144 catch (Exception exc)
\r
146 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
149 private void queueRecovery()
\r
151 if (Main.check_queue_recovery())
\r
153 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
155 if (result == DialogResult.Yes)
\r
156 encodeQueue.recoverQueue("hb_queue_recovery.xml"); // Start Recovery
\r
159 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
160 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
161 if (File.Exists(queuePath))
\r
162 File.Delete(queuePath);
\r
169 // Encoding Events for setting up the GUI
\r
170 private void events()
\r
172 // Handle Window Resize
\r
173 if (Properties.Settings.Default.MainWindowMinimize == "Checked")
\r
174 this.Resize += new EventHandler(frmMain_Resize);
\r
176 // Handle Encode Start / Finish / Pause
\r
177 encodeQueue.OnEncodeEnded += new EventHandler(encodeEnded);
\r
178 encodeQueue.OnPaused += new EventHandler(encodePaused);
\r
179 encodeQueue.OnEncodeStart += new EventHandler(encodeStarted);
\r
181 // Handle a file being draged onto the GUI.
\r
182 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
183 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
186 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
188 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
189 e.Effect = DragDropEffects.All;
\r
191 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
193 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
194 if (fileList != null)
\r
196 if (fileList[0].StartsWith("\\"))
\r
197 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
200 if (fileList[0] != "")
\r
202 setupGUIforScan(fileList[0]);
\r
203 startScan(fileList[0]);
\r
206 text_source.Text = "Click 'Source' to continue";
\r
210 private void encodeStarted(object sender, EventArgs e)
\r
212 lastAction = "encode";
\r
213 setEncodeStarted();
\r
215 // Experimental HBProc Process Monitoring.
\r
216 if (Properties.Settings.Default.enocdeStatusInGui == "Checked")
\r
218 HBProcess = encodeQueue.encodeProcess.hbProcProcess;
\r
219 Thread EncodeMon = new Thread(encodeMonitorThread);
\r
223 private void encodeEnded(object sender, EventArgs e)
\r
225 setEncodeFinished();
\r
227 private void encodePaused(object sender, EventArgs e)
\r
229 setEncodeFinished();
\r
233 // User Interface Menus / Tool Strips *********************************
\r
236 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
240 private void mnu_exit_Click(object sender, EventArgs e)
\r
242 Application.Exit();
\r
247 private void mnu_encode_Click(object sender, EventArgs e)
\r
249 queueWindow.Show();
\r
251 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
253 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
255 frmActivityWindow dvdInfoWindow = new frmActivityWindow(file, encodeQueue, this);
\r
256 dvdInfoWindow.Show();
\r
258 private void mnu_options_Click(object sender, EventArgs e)
\r
260 Form Options = new frmOptions();
\r
261 Options.ShowDialog();
\r
265 #region Presets Menu
\r
266 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
268 presetHandler.updateBuiltInPresets();
\r
270 if (treeView_presets.Nodes.Count == 0)
\r
271 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
273 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
275 treeView_presets.ExpandAll();
\r
277 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
279 // Empty the preset file
\r
280 string presetsFile = Application.StartupPath + "\\presets.xml";
\r
281 if (File.Exists(presetsFile))
\r
282 File.Delete(presetsFile);
\r
286 FileStream strm = new FileStream(presetsFile, FileMode.Create, FileAccess.Write);
\r
290 catch (Exception exc)
\r
292 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
295 // Reload the preset panel
\r
298 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
300 loadNormalPreset();
\r
302 private void btn_new_preset_Click(object sender, EventArgs e)
\r
304 // Remember each nodes expanded status so we can reload it
\r
305 List<Boolean> nodeStatus = saveTreeViewState();
\r
306 nodeStatus.Add(true);
\r
308 Form preset = new frmAddPreset(this, queryGen.GenerateTheQuery(this), presetHandler);
\r
309 preset.ShowDialog();
\r
311 // Now reload the TreeView states
\r
312 loadTreeViewStates(nodeStatus);
\r
317 private void mnu_handbrake_forums_Click(object sender, EventArgs e)
\r
319 Process.Start("http://forum.handbrake.fr/");
\r
321 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
323 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
325 private void mnu_handbrake_home_Click(object sender, EventArgs e)
\r
327 Process.Start("http://handbrake.fr");
\r
329 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
331 Boolean update = Main.updateCheck(true);
\r
334 frmUpdater updateWindow = new frmUpdater();
\r
335 updateWindow.Show();
\r
338 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
340 private void mnu_about_Click(object sender, EventArgs e)
\r
342 Form About = new frmAbout();
\r
343 About.ShowDialog();
\r
348 private void mnu_qptest_Click(object sender, EventArgs e)
\r
350 QueryParserTester qptest = new QueryParserTester();
\r
356 // Right Click Menu Code
\r
357 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
359 treeView_presets.ExpandAll();
\r
361 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
363 treeView_presets.CollapseAll();
\r
365 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
367 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
368 if (result == DialogResult.Yes)
\r
369 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), true);
\r
370 else if (result == DialogResult.No)
\r
371 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), false);
\r
373 private void pmnu_delete_click(object sender, EventArgs e)
\r
375 if (treeView_presets.SelectedNode != null)
\r
377 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
378 List<Boolean> nodeStatus = saveTreeViewState(); // Remember each nodes expanded status so we can reload it
\r
380 loadTreeViewStates(nodeStatus); // Now reload the TreeView states
\r
382 treeView_presets.Select();
\r
384 private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
\r
386 // Make sure that the save menu is always disabled by default
\r
387 pmnu_saveChanges.Enabled = false;
\r
389 // Now enable the save menu if the selected preset is a user preset
\r
390 if (treeView_presets.SelectedNode != null)
\r
391 if (presetHandler.checkIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
392 pmnu_saveChanges.Enabled = true;
\r
394 treeView_presets.Select();
\r
397 // Presets Management
\r
398 private void btn_addPreset_Click(object sender, EventArgs e)
\r
400 // Remember each nodes expanded status so we can reload it
\r
401 List<Boolean> nodeStatus = saveTreeViewState();
\r
402 nodeStatus.Add(true);
\r
404 // Now add the new preset
\r
405 Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);
\r
406 preset.ShowDialog();
\r
408 // Now reload the TreeView states
\r
409 loadTreeViewStates(nodeStatus);
\r
411 private void btn_removePreset_Click(object sender, EventArgs e)
\r
413 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
414 if (result == DialogResult.Yes)
\r
416 if (treeView_presets.SelectedNode != null)
\r
417 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
419 List<Boolean> nodeStatus = saveTreeViewState(); // Remember each nodes expanded status so we can reload it
\r
421 loadTreeViewStates(nodeStatus); // Now reload the TreeView states
\r
423 treeView_presets.Select();
\r
425 private void btn_setDefault_Click(object sender, EventArgs e)
\r
427 if (treeView_presets.SelectedNode != null)
\r
429 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
430 if (result == DialogResult.Yes)
\r
432 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
433 Properties.Settings.Default.Save();
\r
434 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
438 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
440 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
442 if (e.Button == MouseButtons.Right)
\r
443 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
444 else if (e.Button == MouseButtons.Left)
\r
446 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
448 if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
453 treeView_presets.Select();
\r
455 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
459 private void selectPreset()
\r
461 if (treeView_presets.SelectedNode != null)
\r
463 // Ok, so, we've selected a preset. Now we want to load it.
\r
464 string presetName = treeView_presets.SelectedNode.Text;
\r
465 if (presetHandler.getPreset(presetName) != null)
\r
467 string query = presetHandler.getPreset(presetName).Query;
\r
468 Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;
\r
472 //Ok, Reset all the H264 widgets before changing the preset
\r
473 x264Panel.reset2Defaults();
\r
475 // Send the query from the file to the Query Parser class
\r
476 QueryParser presetQuery = QueryParser.Parse(query);
\r
478 // Now load the preset
\r
479 PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);
\r
481 // The x264 widgets will need updated, so do this now:
\r
482 x264Panel.X264_StandardizeOptString();
\r
483 x264Panel.X264_SetCurrentSettingsInPanel();
\r
488 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
490 if (e.KeyCode == Keys.Delete)
\r
492 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
493 if (result == DialogResult.Yes)
\r
495 if (treeView_presets.SelectedNode != null)
\r
496 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
498 // Remember each nodes expanded status so we can reload it
\r
499 List<Boolean> nodeStatus = new List<Boolean>();
\r
500 foreach (TreeNode node in treeView_presets.Nodes)
\r
501 nodeStatus.Add(node.IsExpanded);
\r
503 // Now reload the preset panel
\r
506 // And finally, re-expand any of the nodes if required
\r
508 foreach (TreeNode node in treeView_presets.Nodes)
\r
518 private List<Boolean> saveTreeViewState()
\r
520 // Remember each nodes expanded status so we can reload it
\r
521 List<Boolean> nodeStatus = new List<Boolean>();
\r
522 foreach (TreeNode node in treeView_presets.Nodes)
\r
524 nodeStatus.Add(node.IsExpanded);
\r
525 foreach (TreeNode subNode in node.Nodes)
\r
526 nodeStatus.Add(node.IsExpanded);
\r
530 private void loadTreeViewStates(List<Boolean> nodeStatus)
\r
532 // And finally, re-expand any of the nodes if required
\r
534 foreach (TreeNode node in treeView_presets.Nodes)
\r
539 foreach (TreeNode subNode in node.Nodes)
\r
548 private void loadNormalPreset()
\r
550 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
552 foreach (TreeNode node in treenode.Nodes)
\r
554 if (node.Text.Equals("Normal"))
\r
555 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
562 private void btn_source_Click(object sender, EventArgs e)
\r
564 if (Properties.Settings.Default.drive_detection == "Checked")
\r
566 mnu_dvd_drive.Visible = true;
\r
567 Thread driveInfoThread = new Thread(getDriveInfoThread);
\r
568 driveInfoThread.Start();
\r
571 mnu_dvd_drive.Visible = false;
\r
573 private void btn_start_Click(object sender, EventArgs e)
\r
575 if (btn_start.Text == "Stop")
\r
577 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
579 if (result == DialogResult.Yes)
\r
582 encodeQueue.pauseEncodeQueue();
\r
584 // Allow the CLI to exit cleanly
\r
585 Win32.SetForegroundWindow(encodeQueue.encodeProcess.processHandle);
\r
586 SendKeys.Send("^C");
\r
589 setEncodeFinished();
\r
594 if (encodeQueue.count() != 0 || (text_source.Text != string.Empty && text_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))
\r
596 // Set the last action to encode.
\r
597 // This is used for tracking which file to load in the activity window
\r
598 lastAction = "encode";
\r
600 String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.GenerateTheQuery(this);
\r
602 if (encodeQueue.count() == 0)
\r
604 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
605 encodeQueue.write2disk("hb_queue_recovery.xml");
\r
607 queueWindow.setQueue();
\r
608 if (encodeQueue.count() > 1)
\r
609 queueWindow.Show(false);
\r
611 setEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
612 encodeQueue.startEncode(); // Start The Queue Encoding Process
\r
615 else if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
616 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
619 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
622 if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
623 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
626 String query = queryGen.GenerateTheQuery(this);
\r
627 if (rtf_query.Text != "")
\r
628 query = rtf_query.Text;
\r
630 if (encodeQueue.checkDestinationPath(text_destination.Text))
\r
632 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
633 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
634 if (result == DialogResult.Yes)
\r
635 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
639 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
641 encodeQueue.write2disk("hb_queue_recovery.xml"); // Writes the queue to the recovery file, just incase the GUI crashes.
\r
642 queueWindow.Show();
\r
645 private void btn_showQueue_Click(object sender, EventArgs e)
\r
647 queueWindow.Show();
\r
649 private void tb_preview_Click(object sender, EventArgs e)
\r
651 if (text_source.Text == "" || text_source.Text == "Click 'Source' to continue" || text_destination.Text == "")
\r
652 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
655 if (qtpreview == null)
\r
657 qtpreview = new frmPreview(this);
\r
660 else if (qtpreview.IsDisposed)
\r
662 qtpreview = new frmPreview(this);
\r
666 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
669 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
671 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
673 frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);
\r
674 ActivityWindow.Show();
\r
678 #region System Tray Icon
\r
679 private void frmMain_Resize(object sender, EventArgs e)
\r
681 if (FormWindowState.Minimized == this.WindowState)
\r
683 notifyIcon.Visible = true;
\r
684 if (!encodeQueue.isEncoding)
\r
686 notifyIcon.BalloonTipText = lbl_encode.Text != "" ? lbl_encode.Text : "Not Encoding";
\r
687 if (Properties.Settings.Default.trayIconAlerts == "Checked")
\r
688 notifyIcon.ShowBalloonTip(500);
\r
692 else if (FormWindowState.Normal == this.WindowState)
\r
693 notifyIcon.Visible = false;
\r
695 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
697 this.Visible = true;
\r
699 this.WindowState = FormWindowState.Normal;
\r
700 notifyIcon.Visible = false;
\r
702 private void btn_restore_Click(object sender, EventArgs e)
\r
704 this.Visible = true;
\r
706 this.WindowState = FormWindowState.Normal;
\r
707 notifyIcon.Visible = false;
\r
711 #region Tab Control
\r
714 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
716 // Enable the creation of chapter markers.
\r
717 Check_ChapterMarkers.Enabled = true;
\r
719 // Set the last action to scan.
\r
720 // This is used for tracking which file to load in the activity window
\r
721 lastAction = "scan";
\r
722 text_source.Text = "";
\r
724 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
726 String filename = DVD_Open.SelectedPath;
\r
728 if (filename.StartsWith("\\"))
\r
729 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
732 if (filename != "")
\r
734 setupGUIforScan(filename);
\r
735 startScan(filename);
\r
738 text_source.Text = "Click 'Source' to continue";
\r
742 text_source.Text = "Click 'Source' to continue";
\r
744 private void btn_file_source_Click(object sender, EventArgs e)
\r
746 // Set the last action to scan.
\r
747 // This is used for tracking which file to load in the activity window
\r
748 lastAction = "scan";
\r
749 text_source.Text = "";
\r
751 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
753 String filename = ISO_Open.FileName;
\r
754 if (filename.StartsWith("\\"))
\r
756 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
757 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
760 if (filename != "")
\r
762 setupGUIforScan(filename);
\r
763 startScan(filename);
\r
766 text_source.Text = "Click 'Source' to continue";
\r
770 text_source.Text = "Click 'Source' to continue";
\r
772 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
774 // Enable the creation of chapter markers.
\r
775 Check_ChapterMarkers.Enabled = true;
\r
777 // Set the last action to scan.
\r
778 // This is used for tracking which file to load in the activity window
\r
779 lastAction = "scan";
\r
781 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
783 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
784 String filename = path[0];
\r
785 setupGUIforScan(filename);
\r
786 startScan(filename);
\r
789 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
790 if (drp_dvdtitle.Items.Count == 0)
\r
791 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
793 lbl_encode.Text = "";
\r
795 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
797 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
798 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
800 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
802 // Reset some values on the form
\r
803 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
804 //lbl_RecomendedCrop.Text = "Select a Title";
\r
805 drop_chapterStart.Items.Clear();
\r
806 drop_chapterFinish.Items.Clear();
\r
808 // If the dropdown is set to automatic nothing else needs to be done.
\r
809 // Otheriwse if its not, title data has to be loased from parsing.
\r
810 if (drp_dvdtitle.Text != "Automatic")
\r
812 selectedTitle = drp_dvdtitle.SelectedItem as Parsing.Title;
\r
813 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
814 pictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
816 // Populate the Angles dropdown
\r
817 drop_angle.Items.Clear();
\r
818 if (Properties.Settings.Default.dvdnav == "Checked")
\r
820 drop_angle.Visible = true;
\r
821 lbl_angle.Visible = true;
\r
822 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
823 if (drop_angle.Items.Count != 0)
\r
824 drop_angle.SelectedIndex = 0;
\r
828 drop_angle.Visible = false;
\r
829 lbl_angle.Visible = false;
\r
832 // Populate the Start chapter Dropdown
\r
833 drop_chapterStart.Items.Clear();
\r
834 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
835 if (drop_chapterStart.Items.Count > 0)
\r
836 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
838 // Populate the Final Chapter Dropdown
\r
839 drop_chapterFinish.Items.Clear();
\r
840 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
841 if (drop_chapterFinish.Items.Count > 0)
\r
842 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
844 // Populate the Audio Channels Dropdown
\r
845 audioPanel.setTrackList(selectedTitle);
\r
847 // Populate the Subtitles dropdown
\r
848 drp_subtitle.Items.Clear();
\r
849 drp_subtitle.Items.Add("None");
\r
850 drp_subtitle.Items.Add("Autoselect");
\r
851 drp_subtitle.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
852 if (drp_subtitle.Items.Count > 0)
\r
853 drp_subtitle.Text = drp_subtitle.Items[0].ToString();
\r
857 // Run the autoName & chapterNaming functions
\r
858 if (Properties.Settings.Default.autoNaming == "Checked")
\r
860 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
861 if (autoPath != null)
\r
862 text_destination.Text = autoPath;
\r
864 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
867 data_chpt.Rows.Clear();
\r
868 if (selectedTitle.Chapters.Count != 1)
\r
870 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
871 if (chapterGridView != null)
\r
872 data_chpt = chapterGridView;
\r
876 Check_ChapterMarkers.Checked = false;
\r
877 Check_ChapterMarkers.Enabled = false;
\r
880 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
881 data_chpt.Columns[0].Width = 166;
\r
882 data_chpt.Columns[0].Width = 165;
\r
884 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
886 int c_start, c_end;
\r
888 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
889 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
891 int.TryParse(drop_chapterStart.Text, out c_start);
\r
892 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
896 if (c_start > c_end)
\r
897 drop_chapterFinish.Text = c_start.ToString();
\r
900 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
902 // Run the Autonaming function
\r
903 if (Properties.Settings.Default.autoNaming == "Checked")
\r
904 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
906 // Disable chapter markers if only 1 chapter is selected.
\r
907 if (c_start == c_end)
\r
909 Check_ChapterMarkers.Checked = false;
\r
910 Check_ChapterMarkers.Enabled = false;
\r
913 Check_ChapterMarkers.Enabled = true;
\r
915 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
917 int c_start, c_end;
\r
919 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
920 drop_chapterStart.SelectedIndex = 1;
\r
922 int.TryParse(drop_chapterStart.Text, out c_start);
\r
923 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
927 if (c_end < c_start)
\r
928 drop_chapterFinish.Text = c_start.ToString();
\r
931 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
933 // Run the Autonaming function
\r
934 if (Properties.Settings.Default.autoNaming == "Checked")
\r
935 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
937 // Add more rows to the Chapter menu if needed.
\r
938 if (Check_ChapterMarkers.Checked)
\r
940 int i = data_chpt.Rows.Count, finish = 0;
\r
942 if (drop_chapterFinish.Text != "Auto")
\r
943 int.TryParse(drop_chapterFinish.Text, out finish);
\r
947 int n = data_chpt.Rows.Add();
\r
948 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
949 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
950 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
951 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
956 // Disable chapter markers if only 1 chapter is selected.
\r
957 if (c_start == c_end)
\r
959 Check_ChapterMarkers.Checked = false;
\r
960 Check_ChapterMarkers.Enabled = false;
\r
963 Check_ChapterMarkers.Enabled = true;
\r
967 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
969 // This removes the file extension from the filename box on the save file dialog.
\r
970 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
971 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
973 if (Path.IsPathRooted(text_destination.Text))
\r
974 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
976 // Show the dialog and set the main form file path
\r
977 if (drop_format.SelectedIndex.Equals(0))
\r
978 DVD_Save.FilterIndex = 1;
\r
979 else if (drop_format.SelectedIndex.Equals(1))
\r
980 DVD_Save.FilterIndex = 2;
\r
981 else if (drop_format.SelectedIndex.Equals(2))
\r
982 DVD_Save.FilterIndex = 3;
\r
984 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
986 if (DVD_Save.FileName.StartsWith("\\"))
\r
987 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
990 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
991 switch (DVD_Save.FilterIndex)
\r
994 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
995 DVD_Save.FileName += ".mp4";
\r
998 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
999 DVD_Save.FileName += ".m4v";
\r
1002 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
1003 DVD_Save.FileName += ".mkv";
\r
1009 text_destination.Text = DVD_Save.FileName;
\r
1011 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
1012 if (Check_ChapterMarkers.Checked)
\r
1013 drop_format.SelectedIndex = 1;
\r
1017 private void text_destination_TextChanged(object sender, EventArgs e)
\r
1019 string path = text_destination.Text;
\r
1020 if (path.EndsWith(".mp4"))
\r
1021 drop_format.SelectedIndex = 0;
\r
1022 else if (path.EndsWith(".m4v"))
\r
1023 drop_format.SelectedIndex = 1;
\r
1024 else if (path.EndsWith(".mkv"))
\r
1025 drop_format.SelectedIndex = 2;
\r
1028 // Output Settings
\r
1029 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
1031 if (drop_format.SelectedIndex == 0)
\r
1032 setExtension(".mp4");
\r
1033 else if (drop_format.SelectedIndex == 1)
\r
1034 setExtension(".m4v");
\r
1035 else if (drop_format.SelectedIndex == 2)
\r
1036 setExtension(".mkv");
\r
1038 audioPanel.setAudioByContainer(drop_format.Text);
\r
1041 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1043 oldval = drp_videoEncoder.Text;
\r
1044 drp_videoEncoder.Items.Clear();
\r
1045 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1046 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1047 if (oldval == "VP3 (Theora)")
\r
1048 drp_videoEncoder.SelectedIndex = 1;
\r
1050 drp_videoEncoder.Text = oldval;
\r
1052 else if (drop_format.Text.Contains("MKV"))
\r
1054 oldval = drp_videoEncoder.Text;
\r
1055 drp_videoEncoder.Items.Clear();
\r
1056 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1057 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1058 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1059 drp_videoEncoder.Text = oldval;
\r
1062 private void setExtension(string newExtension)
\r
1064 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1065 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1066 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1070 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1072 setContainerOpts();
\r
1074 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1075 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1077 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1078 check_turbo.Enabled = true;
\r
1080 tab_advanced.Enabled = true;
\r
1081 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1082 check_iPodAtom.Enabled = true;
\r
1084 check_iPodAtom.Enabled = false;
\r
1088 check_turbo.CheckState = CheckState.Unchecked;
\r
1089 check_turbo.Enabled = false;
\r
1090 tab_advanced.Enabled = false;
\r
1091 x264Panel.x264Query = "";
\r
1092 check_iPodAtom.Enabled = false;
\r
1093 check_iPodAtom.Checked = false;
\r
1096 // Setup the CQ Slider
\r
1097 switch (drp_videoEncoder.Text)
\r
1099 case "MPEG-4 (FFmpeg)":
\r
1100 slider_videoQuality.Minimum = 1;
\r
1101 slider_videoQuality.Maximum = 31;
\r
1102 slider_videoQuality.Value = 1;
\r
1103 SliderValue.Text = "0% QP: 31.00";
\r
1105 case "H.264 (x264)":
\r
1106 slider_videoQuality.Minimum = 0;
\r
1107 slider_videoQuality.Value = 0;
\r
1108 slider_videoQuality.TickFrequency = 1;
\r
1109 SliderValue.Text = "0% RF: 51.00";
\r
1110 String step = Properties.Settings.Default.x264cqstep;
\r
1114 slider_videoQuality.Maximum = 255;
\r
1117 slider_videoQuality.Maximum = 204;
\r
1120 slider_videoQuality.Maximum = 155;
\r
1123 slider_videoQuality.Maximum = 102;
\r
1126 slider_videoQuality.Maximum = 51;
\r
1129 slider_videoQuality.Maximum = 51;
\r
1133 case "VP3 (Theora)":
\r
1134 slider_videoQuality.Minimum = 0;
\r
1135 slider_videoQuality.Maximum = 63;
\r
1136 slider_videoQuality.Value = 0;
\r
1137 SliderValue.Text = "0% QP: 0.00";
\r
1142 /// Set the container format options
\r
1144 public void setContainerOpts()
\r
1146 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1148 check_largeFile.Enabled = true;
\r
1149 check_optimiseMP4.Enabled = true;
\r
1150 check_iPodAtom.Enabled = true;
\r
1154 check_largeFile.Enabled = false;
\r
1155 check_optimiseMP4.Enabled = false;
\r
1156 check_iPodAtom.Enabled = false;
\r
1157 check_largeFile.Checked = false;
\r
1158 check_optimiseMP4.Checked = false;
\r
1159 check_iPodAtom.Checked = false;
\r
1162 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1164 switch (drp_videoEncoder.Text)
\r
1166 case "MPEG-4 (FFmpeg)":
\r
1167 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1168 double max = slider_videoQuality.Maximum;
\r
1169 double min = slider_videoQuality.Minimum;
\r
1170 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1171 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1173 case "H.264 (x264)":
\r
1175 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
\r
1176 double.TryParse(Properties.Settings.Default.x264cqstep,
\r
1177 System.Globalization.NumberStyles.Number,
\r
1180 rfValue = 51.0 - slider_videoQuality.Value * divided;
\r
1181 max = slider_videoQuality.Maximum * divided;
\r
1182 min = slider_videoQuality.Minimum;
\r
1183 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1184 rfValue = Math.Round(rfValue, 2);
\r
1185 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1187 case "VP3 (Theora)":
\r
1188 rfValue = slider_videoQuality.Value;
\r
1189 double value = rfValue / 63;
\r
1190 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1194 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1196 text_bitrate.Enabled = false;
\r
1197 text_filesize.Enabled = true;
\r
1198 slider_videoQuality.Enabled = false;
\r
1200 check_2PassEncode.Enabled = true;
\r
1202 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1204 text_bitrate.Enabled = true;
\r
1205 text_filesize.Enabled = false;
\r
1206 slider_videoQuality.Enabled = false;
\r
1208 check_2PassEncode.Enabled = true;
\r
1210 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1212 text_bitrate.Enabled = false;
\r
1213 text_filesize.Enabled = false;
\r
1214 slider_videoQuality.Enabled = true;
\r
1216 check_2PassEncode.Enabled = false;
\r
1217 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1219 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1221 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1223 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1224 check_turbo.Enabled = true;
\r
1228 check_turbo.Enabled = false;
\r
1229 check_turbo.CheckState = CheckState.Unchecked;
\r
1234 private void ctl_decomb_changed(object sender, EventArgs e)
\r
1236 if (ctl_decomb.getDropValue != "Off")
\r
1237 if (ctl_deinterlace.getDropValue != "None")
\r
1238 ctl_deinterlace.setOption("None");
\r
1240 private void ctl_deinterlace_changed(object sender, EventArgs e)
\r
1242 if (ctl_detelecine.getDropValue != "None")
\r
1243 if (ctl_decomb.getDropValue != "Off")
\r
1244 ctl_decomb.setOption("Off");
\r
1246 private void slider_deblock_Scroll(object sender, EventArgs e)
\r
1248 lbl_deblockVal.Text = slider_deblock.Value == 4 ? "Off" : slider_deblock.Value.ToString();
\r
1252 private void drp_subtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1254 if (drp_subtitle.Text.Contains("None"))
\r
1256 check_forced.Enabled = false;
\r
1257 check_forced.Checked = false;
\r
1260 check_forced.Enabled = true;
\r
1263 // Chapter Marker Tab
\r
1264 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1266 if (Check_ChapterMarkers.Checked)
\r
1268 drop_format.SelectedIndex = 1;
\r
1269 data_chpt.Rows.Clear();
\r
1270 data_chpt.Enabled = true;
\r
1271 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1272 if (chapterGridView != null)
\r
1273 data_chpt = chapterGridView;
\r
1277 drop_format.SelectedIndex = 0;
\r
1278 data_chpt.Rows.Clear();
\r
1279 data_chpt.Enabled = false;
\r
1283 // Query Editor Tab
\r
1284 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1286 rtf_query.Text = queryGen.GenerateTheQuery(this);
\r
1288 private void btn_clear_Click(object sender, EventArgs e)
\r
1290 rtf_query.Clear();
\r
1294 // MainWindow Components, Actions and Functions ***********************
\r
1296 #region Source Scan
\r
1297 public Boolean isScanning { get; set; }
\r
1298 private static int scanProcessID { get; set; }
\r
1299 private void setupGUIforScan(String filename)
\r
1301 text_source.Text = filename;
\r
1303 foreach (Control ctrl in Controls)
\r
1305 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1306 ctrl.Enabled = false;
\r
1308 lbl_encode.Visible = true;
\r
1309 lbl_encode.Text = "Scanning ...";
\r
1310 gb_source.Text = "Source: Scanning ...";
\r
1311 btn_source.Enabled = false;
\r
1312 btn_start.Enabled = false;
\r
1313 btn_showQueue.Enabled = false;
\r
1314 btn_add2Queue.Enabled = false;
\r
1315 tb_preview.Enabled = false;
\r
1316 mnu_killCLI.Visible = true;
\r
1318 private void startScan(String filename)
\r
1322 lbl_encode.Visible = true;
\r
1323 lbl_encode.Text = "Scanning...";
\r
1324 isScanning = true;
\r
1325 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1327 catch (Exception exc)
\r
1329 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1332 private void scanProcess(object state)
\r
1336 string inputFile = (string)state;
\r
1337 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1338 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1339 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1341 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1342 if (File.Exists(dvdInfoPath))
\r
1343 File.Delete(dvdInfoPath);
\r
1345 String dvdnav = string.Empty;
\r
1346 if (Properties.Settings.Default.dvdnav == "Checked")
\r
1347 dvdnav = " --dvdnav";
\r
1348 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1350 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1352 Boolean cleanExit = true;
\r
1353 using (hbproc = Process.Start(hbParseDvd))
\r
1355 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1356 scanProcessID = Main.getCliProcess(before);
\r
1357 hbproc.WaitForExit();
\r
1358 if (hbproc.ExitCode != 0)
\r
1359 cleanExit = false;
\r
1362 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1364 if (!File.Exists(dvdInfoPath))
\r
1366 throw new Exception(
\r
1367 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1371 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1373 thisDVD = DVD.Parse(sr);
\r
1378 updateUIafterScan();
\r
1381 catch (Exception exc)
\r
1383 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1387 private void updateUIafterScan()
\r
1391 if (InvokeRequired)
\r
1393 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1397 // Setup some GUI components
\r
1398 drp_dvdtitle.Items.Clear();
\r
1399 if (thisDVD.Titles.Count != 0)
\r
1400 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1401 drp_dvdtitle.Text = "Automatic";
\r
1402 drop_chapterFinish.Text = "Auto";
\r
1403 drop_chapterStart.Text = "Auto";
\r
1405 // Now select the longest title
\r
1406 if (thisDVD.Titles.Count != 0)
\r
1407 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1409 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1410 if (text_source.Text.ToLower().Contains(".iso") || text_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1411 Check_ChapterMarkers.Enabled = true;
\r
1414 Check_ChapterMarkers.Enabled = false;
\r
1415 Check_ChapterMarkers.Checked = false;
\r
1416 data_chpt.Rows.Clear();
\r
1419 // If no titles were found, Display an error message
\r
1420 if (drp_dvdtitle.Items.Count == 0)
\r
1421 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
1423 // Enable the GUI components and enable any disabled components
\r
1426 catch (Exception exc)
\r
1428 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1432 private void enableGUI()
\r
1436 if (InvokeRequired)
\r
1437 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1438 lbl_encode.Text = "Scan Completed";
\r
1439 gb_source.Text = "Source";
\r
1440 foreach (Control ctrl in Controls)
\r
1441 ctrl.Enabled = true;
\r
1442 btn_start.Enabled = true;
\r
1443 btn_showQueue.Enabled = true;
\r
1444 btn_add2Queue.Enabled = true;
\r
1445 tb_preview.Enabled = true;
\r
1446 btn_source.Enabled = true;
\r
1447 mnu_killCLI.Visible = false;
\r
1449 catch (Exception exc)
\r
1451 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1454 private void killScan()
\r
1461 Process[] prs = Process.GetProcesses();
\r
1462 foreach (Process process in prs)
\r
1464 if (process.Id == scanProcessID)
\r
1466 process.Refresh();
\r
1467 if (!process.HasExited)
\r
1472 catch (Exception ex)
\r
1474 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
1477 private void resetGUI()
\r
1479 drp_dvdtitle.Items.Clear();
\r
1480 drp_dvdtitle.Text = "Automatic";
\r
1481 drop_chapterStart.Items.Clear();
\r
1482 drop_chapterStart.Text = "Auto";
\r
1483 drop_chapterFinish.Items.Clear();
\r
1484 drop_chapterFinish.Text = "Auto";
\r
1485 lbl_duration.Text = "Select a Title";
\r
1486 pictureSettings.lbl_src_res.Text = "Select a Title";
\r
1487 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1488 text_source.Text = "Click 'Source' to continue";
\r
1489 text_destination.Text = "";
\r
1491 selectedTitle = null;
\r
1492 isScanning = false;
\r
1498 /// Set the GUI to it's finished encoding state.
\r
1500 private void setEncodeFinished()
\r
1504 if (InvokeRequired)
\r
1506 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1510 lbl_encode.Text = "Encoding Finished";
\r
1511 btn_start.Text = "Start";
\r
1512 btn_start.ToolTipText = "Start the encoding process";
\r
1513 btn_start.Image = Properties.Resources.Play;
\r
1515 // If the window is minimized, display the notification in a popup.
\r
1516 if (FormWindowState.Minimized == this.WindowState)
\r
1518 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1519 notifyIcon.ShowBalloonTip(500);
\r
1522 catch (Exception exc)
\r
1524 MessageBox.Show(exc.ToString());
\r
1529 /// Set the GUI to it's started encoding state.
\r
1531 private void setEncodeStarted()
\r
1535 if (InvokeRequired)
\r
1537 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1541 lbl_encode.Visible = true;
\r
1542 lbl_encode.Text = "Encoding in Progress";
\r
1543 btn_start.Text = "Stop";
\r
1544 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
1545 btn_start.Image = Properties.Resources.stop;
\r
1547 catch (Exception exc)
\r
1549 MessageBox.Show(exc.ToString());
\r
1554 #region DVD Drive Detection
\r
1555 private delegate void ProgressUpdateHandler();
\r
1556 private void getDriveInfoThread()
\r
1560 if (InvokeRequired)
\r
1562 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1566 Boolean foundDrive = false;
\r
1567 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1568 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1570 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1572 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1574 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1575 foundDrive = true;
\r
1581 if (foundDrive == false)
\r
1582 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1586 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1591 #region Public Methods
\r
1593 /// Access the preset Handler and setup the preset panel.
\r
1595 public void loadPresetPanel()
\r
1597 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1598 if (Properties.Settings.Default.presetNotification == "Unchecked")
\r
1600 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1601 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1603 presetHandler.getPresetPanel(ref treeView_presets);
\r
1604 treeView_presets.Update();
\r
1608 /// Either Encode or Scan was last performed.
\r
1610 public string lastAction { get; set; }
\r
1615 /// If the queue is being processed, prompt the user to confirm application close.
\r
1617 /// <param name="e"></param>
\r
1618 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1620 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1621 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1623 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
1624 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1625 if (result == DialogResult.No)
\r
1628 base.OnFormClosing(e);
\r
1632 #region In-GUI Encode Status (Experimental)
\r
1633 private Process HBProcess { get; set; }
\r
1635 private void encodeMonitorThread()
\r
1639 Parser encode = new Parser(HBProcess.StandardOutput.BaseStream);
\r
1640 encode.OnEncodeProgress += encode_OnEncodeProgress;
\r
1641 while (!encode.EndOfStream)
\r
1643 encode.readEncodeStatus();
\r
1646 catch (Exception exc)
\r
1648 MessageBox.Show(exc.ToString());
\r
1652 private void encode_OnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1654 if (this.InvokeRequired)
\r
1656 this.BeginInvoke(new EncodeProgressEventHandler(encode_OnEncodeProgress),
\r
1657 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1660 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1664 // This is the END of the road ****************************************
\r