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)
\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)
\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 && 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)
\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)
\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)
\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)
\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
637 else if (FormWindowState.Normal == this.WindowState)
\r
638 notifyIcon.Visible = false;
\r
640 private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
\r
642 this.Visible = true;
\r
644 this.WindowState = FormWindowState.Normal;
\r
645 notifyIcon.Visible = false;
\r
647 private void btn_restore_Click(object sender, EventArgs e)
\r
649 this.Visible = true;
\r
651 this.WindowState = FormWindowState.Normal;
\r
652 notifyIcon.Visible = false;
\r
656 #region Tab Control
\r
659 private void btn_dvd_source_Click(object sender, EventArgs e)
\r
661 // Enable the creation of chapter markers.
\r
662 Check_ChapterMarkers.Enabled = true;
\r
664 // Set the last action to scan.
\r
665 // This is used for tracking which file to load in the activity window
\r
666 lastAction = "scan";
\r
667 text_source.Text = "";
\r
669 if (DVD_Open.ShowDialog() == DialogResult.OK)
\r
671 String filename = DVD_Open.SelectedPath;
\r
673 if (filename.StartsWith("\\"))
\r
674 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
677 if (filename != "")
\r
679 setupGUIforScan(filename);
\r
680 startScan(filename);
\r
683 text_source.Text = "Click 'Source' to continue";
\r
687 text_source.Text = "Click 'Source' to continue";
\r
689 private void btn_file_source_Click(object sender, EventArgs e)
\r
691 // Set the last action to scan.
\r
692 // This is used for tracking which file to load in the activity window
\r
693 lastAction = "scan";
\r
694 text_source.Text = "";
\r
696 if (ISO_Open.ShowDialog() == DialogResult.OK)
\r
698 String filename = ISO_Open.FileName;
\r
699 if (filename.StartsWith("\\"))
\r
701 "Sorry, HandBrake does not support UNC file paths. \nTry mounting the share as a network drive in My Computer",
\r
702 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
705 if (filename != "")
\r
707 setupGUIforScan(filename);
\r
708 startScan(filename);
\r
711 text_source.Text = "Click 'Source' to continue";
\r
715 text_source.Text = "Click 'Source' to continue";
\r
717 private void mnu_dvd_drive_Click(object sender, EventArgs e)
\r
719 // Enable the creation of chapter markers.
\r
720 Check_ChapterMarkers.Enabled = true;
\r
722 // Set the last action to scan.
\r
723 // This is used for tracking which file to load in the activity window
\r
724 lastAction = "scan";
\r
726 if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))
\r
728 string[] path = mnu_dvd_drive.Text.Split(' ');
\r
729 String filename = path[0];
\r
730 setupGUIforScan(filename);
\r
731 startScan(filename);
\r
734 // If there are no titles in the dropdown menu then the scan has obviously failed. Display an error message explaining to the user.
\r
735 if (drp_dvdtitle.Items.Count == 0)
\r
736 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
738 lbl_encode.Text = "";
\r
740 private void drp_dvdtitle_Click(object sender, EventArgs e)
\r
742 if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))
\r
743 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
745 private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)
\r
747 // Reset some values on the form
\r
748 PictureSettings.lbl_Aspect.Text = "Select a Title";
\r
749 //lbl_RecomendedCrop.Text = "Select a Title";
\r
750 drop_chapterStart.Items.Clear();
\r
751 drop_chapterFinish.Items.Clear();
\r
753 // If the dropdown is set to automatic nothing else needs to be done.
\r
754 // Otheriwse if its not, title data has to be loased from parsing.
\r
755 if (drp_dvdtitle.Text != "Automatic")
\r
757 selectedTitle = drp_dvdtitle.SelectedItem as Title;
\r
758 lbl_duration.Text = selectedTitle.Duration.ToString();
\r
759 PictureSettings.setComponentsAfterScan(selectedTitle); // Setup Picture Settings Tab Control
\r
761 // Populate the Angles dropdown
\r
762 drop_angle.Items.Clear();
\r
763 if (Properties.Settings.Default.dvdnav)
\r
765 drop_angle.Visible = true;
\r
766 lbl_angle.Visible = true;
\r
767 drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());
\r
768 if (drop_angle.Items.Count != 0)
\r
769 drop_angle.SelectedIndex = 0;
\r
773 drop_angle.Visible = false;
\r
774 lbl_angle.Visible = false;
\r
777 // Populate the Start chapter Dropdown
\r
778 drop_chapterStart.Items.Clear();
\r
779 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
780 if (drop_chapterStart.Items.Count > 0)
\r
781 drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();
\r
783 // Populate the Final Chapter Dropdown
\r
784 drop_chapterFinish.Items.Clear();
\r
785 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());
\r
786 if (drop_chapterFinish.Items.Count > 0)
\r
787 drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();
\r
789 // Populate the Audio Channels Dropdown
\r
790 AudioSettings.setTrackList(selectedTitle);
\r
792 // Populate the Subtitles dropdown
\r
793 Subtitles.drp_subtitleTracks.Items.Clear();
\r
794 Subtitles.drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
795 Subtitles.drp_subtitleTracks.Items.AddRange(selectedTitle.Subtitles.ToArray());
\r
796 Subtitles.drp_subtitleTracks.SelectedIndex = 0;
\r
799 // Run the autoName & chapterNaming functions
\r
800 if (Properties.Settings.Default.autoNaming)
\r
802 string autoPath = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
803 if (autoPath != null)
\r
804 text_destination.Text = autoPath;
\r
806 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
809 data_chpt.Rows.Clear();
\r
810 if (selectedTitle.Chapters.Count != 1)
\r
812 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
813 if (chapterGridView != null)
\r
814 data_chpt = chapterGridView;
\r
818 Check_ChapterMarkers.Checked = false;
\r
819 Check_ChapterMarkers.Enabled = false;
\r
822 // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.
\r
823 data_chpt.Columns[0].Width = 166;
\r
824 data_chpt.Columns[0].Width = 165;
\r
826 private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)
\r
828 int c_start, c_end;
\r
830 if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)
\r
831 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;
\r
833 int.TryParse(drop_chapterStart.Text, out c_start);
\r
834 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
838 if (c_start > c_end)
\r
839 drop_chapterFinish.Text = c_start.ToString();
\r
842 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
844 // Run the Autonaming function
\r
845 if (Properties.Settings.Default.autoNaming)
\r
846 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
848 // Disable chapter markers if only 1 chapter is selected.
\r
849 if (c_start == c_end)
\r
851 Check_ChapterMarkers.Checked = false;
\r
852 Check_ChapterMarkers.Enabled = false;
\r
855 Check_ChapterMarkers.Enabled = true;
\r
857 private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)
\r
859 int c_start, c_end;
\r
861 if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)
\r
862 drop_chapterStart.SelectedIndex = 1;
\r
864 int.TryParse(drop_chapterStart.Text, out c_start);
\r
865 int.TryParse(drop_chapterFinish.Text, out c_end);
\r
869 if (c_end < c_start)
\r
870 drop_chapterFinish.Text = c_start.ToString();
\r
873 lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();
\r
875 // Run the Autonaming function
\r
876 if (Properties.Settings.Default.autoNaming)
\r
877 text_destination.Text = Main.autoName(drp_dvdtitle, drop_chapterStart.Text, drop_chapterFinish.Text, text_source.Text, text_destination.Text, drop_format.SelectedIndex);
\r
879 // Add more rows to the Chapter menu if needed.
\r
880 if (Check_ChapterMarkers.Checked)
\r
882 int i = data_chpt.Rows.Count, finish = 0;
\r
884 if (drop_chapterFinish.Text != "Auto")
\r
885 int.TryParse(drop_chapterFinish.Text, out finish);
\r
889 int n = data_chpt.Rows.Add();
\r
890 data_chpt.Rows[n].Cells[0].Value = (i + 1);
\r
891 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);
\r
892 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);
\r
893 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);
\r
898 // Disable chapter markers if only 1 chapter is selected.
\r
899 if (c_start == c_end)
\r
901 Check_ChapterMarkers.Checked = false;
\r
902 Check_ChapterMarkers.Enabled = false;
\r
905 Check_ChapterMarkers.Enabled = true;
\r
909 private void btn_destBrowse_Click(object sender, EventArgs e)
\r
911 // This removes the file extension from the filename box on the save file dialog.
\r
912 // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.
\r
913 DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);
\r
915 if (Path.IsPathRooted(text_destination.Text))
\r
916 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);
\r
918 // Show the dialog and set the main form file path
\r
919 if (drop_format.SelectedIndex.Equals(0))
\r
920 DVD_Save.FilterIndex = 1;
\r
921 else if (drop_format.SelectedIndex.Equals(1))
\r
922 DVD_Save.FilterIndex = 2;
\r
923 else if (drop_format.SelectedIndex.Equals(2))
\r
924 DVD_Save.FilterIndex = 3;
\r
926 if (DVD_Save.ShowDialog() == DialogResult.OK)
\r
928 if (DVD_Save.FileName.StartsWith("\\"))
\r
929 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
932 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames
\r
933 switch (DVD_Save.FilterIndex)
\r
936 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))
\r
937 DVD_Save.FileName += ".mp4";
\r
940 if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))
\r
941 DVD_Save.FileName += ".m4v";
\r
944 if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))
\r
945 DVD_Save.FileName += ".mkv";
\r
951 text_destination.Text = DVD_Save.FileName;
\r
953 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)
\r
954 if (Check_ChapterMarkers.Checked)
\r
955 drop_format.SelectedIndex = 1;
\r
959 private void text_destination_TextChanged(object sender, EventArgs e)
\r
961 string path = text_destination.Text;
\r
962 if (path.EndsWith(".mp4"))
\r
963 drop_format.SelectedIndex = 0;
\r
964 else if (path.EndsWith(".m4v"))
\r
965 drop_format.SelectedIndex = 1;
\r
966 else if (path.EndsWith(".mkv"))
\r
967 drop_format.SelectedIndex = 2;
\r
971 private void drop_format_SelectedIndexChanged(object sender, EventArgs e)
\r
973 if (drop_format.SelectedIndex == 0)
\r
974 setExtension(".mp4");
\r
975 else if (drop_format.SelectedIndex == 1)
\r
976 setExtension(".m4v");
\r
977 else if (drop_format.SelectedIndex == 2)
\r
978 setExtension(".mkv");
\r
980 AudioSettings.setAudioByContainer(drop_format.Text);
\r
981 Subtitles.setContainer(drop_format.SelectedIndex);
\r
984 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
986 oldval = drp_videoEncoder.Text;
\r
987 drp_videoEncoder.Items.Clear();
\r
988 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
989 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
990 if (oldval == "VP3 (Theora)")
\r
991 drp_videoEncoder.SelectedIndex = 1;
\r
993 drp_videoEncoder.Text = oldval;
\r
995 else if (drop_format.Text.Contains("MKV"))
\r
997 oldval = drp_videoEncoder.Text;
\r
998 drp_videoEncoder.Items.Clear();
\r
999 drp_videoEncoder.Items.Add("MPEG-4 (FFmpeg)");
\r
1000 drp_videoEncoder.Items.Add("H.264 (x264)");
\r
1001 drp_videoEncoder.Items.Add("VP3 (Theora)");
\r
1002 drp_videoEncoder.Text = oldval;
\r
1005 private void setExtension(string newExtension)
\r
1007 text_destination.Text = text_destination.Text.Replace(".mp4", newExtension);
\r
1008 text_destination.Text = text_destination.Text.Replace(".m4v", newExtension);
\r
1009 text_destination.Text = text_destination.Text.Replace(".mkv", newExtension);
\r
1013 private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)
\r
1015 setContainerOpts();
\r
1017 //Turn off some options which are H.264 only when the user selects a non h.264 encoder
\r
1018 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1020 if (check_2PassEncode.CheckState == CheckState.Checked)
\r
1021 check_turbo.Enabled = true;
\r
1023 tab_advanced.Enabled = true;
\r
1024 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1025 check_iPodAtom.Enabled = true;
\r
1027 check_iPodAtom.Enabled = false;
\r
1031 check_turbo.CheckState = CheckState.Unchecked;
\r
1032 check_turbo.Enabled = false;
\r
1033 tab_advanced.Enabled = false;
\r
1034 x264Panel.x264Query = "";
\r
1035 check_iPodAtom.Enabled = false;
\r
1036 check_iPodAtom.Checked = false;
\r
1039 // Setup the CQ Slider
\r
1040 switch (drp_videoEncoder.Text)
\r
1042 case "MPEG-4 (FFmpeg)":
\r
1043 slider_videoQuality.Minimum = 1;
\r
1044 slider_videoQuality.Maximum = 31;
\r
1045 slider_videoQuality.Value = 1;
\r
1046 SliderValue.Text = "0% QP: 31.00";
\r
1048 case "H.264 (x264)":
\r
1049 slider_videoQuality.Minimum = 0;
\r
1050 slider_videoQuality.Value = 0;
\r
1051 slider_videoQuality.TickFrequency = 1;
\r
1052 SliderValue.Text = "0% RF: 51.00";
\r
1053 String step = Properties.Settings.Default.x264cqstep;
\r
1057 slider_videoQuality.Maximum = 255;
\r
1060 slider_videoQuality.Maximum = 204;
\r
1063 slider_videoQuality.Maximum = 155;
\r
1066 slider_videoQuality.Maximum = 102;
\r
1069 slider_videoQuality.Maximum = 51;
\r
1072 slider_videoQuality.Maximum = 51;
\r
1076 case "VP3 (Theora)":
\r
1077 slider_videoQuality.Minimum = 0;
\r
1078 slider_videoQuality.Maximum = 63;
\r
1079 slider_videoQuality.Value = 0;
\r
1080 SliderValue.Text = "0% QP: 0.00";
\r
1085 /// Set the container format options
\r
1087 public void setContainerOpts()
\r
1089 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))
\r
1091 check_largeFile.Enabled = true;
\r
1092 check_optimiseMP4.Enabled = true;
\r
1093 check_iPodAtom.Enabled = true;
\r
1097 check_largeFile.Enabled = false;
\r
1098 check_optimiseMP4.Enabled = false;
\r
1099 check_iPodAtom.Enabled = false;
\r
1100 check_largeFile.Checked = false;
\r
1101 check_optimiseMP4.Checked = false;
\r
1102 check_iPodAtom.Checked = false;
\r
1105 private void slider_videoQuality_Scroll(object sender, EventArgs e)
\r
1107 switch (drp_videoEncoder.Text)
\r
1109 case "MPEG-4 (FFmpeg)":
\r
1110 double rfValue = 31 - (slider_videoQuality.Value - 1);
\r
1111 double max = slider_videoQuality.Maximum;
\r
1112 double min = slider_videoQuality.Minimum;
\r
1113 double val = ((max - min) - (rfValue - min)) / (max - min);
\r
1114 SliderValue.Text = Math.Round((val * 100), 2) + "% QP:" + (32 - slider_videoQuality.Value);
\r
1116 case "H.264 (x264)":
\r
1118 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
\r
1119 double.TryParse(Properties.Settings.Default.x264cqstep,
\r
1120 System.Globalization.NumberStyles.Number,
\r
1123 rfValue = 51.0 - slider_videoQuality.Value * divided;
\r
1124 max = slider_videoQuality.Maximum * divided;
\r
1125 min = slider_videoQuality.Minimum;
\r
1126 val = ((max - min) - (rfValue - min)) / (max - min);
\r
1127 rfValue = Math.Round(rfValue, 2);
\r
1128 SliderValue.Text = Math.Round((val * 100), 2) + "% RF:" + rfValue;
\r
1130 case "VP3 (Theora)":
\r
1131 rfValue = slider_videoQuality.Value;
\r
1132 double value = rfValue / 63;
\r
1133 SliderValue.Text = Math.Round((value * 100), 2) + "% QP:" + slider_videoQuality.Value;
\r
1137 private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)
\r
1139 text_bitrate.Enabled = false;
\r
1140 text_filesize.Enabled = true;
\r
1141 slider_videoQuality.Enabled = false;
\r
1143 check_2PassEncode.Enabled = true;
\r
1145 private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)
\r
1147 text_bitrate.Enabled = true;
\r
1148 text_filesize.Enabled = false;
\r
1149 slider_videoQuality.Enabled = false;
\r
1151 check_2PassEncode.Enabled = true;
\r
1153 private void radio_cq_CheckedChanged(object sender, EventArgs e)
\r
1155 text_bitrate.Enabled = false;
\r
1156 text_filesize.Enabled = false;
\r
1157 slider_videoQuality.Enabled = true;
\r
1159 check_2PassEncode.Enabled = false;
\r
1160 check_2PassEncode.CheckState = CheckState.Unchecked;
\r
1162 private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)
\r
1164 if (check_2PassEncode.CheckState.ToString() == "Checked")
\r
1166 if (drp_videoEncoder.Text.Contains("H.264"))
\r
1167 check_turbo.Enabled = true;
\r
1171 check_turbo.Enabled = false;
\r
1172 check_turbo.CheckState = CheckState.Unchecked;
\r
1176 // Chapter Marker Tab
\r
1177 private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)
\r
1179 if (Check_ChapterMarkers.Checked)
\r
1181 drop_format.SelectedIndex = 1;
\r
1182 data_chpt.Rows.Clear();
\r
1183 data_chpt.Enabled = true;
\r
1184 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);
\r
1185 if (chapterGridView != null)
\r
1186 data_chpt = chapterGridView;
\r
1190 drop_format.SelectedIndex = 0;
\r
1191 data_chpt.Rows.Clear();
\r
1192 data_chpt.Enabled = false;
\r
1196 // Query Editor Tab
\r
1197 private void btn_generate_Query_Click(object sender, EventArgs e)
\r
1199 rtf_query.Text = queryGen.generateTheQuery(this);
\r
1201 private void btn_clear_Click(object sender, EventArgs e)
\r
1203 rtf_query.Clear();
\r
1207 // MainWindow Components, Actions and Functions ***********************
\r
1209 #region Source Scan
\r
1210 public Boolean isScanning { get; set; }
\r
1211 private static int scanProcessID { get; set; }
\r
1212 private void setupGUIforScan(String filename)
\r
1214 text_source.Text = filename;
\r
1216 foreach (Control ctrl in Controls)
\r
1218 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))
\r
1219 ctrl.Enabled = false;
\r
1221 lbl_encode.Visible = true;
\r
1222 lbl_encode.Text = "Scanning ...";
\r
1223 gb_source.Text = "Source: Scanning ...";
\r
1224 btn_source.Enabled = false;
\r
1225 btn_start.Enabled = false;
\r
1226 btn_showQueue.Enabled = false;
\r
1227 btn_add2Queue.Enabled = false;
\r
1228 tb_preview.Enabled = false;
\r
1229 mnu_killCLI.Visible = true;
\r
1231 private void startScan(String filename)
\r
1235 lbl_encode.Visible = true;
\r
1236 lbl_encode.Text = "Scanning...";
\r
1237 isScanning = true;
\r
1238 ThreadPool.QueueUserWorkItem(scanProcess, filename);
\r
1240 catch (Exception exc)
\r
1242 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1245 private void scanProcess(object state)
\r
1249 string inputFile = (string)state;
\r
1250 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
1251 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
1252 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
1254 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
1255 if (File.Exists(dvdInfoPath))
\r
1256 File.Delete(dvdInfoPath);
\r
1258 String dvdnav = string.Empty;
\r
1259 if (Properties.Settings.Default.dvdnav)
\r
1260 dvdnav = " --dvdnav";
\r
1261 string strCmdLine = String.Format(@"cmd /c """"{0}"" -i ""{1}"" -t0 {2} -v >""{3}"" 2>&1""", handbrakeCLIPath, inputFile, dvdnav, dvdInfoPath);
\r
1263 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };
\r
1265 Boolean cleanExit = true;
\r
1266 using (hbproc = Process.Start(hbParseDvd))
\r
1268 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.
\r
1269 scanProcessID = Main.getCliProcess(before);
\r
1270 hbproc.WaitForExit();
\r
1271 if (hbproc.ExitCode != 0)
\r
1272 cleanExit = false;
\r
1275 if (cleanExit) // If 0 exit code, CLI exited cleanly.
\r
1277 if (!File.Exists(dvdInfoPath))
\r
1279 throw new Exception(
\r
1280 "Unable to retrieve the DVD Info. last_scan_log.txt is missing. \nExpected location of last_scan_log.txt: \n" +
\r
1284 using (StreamReader sr = new StreamReader(dvdInfoPath))
\r
1286 thisDVD = DVD.Parse(sr);
\r
1291 updateUIafterScan();
\r
1294 catch (Exception exc)
\r
1296 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1300 private void updateUIafterScan()
\r
1304 if (InvokeRequired)
\r
1306 BeginInvoke(new UpdateWindowHandler(updateUIafterScan));
\r
1310 // Setup some GUI components
\r
1311 drp_dvdtitle.Items.Clear();
\r
1312 if (thisDVD.Titles.Count != 0)
\r
1313 drp_dvdtitle.Items.AddRange(thisDVD.Titles.ToArray());
\r
1314 drp_dvdtitle.Text = "Automatic";
\r
1315 drop_chapterFinish.Text = "Auto";
\r
1316 drop_chapterStart.Text = "Auto";
\r
1318 // Now select the longest title
\r
1319 if (thisDVD.Titles.Count != 0)
\r
1320 drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);
\r
1322 // Enable the creation of chapter markers if the file is an image of a dvd.
\r
1323 if (text_source.Text.ToLower().Contains(".iso") || text_source.Text.ToLower().Contains("VIDEO_TS"))
\r
1324 Check_ChapterMarkers.Enabled = true;
\r
1327 Check_ChapterMarkers.Enabled = false;
\r
1328 Check_ChapterMarkers.Checked = false;
\r
1329 data_chpt.Rows.Clear();
\r
1332 // If no titles were found, Display an error message
\r
1333 if (drp_dvdtitle.Items.Count == 0)
\r
1334 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
1336 // Enable the GUI components and enable any disabled components
\r
1339 catch (Exception exc)
\r
1341 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1345 private void enableGUI()
\r
1349 if (InvokeRequired)
\r
1350 BeginInvoke(new UpdateWindowHandler(enableGUI));
\r
1351 lbl_encode.Text = "Scan Completed";
\r
1352 gb_source.Text = "Source";
\r
1353 foreach (Control ctrl in Controls)
\r
1354 ctrl.Enabled = true;
\r
1355 btn_start.Enabled = true;
\r
1356 btn_showQueue.Enabled = true;
\r
1357 btn_add2Queue.Enabled = true;
\r
1358 tb_preview.Enabled = true;
\r
1359 btn_source.Enabled = true;
\r
1360 mnu_killCLI.Visible = false;
\r
1362 catch (Exception exc)
\r
1364 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
1367 private void killScan()
\r
1374 Process[] prs = Process.GetProcesses();
\r
1375 foreach (Process process in prs)
\r
1377 if (process.Id == scanProcessID)
\r
1379 process.Refresh();
\r
1380 if (!process.HasExited)
\r
1385 catch (Exception ex)
\r
1387 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
1390 private void resetGUI()
\r
1392 drp_dvdtitle.Items.Clear();
\r
1393 drp_dvdtitle.Text = "Automatic";
\r
1394 drop_chapterStart.Items.Clear();
\r
1395 drop_chapterStart.Text = "Auto";
\r
1396 drop_chapterFinish.Items.Clear();
\r
1397 drop_chapterFinish.Text = "Auto";
\r
1398 lbl_duration.Text = "Select a Title";
\r
1399 PictureSettings.lbl_src_res.Text = "Select a Title";
\r
1400 PictureSettings.lbl_Aspect.Text = "Select a Title";
\r
1401 text_source.Text = "Click 'Source' to continue";
\r
1402 text_destination.Text = "";
\r
1404 selectedTitle = null;
\r
1405 isScanning = false;
\r
1411 /// Set the GUI to it's finished encoding state.
\r
1413 private void setEncodeFinished()
\r
1417 if (InvokeRequired)
\r
1419 BeginInvoke(new UpdateWindowHandler(setEncodeFinished));
\r
1423 lbl_encode.Text = "Encoding Finished";
\r
1424 btn_start.Text = "Start";
\r
1425 btn_start.ToolTipText = "Start the encoding process";
\r
1426 btn_start.Image = Properties.Resources.Play;
\r
1428 // If the window is minimized, display the notification in a popup.
\r
1429 if (Properties.Settings.Default.trayIconAlerts)
\r
1430 if (FormWindowState.Minimized == this.WindowState)
\r
1432 notifyIcon.BalloonTipText = lbl_encode.Text;
\r
1433 notifyIcon.ShowBalloonTip(500);
\r
1436 catch (Exception exc)
\r
1438 MessageBox.Show(exc.ToString());
\r
1443 /// Set the GUI to it's started encoding state.
\r
1445 private void setEncodeStarted()
\r
1449 if (InvokeRequired)
\r
1451 BeginInvoke(new UpdateWindowHandler(setEncodeStarted));
\r
1455 lbl_encode.Visible = true;
\r
1456 lbl_encode.Text = "Encoding in Progress";
\r
1457 btn_start.Text = "Stop";
\r
1458 btn_start.ToolTipText = "Stop the encoding process.";
\r
1459 btn_start.Image = Properties.Resources.stop;
\r
1461 catch (Exception exc)
\r
1463 MessageBox.Show(exc.ToString());
\r
1468 #region DVD Drive Detection
\r
1469 private delegate void ProgressUpdateHandler();
\r
1470 private void getDriveInfoThread()
\r
1474 if (InvokeRequired)
\r
1476 BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));
\r
1480 Boolean foundDrive = false;
\r
1481 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();
\r
1482 foreach (DriveInfo curDrive in theCollectionOfDrives)
\r
1484 if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)
\r
1486 if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))
\r
1488 mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";
\r
1489 foundDrive = true;
\r
1495 if (foundDrive == false)
\r
1496 mnu_dvd_drive.Text = "[No DVD Drive Ready]";
\r
1500 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";
\r
1505 #region Public Methods
\r
1507 /// Access the preset Handler and setup the preset panel.
\r
1509 public void loadPresetPanel()
\r
1511 if (presetHandler.checkIfPresetsAreOutOfDate())
\r
1512 if (!Properties.Settings.Default.presetNotification)
\r
1514 "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",
\r
1515 "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
\r
1517 presetHandler.getPresetPanel(ref treeView_presets);
\r
1518 treeView_presets.Update();
\r
1522 /// Either Encode or Scan was last performed.
\r
1524 public string lastAction { get; set; }
\r
1529 /// If the queue is being processed, prompt the user to confirm application close.
\r
1531 /// <param name="e"></param>
\r
1532 protected override void OnFormClosing(FormClosingEventArgs e)
\r
1534 // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.
\r
1535 if ((encodeQueue.isEncoding) && (!encodeQueue.isPaused) && (encodeQueue.count() > 0))
\r
1537 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
1538 "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
\r
1539 if (result == DialogResult.No)
\r
1542 base.OnFormClosing(e);
\r
1546 #region In-GUI Encode Status (Experimental)
\r
1548 private void encodeMonitorThread()
\r
1552 Parser encode = new Parser(encodeQueue.encodeHandler.hbProcess.StandardOutput.BaseStream);
\r
1553 encode.OnEncodeProgress += encodeOnEncodeProgress;
\r
1554 while (!encode.EndOfStream)
\r
1556 encode.readEncodeStatus();
\r
1559 catch (Exception exc)
\r
1561 MessageBox.Show(exc.ToString());
\r
1564 private void encodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)
\r
1566 if (this.InvokeRequired)
\r
1568 this.BeginInvoke(new EncodeProgressEventHandler(encodeOnEncodeProgress),
\r
1569 new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });
\r
1572 lbl_encode.Text = string.Format("Encode Progress: {0}%, FPS: {1}, Avg FPS: {2}, Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);
\r
1576 // This is the END of the road ****************************************
\r