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 Form preset = new frmAddPreset(this, queryGen.GenerateTheQuery(this), presetHandler);
\r
305 preset.ShowDialog();
\r
310 private void mnu_handbrake_forums_Click(object sender, EventArgs e)
\r
312 Process.Start("http://forum.handbrake.fr/");
\r
314 private void mnu_user_guide_Click(object sender, EventArgs e)
\r
316 Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");
\r
318 private void mnu_handbrake_home_Click(object sender, EventArgs e)
\r
320 Process.Start("http://handbrake.fr");
\r
322 private void mnu_UpdateCheck_Click(object sender, EventArgs e)
\r
324 Boolean update = Main.updateCheck(true);
\r
327 frmUpdater updateWindow = new frmUpdater();
\r
328 updateWindow.Show();
\r
331 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
333 private void mnu_about_Click(object sender, EventArgs e)
\r
335 Form About = new frmAbout();
\r
336 About.ShowDialog();
\r
341 private void mnu_qptest_Click(object sender, EventArgs e)
\r
343 QueryParserTester qptest = new QueryParserTester();
\r
349 // Right Click Menu Code
\r
350 private void pmnu_expandAll_Click(object sender, EventArgs e)
\r
352 treeView_presets.ExpandAll();
\r
354 private void pmnu_collapse_Click(object sender, EventArgs e)
\r
356 treeView_presets.CollapseAll();
\r
358 private void pmnu_saveChanges_Click(object sender, EventArgs e)
\r
360 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
361 if (result == DialogResult.Yes)
\r
362 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), true);
\r
363 else if (result == DialogResult.No)
\r
364 presetHandler.updatePreset(treeView_presets.SelectedNode.Text, QueryGenerator.generateTabbedComponentsQuery(this), false);
\r
366 private void pmnu_delete_click(object sender, EventArgs e)
\r
368 if (treeView_presets.SelectedNode != null)
\r
370 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
371 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
373 treeView_presets.Select();
\r
375 private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
\r
377 // Make sure that the save menu is always disabled by default
\r
378 pmnu_saveChanges.Enabled = false;
\r
380 // Now enable the save menu if the selected preset is a user preset
\r
381 if (treeView_presets.SelectedNode != null)
\r
382 if (presetHandler.checkIfUserPresetExists(treeView_presets.SelectedNode.Text))
\r
383 pmnu_saveChanges.Enabled = true;
\r
385 treeView_presets.Select();
\r
388 // Presets Management
\r
389 private void btn_addPreset_Click(object sender, EventArgs e)
\r
391 Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);
\r
392 preset.ShowDialog();
\r
394 private void btn_removePreset_Click(object sender, EventArgs e)
\r
396 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
397 if (result == DialogResult.Yes)
\r
399 if (treeView_presets.SelectedNode != null)
\r
401 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
402 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);
\r
405 treeView_presets.Select();
\r
407 private void btn_setDefault_Click(object sender, EventArgs e)
\r
409 if (treeView_presets.SelectedNode != null)
\r
411 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
412 if (result == DialogResult.Yes)
\r
414 Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;
\r
415 Properties.Settings.Default.Save();
\r
416 MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
420 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
422 private void treeview_presets_mouseUp(object sender, MouseEventArgs e)
\r
424 if (e.Button == MouseButtons.Right)
\r
425 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);
\r
426 else if (e.Button == MouseButtons.Left)
\r
428 if (treeView_presets.GetNodeAt(e.Location) != null)
\r
430 if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))
\r
435 treeView_presets.Select();
\r
437 private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)
\r
441 private void treeView_presets_deleteKey(object sender, KeyEventArgs e)
\r
443 if (e.KeyCode == Keys.Delete)
\r
445 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
446 if (result == DialogResult.Yes)
\r
448 if (treeView_presets.SelectedNode != null)
\r
449 presetHandler.remove(treeView_presets.SelectedNode.Text);
\r
451 // Remember each nodes expanded status so we can reload it
\r
452 List<Boolean> nodeStatus = new List<Boolean>();
\r
453 foreach (TreeNode node in treeView_presets.Nodes)
\r
454 nodeStatus.Add(node.IsExpanded);
\r
456 // Now reload the preset panel
\r
459 // And finally, re-expand any of the nodes if required
\r
461 foreach (TreeNode node in treeView_presets.Nodes)
\r
471 private void selectPreset()
\r
473 if (treeView_presets.SelectedNode != null)
\r
475 // Ok, so, we've selected a preset. Now we want to load it.
\r
476 string presetName = treeView_presets.SelectedNode.Text;
\r
477 if (presetHandler.getPreset(presetName) != null)
\r
479 string query = presetHandler.getPreset(presetName).Query;
\r
480 Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;
\r
484 //Ok, Reset all the H264 widgets before changing the preset
\r
485 x264Panel.reset2Defaults();
\r
487 // Send the query from the file to the Query Parser class
\r
488 QueryParser presetQuery = QueryParser.Parse(query);
\r
490 // Now load the preset
\r
491 PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);
\r
493 // The x264 widgets will need updated, so do this now:
\r
494 x264Panel.X264_StandardizeOptString();
\r
495 x264Panel.X264_SetCurrentSettingsInPanel();
\r
500 private void loadNormalPreset()
\r
502 foreach (TreeNode treenode in treeView_presets.Nodes)
\r
504 foreach (TreeNode node in treenode.Nodes)
\r
506 if (node.Text.Equals("Normal"))
\r
507 treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];
\r
514 private void btn_source_Click(object sender, EventArgs e)
\r
516 if (Properties.Settings.Default.drive_detection == "Checked")
\r
518 mnu_dvd_drive.Visible = true;
\r
519 Thread driveInfoThread = new Thread(getDriveInfoThread);
\r
520 driveInfoThread.Start();
\r
523 mnu_dvd_drive.Visible = false;
\r
525 private void btn_start_Click(object sender, EventArgs e)
\r
527 if (btn_start.Text == "Stop")
\r
529 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
531 if (result == DialogResult.Yes)
\r
534 encodeQueue.pauseEncodeQueue();
\r
536 // Allow the CLI to exit cleanly
\r
537 Win32.SetForegroundWindow(encodeQueue.encodeProcess.processHandle);
\r
538 SendKeys.Send("^C");
\r
541 setEncodeFinished();
\r
546 if (encodeQueue.count() != 0 || (text_source.Text != string.Empty && text_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))
\r
548 // Set the last action to encode.
\r
549 // This is used for tracking which file to load in the activity window
\r
550 lastAction = "encode";
\r
552 String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.GenerateTheQuery(this);
\r
554 if (encodeQueue.count() == 0)
\r
556 encodeQueue.add(query, text_source.Text, text_destination.Text);
\r
557 encodeQueue.write2disk("hb_queue_recovery.xml");
\r
559 queueWindow.setQueue();
\r
560 if (encodeQueue.count() > 1)
\r
561 queueWindow.Show(false);
\r
563 setEncodeStarted(); // Encode is running, so setup the GUI appropriately
\r
564 encodeQueue.startEncode(); // Start The Queue Encoding Process
\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 encodeQueue.write2disk("hb_queue_recovery.xml"); // Writes the queue to the recovery file, just incase the GUI crashes.
\r
594 queueWindow.Show();
\r
597 private void btn_showQueue_Click(object sender, EventArgs e)
\r
599 queueWindow.Show();
\r
601 private void tb_preview_Click(object sender, EventArgs e)
\r
603 if (text_source.Text == "" || text_source.Text == "Click 'Source' to continue" || text_destination.Text == "")
\r
604 MessageBox.Show("No source OR destination selected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
607 if (qtpreview == null)
\r
609 qtpreview = new frmPreview(this);
\r
612 else if (qtpreview.IsDisposed)
\r
614 qtpreview = new frmPreview(this);
\r
618 MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
621 private void btn_ActivityWindow_Click(object sender, EventArgs e)
\r
623 String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";
\r
625 frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);
\r
626 ActivityWindow.Show();
\r
630 #region System Tray Icon
\r
631 private void frmMain_Resize(object sender, EventArgs e)
\r
633 if (FormWindowState.Minimized == this.WindowState)
\r
635 notifyIcon.Visible = true;
\r
636 if (!encodeQueue.isEncoding)
\r
638 notifyIcon.BalloonTipText = lbl_encode.Text != "" ? lbl_encode.Text : "Not Encoding";
\r
639 if (Properties.Settings.Default.trayIconAlerts == "Checked")
\r
640 notifyIcon.ShowBalloonTip(500);
\r
644 else if (FormWindowState.Normal == this.WindowState)
\r
645 notifyIcon.Visible = false;
\r
647 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
649 this.Visible = true;
\r
651 this.WindowState = FormWindowState.Normal;
\r
652 notifyIcon.Visible = false;
\r
654 private void btn_restore_Click(object sender, EventArgs e)
\r
656 this.Visible = true;
\r
658 this.WindowState = FormWindowState.Normal;
\r
659 notifyIcon.Visible = false;
\r
663 #region Tab Control
\r
666 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
668 // Enable the creation of chapter markers.
\r
669 Check_ChapterMarkers.Enabled = true;
\r
671 // Set the last action to scan.
\r
672 // This is used for tracking which file to load in the activity window
\r
673 lastAction = "scan";
\r
674 text_source.Text = "";
\r
676 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
678 String filename = DVD_Open.SelectedPath;
\r
680 if (filename.StartsWith("\\"))
\r
681 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
684 if (filename != "")
\r
686 setupGUIforScan(filename);
\r
687 startScan(filename);
\r
690 text_source.Text = "Click 'Source' to continue";
\r
694 text_source.Text = "Click 'Source' to continue";
\r
696 private void btn_file_source_Click(object sender, EventArgs e)
\r
698 // Set the last action to scan.
\r
699 // This is used for tracking which file to load in the activity window
\r
700 lastAction = "scan";
\r
701 text_source.Text = "";
\r
703 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
705 String filename = ISO_Open.FileName;
\r
706 if (filename.StartsWith("\\"))
\r
708 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
709 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
712 if (filename != "")
\r
714 setupGUIforScan(filename);
\r
715 startScan(filename);
\r
718 text_source.Text = "Click 'Source' to continue";
\r
722 text_source.Text = "Click 'Source' to continue";
\r
724 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
726 // Enable the creation of chapter markers.
\r
727 Check_ChapterMarkers.Enabled = true;
\r
729 // Set the last action to scan.
\r
730 // This is used for tracking which file to load in the activity window
\r
731 lastAction = "scan";
\r
733 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
735 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
736 String filename = path[0];
\r
737 setupGUIforScan(filename);
\r
738 startScan(filename);
\r
741 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
742 if (drp_dvdtitle.Items.Count == 0)
\r
743 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
745 lbl_encode.Text = "";
\r
747 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
749 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
750 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
752 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
754 // Reset some values on the form
\r
755 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
756 //lbl_RecomendedCrop.Text = "Select a Title";
\r
757 drop_chapterStart.Items.Clear();
\r
758 drop_chapterFinish.Items.Clear();
\r
760 // If the dropdown is set to automatic nothing else needs to be done.
\r
761 // Otheriwse if its not, title data has to be loased from parsing.
\r
762 if (drp_dvdtitle.Text != "Automatic")
\r
764 selectedTitle = drp_dvdtitle.SelectedItem as Parsing.Title;
\r
765 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
766 pictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
768 // Populate the Angles dropdown
\r
769 drop_angle.Items.Clear();
\r
770 if (Properties.Settings.Default.dvdnav == "Checked")
\r
772 drop_angle.Visible = true;
\r
773 lbl_angle.Visible = true;
\r
774 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
775 if (drop_angle.Items.Count != 0)
\r
776 drop_angle.SelectedIndex = 0;
\r
780 drop_angle.Visible = false;
\r
781 lbl_angle.Visible = false;
\r
784 // Populate the Start chapter Dropdown
\r
785 drop_chapterStart.Items.Clear();
\r
786 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
787 if (drop_chapterStart.Items.Count > 0)
\r
788 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
790 // Populate the Final Chapter Dropdown
\r
791 drop_chapterFinish.Items.Clear();
\r
792 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
793 if (drop_chapterFinish.Items.Count > 0)
\r
794 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
796 // Populate the Audio Channels Dropdown
\r
797 audioPanel.setTrackList(selectedTitle);
\r
799 // Populate the Subtitles dropdown
\r
800 drp_subtitle.Items.Clear();
\r
801 drp_subtitle.Items.Add("None");
\r
802 drp_subtitle.Items.Add("Autoselect");
\r
803 drp_subtitle.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
804 if (drp_subtitle.Items.Count > 0)
\r
805 drp_subtitle.Text = drp_subtitle.Items[0].ToString();
\r
809 // Run the autoName & chapterNaming functions
\r
810 if (Properties.Settings.Default.autoNaming == "Checked")
\r
812 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
813 if (autoPath != null)
\r
814 text_destination.Text = autoPath;
\r
816 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
819 data_chpt.Rows.Clear();
\r
820 if (selectedTitle.Chapters.Count != 1)
\r
822 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
823 if (chapterGridView != null)
\r
824 data_chpt = chapterGridView;
\r
828 Check_ChapterMarkers.Checked = false;
\r
829 Check_ChapterMarkers.Enabled = false;
\r
832 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
833 data_chpt.Columns[0].Width = 166;
\r
834 data_chpt.Columns[0].Width = 165;
\r
836 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
838 int c_start, c_end;
\r
840 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
841 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
843 int.TryParse(drop_chapterStart.Text, out c_start);
\r
844 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
848 if (c_start > c_end)
\r
849 drop_chapterFinish.Text = c_start.ToString();
\r
852 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
854 // Run the Autonaming function
\r
855 if (Properties.Settings.Default.autoNaming == "Checked")
\r
856 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
858 // Disable chapter markers if only 1 chapter is selected.
\r
859 if (c_start == c_end)
\r
861 Check_ChapterMarkers.Checked = false;
\r
862 Check_ChapterMarkers.Enabled = false;
\r
865 Check_ChapterMarkers.Enabled = true;
\r
867 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
869 int c_start, c_end;
\r
871 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
872 drop_chapterStart.SelectedIndex = 1;
\r
874 int.TryParse(drop_chapterStart.Text, out c_start);
\r
875 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
879 if (c_end < c_start)
\r
880 drop_chapterFinish.Text = c_start.ToString();
\r
883 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
885 // Run the Autonaming function
\r
886 if (Properties.Settings.Default.autoNaming == "Checked")
\r
887 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
889 // Add more rows to the Chapter menu if needed.
\r
890 if (Check_ChapterMarkers.Checked)
\r
892 int i = data_chpt.Rows.Count, finish = 0;
\r
894 if (drop_chapterFinish.Text != "Auto")
\r
895 int.TryParse(drop_chapterFinish.Text, out finish);
\r
899 int n = data_chpt.Rows.Add();
\r
900 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
901 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
902 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
903 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
908 // Disable chapter markers if only 1 chapter is selected.
\r
909 if (c_start == c_end)
\r
911 Check_ChapterMarkers.Checked = false;
\r
912 Check_ChapterMarkers.Enabled = false;
\r
915 Check_ChapterMarkers.Enabled = true;
\r
919 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
921 // This removes the file extension from the filename box on the save file dialog.
\r
922 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
923 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
925 if (Path.IsPathRooted(text_destination.Text))
\r
926 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
928 // Show the dialog and set the main form file path
\r
929 if (drop_format.SelectedIndex.Equals(0))
\r
930 DVD_Save.FilterIndex = 1;
\r
931 else if (drop_format.SelectedIndex.Equals(1))
\r
932 DVD_Save.FilterIndex = 2;
\r
933 else if (drop_format.SelectedIndex.Equals(2))
\r
934 DVD_Save.FilterIndex = 3;
\r
936 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
938 if (DVD_Save.FileName.StartsWith("\\"))
\r
939 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
942 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
943 switch (DVD_Save.FilterIndex)
\r
946 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
947 DVD_Save.FileName += ".mp4";
\r
950 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
951 DVD_Save.FileName += ".m4v";
\r
954 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
955 DVD_Save.FileName += ".mkv";
\r
961 text_destination.Text = DVD_Save.FileName;
\r
963 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
964 if (Check_ChapterMarkers.Checked)
\r
965 drop_format.SelectedIndex = 1;
\r
969 private void text_destination_TextChanged(object sender, EventArgs e)
\r
971 string path = text_destination.Text;
\r
972 if (path.EndsWith(".mp4"))
\r
973 drop_format.SelectedIndex = 0;
\r
974 else if (path.EndsWith(".m4v"))
\r
975 drop_format.SelectedIndex = 1;
\r
976 else if (path.EndsWith(".mkv"))
\r
977 drop_format.SelectedIndex = 2;
\r
981 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
983 if (drop_format.SelectedIndex == 0)
\r
984 setExtension(".mp4");
\r
985 else if (drop_format.SelectedIndex == 1)
\r
986 setExtension(".m4v");
\r
987 else if (drop_format.SelectedIndex == 2)
\r
988 setExtension(".mkv");
\r
990 audioPanel.setAudioByContainer(drop_format.Text);
\r
993 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
995 oldval = drp_videoEncoder.Text;
\r
996 drp_videoEncoder.Items.Clear();
\r
997 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
998 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
999 if (oldval == "VP3 (Theora)")
\r
1000 drp_videoEncoder.SelectedIndex = 1;
\r
1002 drp_videoEncoder.Text = oldval;
\r
1004 else if (drop_format.Text.Contains("MKV"))
\r
1006 oldval = drp_videoEncoder.Text;
\r
1007 drp_videoEncoder.Items.Clear();
\r
1008 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1009 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1010 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1011 drp_videoEncoder.Text = oldval;
\r
1014 private void setExtension(string newExtension)
\r
1016 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1017 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1018 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1022 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1024 setContainerOpts();
\r
1026 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1027 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1029 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1030 check_turbo.Enabled = true;
\r
1032 tab_advanced.Enabled = true;
\r
1033 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1034 check_iPodAtom.Enabled = true;
\r
1036 check_iPodAtom.Enabled = false;
\r
1040 check_turbo.CheckState = CheckState.Unchecked;
\r
1041 check_turbo.Enabled = false;
\r
1042 tab_advanced.Enabled = false;
\r
1043 x264Panel.x264Query = "";
\r
1044 check_iPodAtom.Enabled = false;
\r
1045 check_iPodAtom.Checked = false;
\r
1048 // Setup the CQ Slider
\r
1049 switch (drp_videoEncoder.Text)
\r
1051 case "MPEG-4 (FFmpeg)":
\r
1052 slider_videoQuality.Minimum = 1;
\r
1053 slider_videoQuality.Maximum = 31;
\r
1054 slider_videoQuality.Value = 1;
\r
1055 SliderValue.Text = "0% QP: 31.00";
\r
1057 case "H.264 (x264)":
\r
1058 slider_videoQuality.Minimum = 0;
\r
1059 slider_videoQuality.Value = 0;
\r
1060 slider_videoQuality.TickFrequency = 1;
\r
1061 SliderValue.Text = "0% RF: 51.00";
\r
1062 String step = Properties.Settings.Default.x264cqstep;
\r
1066 slider_videoQuality.Maximum = 255;
\r
1069 slider_videoQuality.Maximum = 204;
\r
1072 slider_videoQuality.Maximum = 155;
\r
1075 slider_videoQuality.Maximum = 102;
\r
1078 slider_videoQuality.Maximum = 51;
\r
1081 slider_videoQuality.Maximum = 51;
\r
1085 case "VP3 (Theora)":
\r
1086 slider_videoQuality.Minimum = 0;
\r
1087 slider_videoQuality.Maximum = 63;
\r
1088 slider_videoQuality.Value = 0;
\r
1089 SliderValue.Text = "0% QP: 0.00";
\r
1094 /// Set the container format options
\r
1096 public void setContainerOpts()
\r
1098 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1100 check_largeFile.Enabled = true;
\r
1101 check_optimiseMP4.Enabled = true;
\r
1102 check_iPodAtom.Enabled = true;
\r
1106 check_largeFile.Enabled = false;
\r
1107 check_optimiseMP4.Enabled = false;
\r
1108 check_iPodAtom.Enabled = false;
\r
1109 check_largeFile.Checked = false;
\r
1110 check_optimiseMP4.Checked = false;
\r
1111 check_iPodAtom.Checked = false;
\r
1114 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1116 switch (drp_videoEncoder.Text)
\r
1118 case "MPEG-4 (FFmpeg)":
\r
1119 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1120 double max = slider_videoQuality.Maximum;
\r
1121 double min = slider_videoQuality.Minimum;
\r
1122 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1123 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1125 case "H.264 (x264)":
\r
1127 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
\r
1128 double.TryParse(Properties.Settings.Default.x264cqstep,
\r
1129 System.Globalization.NumberStyles.Number,
\r
1132 rfValue = 51.0 - slider_videoQuality.Value * divided;
\r
1133 max = slider_videoQuality.Maximum * divided;
\r
1134 min = slider_videoQuality.Minimum;
\r
1135 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1136 rfValue = Math.Round(rfValue, 2);
\r
1137 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1139 case "VP3 (Theora)":
\r
1140 rfValue = slider_videoQuality.Value;
\r
1141 double value = rfValue / 63;
\r
1142 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1146 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1148 text_bitrate.Enabled = false;
\r
1149 text_filesize.Enabled = true;
\r
1150 slider_videoQuality.Enabled = false;
\r
1152 check_2PassEncode.Enabled = true;
\r
1154 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1156 text_bitrate.Enabled = true;
\r
1157 text_filesize.Enabled = false;
\r
1158 slider_videoQuality.Enabled = false;
\r
1160 check_2PassEncode.Enabled = true;
\r
1162 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1164 text_bitrate.Enabled = false;
\r
1165 text_filesize.Enabled = false;
\r
1166 slider_videoQuality.Enabled = true;
\r
1168 check_2PassEncode.Enabled = false;
\r
1169 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1171 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1173 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1175 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1176 check_turbo.Enabled = true;
\r
1180 check_turbo.Enabled = false;
\r
1181 check_turbo.CheckState = CheckState.Unchecked;
\r
1186 private void ctl_decomb_changed(object sender, EventArgs e)
\r
1188 if (ctl_decomb.getDropValue != "Off")
\r
1189 if (ctl_deinterlace.getDropValue != "None")
\r
1190 ctl_deinterlace.setOption("None");
\r
1192 private void ctl_deinterlace_changed(object sender, EventArgs e)
\r
1194 if (ctl_detelecine.getDropValue != "None")
\r
1195 if (ctl_decomb.getDropValue != "Off")
\r
1196 ctl_decomb.setOption("Off");
\r
1198 private void slider_deblock_Scroll(object sender, EventArgs e)
\r
1200 lbl_deblockVal.Text = slider_deblock.Value == 4 ? "Off" : slider_deblock.Value.ToString();
\r
1204 private void drp_subtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
1206 if (drp_subtitle.Text.Contains("None"))
\r
1208 check_forced.Enabled = false;
\r
1209 check_forced.Checked = false;
\r
1212 check_forced.Enabled = true;
\r
1215 // Chapter Marker Tab
\r
1216 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1218 if (Check_ChapterMarkers.Checked)
\r
1220 drop_format.SelectedIndex = 1;
\r
1221 data_chpt.Rows.Clear();
\r
1222 data_chpt.Enabled = true;
\r
1223 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1224 if (chapterGridView != null)
\r
1225 data_chpt = chapterGridView;
\r
1229 drop_format.SelectedIndex = 0;
\r
1230 data_chpt.Rows.Clear();
\r
1231 data_chpt.Enabled = false;
\r
1235 // Query Editor Tab
\r
1236 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1238 rtf_query.Text = queryGen.GenerateTheQuery(this);
\r
1240 private void btn_clear_Click(object sender, EventArgs e)
\r
1242 rtf_query.Clear();
\r
1246 // MainWindow Components, Actions and Functions ***********************
\r
1248 #region Source Scan
\r
1249 public Boolean isScanning { get; set; }
\r
1250 private static int scanProcessID { get; set; }
\r
1251 private void setupGUIforScan(String filename)
\r
1253 text_source.Text = filename;
\r
1255 foreach (Control ctrl in Controls)
\r
1257 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1258 ctrl.Enabled = false;
\r
1260 lbl_encode.Visible = true;
\r
1261 lbl_encode.Text = "Scanning ...";
\r
1262 gb_source.Text = "Source: Scanning ...";
\r
1263 btn_source.Enabled = false;
\r
1264 btn_start.Enabled = false;
\r
1265 btn_showQueue.Enabled = false;
\r
1266 btn_add2Queue.Enabled = false;
\r
1267 tb_preview.Enabled = false;
\r
1268 mnu_killCLI.Visible = true;
\r
1270 private void startScan(String filename)
\r
1274 lbl_encode.Visible = true;
\r
1275 lbl_encode.Text = "Scanning...";
\r
1276 isScanning = true;
\r
1277 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1279 catch (Exception exc)
\r
1281 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1284 private void scanProcess(object state)
\r
1288 string inputFile = (string)state;
\r
1289 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1290 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1291 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1293 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1294 if (File.Exists(dvdInfoPath))
\r
1295 File.Delete(dvdInfoPath);
\r
1297 String dvdnav = string.Empty;
\r
1298 if (Properties.Settings.Default.dvdnav == "Checked")
\r
1299 dvdnav = " --dvdnav";
\r
1300 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1302 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1304 Boolean cleanExit = true;
\r
1305 using (hbproc = Process.Start(hbParseDvd))
\r
1307 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1308 scanProcessID = Main.getCliProcess(before);
\r
1309 hbproc.WaitForExit();
\r
1310 if (hbproc.ExitCode != 0)
\r
1311 cleanExit = false;
\r
1314 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1316 if (!File.Exists(dvdInfoPath))
\r
1318 throw new Exception(
\r
1319 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1323 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1325 thisDVD = DVD.Parse(sr);
\r
1330 updateUIafterScan();
\r
1333 catch (Exception exc)
\r
1335 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1339 private void updateUIafterScan()
\r
1343 if (InvokeRequired)
\r
1345 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1349 // Setup some GUI components
\r
1350 drp_dvdtitle.Items.Clear();
\r
1351 if (thisDVD.Titles.Count != 0)
\r
1352 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1353 drp_dvdtitle.Text = "Automatic";
\r
1354 drop_chapterFinish.Text = "Auto";
\r
1355 drop_chapterStart.Text = "Auto";
\r
1357 // Now select the longest title
\r
1358 if (thisDVD.Titles.Count != 0)
\r
1359 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1361 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1362 if (text_source.Text.ToLower().Contains(".iso") || text_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1363 Check_ChapterMarkers.Enabled = true;
\r
1366 Check_ChapterMarkers.Enabled = false;
\r
1367 Check_ChapterMarkers.Checked = false;
\r
1368 data_chpt.Rows.Clear();
\r
1371 // If no titles were found, Display an error message
\r
1372 if (drp_dvdtitle.Items.Count == 0)
\r
1373 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
1375 // Enable the GUI components and enable any disabled components
\r
1378 catch (Exception exc)
\r
1380 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1384 private void enableGUI()
\r
1388 if (InvokeRequired)
\r
1389 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1390 lbl_encode.Text = "Scan Completed";
\r
1391 gb_source.Text = "Source";
\r
1392 foreach (Control ctrl in Controls)
\r
1393 ctrl.Enabled = true;
\r
1394 btn_start.Enabled = true;
\r
1395 btn_showQueue.Enabled = true;
\r
1396 btn_add2Queue.Enabled = true;
\r
1397 tb_preview.Enabled = true;
\r
1398 btn_source.Enabled = true;
\r
1399 mnu_killCLI.Visible = false;
\r
1401 catch (Exception exc)
\r
1403 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1406 private void killScan()
\r
1413 Process[] prs = Process.GetProcesses();
\r
1414 foreach (Process process in prs)
\r
1416 if (process.Id == scanProcessID)
\r
1418 process.Refresh();
\r
1419 if (!process.HasExited)
\r
1424 catch (Exception ex)
\r
1426 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
1429 private void resetGUI()
\r
1431 drp_dvdtitle.Items.Clear();
\r
1432 drp_dvdtitle.Text = "Automatic";
\r
1433 drop_chapterStart.Items.Clear();
\r
1434 drop_chapterStart.Text = "Auto";
\r
1435 drop_chapterFinish.Items.Clear();
\r
1436 drop_chapterFinish.Text = "Auto";
\r
1437 lbl_duration.Text = "Select a Title";
\r
1438 pictureSettings.lbl_src_res.Text = "Select a Title";
\r
1439 pictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1440 text_source.Text = "Click 'Source' to continue";
\r
1441 text_destination.Text = "";
\r
1443 selectedTitle = null;
\r
1444 isScanning = false;
\r
1450 /// Set the GUI to it's finished encoding state.
\r
1452 private void setEncodeFinished()
\r
1456 if (InvokeRequired)
\r
1458 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1462 lbl_encode.Text = "Encoding Finished";
\r
1463 btn_start.Text = "Start";
\r
1464 btn_start.ToolTipText = "Start the encoding process";
\r
1465 btn_start.Image = Properties.Resources.Play;
\r
1467 // If the window is minimized, display the notification in a popup.
\r
1468 if (FormWindowState.Minimized == this.WindowState)
\r
1470 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1471 notifyIcon.ShowBalloonTip(500);
\r
1474 catch (Exception exc)
\r
1476 MessageBox.Show(exc.ToString());
\r
1481 /// Set the GUI to it's started encoding state.
\r
1483 private void setEncodeStarted()
\r
1487 if (InvokeRequired)
\r
1489 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1493 lbl_encode.Visible = true;
\r
1494 lbl_encode.Text = "Encoding in Progress";
\r
1495 btn_start.Text = "Stop";
\r
1496 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
1497 btn_start.Image = Properties.Resources.stop;
\r
1499 catch (Exception exc)
\r
1501 MessageBox.Show(exc.ToString());
\r
1506 #region DVD Drive Detection
\r
1507 private delegate void ProgressUpdateHandler();
\r
1508 private void getDriveInfoThread()
\r
1512 if (InvokeRequired)
\r
1514 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1518 Boolean foundDrive = false;
\r
1519 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1520 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1522 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1524 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1526 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1527 foundDrive = true;
\r
1533 if (foundDrive == false)
\r
1534 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1538 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1543 #region Public Methods
\r
1545 /// Access the preset Handler and setup the preset panel.
\r
1547 public void loadPresetPanel()
\r
1549 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1550 if (Properties.Settings.Default.presetNotification == "Unchecked")
\r
1552 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1553 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1555 presetHandler.getPresetPanel(ref treeView_presets);
\r
1556 treeView_presets.Update();
\r
1560 /// Either Encode or Scan was last performed.
\r
1562 public string lastAction { get; set; }
\r
1567 /// If the queue is being processed, prompt the user to confirm application close.
\r
1569 /// <param name="e"></param>
\r
1570 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1572 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1573 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1575 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
1576 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1577 if (result == DialogResult.No)
\r
1580 base.OnFormClosing(e);
\r
1584 #region In-GUI Encode Status (Experimental)
\r
1585 private Process HBProcess { get; set; }
\r
1587 private void encodeMonitorThread()
\r
1591 Parser encode = new Parser(HBProcess.StandardOutput.BaseStream);
\r
1592 encode.OnEncodeProgress += encode_OnEncodeProgress;
\r
1593 while (!encode.EndOfStream)
\r
1595 encode.readEncodeStatus();
\r
1598 catch (Exception exc)
\r
1600 MessageBox.Show(exc.ToString());
\r
1604 private void encode_OnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1606 if (this.InvokeRequired)
\r
1608 this.BeginInvoke(new EncodeProgressEventHandler(encode_OnEncodeProgress),
\r
1609 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1612 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1616 // This is the END of the road ****************************************
\r