OSDN Git Service

3f67f3bc9865f36588e25eb60b4854d7e5642124
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmMain.cs
1 /*  frmMain.cs $\r
2         \r
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
6 \r
7 using System;\r
8 using System.Collections.Generic;\r
9 using System.Drawing;\r
10 using System.Windows.Forms;\r
11 using System.IO;\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
18 \r
19 namespace Handbrake\r
20 {\r
21     public partial class frmMain : Form\r
22     {\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
27 \r
28         // Globals: Mainly used for tracking. *********************************\r
29         Title selectedTitle;\r
30         DVD thisDVD;\r
31         private frmQueue queueWindow;\r
32         private frmPreview qtpreview;\r
33         private Form splash;\r
34 \r
35         // Delegates **********************************************************\r
36         private delegate void UpdateWindowHandler();\r
37         private delegate void UpdateStatusChanger();\r
38 \r
39         // Applicaiton Startup ************************************************\r
40 \r
41         #region Application Startup\r
42         public frmMain()\r
43         {\r
44             // Load and setup the splash screen in this thread\r
45             splash = new frmSplashScreen();\r
46             splash.Show();\r
47             Label lblStatus = new Label { Size = new Size(250, 20), Location = new Point(10, 280) };\r
48             splash.Controls.Add(lblStatus);\r
49 \r
50             InitializeComponent();\r
51 \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
56 \r
57             // Show the form, but leave disabled until preloading is complete then show the main form\r
58             this.Enabled = false;\r
59             this.Show();\r
60             Application.DoEvents(); // Forces frmMain to draw\r
61 \r
62             // Check for new versions, if update checking is enabled\r
63             if (Properties.Settings.Default.updateStatus == "Checked")\r
64             {\r
65                 lblStatus.Text = "Checking for updates ...";\r
66                 Application.DoEvents();\r
67 \r
68                 Thread updateCheckThread = new Thread(startupUpdateCheck);\r
69                 updateCheckThread.Start();\r
70             }\r
71 \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
81 \r
82             // Load the user's default settings or Normal Preset\r
83             if (Properties.Settings.Default.defaultSettings == "Checked" && Properties.Settings.Default.defaultPreset != "")\r
84             {\r
85                 if (presetHandler.getPreset(Properties.Settings.Default.defaultPreset) != null)\r
86                 {\r
87                     string query = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).Query;\r
88                     Boolean loadPictureSettings = presetHandler.getPreset(Properties.Settings.Default.defaultPreset).PictureSettings;\r
89 \r
90                     if (query != null)\r
91                     {\r
92                         //Ok, Reset all the H264 widgets before changing the preset\r
93                         x264Panel.reset2Defaults();\r
94 \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
98 \r
99                         // The x264 widgets will need updated, so do this now:\r
100                         x264Panel.X264_StandardizeOptString();\r
101                         x264Panel.X264_SetCurrentSettingsInPanel();\r
102                     }\r
103                 }\r
104                 else\r
105                     loadNormalPreset();\r
106             }\r
107             else\r
108                 loadNormalPreset();\r
109 \r
110             // Enabled GUI tooltip's if Required\r
111             if (Properties.Settings.Default.tooltipEnable == "Checked")\r
112                 ToolTip.Active = true;\r
113 \r
114             //Finished Loading\r
115             lblStatus.Text = "Loading Complete!";\r
116             Application.DoEvents();\r
117             splash.Close();\r
118             splash.Dispose();\r
119             this.Enabled = true;\r
120 \r
121             // Event Handlers and Queue Recovery\r
122             events();\r
123             queueRecovery();\r
124         }\r
125 \r
126         // Startup Functions   \r
127         private void startupUpdateCheck()\r
128         {\r
129             try\r
130             {\r
131                 if (InvokeRequired)\r
132                 {\r
133                     BeginInvoke(new UpdateStatusChanger(startupUpdateCheck));\r
134                     return;\r
135                 }\r
136 \r
137                 Boolean update = Main.updateCheck(false);\r
138                 if (update)\r
139                 {\r
140                     frmUpdater updateWindow = new frmUpdater();\r
141                     updateWindow.Show();\r
142                 }\r
143             }\r
144             catch (Exception exc)\r
145             {\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
147             }\r
148         }\r
149         private void queueRecovery()\r
150         {\r
151             if (Main.check_queue_recovery())\r
152             {\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
154 \r
155                 if (result == DialogResult.Yes)\r
156                     encodeQueue.recoverQueue("hb_queue_recovery.xml"); // Start Recovery\r
157                 else\r
158                 {\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
163                 }\r
164             }\r
165         }\r
166         #endregion\r
167 \r
168         #region Events\r
169         // Encoding Events for setting up the GUI\r
170         private void events()\r
171         {\r
172             // Handle Window Resize\r
173             if (Properties.Settings.Default.MainWindowMinimize == "Checked")\r
174                 this.Resize += new EventHandler(frmMain_Resize);\r
175 \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
180 \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
184         }\r
185 \r
186         private static void frmMain_DragEnter(object sender, DragEventArgs e)\r
187         {\r
188             if (e.Data.GetDataPresent(DataFormats.FileDrop, false))\r
189                 e.Effect = DragDropEffects.All;\r
190         }\r
191         private void frmMain_DragDrop(object sender, DragEventArgs e)\r
192         {\r
193             string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];\r
194             if (fileList != null)\r
195             {\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
198                 else\r
199                 {\r
200                     if (fileList[0] != "")\r
201                     {\r
202                         setupGUIforScan(fileList[0]);\r
203                         startScan(fileList[0]);\r
204                     }\r
205                     else\r
206                         text_source.Text = "Click 'Source' to continue";\r
207                 }\r
208             }\r
209         }\r
210         private void encodeStarted(object sender, EventArgs e)\r
211         {\r
212             lastAction = "encode";\r
213             setEncodeStarted();\r
214 \r
215             // Experimental HBProc Process Monitoring.\r
216             if (Properties.Settings.Default.enocdeStatusInGui == "Checked")\r
217             {\r
218                 HBProcess = encodeQueue.encodeProcess.hbProcProcess;\r
219                 Thread EncodeMon = new Thread(encodeMonitorThread);\r
220                 EncodeMon.Start();\r
221             }\r
222         }\r
223         private void encodeEnded(object sender, EventArgs e)\r
224         {\r
225             setEncodeFinished();\r
226         }\r
227         private void encodePaused(object sender, EventArgs e)\r
228         {\r
229             setEncodeFinished();\r
230         }\r
231         #endregion\r
232 \r
233         // User Interface Menus / Tool Strips *********************************\r
234 \r
235         #region File Menu\r
236         private void mnu_killCLI_Click(object sender, EventArgs e)\r
237         {\r
238             killScan();\r
239         }\r
240         private void mnu_exit_Click(object sender, EventArgs e)\r
241         {\r
242             Application.Exit();\r
243         }\r
244         #endregion\r
245 \r
246         #region Tools Menu\r
247         private void mnu_encode_Click(object sender, EventArgs e)\r
248         {\r
249             queueWindow.Show();\r
250         }\r
251         private void mnu_encodeLog_Click(object sender, EventArgs e)\r
252         {\r
253             String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";\r
254 \r
255             frmActivityWindow dvdInfoWindow = new frmActivityWindow(file, encodeQueue, this);\r
256             dvdInfoWindow.Show();\r
257         }\r
258         private void mnu_options_Click(object sender, EventArgs e)\r
259         {\r
260             Form Options = new frmOptions();\r
261             Options.ShowDialog();\r
262         }\r
263         #endregion\r
264 \r
265         #region Presets Menu\r
266         private void mnu_presetReset_Click(object sender, EventArgs e)\r
267         {\r
268             presetHandler.updateBuiltInPresets();\r
269             loadPresetPanel();\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
272             else\r
273                 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
274 \r
275             treeView_presets.ExpandAll();\r
276         }\r
277         private void mnu_delete_preset_Click(object sender, EventArgs e)\r
278         {\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
283 \r
284             try\r
285             {\r
286                 FileStream strm = new FileStream(presetsFile, FileMode.Create, FileAccess.Write);\r
287                 strm.Close();\r
288                 strm.Dispose();\r
289             }\r
290             catch (Exception exc)\r
291             {\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
293             }\r
294 \r
295             // Reload the preset panel\r
296             loadPresetPanel();\r
297         }\r
298         private void mnu_SelectDefault_Click(object sender, EventArgs e)\r
299         {\r
300             loadNormalPreset();\r
301         }\r
302         private void btn_new_preset_Click(object sender, EventArgs e)\r
303         {\r
304             Form preset = new frmAddPreset(this, queryGen.GenerateTheQuery(this), presetHandler);\r
305             preset.ShowDialog();\r
306         }\r
307         #endregion\r
308 \r
309         #region Help Menu\r
310         private void mnu_handbrake_forums_Click(object sender, EventArgs e)\r
311         {\r
312             Process.Start("http://forum.handbrake.fr/");\r
313         }\r
314         private void mnu_user_guide_Click(object sender, EventArgs e)\r
315         {\r
316             Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");\r
317         }\r
318         private void mnu_handbrake_home_Click(object sender, EventArgs e)\r
319         {\r
320             Process.Start("http://handbrake.fr");\r
321         }\r
322         private void mnu_UpdateCheck_Click(object sender, EventArgs e)\r
323         {\r
324             Boolean update = Main.updateCheck(true);\r
325             if (update)\r
326             {\r
327                 frmUpdater updateWindow = new frmUpdater();\r
328                 updateWindow.Show();\r
329             }\r
330             else\r
331                 MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
332         }\r
333         private void mnu_about_Click(object sender, EventArgs e)\r
334         {\r
335             Form About = new frmAbout();\r
336             About.ShowDialog();\r
337         }\r
338         #endregion\r
339 \r
340         #region Debug Menu\r
341         private void mnu_qptest_Click(object sender, EventArgs e)\r
342         {\r
343             QueryParserTester qptest = new QueryParserTester();\r
344             qptest.Show();\r
345         }\r
346         #endregion\r
347 \r
348         #region Preset Bar\r
349         // Right Click Menu Code\r
350         private void pmnu_expandAll_Click(object sender, EventArgs e)\r
351         {\r
352             treeView_presets.ExpandAll();\r
353         }\r
354         private void pmnu_collapse_Click(object sender, EventArgs e)\r
355         {\r
356             treeView_presets.CollapseAll();\r
357         }\r
358         private void pmnu_saveChanges_Click(object sender, EventArgs e)\r
359         {\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
365         }\r
366         private void pmnu_delete_click(object sender, EventArgs e)\r
367         {\r
368             if (treeView_presets.SelectedNode != null)\r
369             {\r
370                 presetHandler.remove(treeView_presets.SelectedNode.Text);\r
371                 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode); \r
372             }\r
373             treeView_presets.Select();\r
374         }\r
375         private void presets_menu_Opening(object sender, System.ComponentModel.CancelEventArgs e)\r
376         {\r
377             // Make sure that the save menu is always disabled by default\r
378             pmnu_saveChanges.Enabled = false;\r
379 \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
384 \r
385             treeView_presets.Select();\r
386         }\r
387 \r
388         // Presets Management\r
389         private void btn_addPreset_Click(object sender, EventArgs e)\r
390         {\r
391             Form preset = new frmAddPreset(this, QueryGenerator.generateTabbedComponentsQuery(this), presetHandler);\r
392             preset.ShowDialog();\r
393         }\r
394         private void btn_removePreset_Click(object sender, EventArgs e)\r
395         {\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
398             {\r
399                 if (treeView_presets.SelectedNode != null)\r
400                 {\r
401                     presetHandler.remove(treeView_presets.SelectedNode.Text);\r
402                     treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
403                 }\r
404             }\r
405             treeView_presets.Select();\r
406         }\r
407         private void btn_setDefault_Click(object sender, EventArgs e)\r
408         {\r
409             if (treeView_presets.SelectedNode != null)\r
410             {\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
413                 {\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
417                 }\r
418             }\r
419             else\r
420                 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
421         }\r
422         private void treeview_presets_mouseUp(object sender, MouseEventArgs e)\r
423         {\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
427             {\r
428                 if (treeView_presets.GetNodeAt(e.Location) != null)\r
429                 {\r
430                     if (groupBox_output.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))\r
431                         selectPreset();\r
432                 }\r
433             }\r
434 \r
435             treeView_presets.Select();\r
436         }\r
437         private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)\r
438         {\r
439             selectPreset();\r
440         }\r
441         private void treeView_presets_deleteKey(object sender, KeyEventArgs e)\r
442         {\r
443             if (e.KeyCode == Keys.Delete)\r
444             {\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
447                 {\r
448                     if (treeView_presets.SelectedNode != null)\r
449                         presetHandler.remove(treeView_presets.SelectedNode.Text);\r
450 \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
455 \r
456                     // Now reload the preset panel\r
457                     loadPresetPanel();\r
458 \r
459                     // And finally, re-expand any of the nodes if required\r
460                     int i = 0;\r
461                     foreach (TreeNode node in treeView_presets.Nodes)\r
462                     {\r
463                         if (nodeStatus[i])\r
464                             node.Expand();\r
465 \r
466                         i++;\r
467                     }\r
468                 }\r
469             }\r
470         }\r
471         private void selectPreset()\r
472         {\r
473             if (treeView_presets.SelectedNode != null)\r
474             {\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
478                 {\r
479                     string query = presetHandler.getPreset(presetName).Query;\r
480                     Boolean loadPictureSettings = presetHandler.getPreset(presetName).PictureSettings;\r
481 \r
482                     if (query != null)\r
483                     {\r
484                         //Ok, Reset all the H264 widgets before changing the preset\r
485                         x264Panel.reset2Defaults();\r
486 \r
487                         // Send the query from the file to the Query Parser class\r
488                         QueryParser presetQuery = QueryParser.Parse(query);\r
489 \r
490                         // Now load the preset\r
491                         PresetLoader.presetLoader(this, presetQuery, presetName, loadPictureSettings);\r
492 \r
493                         // The x264 widgets will need updated, so do this now:\r
494                         x264Panel.X264_StandardizeOptString();\r
495                         x264Panel.X264_SetCurrentSettingsInPanel();\r
496                     }\r
497                 }\r
498             }\r
499         }      \r
500         private void loadNormalPreset()\r
501         {\r
502             foreach (TreeNode treenode in treeView_presets.Nodes)\r
503             {\r
504                 foreach (TreeNode node in treenode.Nodes)\r
505                 {\r
506                     if (node.Text.Equals("Normal"))\r
507                         treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];\r
508                 }\r
509             }\r
510         }\r
511         #endregion\r
512 \r
513         #region ToolStrip\r
514         private void btn_source_Click(object sender, EventArgs e)\r
515         {\r
516             if (Properties.Settings.Default.drive_detection == "Checked")\r
517             {\r
518                 mnu_dvd_drive.Visible = true;\r
519                 Thread driveInfoThread = new Thread(getDriveInfoThread);\r
520                 driveInfoThread.Start();\r
521             }\r
522             else\r
523                 mnu_dvd_drive.Visible = false;\r
524         }\r
525         private void btn_start_Click(object sender, EventArgs e)\r
526         {\r
527             if (btn_start.Text == "Stop")\r
528             {\r
529                 DialogResult result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
530 \r
531                 if (result == DialogResult.Yes)\r
532                 {\r
533                     // Pause The Queue\r
534                     encodeQueue.pauseEncodeQueue();\r
535 \r
536                     // Allow the CLI to exit cleanly\r
537                     Win32.SetForegroundWindow(encodeQueue.encodeProcess.processHandle);\r
538                     SendKeys.Send("^C");\r
539 \r
540                     // Update the GUI\r
541                     setEncodeFinished();\r
542                 }\r
543             }\r
544             else\r
545             {\r
546                 if (encodeQueue.count() != 0 || (text_source.Text != string.Empty && text_source.Text != "Click 'Source' to continue" && text_destination.Text != string.Empty))\r
547                 {\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
551 \r
552                     String query = rtf_query.Text != "" ? rtf_query.Text : queryGen.GenerateTheQuery(this);\r
553 \r
554                     if (encodeQueue.count() == 0)\r
555                     {\r
556                         encodeQueue.add(query, text_source.Text, text_destination.Text);\r
557                         encodeQueue.write2disk("hb_queue_recovery.xml");\r
558                     }\r
559                     queueWindow.setQueue();\r
560                     if (encodeQueue.count() > 1)\r
561                         queueWindow.Show(false);\r
562 \r
563                     setEncodeStarted(); // Encode is running, so setup the GUI appropriately\r
564                     encodeQueue.startEncode(); // Start The Queue Encoding Process\r
565                     this.Focus();\r
566                 }\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
569             }\r
570         }\r
571         private void btn_add2Queue_Click(object sender, EventArgs e)\r
572         {\r
573 \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
576             else\r
577             {\r
578                 String query = queryGen.GenerateTheQuery(this);\r
579                 if (rtf_query.Text != "")\r
580                     query = rtf_query.Text;\r
581 \r
582                 if (encodeQueue.checkDestinationPath(text_destination.Text))\r
583                 {\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
588 \r
589                 }\r
590                 else\r
591                     encodeQueue.add(query, text_source.Text, text_destination.Text);\r
592 \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
595             }\r
596         }\r
597         private void btn_showQueue_Click(object sender, EventArgs e)\r
598         {\r
599             queueWindow.Show();\r
600         }\r
601         private void tb_preview_Click(object sender, EventArgs e)\r
602         {\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
605             else\r
606             {\r
607                 if (qtpreview == null)\r
608                 {\r
609                     qtpreview = new frmPreview(this);\r
610                     qtpreview.Show();\r
611                 }\r
612                 else if (qtpreview.IsDisposed)\r
613                 {\r
614                     qtpreview = new frmPreview(this);\r
615                     qtpreview.Show();\r
616                 }\r
617                 else\r
618                     MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
619             }\r
620         }\r
621         private void btn_ActivityWindow_Click(object sender, EventArgs e)\r
622         {\r
623             String file = lastAction == "scan" ? "last_scan_log.txt" : "last_encode_log.txt";\r
624 \r
625             frmActivityWindow ActivityWindow = new frmActivityWindow(file, encodeQueue, this);\r
626             ActivityWindow.Show();\r
627         }\r
628         #endregion\r
629 \r
630         #region System Tray Icon\r
631         private void frmMain_Resize(object sender, EventArgs e)\r
632         {\r
633             if (FormWindowState.Minimized == this.WindowState)\r
634             {\r
635                 notifyIcon.Visible = true;\r
636                 if (!encodeQueue.isEncoding)\r
637                 {\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
641                 }\r
642                 this.Hide();\r
643             }\r
644             else if (FormWindowState.Normal == this.WindowState)\r
645                 notifyIcon.Visible = false;\r
646         }\r
647         private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)\r
648         {\r
649             this.Visible = true;\r
650             this.Activate();\r
651             this.WindowState = FormWindowState.Normal;\r
652             notifyIcon.Visible = false;\r
653         }\r
654         private void btn_restore_Click(object sender, EventArgs e)\r
655         {\r
656             this.Visible = true;\r
657             this.Activate();\r
658             this.WindowState = FormWindowState.Normal;\r
659             notifyIcon.Visible = false;\r
660         }\r
661         #endregion\r
662 \r
663         #region Tab Control\r
664 \r
665         //Source\r
666         private void btn_dvd_source_Click(object sender, EventArgs e)\r
667         {\r
668             // Enable the creation of chapter markers.\r
669             Check_ChapterMarkers.Enabled = true;\r
670 \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
675 \r
676             if (DVD_Open.ShowDialog() == DialogResult.OK)\r
677             {\r
678                 String filename = DVD_Open.SelectedPath;\r
679 \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
682                 else\r
683                 {\r
684                     if (filename != "")\r
685                     {\r
686                         setupGUIforScan(filename);\r
687                         startScan(filename);\r
688                     }\r
689                     else\r
690                         text_source.Text = "Click 'Source' to continue";\r
691                 }\r
692             }\r
693             else\r
694                 text_source.Text = "Click 'Source' to continue";\r
695         }\r
696         private void btn_file_source_Click(object sender, EventArgs e)\r
697         {\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
702 \r
703             if (ISO_Open.ShowDialog() == DialogResult.OK)\r
704             {\r
705                 String filename = ISO_Open.FileName;\r
706                 if (filename.StartsWith("\\"))\r
707                     MessageBox.Show(\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
710                 else\r
711                 {\r
712                     if (filename != "")\r
713                     {\r
714                         setupGUIforScan(filename);\r
715                         startScan(filename);\r
716                     }\r
717                     else\r
718                         text_source.Text = "Click 'Source' to continue";\r
719                 }\r
720             }\r
721             else\r
722                 text_source.Text = "Click 'Source' to continue";\r
723         }\r
724         private void mnu_dvd_drive_Click(object sender, EventArgs e)\r
725         {\r
726             // Enable the creation of chapter markers.\r
727             Check_ChapterMarkers.Enabled = true;\r
728 \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
732 \r
733             if (mnu_dvd_drive.Text.Contains("VIDEO_TS"))\r
734             {\r
735                 string[] path = mnu_dvd_drive.Text.Split(' ');\r
736                 String filename = path[0];\r
737                 setupGUIforScan(filename);\r
738                 startScan(filename);\r
739             }\r
740 \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
744 \r
745             lbl_encode.Text = "";\r
746         }\r
747         private void drp_dvdtitle_Click(object sender, EventArgs e)\r
748         {\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
751         }\r
752         private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)\r
753         {\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
759 \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
763             {\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
767 \r
768                 // Populate the Angles dropdown\r
769                 drop_angle.Items.Clear();\r
770                 if (Properties.Settings.Default.dvdnav == "Checked")\r
771                 {\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
777                 }\r
778                 else\r
779                 {\r
780                     drop_angle.Visible = false;\r
781                     lbl_angle.Visible = false;\r
782                 }\r
783 \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
789 \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
795 \r
796                 // Populate the Audio Channels Dropdown\r
797                 audioPanel.setTrackList(selectedTitle);\r
798 \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
806 \r
807             }\r
808 \r
809             // Run the autoName & chapterNaming functions\r
810             if (Properties.Settings.Default.autoNaming == "Checked")\r
811             {\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
815                 else\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
817             }\r
818 \r
819             data_chpt.Rows.Clear();\r
820             if (selectedTitle.Chapters.Count != 1)\r
821             {\r
822                 DataGridView chapterGridView = Main.chapterNaming(data_chpt, drop_chapterFinish.Text);\r
823                 if (chapterGridView != null)\r
824                     data_chpt = chapterGridView;\r
825             }\r
826             else\r
827             {\r
828                 Check_ChapterMarkers.Checked = false;\r
829                 Check_ChapterMarkers.Enabled = false;\r
830             }\r
831 \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
835         }\r
836         private void drop_chapterStart_SelectedIndexChanged(object sender, EventArgs e)\r
837         {\r
838             int c_start, c_end;\r
839 \r
840             if (drop_chapterFinish.Text == "Auto" && drop_chapterFinish.Items.Count != 0)\r
841                 drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
842 \r
843             int.TryParse(drop_chapterStart.Text, out c_start);\r
844             int.TryParse(drop_chapterFinish.Text, out c_end);\r
845 \r
846             if (c_end != 0)\r
847             {\r
848                 if (c_start > c_end)\r
849                     drop_chapterFinish.Text = c_start.ToString();\r
850             }\r
851 \r
852             lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();\r
853 \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
857 \r
858             // Disable chapter markers if only 1 chapter is selected.\r
859             if (c_start == c_end)\r
860             {\r
861                 Check_ChapterMarkers.Checked = false;\r
862                 Check_ChapterMarkers.Enabled = false;\r
863             }\r
864             else\r
865                 Check_ChapterMarkers.Enabled = true;\r
866         }\r
867         private void drop_chapterFinish_SelectedIndexChanged(object sender, EventArgs e)\r
868         {\r
869             int c_start, c_end;\r
870 \r
871             if (drop_chapterStart.Text == "Auto" && drop_chapterStart.Items.Count >= 1)\r
872                 drop_chapterStart.SelectedIndex = 1;\r
873 \r
874             int.TryParse(drop_chapterStart.Text, out c_start);\r
875             int.TryParse(drop_chapterFinish.Text, out c_end);\r
876 \r
877             if (c_start != 0)\r
878             {\r
879                 if (c_end < c_start)\r
880                     drop_chapterFinish.Text = c_start.ToString();\r
881             }\r
882 \r
883             lbl_duration.Text = Main.calculateDuration(drop_chapterStart.Text, drop_chapterFinish.Text, selectedTitle).ToString();\r
884 \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
888 \r
889             // Add more rows to the Chapter menu if needed.\r
890             if (Check_ChapterMarkers.Checked)\r
891             {\r
892                 int i = data_chpt.Rows.Count, finish = 0;\r
893 \r
894                 if (drop_chapterFinish.Text != "Auto")\r
895                     int.TryParse(drop_chapterFinish.Text, out finish);\r
896 \r
897                 while (i < finish)\r
898                 {\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
904                     i++;\r
905                 }\r
906             }\r
907 \r
908             // Disable chapter markers if only 1 chapter is selected.\r
909             if (c_start == c_end)\r
910             {\r
911                 Check_ChapterMarkers.Checked = false;\r
912                 Check_ChapterMarkers.Enabled = false;\r
913             }\r
914             else\r
915                 Check_ChapterMarkers.Enabled = true;\r
916         }\r
917 \r
918         //Destination\r
919         private void btn_destBrowse_Click(object sender, EventArgs e)\r
920         {\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
924 \r
925             if (Path.IsPathRooted(text_destination.Text))\r
926                 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);\r
927 \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
935 \r
936             if (DVD_Save.ShowDialog() == DialogResult.OK)\r
937             {\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
940                 else\r
941                 {\r
942                     // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames\r
943                     switch (DVD_Save.FilterIndex)\r
944                     {\r
945                         case 1:\r
946                             if (!Path.GetExtension(DVD_Save.FileName).Equals(".mp4", StringComparison.InvariantCultureIgnoreCase))\r
947                                 DVD_Save.FileName += ".mp4";\r
948                             break;\r
949                         case 2:\r
950                             if (!Path.GetExtension(DVD_Save.FileName).Equals(".m4v", StringComparison.InvariantCultureIgnoreCase))\r
951                                 DVD_Save.FileName += ".m4v";\r
952                             break;\r
953                         case 3:\r
954                             if (!Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))\r
955                                 DVD_Save.FileName += ".mkv";\r
956                             break;\r
957                         default:\r
958                             //do nothing  \r
959                             break;\r
960                     }\r
961                     text_destination.Text = DVD_Save.FileName;\r
962 \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
966                 }\r
967             }\r
968         }\r
969         private void text_destination_TextChanged(object sender, EventArgs e)\r
970         {\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
978         }\r
979 \r
980         // Output Settings\r
981         private void drop_format_SelectedIndexChanged(object sender, EventArgs e)\r
982         {\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
989 \r
990             audioPanel.setAudioByContainer(drop_format.Text);\r
991 \r
992             string oldval;\r
993             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
994             {\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
1001                 else\r
1002                     drp_videoEncoder.Text = oldval;\r
1003             }\r
1004             else if (drop_format.Text.Contains("MKV"))\r
1005             {\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
1012             }\r
1013         }\r
1014         private void setExtension(string newExtension)\r
1015         {\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
1019         }\r
1020 \r
1021         //Video Tab\r
1022         private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)\r
1023         {\r
1024             setContainerOpts();\r
1025 \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
1028             {\r
1029                 if (check_2PassEncode.CheckState == CheckState.Checked)\r
1030                     check_turbo.Enabled = true;\r
1031 \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
1035                 else\r
1036                     check_iPodAtom.Enabled = false;\r
1037             }\r
1038             else\r
1039             {\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
1046             }\r
1047 \r
1048             // Setup the CQ Slider\r
1049             switch (drp_videoEncoder.Text)\r
1050             {\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
1056                     break;\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
1063                     switch (step)\r
1064                     {\r
1065                         case "0.20":\r
1066                             slider_videoQuality.Maximum = 255;\r
1067                             break;\r
1068                         case "0.25":\r
1069                             slider_videoQuality.Maximum = 204;\r
1070                             break;\r
1071                         case "0.33":\r
1072                             slider_videoQuality.Maximum = 155;\r
1073                             break;\r
1074                         case "0.50":\r
1075                             slider_videoQuality.Maximum = 102;\r
1076                             break;\r
1077                         case "1.0":\r
1078                             slider_videoQuality.Maximum = 51;\r
1079                             break;\r
1080                         default:\r
1081                             slider_videoQuality.Maximum = 51;\r
1082                             break;\r
1083                     }\r
1084                     break;\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
1090                     break;\r
1091             }\r
1092         }\r
1093         /// <summary>\r
1094         /// Set the container format options\r
1095         /// </summary>\r
1096         public void setContainerOpts()\r
1097         {\r
1098             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1099             {\r
1100                 check_largeFile.Enabled = true;\r
1101                 check_optimiseMP4.Enabled = true;\r
1102                 check_iPodAtom.Enabled = true;\r
1103             }\r
1104             else\r
1105             {\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
1112             }\r
1113         }\r
1114         private void slider_videoQuality_Scroll(object sender, EventArgs e)\r
1115         {\r
1116             switch (drp_videoEncoder.Text)\r
1117             {\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
1124                     break;\r
1125                 case "H.264 (x264)":\r
1126                     double divided;\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
1130                                     culture,\r
1131                                     out divided);\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
1138                     break;\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
1143                     break;\r
1144             }\r
1145         }\r
1146         private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)\r
1147         {\r
1148             text_bitrate.Enabled = false;\r
1149             text_filesize.Enabled = true;\r
1150             slider_videoQuality.Enabled = false;\r
1151 \r
1152             check_2PassEncode.Enabled = true;\r
1153         }\r
1154         private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)\r
1155         {\r
1156             text_bitrate.Enabled = true;\r
1157             text_filesize.Enabled = false;\r
1158             slider_videoQuality.Enabled = false;\r
1159 \r
1160             check_2PassEncode.Enabled = true;\r
1161         }\r
1162         private void radio_cq_CheckedChanged(object sender, EventArgs e)\r
1163         {\r
1164             text_bitrate.Enabled = false;\r
1165             text_filesize.Enabled = false;\r
1166             slider_videoQuality.Enabled = true;\r
1167 \r
1168             check_2PassEncode.Enabled = false;\r
1169             check_2PassEncode.CheckState = CheckState.Unchecked;\r
1170         }\r
1171         private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)\r
1172         {\r
1173             if (check_2PassEncode.CheckState.ToString() == "Checked")\r
1174             {\r
1175                 if (drp_videoEncoder.Text.Contains("H.264"))\r
1176                     check_turbo.Enabled = true;\r
1177             }\r
1178             else\r
1179             {\r
1180                 check_turbo.Enabled = false;\r
1181                 check_turbo.CheckState = CheckState.Unchecked;\r
1182             }\r
1183         }\r
1184 \r
1185         // Filter Tab\r
1186         private void ctl_decomb_changed(object sender, EventArgs e)\r
1187         {\r
1188             if (ctl_decomb.getDropValue != "Off")\r
1189                 if (ctl_deinterlace.getDropValue != "None")\r
1190                     ctl_deinterlace.setOption("None");\r
1191         }\r
1192         private void ctl_deinterlace_changed(object sender, EventArgs e)\r
1193         {\r
1194             if (ctl_detelecine.getDropValue != "None")\r
1195                 if (ctl_decomb.getDropValue != "Off")\r
1196                     ctl_decomb.setOption("Off");\r
1197         }\r
1198         private void slider_deblock_Scroll(object sender, EventArgs e)\r
1199         {\r
1200             lbl_deblockVal.Text = slider_deblock.Value == 4 ? "Off" : slider_deblock.Value.ToString();\r
1201         }\r
1202 \r
1203         //Subtitles Tab\r
1204         private void drp_subtitle_SelectedIndexChanged(object sender, EventArgs e)\r
1205         {\r
1206             if (drp_subtitle.Text.Contains("None"))\r
1207             {\r
1208                 check_forced.Enabled = false;\r
1209                 check_forced.Checked = false;\r
1210             }\r
1211             else\r
1212                 check_forced.Enabled = true;\r
1213         }\r
1214 \r
1215         // Chapter Marker Tab\r
1216         private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)\r
1217         {\r
1218             if (Check_ChapterMarkers.Checked)\r
1219             {\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
1226             }\r
1227             else\r
1228             {\r
1229                 drop_format.SelectedIndex = 0;\r
1230                 data_chpt.Rows.Clear();\r
1231                 data_chpt.Enabled = false;\r
1232             }\r
1233         }\r
1234 \r
1235         // Query Editor Tab\r
1236         private void btn_generate_Query_Click(object sender, EventArgs e)\r
1237         {\r
1238             rtf_query.Text = queryGen.GenerateTheQuery(this);\r
1239         }\r
1240         private void btn_clear_Click(object sender, EventArgs e)\r
1241         {\r
1242             rtf_query.Clear();\r
1243         }\r
1244         #endregion\r
1245 \r
1246         // MainWindow Components, Actions and Functions ***********************\r
1247 \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
1252         {\r
1253             text_source.Text = filename;\r
1254 \r
1255             foreach (Control ctrl in Controls)\r
1256             {\r
1257                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
1258                     ctrl.Enabled = false;\r
1259             }\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
1269         }\r
1270         private void startScan(String filename)\r
1271         {\r
1272             try\r
1273             {\r
1274                 lbl_encode.Visible = true;\r
1275                 lbl_encode.Text = "Scanning...";\r
1276                 isScanning = true;\r
1277                 ThreadPool.QueueUserWorkItem(scanProcess, filename);\r
1278             }\r
1279             catch (Exception exc)\r
1280             {\r
1281                 MessageBox.Show("frmMain.cs - startScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1282             }\r
1283         }\r
1284         private void scanProcess(object state)\r
1285         {\r
1286             try\r
1287             {\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
1292 \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
1296 \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
1301 \r
1302                 ProcessStartInfo hbParseDvd = new ProcessStartInfo("CMD.exe", strCmdLine) { WindowStyle = ProcessWindowStyle.Hidden };\r
1303 \r
1304                 Boolean cleanExit = true;\r
1305                 using (hbproc = Process.Start(hbParseDvd))\r
1306                 {\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
1312                 }\r
1313 \r
1314                 if (cleanExit) // If 0 exit code, CLI exited cleanly.\r
1315                 {\r
1316                     if (!File.Exists(dvdInfoPath))\r
1317                     {\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
1320                             dvdInfoPath);\r
1321                     }\r
1322 \r
1323                     using (StreamReader sr = new StreamReader(dvdInfoPath))\r
1324                     {\r
1325                         thisDVD = DVD.Parse(sr);\r
1326                         sr.Close();\r
1327                         sr.Dispose();\r
1328                     }\r
1329 \r
1330                     updateUIafterScan();\r
1331                 }\r
1332             }\r
1333             catch (Exception exc)\r
1334             {\r
1335                 MessageBox.Show("frmMain.cs - scanProcess() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1336                 enableGUI();\r
1337             }\r
1338         }\r
1339         private void updateUIafterScan()\r
1340         {\r
1341             try\r
1342             {\r
1343                 if (InvokeRequired)\r
1344                 {\r
1345                     BeginInvoke(new UpdateWindowHandler(updateUIafterScan));\r
1346                     return;\r
1347                 }\r
1348 \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
1356 \r
1357                 // Now select the longest title\r
1358                 if (thisDVD.Titles.Count != 0)\r
1359                     drp_dvdtitle.SelectedItem = Main.selectLongestTitle(drp_dvdtitle);\r
1360 \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
1364                 else\r
1365                 {\r
1366                     Check_ChapterMarkers.Enabled = false;\r
1367                     Check_ChapterMarkers.Checked = false;\r
1368                     data_chpt.Rows.Clear();\r
1369                 }\r
1370 \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
1374 \r
1375                 // Enable the GUI components and enable any disabled components\r
1376                 enableGUI();\r
1377             }\r
1378             catch (Exception exc)\r
1379             {\r
1380                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1381                 enableGUI();\r
1382             }\r
1383         }\r
1384         private void enableGUI()\r
1385         {\r
1386             try\r
1387             {\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
1400             }\r
1401             catch (Exception exc)\r
1402             {\r
1403                 MessageBox.Show("frmMain.cs - enableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1404             }\r
1405         }\r
1406         private void killScan()\r
1407         {\r
1408             try\r
1409             {\r
1410                 enableGUI();\r
1411                 resetGUI();\r
1412 \r
1413                 Process[] prs = Process.GetProcesses();\r
1414                 foreach (Process process in prs)\r
1415                 {\r
1416                     if (process.Id == scanProcessID)\r
1417                     {\r
1418                         process.Refresh();\r
1419                         if (!process.HasExited)\r
1420                             process.Kill();\r
1421                     }\r
1422                 }\r
1423             }\r
1424             catch (Exception ex)\r
1425             {\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
1427             }\r
1428         }\r
1429         private void resetGUI()\r
1430         {\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
1442             thisDVD = null;\r
1443             selectedTitle = null;\r
1444             isScanning = false;\r
1445         }\r
1446         #endregion\r
1447 \r
1448         #region GUI\r
1449         /// <summary>\r
1450         /// Set the GUI to it's finished encoding state.\r
1451         /// </summary>\r
1452         private void setEncodeFinished()\r
1453         {\r
1454             try\r
1455             {\r
1456                 if (InvokeRequired)\r
1457                 {\r
1458                     BeginInvoke(new UpdateWindowHandler(setEncodeFinished));\r
1459                     return;\r
1460                 }\r
1461 \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
1466 \r
1467                 // If the window is minimized, display the notification in a popup.\r
1468                 if (FormWindowState.Minimized == this.WindowState)\r
1469                 {\r
1470                     notifyIcon.BalloonTipText = lbl_encode.Text;\r
1471                     notifyIcon.ShowBalloonTip(500);\r
1472                 }\r
1473             }\r
1474             catch (Exception exc)\r
1475             {\r
1476                 MessageBox.Show(exc.ToString());\r
1477             }\r
1478         }\r
1479 \r
1480         /// <summary>\r
1481         /// Set the GUI to it's started encoding state.\r
1482         /// </summary>\r
1483         private void setEncodeStarted()\r
1484         {\r
1485             try\r
1486             {\r
1487                 if (InvokeRequired)\r
1488                 {\r
1489                     BeginInvoke(new UpdateWindowHandler(setEncodeStarted));\r
1490                     return;\r
1491                 }\r
1492 \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
1498             }\r
1499             catch (Exception exc)\r
1500             {\r
1501                 MessageBox.Show(exc.ToString());\r
1502             }\r
1503         }\r
1504         #endregion\r
1505 \r
1506         #region DVD Drive Detection\r
1507         private delegate void ProgressUpdateHandler();\r
1508         private void getDriveInfoThread()\r
1509         {\r
1510             try\r
1511             {\r
1512                 if (InvokeRequired)\r
1513                 {\r
1514                     BeginInvoke(new ProgressUpdateHandler(getDriveInfoThread));\r
1515                     return;\r
1516                 }\r
1517 \r
1518                 Boolean foundDrive = false;\r
1519                 DriveInfo[] theCollectionOfDrives = DriveInfo.GetDrives();\r
1520                 foreach (DriveInfo curDrive in theCollectionOfDrives)\r
1521                 {\r
1522                     if (curDrive.DriveType == DriveType.CDRom && curDrive.IsReady)\r
1523                     {\r
1524                         if (File.Exists(curDrive.RootDirectory + "VIDEO_TS\\VIDEO_TS.IFO"))\r
1525                         {\r
1526                             mnu_dvd_drive.Text = curDrive.RootDirectory + "VIDEO_TS (" + curDrive.VolumeLabel + ")";\r
1527                             foundDrive = true;\r
1528                             break;\r
1529                         }\r
1530                     }\r
1531                 }\r
1532 \r
1533                 if (foundDrive == false)\r
1534                     mnu_dvd_drive.Text = "[No DVD Drive Ready]";\r
1535             }\r
1536             catch (Exception)\r
1537             {\r
1538                 mnu_dvd_drive.Text = "[No DVD Drive Ready / Found]";\r
1539             }\r
1540         }\r
1541         #endregion\r
1542 \r
1543         #region Public Methods\r
1544         /// <summary>\r
1545         /// Access the preset Handler and setup the preset panel.\r
1546         /// </summary>\r
1547         public void loadPresetPanel()\r
1548         {\r
1549             if (presetHandler.checkIfPresetsAreOutOfDate())\r
1550                 if (Properties.Settings.Default.presetNotification == "Unchecked")\r
1551                     MessageBox.Show(\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
1554 \r
1555             presetHandler.getPresetPanel(ref treeView_presets);\r
1556             treeView_presets.Update();\r
1557         }\r
1558 \r
1559         /// <summary>\r
1560         /// Either Encode or Scan was last performed.\r
1561         /// </summary>\r
1562         public string lastAction { get; set; }\r
1563         #endregion\r
1564 \r
1565         #region Overrides\r
1566         /// <summary>\r
1567         /// If the queue is being processed, prompt the user to confirm application close.\r
1568         /// </summary>\r
1569         /// <param name="e"></param>\r
1570         protected override void OnFormClosing(FormClosingEventArgs e)\r
1571         {\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
1574             {\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
1578                     e.Cancel = true;\r
1579             }\r
1580             base.OnFormClosing(e);\r
1581         }\r
1582         #endregion\r
1583 \r
1584         #region In-GUI Encode Status (Experimental)\r
1585         private Process HBProcess { get; set; }\r
1586 \r
1587         private void encodeMonitorThread()\r
1588         {\r
1589             try\r
1590             {\r
1591                 Parser encode = new Parser(HBProcess.StandardOutput.BaseStream);\r
1592                 encode.OnEncodeProgress += encode_OnEncodeProgress;\r
1593                 while (!encode.EndOfStream)\r
1594                 {\r
1595                     encode.readEncodeStatus();\r
1596                 }\r
1597             }\r
1598             catch (Exception exc)\r
1599             {\r
1600                 MessageBox.Show(exc.ToString());\r
1601             }\r
1602         }\r
1603 \r
1604         private void encode_OnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)\r
1605         {\r
1606             if (this.InvokeRequired)\r
1607             {\r
1608                 this.BeginInvoke(new EncodeProgressEventHandler(encode_OnEncodeProgress),\r
1609                     new object[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });\r
1610                 return;\r
1611             }\r
1612             lbl_encode.Text = string.Format("Encode Progress: {0}%,       FPS: {1},       Avg FPS: {2},       Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);\r
1613         }\r
1614         #endregion\r
1615 \r
1616         // This is the END of the road ****************************************\r
1617     }\r
1618 }