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 private Title selectedTitle;
\r
30 private DVD thisDVD;
\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 DateTime now = DateTime.Now;
\r
66 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;
\r
67 TimeSpan elapsed = now.Subtract(lastCheck);
\r
68 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)
\r
70 lblStatus.Text = "Checking for updates ...";
\r
71 Application.DoEvents();
\r
73 Thread updateCheckThread = new Thread(startupUpdateCheck);
\r
74 updateCheckThread.Start();
\r
78 // Setup the GUI components
\r
79 lblStatus.Text = "Setting up the GUI ...";
\r
80 Application.DoEvents();
\r
81 loadPresetPanel(); // Load the Preset Panel
\r
82 treeView_presets.ExpandAll();
\r
83 lbl_encode.Text = "";
\r
84 queueWindow = new frmQueue(encodeQueue); // Prepare the Queue
\r
85 if (Properties.Settings.Default.QueryEditorTab != "Checked")
\r
86 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.
\r
88 // Load the user's default settings or Normal Preset
\r
89 if (Properties.Settings.Default.defaultSettings == "Checked" && Properties.Settings.Default.defaultPreset != "")
\r
91 if (presetHandler.getPreset(Properties.Settings.Default.defaultPreset) != null)
\r
93 string query = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).Query;
\r
94 Boolean loadPictureSettings = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).PictureSettings;
\r
98 //Ok, Reset all the H264 widgets before changing the preset
\r
99 x264Panel.reset2Defaults();
\r
101 // Send the query from the file to the Query Parser class, then load the preset
\r
102 QueryParser presetQuery = QueryParser.Parse(query);
\r
103 PresetLoader.presetLoader(this, presetQuery, Properties.Settings.Default.defaultPreset, loadPictureSettings);
\r
105 // The x264 widgets will need updated, so do this now:
\r
106 x264Panel.X264_StandardizeOptString();
\r
107 x264Panel.X264_SetCurrentSettingsInPanel();
\r
111 loadNormalPreset();
\r
114 loadNormalPreset();
\r
116 // Enabled GUI tooltip's if Required
\r
117 if (Properties.Settings.Default.tooltipEnable == "Checked")
\r
118 ToolTip.Active = true;
\r
121 lblStatus.Text = "Loading Complete!";
\r
122 Application.DoEvents();
\r
125 this.Enabled = true;
\r
127 // Event Handlers and Queue Recovery
\r
132 // Startup Functions
\r
133 private void startupUpdateCheck()
\r
137 if (InvokeRequired)
\r
139 BeginInvoke(new UpdateStatusChanger(startupUpdateCheck));
\r
143 Boolean update = Main.updateCheck(false);
\r
146 frmUpdater updateWindow = new frmUpdater();
\r
147 updateWindow.Show();
\r
150 catch (Exception exc)
\r
152 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
155 private void queueRecovery()
\r
157 if (Main.check_queue_recovery())
\r
159 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
161 if (result == DialogResult.Yes)
\r
162 encodeQueue.recoverQueue("hb_queue_recovery.xml"); // Start Recovery
\r
165 // Remove the Queue recovery file if the user doesn't want to recovery the last queue.
\r
166 string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
\r
167 if (File.Exists(queuePath))
\r
168 File.Delete(queuePath);
\r
175 // Encoding Events for setting up the GUI
\r
176 private void events()
\r
178 // Handle Window Resize
\r
179 if (Properties.Settings.Default.MainWindowMinimize == "Checked")
\r
180 this.Resize += new EventHandler(frmMain_Resize);
\r
182 // Handle Encode Start / Finish / Pause
\r
183 encodeQueue.OnEncodeEnded += new EventHandler(encodeEnded);
\r
184 encodeQueue.OnPaused += new EventHandler(encodePaused);
\r
185 encodeQueue.OnEncodeStart += new EventHandler(encodeStarted);
\r
187 // Handle a file being draged onto the GUI.
\r
188 this.DragEnter += new DragEventHandler(frmMain_DragEnter);
\r
189 this.DragDrop += new DragEventHandler(frmMain_DragDrop);
\r
192 private static void frmMain_DragEnter(object sender, DragEventArgs e)
\r
194 if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
\r
195 e.Effect = DragDropEffects.All;
\r
197 private void frmMain_DragDrop(object sender, DragEventArgs e)
\r
199 string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
\r
200 if (fileList != null)
\r
202 if (fileList[0].StartsWith("\\"))
\r
203 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
206 if (fileList[0] != "")
\r
208 setupGUIforScan(fileList[0]);
\r
209 startScan(fileList[0]);
\r
212 text_source.Text = "Click 'Source' to continue";
\r
216 private void encodeStarted(object sender, EventArgs e)
\r
218 lastAction = "encode";
\r
219 setEncodeStarted();
\r
221 // Experimental HBProc Process Monitoring.
\r
222 if (Properties.Settings.Default.enocdeStatusInGui == "Checked")
\r
224 Thread encodeMon = new Thread(encodeMonitorThread);
\r
228 private void encodeEnded(object sender, EventArgs e)
\r
230 setEncodeFinished();
\r
232 private void encodePaused(object sender, EventArgs e)
\r
234 setEncodeFinished();
\r
238 // User Interface Menus / Tool Strips *********************************
\r
241 private void mnu_killCLI_Click(object sender, EventArgs e)
\r
245 private void mnu_exit_Click(object sender, EventArgs e)
\r
247 Application.Exit();
\r
252 private void mnu_encode_Click(object sender, EventArgs e)
\r
254 queueWindow.Show();
\r
256 private void mnu_encodeLog_Click(object sender, EventArgs e)
\r
258 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
260 frmActivityWindow dvdInfoWindow = new frmActivityWindow(file, encodeQueue, this);
\r
261 dvdInfoWindow.Show();
\r
263 private void mnu_options_Click(object sender, EventArgs e)
\r
265 Form Options = new frmOptions();
\r
266 Options.ShowDialog();
\r
270 #region Presets Menu
\r
271 private void mnu_presetReset_Click(object sender, EventArgs e)
\r
273 presetHandler.updateBuiltInPresets();
\r
275 if (treeView_presets.Nodes.Count == 0)
\r
276 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
278 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
280 treeView_presets.ExpandAll();
\r
282 private void mnu_delete_preset_Click(object sender, EventArgs e)
\r
284 // Empty the preset file
\r
285 string presetsFile = Application.StartupPath + "\\presets.xml";
\r
286 if (File.Exists(presetsFile))
\r
287 File.Delete(presetsFile);
\r
291 FileStream strm = new FileStream(presetsFile, FileMode.Create, FileAccess.Write);
\r
295 catch (Exception exc)
\r
297 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
300 // Reload the preset panel
\r
303 private void mnu_SelectDefault_Click(object sender, EventArgs e)
\r
305 loadNormalPreset();
\r
307 private void btn_new_preset_Click(object sender, EventArgs e)
\r
309 Form preset = new frmAddPreset(this, queryGen.generateTheQuery(this), presetHandler);
\r
310 preset.ShowDialog();
\r
315 private void mnu_handbrake_forums_Click(object sender, EventArgs e)
\r
317 Process.Start("http://forum.handbrake.fr/");
\r
319 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
321 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
323 private void mnu_handbrake_home_Click(object sender, EventArgs e)
\r
325 Process.Start("http://handbrake.fr");
\r
327 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
329 Boolean update = Main.updateCheck(true);
\r
332 frmUpdater updateWindow = new frmUpdater();
\r
333 updateWindow.Show();
\r
336 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
338 private void mnu_about_Click(object sender, EventArgs e)
\r
340 Form About = new frmAbout();
\r
341 About.ShowDialog();
\r
346 // Right Click Menu Code
\r
347 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
349 treeView_presets.ExpandAll();
\r
351 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
353 treeView_presets.CollapseAll();
\r
355 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
357 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
358 if (result == DialogResult.Yes)
\r
359 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), true);
\r
360 else if (result == DialogResult.No)
\r
361 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), false);
\r
363 private void pmnu_delete_click(object sender, EventArgs e)
\r
365 if (treeView_presets.SelectedNode != null)
\r
367 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
368 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
370 treeView_presets.Select();
\r
372 private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
\r
374 // Make sure that the save menu is always disabled by default
\r
375 pmnu_saveChanges.Enabled = false;
\r
377 // Now enable the save menu if the selected preset is a user preset
\r
378 if (treeView_presets.SelectedNode != null)
\r
379 if (presetHandler.checkIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
380 pmnu_saveChanges.Enabled = true;
\r
382 treeView_presets.Select();
\r
385 // Presets Management
\r
386 private void btn_addPreset_Click(object sender, EventArgs e)
\r
388 Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);
\r
389 preset.ShowDialog();
\r
391 private void btn_removePreset_Click(object sender, EventArgs e)
\r
393 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
394 if (result == DialogResult.Yes)
\r
396 if (treeView_presets.SelectedNode != null)
\r
398 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
399 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
402 treeView_presets.Select();
\r
404 private void btn_setDefault_Click(object sender, EventArgs e)
\r
406 if (treeView_presets.SelectedNode != null)
\r
408 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
409 if (result == DialogResult.Yes)
\r
411 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
412 Properties.Settings.Default.Save();
\r
413 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
417 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
419 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
421 if (e.Button == MouseButtons.Right)
\r
422 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
423 else if (e.Button == MouseButtons.Left)
\r
425 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
427 if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
432 treeView_presets.Select();
\r
434 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
438 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
440 if (e.KeyCode == Keys.Delete)
\r
442 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
443 if (result == DialogResult.Yes)
\r
445 if (treeView_presets.SelectedNode != null)
\r
446 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
448 // Remember each nodes expanded status so we can reload it
\r
449 List<Boolean> nodeStatus = new List<Boolean>();
\r
450 foreach (TreeNode node in treeView_presets.Nodes)
\r
451 nodeStatus.Add(node.IsExpanded);
\r
453 // Now reload the preset panel
\r
456 // And finally, re-expand any of the nodes if required
\r
458 foreach (TreeNode node in treeView_presets.Nodes)
\r
468 private void selectPreset()
\r
470 if (treeView_presets.SelectedNode != null)
\r
472 // Ok, so, we've selected a preset. Now we want to load it.
\r
473 string presetName = treeView_presets.SelectedNode.Text;
\r
474 if (presetHandler.getPreset(presetName) != null)
\r
476 string query = presetHandler.getPreset(presetName).Query;
\r
477 Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;
\r
481 //Ok, Reset all the H264 widgets before changing the preset
\r
482 x264Panel.reset2Defaults();
\r
484 // Send the query from the file to the Query Parser class
\r
485 QueryParser presetQuery = QueryParser.Parse(query);
\r
487 // Now load the preset
\r
488 PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);
\r
490 // The x264 widgets will need updated, so do this now:
\r
491 x264Panel.X264_StandardizeOptString();
\r
492 x264Panel.X264_SetCurrentSettingsInPanel();
\r
497 private void loadNormalPreset()
\r
499 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
501 foreach (TreeNode node in treenode.Nodes)
\r
503 if (node.Text.Equals("Normal"))
\r
504 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
511 private void btn_source_Click(object sender, EventArgs e)
\r
513 if (Properties.Settings.Default.drive_detection == "Checked")
\r
515 mnu_dvd_drive.Visible = true;
\r
516 Thread driveInfoThread = new Thread(getDriveInfoThread);
\r
517 driveInfoThread.Start();
\r
520 mnu_dvd_drive.Visible = false;
\r
522 private void btn_start_Click(object sender, EventArgs e)
\r
524 if (btn_start.Text == "Stop")
\r
526 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
528 if (result == DialogResult.Yes)
\r
531 encodeQueue.pauseEncodeQueue();
\r
533 // Allow the CLI to exit cleanly
\r
534 Win32.SetForegroundWindow((int)encodeQueue.encodeHandler.processHandle);
\r
535 SendKeys.Send("^C");
\r
538 setEncodeFinished();
\r
543 if (encodeQueue.count() != 0 || (text_source.Text != string.Empty && text_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))
\r
545 String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.generateTheQuery(this);
\r
547 DialogResult overwrite = DialogResult.Yes;
\r
548 if (text_destination.Text != "")
\r
549 if (File.Exists(text_destination.Text))
\r
550 overwrite = MessageBox.Show("The destination file already exists. Are you sure you want to overwrite it?", "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
552 if (overwrite == DialogResult.Yes)
\r
554 if (encodeQueue.count() == 0)
\r
555 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
557 queueWindow.setQueue();
\r
558 if (encodeQueue.count() > 1)
\r
559 queueWindow.Show(false);
\r
561 setEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
562 encodeQueue.startEncode(); // Start The Queue Encoding Process
\r
563 lastAction = "encode"; // Set the last action to encode - Used for activity window.
\r
567 else if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
568 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
571 private void btn_add2Queue_Click(object sender, EventArgs e)
\r
574 if (text_source.Text == string.Empty || text_source.Text == "Click 'Source' to continue" || text_destination.Text == string.Empty)
\r
575 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
578 String query = queryGen.generateTheQuery(this);
\r
579 if (rtf_query.Text != "")
\r
580 query = rtf_query.Text;
\r
582 if (encodeQueue.checkDestinationPath(text_destination.Text))
\r
584 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
585 "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
\r
586 if (result == DialogResult.Yes)
\r
587 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
591 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
593 queueWindow.Show();
\r
596 private void btn_showQueue_Click(object sender, EventArgs e)
\r
598 queueWindow.Show();
\r
600 private void tb_preview_Click(object sender, EventArgs e)
\r
602 if (text_source.Text == "" || text_source.Text == "Click 'Source' to continue" || text_destination.Text == "")
\r
603 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
606 if (qtpreview == null)
\r
608 qtpreview = new frmPreview(this);
\r
611 else if (qtpreview.IsDisposed)
\r
613 qtpreview = new frmPreview(this);
\r
617 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
620 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
622 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
624 frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);
\r
625 ActivityWindow.Show();
\r
629 #region System Tray Icon
\r
630 private void frmMain_Resize(object sender, EventArgs e)
\r
632 if (FormWindowState.Minimized == this.WindowState)
\r
634 notifyIcon.Visible = true;
\r
635 if (!encodeQueue.isEncoding)
\r
637 notifyIcon.BalloonTipText = lbl_encode.Text != "" ? lbl_encode.Text : "Not Encoding";
\r
638 if (Properties.Settings.Default.trayIconAlerts == "Checked")
\r
639 notifyIcon.ShowBalloonTip(500);
\r
643 else if (FormWindowState.Normal == this.WindowState)
\r
644 notifyIcon.Visible = false;
\r
646 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
648 this.Visible = true;
\r
650 this.WindowState = FormWindowState.Normal;
\r
651 notifyIcon.Visible = false;
\r
653 private void btn_restore_Click(object sender, EventArgs e)
\r
655 this.Visible = true;
\r
657 this.WindowState = FormWindowState.Normal;
\r
658 notifyIcon.Visible = false;
\r
662 #region Tab Control
\r
665 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
667 // Enable the creation of chapter markers.
\r
668 Check_ChapterMarkers.Enabled = true;
\r
670 // Set the last action to scan.
\r
671 // This is used for tracking which file to load in the activity window
\r
672 lastAction = "scan";
\r
673 text_source.Text = "";
\r
675 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
677 String filename = DVD_Open.SelectedPath;
\r
679 if (filename.StartsWith("\\"))
\r
680 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
683 if (filename != "")
\r
685 setupGUIforScan(filename);
\r
686 startScan(filename);
\r
689 text_source.Text = "Click 'Source' to continue";
\r
693 text_source.Text = "Click 'Source' to continue";
\r
695 private void btn_file_source_Click(object sender, EventArgs e)
\r
697 // Set the last action to scan.
\r
698 // This is used for tracking which file to load in the activity window
\r
699 lastAction = "scan";
\r
700 text_source.Text = "";
\r
702 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
704 String filename = ISO_Open.FileName;
\r
705 if (filename.StartsWith("\\"))
\r
707 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
708 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
711 if (filename != "")
\r
713 setupGUIforScan(filename);
\r
714 startScan(filename);
\r
717 text_source.Text = "Click 'Source' to continue";
\r
721 text_source.Text = "Click 'Source' to continue";
\r
723 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
725 // Enable the creation of chapter markers.
\r
726 Check_ChapterMarkers.Enabled = true;
\r
728 // Set the last action to scan.
\r
729 // This is used for tracking which file to load in the activity window
\r
730 lastAction = "scan";
\r
732 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
734 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
735 String filename = path[0];
\r
736 setupGUIforScan(filename);
\r
737 startScan(filename);
\r
740 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
741 if (drp_dvdtitle.Items.Count == 0)
\r
742 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
744 lbl_encode.Text = "";
\r
746 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
748 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
749 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
751 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
753 // Reset some values on the form
\r
754 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
755 //lbl_RecomendedCrop.Text = "Select a Title";
\r
756 drop_chapterStart.Items.Clear();
\r
757 drop_chapterFinish.Items.Clear();
\r
759 // If the dropdown is set to automatic nothing else needs to be done.
\r
760 // Otheriwse if its not, title data has to be loased from parsing.
\r
761 if (drp_dvdtitle.Text != "Automatic")
\r
763 selectedTitle = drp_dvdtitle.SelectedItem as Parsing.Title;
\r
764 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
765 pictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
767 // Populate the Angles dropdown
\r
768 drop_angle.Items.Clear();
\r
769 if (Properties.Settings.Default.dvdnav == "Checked")
\r
771 drop_angle.Visible = true;
\r
772 lbl_angle.Visible = true;
\r
773 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
774 if (drop_angle.Items.Count != 0)
\r
775 drop_angle.SelectedIndex = 0;
\r
779 drop_angle.Visible = false;
\r
780 lbl_angle.Visible = false;
\r
783 // Populate the Start chapter Dropdown
\r
784 drop_chapterStart.Items.Clear();
\r
785 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
786 if (drop_chapterStart.Items.Count > 0)
\r
787 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
789 // Populate the Final Chapter Dropdown
\r
790 drop_chapterFinish.Items.Clear();
\r
791 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
792 if (drop_chapterFinish.Items.Count > 0)
\r
793 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
795 // Populate the Audio Channels Dropdown
\r
796 audioPanel.setTrackList(selectedTitle);
\r
798 // Populate the Subtitles dropdown
\r
799 Subtitles.drp_subtitleTracks.Items.Clear();
\r
800 Subtitles.drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
801 Subtitles.drp_subtitleTracks.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
802 Subtitles.drp_subtitleTracks.SelectedIndex = 0;
\r
805 // Run the autoName & chapterNaming functions
\r
806 if (Properties.Settings.Default.autoNaming == "Checked")
\r
808 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
809 if (autoPath != null)
\r
810 text_destination.Text = autoPath;
\r
812 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
815 data_chpt.Rows.Clear();
\r
816 if (selectedTitle.Chapters.Count != 1)
\r
818 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
819 if (chapterGridView != null)
\r
820 data_chpt = chapterGridView;
\r
824 Check_ChapterMarkers.Checked = false;
\r
825 Check_ChapterMarkers.Enabled = false;
\r
828 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
829 data_chpt.Columns[0].Width = 166;
\r
830 data_chpt.Columns[0].Width = 165;
\r
832 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
834 int c_start, c_end;
\r
836 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
837 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
839 int.TryParse(drop_chapterStart.Text, out c_start);
\r
840 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
844 if (c_start > c_end)
\r
845 drop_chapterFinish.Text = c_start.ToString();
\r
848 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
850 // Run the Autonaming function
\r
851 if (Properties.Settings.Default.autoNaming == "Checked")
\r
852 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
854 // Disable chapter markers if only 1 chapter is selected.
\r
855 if (c_start == c_end)
\r
857 Check_ChapterMarkers.Checked = false;
\r
858 Check_ChapterMarkers.Enabled = false;
\r
861 Check_ChapterMarkers.Enabled = true;
\r
863 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
865 int c_start, c_end;
\r
867 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
868 drop_chapterStart.SelectedIndex = 1;
\r
870 int.TryParse(drop_chapterStart.Text, out c_start);
\r
871 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
875 if (c_end < c_start)
\r
876 drop_chapterFinish.Text = c_start.ToString();
\r
879 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
881 // Run the Autonaming function
\r
882 if (Properties.Settings.Default.autoNaming == "Checked")
\r
883 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
885 // Add more rows to the Chapter menu if needed.
\r
886 if (Check_ChapterMarkers.Checked)
\r
888 int i = data_chpt.Rows.Count, finish = 0;
\r
890 if (drop_chapterFinish.Text != "Auto")
\r
891 int.TryParse(drop_chapterFinish.Text, out finish);
\r
895 int n = data_chpt.Rows.Add();
\r
896 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
897 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
898 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
899 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
904 // Disable chapter markers if only 1 chapter is selected.
\r
905 if (c_start == c_end)
\r
907 Check_ChapterMarkers.Checked = false;
\r
908 Check_ChapterMarkers.Enabled = false;
\r
911 Check_ChapterMarkers.Enabled = true;
\r
915 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
917 // This removes the file extension from the filename box on the save file dialog.
\r
918 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
919 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
921 if (Path.IsPathRooted(text_destination.Text))
\r
922 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
924 // Show the dialog and set the main form file path
\r
925 if (drop_format.SelectedIndex.Equals(0))
\r
926 DVD_Save.FilterIndex = 1;
\r
927 else if (drop_format.SelectedIndex.Equals(1))
\r
928 DVD_Save.FilterIndex = 2;
\r
929 else if (drop_format.SelectedIndex.Equals(2))
\r
930 DVD_Save.FilterIndex = 3;
\r
932 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
934 if (DVD_Save.FileName.StartsWith("\\"))
\r
935 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
938 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
939 switch (DVD_Save.FilterIndex)
\r
942 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
943 DVD_Save.FileName += ".mp4";
\r
946 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
947 DVD_Save.FileName += ".m4v";
\r
950 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
951 DVD_Save.FileName += ".mkv";
\r
957 text_destination.Text = DVD_Save.FileName;
\r
959 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
960 if (Check_ChapterMarkers.Checked)
\r
961 drop_format.SelectedIndex = 1;
\r
965 private void text_destination_TextChanged(object sender, EventArgs e)
\r
967 string path = text_destination.Text;
\r
968 if (path.EndsWith(".mp4"))
\r
969 drop_format.SelectedIndex = 0;
\r
970 else if (path.EndsWith(".m4v"))
\r
971 drop_format.SelectedIndex = 1;
\r
972 else if (path.EndsWith(".mkv"))
\r
973 drop_format.SelectedIndex = 2;
\r
977 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
979 if (drop_format.SelectedIndex == 0)
\r
980 setExtension(".mp4");
\r
981 else if (drop_format.SelectedIndex == 1)
\r
982 setExtension(".m4v");
\r
983 else if (drop_format.SelectedIndex == 2)
\r
984 setExtension(".mkv");
\r
986 audioPanel.setAudioByContainer(drop_format.Text);
\r
987 Subtitles.setContainer(drop_format.SelectedIndex);
\r
990 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
992 oldval = drp_videoEncoder.Text;
\r
993 drp_videoEncoder.Items.Clear();
\r
994 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
995 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
996 if (oldval == "VP3 (Theora)")
\r
997 drp_videoEncoder.SelectedIndex = 1;
\r
999 drp_videoEncoder.Text = oldval;
\r
1001 else if (drop_format.Text.Contains("MKV"))
\r
1003 oldval = drp_videoEncoder.Text;
\r
1004 drp_videoEncoder.Items.Clear();
\r
1005 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1006 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1007 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1008 drp_videoEncoder.Text = oldval;
\r
1011 private void setExtension(string newExtension)
\r
1013 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1014 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1015 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1019 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1021 setContainerOpts();
\r
1023 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1024 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1026 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1027 check_turbo.Enabled = true;
\r
1029 tab_advanced.Enabled = true;
\r
1030 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1031 check_iPodAtom.Enabled = true;
\r
1033 check_iPodAtom.Enabled = false;
\r
1037 check_turbo.CheckState = CheckState.Unchecked;
\r
1038 check_turbo.Enabled = false;
\r
1039 tab_advanced.Enabled = false;
\r
1040 x264Panel.x264Query = "";
\r
1041 check_iPodAtom.Enabled = false;
\r
1042 check_iPodAtom.Checked = false;
\r
1045 // Setup the CQ Slider
\r
1046 switch (drp_videoEncoder.Text)
\r
1048 case "MPEG-4 (FFmpeg)":
\r
1049 slider_videoQuality.Minimum = 1;
\r
1050 slider_videoQuality.Maximum = 31;
\r
1051 slider_videoQuality.Value = 1;
\r
1052 SliderValue.Text = "0% QP: 31.00";
\r
1054 case "H.264 (x264)":
\r
1055 slider_videoQuality.Minimum = 0;
\r
1056 slider_videoQuality.Value = 0;
\r
1057 slider_videoQuality.TickFrequency = 1;
\r
1058 SliderValue.Text = "0% RF: 51.00";
\r
1059 String step = Properties.Settings.Default.x264cqstep;
\r
1063 slider_videoQuality.Maximum = 255;
\r
1066 slider_videoQuality.Maximum = 204;
\r
1069 slider_videoQuality.Maximum = 155;
\r
1072 slider_videoQuality.Maximum = 102;
\r
1075 slider_videoQuality.Maximum = 51;
\r
1078 slider_videoQuality.Maximum = 51;
\r
1082 case "VP3 (Theora)":
\r
1083 slider_videoQuality.Minimum = 0;
\r
1084 slider_videoQuality.Maximum = 63;
\r
1085 slider_videoQuality.Value = 0;
\r
1086 SliderValue.Text = "0% QP: 0.00";
\r
1091 /// Set the container format options
\r
1093 public void setContainerOpts()
\r
1095 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1097 check_largeFile.Enabled = true;
\r
1098 check_optimiseMP4.Enabled = true;
\r
1099 check_iPodAtom.Enabled = true;
\r
1103 check_largeFile.Enabled = false;
\r
1104 check_optimiseMP4.Enabled = false;
\r
1105 check_iPodAtom.Enabled = false;
\r
1106 check_largeFile.Checked = false;
\r
1107 check_optimiseMP4.Checked = false;
\r
1108 check_iPodAtom.Checked = false;
\r
1111 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1113 switch (drp_videoEncoder.Text)
\r
1115 case "MPEG-4 (FFmpeg)":
\r
1116 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1117 double max = slider_videoQuality.Maximum;
\r
1118 double min = slider_videoQuality.Minimum;
\r
1119 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1120 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1122 case "H.264 (x264)":
\r
1124 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
\r
1125 double.TryParse(Properties.Settings.Default.x264cqstep,
\r
1126 System.Globalization.NumberStyles.Number,
\r
1129 rfValue = 51.0 - slider_videoQuality.Value * divided;
\r
1130 max = slider_videoQuality.Maximum * divided;
\r
1131 min = slider_videoQuality.Minimum;
\r
1132 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1133 rfValue = Math.Round(rfValue, 2);
\r
1134 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1136 case "VP3 (Theora)":
\r
1137 rfValue = slider_videoQuality.Value;
\r
1138 double value = rfValue / 63;
\r
1139 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1143 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1145 text_bitrate.Enabled = false;
\r
1146 text_filesize.Enabled = true;
\r
1147 slider_videoQuality.Enabled = false;
\r
1149 check_2PassEncode.Enabled = true;
\r
1151 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1153 text_bitrate.Enabled = true;
\r
1154 text_filesize.Enabled = false;
\r
1155 slider_videoQuality.Enabled = false;
\r
1157 check_2PassEncode.Enabled = true;
\r
1159 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1161 text_bitrate.Enabled = false;
\r
1162 text_filesize.Enabled = false;
\r
1163 slider_videoQuality.Enabled = true;
\r
1165 check_2PassEncode.Enabled = false;
\r
1166 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1168 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1170 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1172 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1173 check_turbo.Enabled = true;
\r
1177 check_turbo.Enabled = false;
\r
1178 check_turbo.CheckState = CheckState.Unchecked;
\r
1183 private void ctl_decomb_changed(object sender, EventArgs e)
\r
1185 if (ctl_decomb.getDropValue != "Off")
\r
1186 if (ctl_deinterlace.getDropValue != "None")
\r
1187 ctl_deinterlace.setOption("None");
\r
1189 private void ctl_deinterlace_changed(object sender, EventArgs e)
\r
1191 if (ctl_detelecine.getDropValue != "None")
\r
1192 if (ctl_decomb.getDropValue != "Off")
\r
1193 ctl_decomb.setOption("Off");
\r
1195 private void slider_deblock_Scroll(object sender, EventArgs e)
\r
1197 lbl_deblockVal.Text = slider_deblock.Value == 4 ? "Off" : slider_deblock.Value.ToString();
\r
1200 // Chapter Marker Tab
\r
1201 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1203 if (Check_ChapterMarkers.Checked)
\r
1205 drop_format.SelectedIndex = 1;
\r
1206 data_chpt.Rows.Clear();
\r
1207 data_chpt.Enabled = true;
\r
1208 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1209 if (chapterGridView != null)
\r
1210 data_chpt = chapterGridView;
\r
1214 drop_format.SelectedIndex = 0;
\r
1215 data_chpt.Rows.Clear();
\r
1216 data_chpt.Enabled = false;
\r
1220 // Query Editor Tab
\r
1221 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1223 rtf_query.Text = queryGen.generateTheQuery(this);
\r
1225 private void btn_clear_Click(object sender, EventArgs e)
\r
1227 rtf_query.Clear();
\r
1231 // MainWindow Components, Actions and Functions ***********************
\r
1233 #region Source Scan
\r
1234 public Boolean isScanning { get; set; }
\r
1235 private static int scanProcessID { get; set; }
\r
1236 private void setupGUIforScan(String filename)
\r
1238 text_source.Text = filename;
\r
1240 foreach (Control ctrl in Controls)
\r
1242 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1243 ctrl.Enabled = false;
\r
1245 lbl_encode.Visible = true;
\r
1246 lbl_encode.Text = "Scanning ...";
\r
1247 gb_source.Text = "Source: Scanning ...";
\r
1248 btn_source.Enabled = false;
\r
1249 btn_start.Enabled = false;
\r
1250 btn_showQueue.Enabled = false;
\r
1251 btn_add2Queue.Enabled = false;
\r
1252 tb_preview.Enabled = false;
\r
1253 mnu_killCLI.Visible = true;
\r
1255 private void startScan(String filename)
\r
1259 lbl_encode.Visible = true;
\r
1260 lbl_encode.Text = "Scanning...";
\r
1261 isScanning = true;
\r
1262 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1264 catch (Exception exc)
\r
1266 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1269 private void scanProcess(object state)
\r
1273 string inputFile = (string)state;
\r
1274 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1275 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1276 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1278 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1279 if (File.Exists(dvdInfoPath))
\r
1280 File.Delete(dvdInfoPath);
\r
1282 String dvdnav = string.Empty;
\r
1283 if (Properties.Settings.Default.dvdnav == "Checked")
\r
1284 dvdnav = " --dvdnav";
\r
1285 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1287 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1289 Boolean cleanExit = true;
\r
1290 using (hbproc = Process.Start(hbParseDvd))
\r
1292 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1293 scanProcessID = Main.getCliProcess(before);
\r
1294 hbproc.WaitForExit();
\r
1295 if (hbproc.ExitCode != 0)
\r
1296 cleanExit = false;
\r
1299 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1301 if (!File.Exists(dvdInfoPath))
\r
1303 throw new Exception(
\r
1304 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1308 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1310 thisDVD = DVD.Parse(sr);
\r
1315 updateUIafterScan();
\r
1318 catch (Exception exc)
\r
1320 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1324 private void updateUIafterScan()
\r
1328 if (InvokeRequired)
\r
1330 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1334 // Setup some GUI components
\r
1335 drp_dvdtitle.Items.Clear();
\r
1336 if (thisDVD.Titles.Count != 0)
\r
1337 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1338 drp_dvdtitle.Text = "Automatic";
\r
1339 drop_chapterFinish.Text = "Auto";
\r
1340 drop_chapterStart.Text = "Auto";
\r
1342 // Now select the longest title
\r
1343 if (thisDVD.Titles.Count != 0)
\r
1344 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1346 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1347 if (text_source.Text.ToLower().Contains(".iso") || text_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1348 Check_ChapterMarkers.Enabled = true;
\r
1351 Check_ChapterMarkers.Enabled = false;
\r
1352 Check_ChapterMarkers.Checked = false;
\r
1353 data_chpt.Rows.Clear();
\r
1356 // If no titles were found, Display an error message
\r
1357 if (drp_dvdtitle.Items.Count == 0)
\r
1358 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
1360 // Enable the GUI components and enable any disabled components
\r
1363 catch (Exception exc)
\r
1365 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1369 private void enableGUI()
\r
1373 if (InvokeRequired)
\r
1374 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1375 lbl_encode.Text = "Scan Completed";
\r
1376 gb_source.Text = "Source";
\r
1377 foreach (Control ctrl in Controls)
\r
1378 ctrl.Enabled = true;
\r
1379 btn_start.Enabled = true;
\r
1380 btn_showQueue.Enabled = true;
\r
1381 btn_add2Queue.Enabled = true;
\r
1382 tb_preview.Enabled = true;
\r
1383 btn_source.Enabled = true;
\r
1384 mnu_killCLI.Visible = false;
\r
1386 catch (Exception exc)
\r
1388 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1391 private void killScan()
\r
1398 Process[] prs = Process.GetProcesses();
\r
1399 foreach (Process process in prs)
\r
1401 if (process.Id == scanProcessID)
\r
1403 process.Refresh();
\r
1404 if (!process.HasExited)
\r
1409 catch (Exception ex)
\r
1411 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
1414 private void resetGUI()
\r
1416 drp_dvdtitle.Items.Clear();
\r
1417 drp_dvdtitle.Text = "Automatic";
\r
1418 drop_chapterStart.Items.Clear();
\r
1419 drop_chapterStart.Text = "Auto";
\r
1420 drop_chapterFinish.Items.Clear();
\r
1421 drop_chapterFinish.Text = "Auto";
\r
1422 lbl_duration.Text = "Select a Title";
\r
1423 pictureSettings.lbl_src_res.Text = "Select a Title";
\r
1424 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1425 text_source.Text = "Click 'Source' to continue";
\r
1426 text_destination.Text = "";
\r
1428 selectedTitle = null;
\r
1429 isScanning = false;
\r
1435 /// Set the GUI to it's finished encoding state.
\r
1437 private void setEncodeFinished()
\r
1441 if (InvokeRequired)
\r
1443 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1447 lbl_encode.Text = "Encoding Finished";
\r
1448 btn_start.Text = "Start";
\r
1449 btn_start.ToolTipText = "Start the encoding process";
\r
1450 btn_start.Image = Properties.Resources.Play;
\r
1452 // If the window is minimized, display the notification in a popup.
\r
1453 if (FormWindowState.Minimized == this.WindowState)
\r
1455 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1456 notifyIcon.ShowBalloonTip(500);
\r
1459 catch (Exception exc)
\r
1461 MessageBox.Show(exc.ToString());
\r
1466 /// Set the GUI to it's started encoding state.
\r
1468 private void setEncodeStarted()
\r
1472 if (InvokeRequired)
\r
1474 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1478 lbl_encode.Visible = true;
\r
1479 lbl_encode.Text = "Encoding in Progress";
\r
1480 btn_start.Text = "Stop";
\r
1481 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
1482 btn_start.Image = Properties.Resources.stop;
\r
1484 catch (Exception exc)
\r
1486 MessageBox.Show(exc.ToString());
\r
1491 #region DVD Drive Detection
\r
1492 private delegate void ProgressUpdateHandler();
\r
1493 private void getDriveInfoThread()
\r
1497 if (InvokeRequired)
\r
1499 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1503 Boolean foundDrive = false;
\r
1504 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1505 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1507 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1509 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1511 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1512 foundDrive = true;
\r
1518 if (foundDrive == false)
\r
1519 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1523 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1528 #region Public Methods
\r
1530 /// Access the preset Handler and setup the preset panel.
\r
1532 public void loadPresetPanel()
\r
1534 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1535 if (Properties.Settings.Default.presetNotification == "Unchecked")
\r
1537 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1538 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1540 presetHandler.getPresetPanel(ref treeView_presets);
\r
1541 treeView_presets.Update();
\r
1545 /// Either Encode or Scan was last performed.
\r
1547 public string lastAction { get; set; }
\r
1552 /// If the queue is being processed, prompt the user to confirm application close.
\r
1554 /// <param name="e"></param>
\r
1555 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1557 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1558 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1560 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
1561 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1562 if (result == DialogResult.No)
\r
1565 base.OnFormClosing(e);
\r
1569 #region In-GUI Encode Status (Experimental)
\r
1571 private void encodeMonitorThread()
\r
1575 Parser encode = new Parser(encodeQueue.encodeHandler.hbProcess.StandardOutput.BaseStream);
\r
1576 encode.OnEncodeProgress += encodeOnEncodeProgress;
\r
1577 while (!encode.EndOfStream)
\r
1579 encode.readEncodeStatus();
\r
1582 catch (Exception exc)
\r
1584 MessageBox.Show(exc.ToString());
\r
1587 private void encodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1589 if (this.InvokeRequired)
\r
1591 this.BeginInvoke(new EncodeProgressEventHandler(encodeOnEncodeProgress),
\r
1592 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1595 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1600 // This is the END of the road ****************************************
\r