OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / frmMain.cs
1 /*  frmMain.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr/>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.ComponentModel;\r
11     using System.Diagnostics;\r
12     using System.Drawing;\r
13     using System.Globalization;\r
14     using System.IO;\r
15     using System.Reflection;\r
16     using System.Threading;\r
17     using System.Windows.Forms;\r
18     using Functions;\r
19     using Model;\r
20     using Parsing;\r
21     using Presets;\r
22     using Properties;\r
23     using Services;\r
24 \r
25     public partial class frmMain : Form\r
26     {\r
27         // Objects which may be used by one or more other objects *************\r
28         private Queue encodeQueue = new Queue();\r
29         private PresetsHandler presetHandler = new PresetsHandler();\r
30 \r
31         // Globals: Mainly used for tracking. *********************************\r
32         public Title selectedTitle;\r
33         private frmQueue queueWindow;\r
34         private frmPreview qtpreview;\r
35         private frmActivityWindow ActivityWindow;\r
36         private Form splash;\r
37         public string sourcePath;\r
38         private ActivityLogMode lastAction;\r
39         private SourceType selectedSourceType;\r
40         private string dvdDrivePath;\r
41         private string dvdDriveLabel;\r
42         private Preset CurrentlySelectedPreset;\r
43         private DVD currentSource;\r
44         private Scan SourceScan = new Scan();\r
45         private List<DriveInformation> drives;\r
46 \r
47         // Delegates **********************************************************\r
48         private delegate void UpdateWindowHandler();\r
49 \r
50         // Applicaiton Startup ************************************************\r
51 \r
52         #region Application Startup\r
53 \r
54         public frmMain()\r
55         {\r
56             // Load and setup the splash screen in this thread\r
57             splash = new frmSplashScreen();\r
58             splash.Show(this);\r
59             Label lblStatus = new Label { Size = new Size(150, 20), Location = new Point(182, 102) };\r
60             splash.Controls.Add(lblStatus);\r
61 \r
62             InitializeComponent();\r
63 \r
64             // Update the users config file with the CLI version data.\r
65             lblStatus.Text = "Checking CLI Version Data ...";\r
66             Application.DoEvents();\r
67             Main.SetCliVersionData();\r
68             Main.CheckForValidCliVersion();\r
69 \r
70             if (Settings.Default.hb_version.Contains("svn"))\r
71             {\r
72                 Version v = Assembly.GetExecutingAssembly().GetName().Version;\r
73                 this.Text += " " + v.ToString(4);\r
74             }\r
75 \r
76             // Show the form, but leave disabled until preloading is complete then show the main form)\r
77             this.Enabled = false;\r
78             this.Show();\r
79             Application.DoEvents(); // Forces frmMain to draw\r
80 \r
81             // Check for new versions, if update checking is enabled\r
82             if (Properties.Settings.Default.updateStatus)\r
83             {\r
84                 DateTime now = DateTime.Now;\r
85                 DateTime lastCheck = Properties.Settings.Default.lastUpdateCheckDate;\r
86                 TimeSpan elapsed = now.Subtract(lastCheck);\r
87                 if (elapsed.TotalDays > Properties.Settings.Default.daysBetweenUpdateCheck)\r
88                 {\r
89                     lblStatus.Text = "Checking for updates ...";\r
90                     Application.DoEvents();\r
91 \r
92                     Main.BeginCheckForUpdates(new AsyncCallback(UpdateCheckDone), false);\r
93                 }\r
94             }\r
95 \r
96             // Clear the log files in the background\r
97             if (Properties.Settings.Default.clearOldLogs)\r
98             {\r
99                 lblStatus.Text = "Clearing Old Log Files ...";\r
100                 Application.DoEvents();\r
101                 Thread clearLog = new Thread(Main.ClearOldLogs);\r
102                 clearLog.Start();\r
103             }\r
104 \r
105             // Setup the GUI components\r
106             lblStatus.Text = "Setting up the GUI ...";\r
107             Application.DoEvents();\r
108             LoadPresetPanel(); // Load the Preset Panel\r
109             treeView_presets.ExpandAll();\r
110             lbl_encode.Text = string.Empty;\r
111             drop_mode.SelectedIndex = 0;\r
112             queueWindow = new frmQueue(encodeQueue, this); // Prepare the Queue\r
113             if (!Properties.Settings.Default.QueryEditorTab)\r
114                 tabs_panel.TabPages.RemoveAt(7); // Remove the query editor tab if the user does not want it enabled.\r
115 \r
116             // Load the user's default settings or Normal Preset\r
117             if (Properties.Settings.Default.defaultPreset != string.Empty)\r
118             {\r
119                 if (presetHandler.GetPreset(Properties.Settings.Default.defaultPreset) != null)\r
120                 {\r
121                     string query = presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).Query;\r
122                     bool loadPictureSettings =\r
123                         presetHandler.GetPreset(Properties.Settings.Default.defaultPreset).PictureSettings;\r
124 \r
125                     if (query != null)\r
126                     {\r
127                         x264Panel.Reset2Defaults();\r
128 \r
129                         QueryParser presetQuery = QueryParser.Parse(query);\r
130                         PresetLoader.LoadPreset(this, presetQuery, Properties.Settings.Default.defaultPreset,\r
131                                                 loadPictureSettings);\r
132 \r
133                         x264Panel.X264_StandardizeOptString();\r
134                         x264Panel.X264_SetCurrentSettingsInPanel();\r
135                     }\r
136                 }\r
137                 else\r
138                     loadNormalPreset();\r
139             }\r
140             else\r
141                 loadNormalPreset();\r
142 \r
143             // Enabled GUI tooltip's if Required\r
144             if (Properties.Settings.Default.tooltipEnable)\r
145                 ToolTip.Active = true;\r
146 \r
147             // Register with Growl (if not using Growl for the encoding completion action, this wont hurt anything)\r
148             GrowlCommunicator.Register();\r
149 \r
150             // Finished Loading\r
151             lblStatus.Text = "Loading Complete!";\r
152             Application.DoEvents();\r
153             splash.Close();\r
154             splash.Dispose();\r
155             this.Enabled = true;\r
156 \r
157             // Event Handlers and Queue Recovery\r
158             events();\r
159             queueRecovery();\r
160         }\r
161 \r
162         private void UpdateCheckDone(IAsyncResult result)\r
163         {\r
164             if (InvokeRequired)\r
165             {\r
166                 Invoke(new MethodInvoker(() => UpdateCheckDone(result)));\r
167                 return;\r
168             }\r
169 \r
170             UpdateCheckInformation info;\r
171 \r
172             try\r
173             {\r
174                 info = Main.EndCheckForUpdates(result);\r
175 \r
176                 if (info.NewVersionAvailable)\r
177                 {\r
178                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
179                     updateWindow.ShowDialog();\r
180                 }\r
181             }\r
182             catch (Exception ex)\r
183             {\r
184                 if ((bool)result.AsyncState)\r
185                     MessageBox.Show(\r
186                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,\r
187                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
188             }\r
189         }\r
190 \r
191         // Startup Functions   \r
192         private void queueRecovery()\r
193         {\r
194             if (Main.CheckQueueRecovery())\r
195             {\r
196                 DialogResult result =\r
197                     MessageBox.Show(\r
198                         "HandBrake has detected unfinished items on the queue from the last time the application was launched. Would you like to recover these?",\r
199                         "Queue Recovery Possible", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
200 \r
201                 if (result == DialogResult.Yes)\r
202                     encodeQueue.LoadQueueFromFile("hb_queue_recovery.xml"); // Start Recovery\r
203                 else\r
204                 {\r
205                     // Remove the Queue recovery file if the user doesn't want to recovery the last queue.\r
206                     string queuePath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
207                     if (File.Exists(queuePath))\r
208                         File.Delete(queuePath);\r
209                 }\r
210             }\r
211         }\r
212 \r
213         #endregion\r
214 \r
215         #region Properties\r
216 \r
217         public string SourceName\r
218         {\r
219             get\r
220             {\r
221                 if (this.selectedSourceType == SourceType.DvdDrive)\r
222                 {\r
223                     return this.dvdDriveLabel;\r
224                 }\r
225 \r
226                 if (Path.GetFileNameWithoutExtension(this.sourcePath) != "VIDEO_TS")\r
227                     return Path.GetFileNameWithoutExtension(this.sourcePath);\r
228 \r
229                 return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.sourcePath));\r
230             }\r
231         }\r
232 \r
233         #endregion\r
234 \r
235         #region Events\r
236 \r
237         // Encoding Events for setting up the GUI\r
238         private void events()\r
239         {\r
240             // Handle Widget changes when preset is selected.\r
241             RegisterPresetEventHandler();\r
242 \r
243             // Handle Window Resize\r
244             if (Properties.Settings.Default.MainWindowMinimize)\r
245                 this.Resize += new EventHandler(frmMain_Resize);\r
246 \r
247             // Handle Encode Start / Finish / Pause\r
248 \r
249             encodeQueue.QueuePauseRequested += new EventHandler(encodePaused);\r
250             encodeQueue.EncodeStarted += new EventHandler(encodeStarted);\r
251             encodeQueue.EncodeEnded += new EventHandler(encodeEnded);\r
252 \r
253             // Handle a file being draged onto the GUI.\r
254             this.DragEnter += new DragEventHandler(frmMain_DragEnter);\r
255             this.DragDrop += new DragEventHandler(frmMain_DragDrop);\r
256         }\r
257 \r
258         // Change the preset label to custom when a user changes a setting. Don't want to give the impression that users can change settings and still be using a preset\r
259         private void RegisterPresetEventHandler()\r
260         {\r
261             // Output Settings\r
262             drop_format.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
263             check_largeFile.CheckedChanged += new EventHandler(changePresetLabel);\r
264             check_iPodAtom.CheckedChanged += new EventHandler(changePresetLabel);\r
265             check_optimiseMP4.CheckedChanged += new EventHandler(changePresetLabel);\r
266 \r
267             // Picture Settings\r
268             // PictureSettings.PictureSettingsChanged += new EventHandler(changePresetLabel);\r
269 \r
270             // Filter Settings\r
271             Filters.FilterSettingsChanged += new EventHandler(changePresetLabel);\r
272 \r
273             // Video Tab\r
274             drp_videoEncoder.SelectedIndexChanged += new EventHandler(changePresetLabel);\r
275             check_2PassEncode.CheckedChanged += new EventHandler(changePresetLabel);\r
276             check_turbo.CheckedChanged += new EventHandler(changePresetLabel);\r
277             text_filesize.TextChanged += new EventHandler(changePresetLabel);\r
278             text_bitrate.TextChanged += new EventHandler(changePresetLabel);\r
279             slider_videoQuality.ValueChanged += new EventHandler(changePresetLabel);\r
280 \r
281             // Audio Panel\r
282             AudioSettings.AudioListChanged += new EventHandler(changePresetLabel);\r
283 \r
284             // Advanced Tab\r
285             x264Panel.rtf_x264Query.TextChanged += new EventHandler(changePresetLabel);\r
286         }\r
287 \r
288         private void UnRegisterPresetEventHandler()\r
289         {\r
290             // Output Settings \r
291             drop_format.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
292             check_largeFile.CheckedChanged -= new EventHandler(changePresetLabel);\r
293             check_iPodAtom.CheckedChanged -= new EventHandler(changePresetLabel);\r
294             check_optimiseMP4.CheckedChanged -= new EventHandler(changePresetLabel);\r
295 \r
296             // Picture Settings\r
297             // PictureSettings.PictureSettingsChanged -= new EventHandler(changePresetLabel);\r
298 \r
299             // Filter Settings\r
300             Filters.FilterSettingsChanged -= new EventHandler(changePresetLabel);\r
301 \r
302             // Video Tab\r
303             drp_videoEncoder.SelectedIndexChanged -= new EventHandler(changePresetLabel);\r
304             check_2PassEncode.CheckedChanged -= new EventHandler(changePresetLabel);\r
305             check_turbo.CheckedChanged -= new EventHandler(changePresetLabel);\r
306             text_filesize.TextChanged -= new EventHandler(changePresetLabel);\r
307             text_bitrate.TextChanged -= new EventHandler(changePresetLabel);\r
308             slider_videoQuality.ValueChanged -= new EventHandler(changePresetLabel);\r
309 \r
310             // Audio Panel\r
311             AudioSettings.AudioListChanged -= new EventHandler(changePresetLabel);\r
312 \r
313             // Advanced Tab\r
314             x264Panel.rtf_x264Query.TextChanged -= new EventHandler(changePresetLabel);\r
315         }\r
316 \r
317         private void changePresetLabel(object sender, EventArgs e)\r
318         {\r
319             labelPreset.Text = "Output Settings (Preset: Custom)";\r
320             CurrentlySelectedPreset = null;\r
321         }\r
322 \r
323         private static void frmMain_DragEnter(object sender, DragEventArgs e)\r
324         {\r
325             if (e.Data.GetDataPresent(DataFormats.FileDrop, false))\r
326                 e.Effect = DragDropEffects.All;\r
327         }\r
328 \r
329         private void frmMain_DragDrop(object sender, DragEventArgs e)\r
330         {\r
331             string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];\r
332             sourcePath = string.Empty;\r
333 \r
334             if (fileList != null)\r
335             {\r
336                 if (fileList[0] != string.Empty)\r
337                 {\r
338                     this.selectedSourceType = SourceType.VideoFile;\r
339                     StartScan(fileList[0], 0);\r
340                 }\r
341                 else\r
342                     UpdateSourceLabel();\r
343             }\r
344             else\r
345                 UpdateSourceLabel();\r
346         }\r
347 \r
348         private void encodeStarted(object sender, EventArgs e)\r
349         {\r
350             lastAction = ActivityLogMode.Encode;\r
351             SetEncodeStarted();\r
352 \r
353             // Experimental HBProc Process Monitoring.\r
354             if (Properties.Settings.Default.enocdeStatusInGui)\r
355             {\r
356                 Thread encodeMon = new Thread(EncodeMonitorThread);\r
357                 encodeMon.Start();\r
358             }\r
359         }\r
360 \r
361         private void encodeEnded(object sender, EventArgs e)\r
362         {\r
363             SetEncodeFinished();\r
364         }\r
365 \r
366         private void encodePaused(object sender, EventArgs e)\r
367         {\r
368             SetEncodeFinished();\r
369         }\r
370 \r
371         #endregion\r
372 \r
373         // User Interface Menus / Tool Strips *********************************\r
374 \r
375         #region File Menu\r
376 \r
377         private void mnu_killCLI_Click(object sender, EventArgs e)\r
378         {\r
379             KillScan();\r
380         }\r
381 \r
382         private void mnu_exit_Click(object sender, EventArgs e)\r
383         {\r
384             Application.Exit();\r
385         }\r
386 \r
387         #endregion\r
388 \r
389         #region Tools Menu\r
390 \r
391         private void mnu_encode_Click(object sender, EventArgs e)\r
392         {\r
393             queueWindow.Show();\r
394         }\r
395 \r
396         private void mnu_encodeLog_Click(object sender, EventArgs e)\r
397         {\r
398             frmActivityWindow dvdInfoWindow = new frmActivityWindow(lastAction, encodeQueue, SourceScan);\r
399             dvdInfoWindow.Show();\r
400         }\r
401 \r
402         private void mnu_options_Click(object sender, EventArgs e)\r
403         {\r
404             Form options = new frmOptions(this);\r
405             options.ShowDialog();\r
406         }\r
407 \r
408         #endregion\r
409 \r
410         #region Presets Menu\r
411 \r
412         private void mnu_presetReset_Click(object sender, EventArgs e)\r
413         {\r
414             presetHandler.UpdateBuiltInPresets();\r
415             LoadPresetPanel();\r
416             if (treeView_presets.Nodes.Count == 0)\r
417                 MessageBox.Show(\r
418                     "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!",\r
419                     "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
420             else\r
421                 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
422 \r
423             treeView_presets.ExpandAll();\r
424         }\r
425 \r
426         private void mnu_delete_preset_Click(object sender, EventArgs e)\r
427         {\r
428             presetHandler.RemoveBuiltInPresets();\r
429             LoadPresetPanel(); // Reload the preset panel\r
430         }\r
431 \r
432         private void mnu_SelectDefault_Click(object sender, EventArgs e)\r
433         {\r
434             loadNormalPreset();\r
435         }\r
436 \r
437         private void mnu_importMacPreset_Click(object sender, EventArgs e)\r
438         {\r
439             ImportPreset();\r
440         }\r
441 \r
442         private void btn_new_preset_Click(object sender, EventArgs e)\r
443         {\r
444             Form preset = new frmAddPreset(this, QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
445                                            presetHandler);\r
446             preset.ShowDialog();\r
447         }\r
448 \r
449         #endregion\r
450 \r
451         #region Help Menu\r
452 \r
453         private void mnu_user_guide_Click(object sender, EventArgs e)\r
454         {\r
455             Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");\r
456         }\r
457 \r
458         private void mnu_handbrake_home_Click(object sender, EventArgs e)\r
459         {\r
460             Process.Start("http://handbrake.fr");\r
461         }\r
462 \r
463         private void mnu_UpdateCheck_Click(object sender, EventArgs e)\r
464         {\r
465             lbl_updateCheck.Visible = true;\r
466             Main.BeginCheckForUpdates(new AsyncCallback(updateCheckDoneMenu), false);\r
467         }\r
468 \r
469         private void updateCheckDoneMenu(IAsyncResult result)\r
470         {\r
471             // Make sure it's running on the calling thread\r
472             if (InvokeRequired)\r
473             {\r
474                 Invoke(new MethodInvoker(() => updateCheckDoneMenu(result)));\r
475                 return;\r
476             }\r
477             UpdateCheckInformation info;\r
478             try\r
479             {\r
480                 // Get the information about the new build, if any, and close the window\r
481                 info = Main.EndCheckForUpdates(result);\r
482 \r
483                 if (info.NewVersionAvailable && info.BuildInformation != null)\r
484                 {\r
485                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
486                     updateWindow.ShowDialog();\r
487                 }\r
488                 else\r
489                     MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,\r
490                                     MessageBoxIcon.Information);\r
491                 lbl_updateCheck.Visible = false;\r
492                 return;\r
493             }\r
494             catch (Exception ex)\r
495             {\r
496                 if ((bool)result.AsyncState)\r
497                     MessageBox.Show(\r
498                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,\r
499                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
500             }\r
501         }\r
502 \r
503         private void mnu_about_Click(object sender, EventArgs e)\r
504         {\r
505             using (frmAbout About = new frmAbout())\r
506             {\r
507                 About.ShowDialog();\r
508             }\r
509         }\r
510 \r
511         #endregion\r
512 \r
513         #region Preset Bar\r
514 \r
515         // Right Click Menu Code\r
516         private void pmnu_expandAll_Click(object sender, EventArgs e)\r
517         {\r
518             treeView_presets.ExpandAll();\r
519         }\r
520 \r
521         private void pmnu_collapse_Click(object sender, EventArgs e)\r
522         {\r
523             treeView_presets.CollapseAll();\r
524         }\r
525 \r
526         private void pmnu_import_Click(object sender, EventArgs e)\r
527         {\r
528             ImportPreset();\r
529         }\r
530 \r
531         private void pmnu_saveChanges_Click(object sender, EventArgs e)\r
532         {\r
533             DialogResult result =\r
534                 MessageBox.Show(\r
535                     "Do you wish to include picture settings when updating the preset: " +\r
536                     treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,\r
537                     MessageBoxIcon.Question);\r
538             if (result == DialogResult.Yes)\r
539                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
540                                      QueryGenerator.GenerateTabbedComponentsQuery(this), true);\r
541             else if (result == DialogResult.No)\r
542                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
543                                      QueryGenerator.GenerateTabbedComponentsQuery(this), false);\r
544         }\r
545 \r
546         private void pmnu_delete_click(object sender, EventArgs e)\r
547         {\r
548             if (treeView_presets.SelectedNode != null)\r
549             {\r
550                 presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
551                 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
552             }\r
553             treeView_presets.Select();\r
554         }\r
555 \r
556         private void presets_menu_Opening(object sender, CancelEventArgs e)\r
557         {\r
558             // Make sure that the save menu is always disabled by default\r
559             pmnu_saveChanges.Enabled = false;\r
560 \r
561             // Now enable the save menu if the selected preset is a user preset\r
562             if (treeView_presets.SelectedNode != null)\r
563                 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))\r
564                     pmnu_saveChanges.Enabled = true;\r
565 \r
566             treeView_presets.Select();\r
567         }\r
568 \r
569         // Presets Management\r
570         private void btn_addPreset_Click(object sender, EventArgs e)\r
571         {\r
572             Form preset = new frmAddPreset(this, QueryGenerator.GenerateTabbedComponentsQuery(this), presetHandler);\r
573             preset.ShowDialog();\r
574         }\r
575 \r
576         private void btn_removePreset_Click(object sender, EventArgs e)\r
577         {\r
578             DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
579                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
580             if (result == DialogResult.Yes)\r
581             {\r
582                 if (treeView_presets.SelectedNode != null)\r
583                 {\r
584                     presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
585                     treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
586                 }\r
587             }\r
588             treeView_presets.Select();\r
589         }\r
590 \r
591         private void btn_setDefault_Click(object sender, EventArgs e)\r
592         {\r
593             if (treeView_presets.SelectedNode != null)\r
594             {\r
595                 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",\r
596                                                       "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
597                 if (result == DialogResult.Yes)\r
598                 {\r
599                     Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;\r
600                     Properties.Settings.Default.Save();\r
601                     MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
602                 }\r
603             }\r
604             else\r
605                 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
606         }\r
607 \r
608         private void treeview_presets_mouseUp(object sender, MouseEventArgs e)\r
609         {\r
610             if (e.Button == MouseButtons.Right)\r
611                 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);\r
612             else if (e.Button == MouseButtons.Left)\r
613             {\r
614                 if (treeView_presets.GetNodeAt(e.Location) != null)\r
615                 {\r
616                     if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))\r
617                         selectPreset();\r
618                 }\r
619             }\r
620 \r
621             treeView_presets.Select();\r
622         }\r
623 \r
624         private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)\r
625         {\r
626             selectPreset();\r
627         }\r
628 \r
629         private void treeView_presets_deleteKey(object sender, KeyEventArgs e)\r
630         {\r
631             if (e.KeyCode == Keys.Delete)\r
632             {\r
633                 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
634                                                       MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
635                 if (result == DialogResult.Yes)\r
636                 {\r
637                     if (treeView_presets.SelectedNode != null)\r
638                         presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
639 \r
640                     // Remember each nodes expanded status so we can reload it\r
641                     List<bool> nodeStatus = new List<bool>();\r
642                     foreach (TreeNode node in treeView_presets.Nodes)\r
643                         nodeStatus.Add(node.IsExpanded);\r
644 \r
645                     // Now reload the preset panel\r
646                     LoadPresetPanel();\r
647 \r
648                     // And finally, re-expand any of the nodes if required\r
649                     int i = 0;\r
650                     foreach (TreeNode node in treeView_presets.Nodes)\r
651                     {\r
652                         if (nodeStatus[i])\r
653                             node.Expand();\r
654 \r
655                         i++;\r
656                     }\r
657                 }\r
658             }\r
659         }\r
660 \r
661         private void selectPreset()\r
662         {\r
663             if (treeView_presets.SelectedNode != null)\r
664             {\r
665                 // Ok, so, we've selected a preset. Now we want to load it.\r
666                 string presetName = treeView_presets.SelectedNode.Text;\r
667                 Preset preset = presetHandler.GetPreset(presetName);\r
668                 if (preset != null)\r
669                 {\r
670                     string query = presetHandler.GetPreset(presetName).Query;\r
671                     bool loadPictureSettings = presetHandler.GetPreset(presetName).PictureSettings;\r
672 \r
673                     if (query != null)\r
674                     {\r
675                         // Ok, Reset all the H264 widgets before changing the preset\r
676                         x264Panel.Reset2Defaults();\r
677 \r
678                         // Send the query from the file to the Query Parser class\r
679                         QueryParser presetQuery = QueryParser.Parse(query);\r
680 \r
681                         // Now load the preset\r
682                         PresetLoader.LoadPreset(this, presetQuery, presetName, loadPictureSettings);\r
683 \r
684                         // The x264 widgets will need updated, so do this now:\r
685                         x264Panel.X264_StandardizeOptString();\r
686                         x264Panel.X264_SetCurrentSettingsInPanel();\r
687 \r
688                         // Finally, let this window have a copy of the preset settings.\r
689                         CurrentlySelectedPreset = preset;\r
690                         PictureSettings.SetPresetCropWarningLabel(preset);\r
691                     }\r
692                 }\r
693             }\r
694         }\r
695 \r
696         private void loadNormalPreset()\r
697         {\r
698             foreach (TreeNode treenode in treeView_presets.Nodes)\r
699             {\r
700                 foreach (TreeNode node in treenode.Nodes)\r
701                 {\r
702                     if (node.Text.Equals("Normal"))\r
703                         treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];\r
704                 }\r
705             }\r
706         }\r
707 \r
708         private void ImportPreset()\r
709         {\r
710             if (openPreset.ShowDialog() == DialogResult.OK)\r
711             {\r
712                 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);\r
713                 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))\r
714                 {\r
715                     DialogResult result =\r
716                         MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",\r
717                                         "Overwrite preset?",\r
718                                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
719                     if (result == DialogResult.Yes)\r
720                     {\r
721                         PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
722                         presetHandler.Update(parsed.PresetName + " (Imported)",\r
723                                              QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
724                                              parsed.UsesPictureSettings);\r
725                     }\r
726                 }\r
727                 else\r
728                 {\r
729                     PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
730                     if (presetHandler.Add(parsed.PresetName + " (Imported)",\r
731                                           QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
732                                           parsed.UsesPictureSettings))\r
733                     {\r
734                         TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")\r
735                                                        {\r
736                                                            ForeColor = Color.Black\r
737                                                        };\r
738                         treeView_presets.Nodes.Add(preset_treeview);\r
739                     }\r
740                 }\r
741             }\r
742         }\r
743 \r
744         #endregion\r
745 \r
746         #region ToolStrip\r
747 \r
748         private void btn_source_Click(object sender, EventArgs e)\r
749         {\r
750             // Remove old Drive Menu Items.\r
751             List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();\r
752             foreach (var item in btn_source.DropDownItems)\r
753             {\r
754                 if (item.GetType() == typeof(ToolStripMenuItem))\r
755                 {\r
756                     ToolStripMenuItem menuItem = (ToolStripMenuItem)item;\r
757                     if (menuItem.Name.StartsWith("Drive"))\r
758                     {\r
759                         itemsToRemove.Add(menuItem);\r
760                     }\r
761                 }\r
762             }\r
763 \r
764             foreach (ToolStripMenuItem item in itemsToRemove)\r
765                 btn_source.DropDownItems.Remove(item);\r
766 \r
767             Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);\r
768             driveInfoThread.Start();\r
769         }\r
770 \r
771         private void btn_start_Click(object sender, EventArgs e)\r
772         {\r
773             if (btn_start.Text == "Stop")\r
774             {\r
775                 DialogResult result;\r
776                 if (Properties.Settings.Default.enocdeStatusInGui &&\r
777                     !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
778                 {\r
779                     result = MessageBox.Show(\r
780                         "Are you sure you wish to cancel the encode?\n\nPlease note, when 'Enable in-GUI encode status' is enabled, stopping this encode will render the file unplayable. ",\r
781                         "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
782                 }\r
783                 else\r
784                 {\r
785                     result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?",\r
786                                              MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
787                 }\r
788 \r
789                 if (result == DialogResult.Yes)\r
790                 {\r
791                     // Pause The Queue\r
792                     encodeQueue.Pause();\r
793 \r
794                     if (Properties.Settings.Default.enocdeStatusInGui &&\r
795                         !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
796                     {\r
797                         encodeQueue.Stop();\r
798                         if (encodeQueue.HbProcess != null)\r
799                             encodeQueue.HbProcess.WaitForExit();\r
800                     }\r
801                     else\r
802                     {\r
803                         encodeQueue.SafelyClose();\r
804                     }\r
805 \r
806                     // Update the GUI\r
807                     SetEncodeFinished();\r
808                 }\r
809             }\r
810             else\r
811             {\r
812                 if (encodeQueue.Count != 0 ||\r
813                     (!string.IsNullOrEmpty(sourcePath) && !string.IsNullOrEmpty(text_destination.Text)))\r
814                 {\r
815                     string generatedQuery = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
816                     string specifiedQuery = rtf_query.Text != string.Empty\r
817                                                 ? rtf_query.Text\r
818                                                 : QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
819                     string query = string.Empty;\r
820 \r
821                     // Check to make sure the generated query matches the GUI settings\r
822                     if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&\r
823                         generatedQuery != specifiedQuery)\r
824                     {\r
825                         DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +\r
826                                                               "does not match the current GUI settings.\n\nBecause the manual query takes " +\r
827                                                               "priority over the GUI, your recently updated settings will not be taken " +\r
828                                                               "into account when encoding this job." +\r
829                                                               Environment.NewLine + Environment.NewLine +\r
830                                                               "Do you want to replace the manual query with the updated GUI-generated query?",\r
831                                                               "Manual Query does not Match GUI",\r
832                                                               MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,\r
833                                                               MessageBoxDefaultButton.Button3);\r
834 \r
835                         switch (result)\r
836                         {\r
837                             case DialogResult.Yes:\r
838                                 // Replace the manual query with the generated one\r
839                                 query = generatedQuery;\r
840                                 rtf_query.Text = generatedQuery;\r
841                                 break;\r
842                             case DialogResult.No:\r
843                                 // Use the manual query\r
844                                 query = specifiedQuery;\r
845                                 break;\r
846                             case DialogResult.Cancel:\r
847                                 // Don't start the encode\r
848                                 return;\r
849                         }\r
850                     }\r
851                     else\r
852                     {\r
853                         query = specifiedQuery;\r
854                     }\r
855 \r
856                     DialogResult overwrite = DialogResult.Yes;\r
857                     if (text_destination.Text != string.Empty)\r
858                         if (File.Exists(text_destination.Text))\r
859                             overwrite =\r
860                                 MessageBox.Show(\r
861                                     "The destination file already exists. Are you sure you want to overwrite it?",\r
862                                     "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
863 \r
864                     if (overwrite == DialogResult.Yes)\r
865                     {\r
866                         if (encodeQueue.Count == 0)\r
867                             encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
868 \r
869                         queueWindow.SetQueue();\r
870                         if (encodeQueue.Count > 1)\r
871                             queueWindow.Show(false);\r
872 \r
873                         SetEncodeStarted(); // Encode is running, so setup the GUI appropriately\r
874                         encodeQueue.Start(); // Start The Queue Encoding Process\r
875                         lastAction = ActivityLogMode.Encode; // Set the last action to encode - Used for activity window.\r
876                     }\r
877                     if (ActivityWindow != null)\r
878                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
879 \r
880                     this.Focus();\r
881                 }\r
882                 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
883                     MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
884                                     MessageBoxIcon.Warning);\r
885             }\r
886         }\r
887 \r
888         private void btn_add2Queue_Click(object sender, EventArgs e)\r
889         {\r
890             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
891                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
892                                 MessageBoxIcon.Warning);\r
893             else\r
894             {\r
895                 string query = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
896                 if (rtf_query.Text != string.Empty)\r
897                     query = rtf_query.Text;\r
898 \r
899                 if (encodeQueue.CheckForDestinationDuplicate(text_destination.Text))\r
900                 {\r
901                     DialogResult result =\r
902                         MessageBox.Show(\r
903                             "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
904                             "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
905                     if (result == DialogResult.Yes)\r
906                         encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
907                 }\r
908                 else\r
909                     encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
910 \r
911                 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";\r
912 \r
913                 queueWindow.Show();\r
914             }\r
915         }\r
916 \r
917         private void btn_showQueue_Click(object sender, EventArgs e)\r
918         {\r
919             queueWindow.Show();\r
920             queueWindow.Activate();\r
921         }\r
922 \r
923         private void tb_preview_Click(object sender, EventArgs e)\r
924         {\r
925             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
926                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
927                                 MessageBoxIcon.Warning);\r
928             else\r
929             {\r
930                 if (qtpreview == null)\r
931                 {\r
932                     qtpreview = new frmPreview(this);\r
933                     qtpreview.Show();\r
934                 }\r
935                 else if (qtpreview.IsDisposed)\r
936                 {\r
937                     qtpreview = new frmPreview(this);\r
938                     qtpreview.Show();\r
939                 }\r
940                 else\r
941                     MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,\r
942                                     MessageBoxIcon.Warning);\r
943             }\r
944         }\r
945 \r
946         private void btn_ActivityWindow_Click(object sender, EventArgs e)\r
947         {\r
948             if (ActivityWindow == null || !ActivityWindow.IsHandleCreated)\r
949                 ActivityWindow = new frmActivityWindow(lastAction, encodeQueue, SourceScan);\r
950             else\r
951                 switch (lastAction)\r
952                 {\r
953                     case ActivityLogMode.Scan:\r
954                         ActivityWindow.SetMode(ActivityLogMode.Scan);\r
955                         break;\r
956                     case ActivityLogMode.Encode:\r
957                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
958                         break;\r
959                     default:\r
960                         ActivityWindow.SetMode(ActivityLogMode.Encode);\r
961                         break;\r
962                 }\r
963 \r
964             ActivityWindow.Show();\r
965             ActivityWindow.Activate();\r
966         }\r
967 \r
968         #endregion\r
969 \r
970         #region System Tray Icon\r
971 \r
972         private void frmMain_Resize(object sender, EventArgs e)\r
973         {\r
974             if (FormWindowState.Minimized == this.WindowState)\r
975             {\r
976                 notifyIcon.Visible = true;\r
977                 this.Hide();\r
978             }\r
979             else if (FormWindowState.Normal == this.WindowState)\r
980                 notifyIcon.Visible = false;\r
981         }\r
982 \r
983         private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)\r
984         {\r
985             this.Visible = true;\r
986             this.Activate();\r
987             this.WindowState = FormWindowState.Normal;\r
988             notifyIcon.Visible = false;\r
989         }\r
990 \r
991         private void btn_restore_Click(object sender, EventArgs e)\r
992         {\r
993             this.Visible = true;\r
994             this.Activate();\r
995             this.WindowState = FormWindowState.Normal;\r
996             notifyIcon.Visible = false;\r
997         }\r
998 \r
999         #endregion\r
1000 \r
1001         #region Tab Control\r
1002 \r
1003         // Source\r
1004         private void btn_dvd_source_Click(object sender, EventArgs e)\r
1005         {\r
1006             if (DVD_Open.ShowDialog() == DialogResult.OK)\r
1007             {\r
1008                 this.selectedSourceType = SourceType.Folder;\r
1009                 SelectSource(DVD_Open.SelectedPath);\r
1010             }\r
1011             else\r
1012                 UpdateSourceLabel();\r
1013         }\r
1014 \r
1015         private void btn_file_source_Click(object sender, EventArgs e)\r
1016         {\r
1017             if (ISO_Open.ShowDialog() == DialogResult.OK)\r
1018             {\r
1019                 this.selectedSourceType = SourceType.VideoFile;\r
1020                 SelectSource(ISO_Open.FileName);\r
1021             }\r
1022             else\r
1023                 UpdateSourceLabel();\r
1024         }\r
1025 \r
1026         private void mnu_dvd_drive_Click(object sender, EventArgs e)\r
1027         {\r
1028             ToolStripMenuItem item = sender as ToolStripMenuItem;\r
1029             if (item != null)\r
1030             {\r
1031                 string driveId = item.Name.Replace("Drive", string.Empty);\r
1032                 int id;\r
1033                 if (int.TryParse(driveId, out id))\r
1034                 {\r
1035 \r
1036                     this.dvdDrivePath = drives[id].RootDirectory;\r
1037                     this.dvdDriveLabel = drives[id].VolumeLabel;\r
1038 \r
1039                     if (this.dvdDrivePath == null) return;\r
1040                     this.selectedSourceType = SourceType.DvdDrive;\r
1041                     SelectSource(this.dvdDrivePath);\r
1042                 }\r
1043             }\r
1044         }\r
1045 \r
1046         private void SelectSource(string file)\r
1047         {\r
1048             Check_ChapterMarkers.Enabled = true;\r
1049             lastAction = ActivityLogMode.Scan;\r
1050             sourcePath = string.Empty;\r
1051 \r
1052             if (file == string.Empty) // Must have a file or path\r
1053             {\r
1054                 UpdateSourceLabel();\r
1055                 return;\r
1056             }\r
1057 \r
1058             sourcePath = Path.GetFileName(file);\r
1059             StartScan(file, 0);\r
1060         }\r
1061 \r
1062         private void drp_dvdtitle_Click(object sender, EventArgs e)\r
1063         {\r
1064             if ((drp_dvdtitle.Items.Count == 1) && (drp_dvdtitle.Items[0].ToString() == "Automatic"))\r
1065                 MessageBox.Show(\r
1066                     "There are no titles to select. Please load a source file by clicking the 'Source' button above before trying to select a title.",\r
1067                     "Alert", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\r
1068         }\r
1069 \r
1070         private void drp_dvdtitle_SelectedIndexChanged(object sender, EventArgs e)\r
1071         {\r
1072             UnRegisterPresetEventHandler();\r
1073             drop_mode.SelectedIndex = 0;\r
1074 \r
1075             drop_chapterStart.Items.Clear();\r
1076             drop_chapterFinish.Items.Clear();\r
1077 \r
1078             // If the dropdown is set to automatic nothing else needs to be done.\r
1079             // Otheriwse if its not, title data has to be loaded from parsing.\r
1080             if (drp_dvdtitle.Text != "Automatic")\r
1081             {\r
1082                 selectedTitle = drp_dvdtitle.SelectedItem as Title;\r
1083                 lbl_duration.Text = selectedTitle.Duration.ToString();\r
1084                 PictureSettings.CurrentlySelectedPreset = CurrentlySelectedPreset;\r
1085                 PictureSettings.Source = selectedTitle; // Setup Picture Settings Tab Control\r
1086 \r
1087                 // Populate the Angles dropdown\r
1088                 drop_angle.Items.Clear();\r
1089                 if (!Properties.Settings.Default.noDvdNav)\r
1090                 {\r
1091                     drop_angle.Visible = true;\r
1092                     lbl_angle.Visible = true;\r
1093                     drop_angle.Items.AddRange(selectedTitle.Angles.ToArray());\r
1094                     if (drop_angle.Items.Count != 0)\r
1095                         drop_angle.SelectedIndex = 0;\r
1096                 }\r
1097                 else\r
1098                 {\r
1099                     drop_angle.Visible = false;\r
1100                     lbl_angle.Visible = false;\r
1101                 }\r
1102 \r
1103                 // Populate the Start chapter Dropdown\r
1104                 drop_chapterStart.Items.Clear();\r
1105                 drop_chapterStart.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1106                 if (drop_chapterStart.Items.Count > 0)\r
1107                     drop_chapterStart.Text = drop_chapterStart.Items[0].ToString();\r
1108 \r
1109                 // Populate the Final Chapter Dropdown\r
1110                 drop_chapterFinish.Items.Clear();\r
1111                 drop_chapterFinish.Items.AddRange(selectedTitle.Chapters.ToArray());\r
1112                 if (drop_chapterFinish.Items.Count > 0)\r
1113                     drop_chapterFinish.Text = drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString();\r
1114 \r
1115                 // Populate the Audio Channels Dropdown\r
1116                 AudioSettings.SetTrackList(selectedTitle, CurrentlySelectedPreset);\r
1117 \r
1118                 // Populate the Subtitles dropdown\r
1119                 Subtitles.SetSubtitleTrackAuto(selectedTitle.Subtitles.ToArray());\r
1120             }\r
1121             // Update the source label if we have multiple streams\r
1122             if (selectedTitle != null)\r
1123                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1124                     labelSource.Text = labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1125 \r
1126             // Run the AutoName & ChapterNaming functions\r
1127             if (Properties.Settings.Default.autoNaming)\r
1128             {\r
1129                 string autoPath = Main.AutoName(this);\r
1130                 if (autoPath != null)\r
1131                     text_destination.Text = autoPath;\r
1132                 else\r
1133                     MessageBox.Show(\r
1134                         "You currently have \"Automatically name output files\" enabled for the destination file box, but you do not have a default directory set.\n\nYou should set a \"Default Path\" in HandBrakes preferences. (See 'Tools' menu -> 'Options' -> 'General' Tab -> 'Default Path')",\r
1135                         "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
1136             }\r
1137 \r
1138             data_chpt.Rows.Clear();\r
1139             if (selectedTitle.Chapters.Count != 1)\r
1140             {\r
1141                 DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1142                 if (chapterGridView != null)\r
1143                     data_chpt = chapterGridView;\r
1144             }\r
1145             else\r
1146             {\r
1147                 Check_ChapterMarkers.Checked = false;\r
1148                 Check_ChapterMarkers.Enabled = false;\r
1149             }\r
1150 \r
1151             // Hack to force the redraw of the scrollbars which don't resize properly when the control is disabled.\r
1152             data_chpt.Columns[0].Width = 166;\r
1153             data_chpt.Columns[0].Width = 165;\r
1154 \r
1155             RegisterPresetEventHandler();\r
1156         }\r
1157 \r
1158         private void chapersChanged(object sender, EventArgs e)\r
1159         {\r
1160             if (drop_mode.SelectedIndex != 0) // Function is not used if we are not in chapters mode.\r
1161                 return;\r
1162 \r
1163             Control ctl = (Control)sender;\r
1164             int chapterStart, chapterEnd;\r
1165             int.TryParse(drop_chapterStart.Text, out chapterStart);\r
1166             int.TryParse(drop_chapterFinish.Text, out chapterEnd);\r
1167 \r
1168             switch (ctl.Name)\r
1169             {\r
1170                 case "drop_chapterStart":\r
1171                     if (drop_chapterFinish.SelectedIndex == -1 && drop_chapterFinish.Items.Count != 0)\r
1172                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1173 \r
1174                     if (chapterEnd != 0)\r
1175                         if (chapterStart > chapterEnd)\r
1176                             drop_chapterFinish.Text = chapterStart.ToString();\r
1177                     break;\r
1178                 case "drop_chapterFinish":\r
1179                     if (drop_chapterStart.Items.Count >= 1 && drop_chapterStart.SelectedIndex == -1)\r
1180                         drop_chapterStart.SelectedIndex = 0;\r
1181 \r
1182                     if (chapterStart != 0)\r
1183                         if (chapterEnd < chapterStart)\r
1184                             drop_chapterFinish.Text = chapterStart.ToString();\r
1185 \r
1186                     // Add more rows to the Chapter menu if needed.\r
1187                     if (Check_ChapterMarkers.Checked)\r
1188                     {\r
1189                         int i = data_chpt.Rows.Count, finish = 0;\r
1190                         int.TryParse(drop_chapterFinish.Text, out finish);\r
1191 \r
1192                         while (i < finish)\r
1193                         {\r
1194                             int n = data_chpt.Rows.Add();\r
1195                             data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
1196                             data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
1197                             data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
1198                             data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
1199                             i++;\r
1200                         }\r
1201                     }\r
1202                     break;\r
1203             }\r
1204 \r
1205             // Update the Duration\r
1206             lbl_duration.Text =\r
1207                 Main.CalculateDuration(drop_chapterStart.SelectedIndex, drop_chapterFinish.SelectedIndex, selectedTitle)\r
1208                     .ToString();\r
1209 \r
1210             // Run the Autonaming function\r
1211             if (Properties.Settings.Default.autoNaming)\r
1212                 text_destination.Text = Main.AutoName(this);\r
1213 \r
1214             // Disable chapter markers if only 1 chapter is selected.\r
1215             if (chapterStart == chapterEnd)\r
1216             {\r
1217                 Check_ChapterMarkers.Enabled = false;\r
1218                 btn_importChapters.Enabled = false;\r
1219                 data_chpt.Enabled = false;\r
1220             }\r
1221             else\r
1222             {\r
1223                 Check_ChapterMarkers.Enabled = true;\r
1224                 if (Check_ChapterMarkers.Checked)\r
1225                 {\r
1226                     btn_importChapters.Enabled = true;\r
1227                     data_chpt.Enabled = true;\r
1228                 }\r
1229             }\r
1230         }\r
1231 \r
1232         private void SecondsOrFramesChanged(object sender, EventArgs e)\r
1233         {\r
1234             int start, end;\r
1235             int.TryParse(drop_chapterStart.Text, out start);\r
1236             int.TryParse(drop_chapterFinish.Text, out end);\r
1237             double duration = end - start;\r
1238 \r
1239             switch (drop_mode.SelectedIndex)\r
1240             {\r
1241                 case 1:\r
1242                     lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1243                     return;\r
1244                 case 2:\r
1245                     if (selectedTitle != null)\r
1246                     {\r
1247                         duration = duration / selectedTitle.Fps;\r
1248                         lbl_duration.Text = TimeSpan.FromSeconds(duration).ToString();\r
1249                     }\r
1250                     else\r
1251                         lbl_duration.Text = "--:--:--";\r
1252 \r
1253                     return;\r
1254             }\r
1255         }\r
1256 \r
1257         private void drop_mode_SelectedIndexChanged(object sender, EventArgs e)\r
1258         {\r
1259             // Reset\r
1260             this.drop_chapterFinish.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1261             this.drop_chapterStart.TextChanged -= new EventHandler(this.SecondsOrFramesChanged);\r
1262 \r
1263             // Do Work\r
1264             switch (drop_mode.SelectedIndex)\r
1265             {\r
1266                 case 0:\r
1267                     drop_chapterStart.DropDownStyle = ComboBoxStyle.DropDownList;\r
1268                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.DropDownList;\r
1269                     if (drop_chapterStart.Items.Count != 0)\r
1270                     {\r
1271                         drop_chapterStart.SelectedIndex = 0;\r
1272                         drop_chapterFinish.SelectedIndex = drop_chapterFinish.Items.Count - 1;\r
1273                     }\r
1274                     else\r
1275                         lbl_duration.Text = "--:--:--";\r
1276                     return;\r
1277                 case 1:\r
1278                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1279                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1280                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1281                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1282                     if (selectedTitle != null)\r
1283                     {\r
1284                         drop_chapterStart.Text = "0";\r
1285                         drop_chapterFinish.Text = selectedTitle.Duration.TotalSeconds.ToString();\r
1286                     }\r
1287                     return;\r
1288                 case 2:\r
1289                     this.drop_chapterStart.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1290                     this.drop_chapterFinish.TextChanged += new EventHandler(this.SecondsOrFramesChanged);\r
1291                     drop_chapterStart.DropDownStyle = ComboBoxStyle.Simple;\r
1292                     drop_chapterFinish.DropDownStyle = ComboBoxStyle.Simple;\r
1293                     if (selectedTitle != null)\r
1294                     {\r
1295                         drop_chapterStart.Text = "0";\r
1296                         drop_chapterFinish.Text = (selectedTitle.Fps * selectedTitle.Duration.TotalSeconds).ToString();\r
1297                     }\r
1298                     return;\r
1299             }\r
1300         }\r
1301 \r
1302         // Destination\r
1303         private void btn_destBrowse_Click(object sender, EventArgs e)\r
1304         {\r
1305             // This removes the file extension from the filename box on the save file dialog.\r
1306             // It's daft but some users don't realise that typing an extension overrides the dropdown extension selected.\r
1307             DVD_Save.FileName = Path.GetFileNameWithoutExtension(text_destination.Text);\r
1308 \r
1309             if (Path.IsPathRooted(text_destination.Text))\r
1310                 DVD_Save.InitialDirectory = Path.GetDirectoryName(text_destination.Text);\r
1311 \r
1312             // Show the dialog and set the main form file path\r
1313             if (drop_format.SelectedIndex.Equals(0))\r
1314                 DVD_Save.FilterIndex = 1;\r
1315             else if (drop_format.SelectedIndex.Equals(1))\r
1316                 DVD_Save.FilterIndex = 2;\r
1317 \r
1318             if (DVD_Save.ShowDialog() == DialogResult.OK)\r
1319             {\r
1320                 // Add a file extension manually, as FileDialog.AddExtension has issues with dots in filenames\r
1321                 switch (DVD_Save.FilterIndex)\r
1322                 {\r
1323                     case 1:\r
1324                         if (\r
1325                             !Path.GetExtension(DVD_Save.FileName).Equals(".mp4",\r
1326                                                                          StringComparison.InvariantCultureIgnoreCase))\r
1327                             if (Properties.Settings.Default.useM4v)\r
1328                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".m4v").Replace(".mkv", ".m4v");\r
1329                             else\r
1330                                 DVD_Save.FileName = DVD_Save.FileName.Replace(".m4v", ".mp4").Replace(".mkv", ".mp4");\r
1331                         break;\r
1332                     case 2:\r
1333                         if (\r
1334                             !Path.GetExtension(DVD_Save.FileName).Equals(".mkv", StringComparison.InvariantCultureIgnoreCase))\r
1335                             DVD_Save.FileName = DVD_Save.FileName.Replace(".mp4", ".mkv").Replace(".m4v", ".mkv");\r
1336                         break;\r
1337                     default:\r
1338                         // do nothing  \r
1339                         break;\r
1340                 }\r
1341                 text_destination.Text = DVD_Save.FileName;\r
1342 \r
1343                 // Quicktime requires .m4v file for chapter markers to work. If checked, change the extension to .m4v (mp4 and m4v are the same thing)\r
1344                 if (Check_ChapterMarkers.Checked && DVD_Save.FilterIndex != 2)\r
1345                     SetExtension(".m4v");\r
1346             }\r
1347         }\r
1348 \r
1349         private void text_destination_TextChanged(object sender, EventArgs e)\r
1350         {\r
1351             string path = text_destination.Text;\r
1352             if (path.EndsWith(".mp4") || path.EndsWith(".m4v"))\r
1353                 drop_format.SelectedIndex = 0;\r
1354             else if (path.EndsWith(".mkv"))\r
1355                 drop_format.SelectedIndex = 1;\r
1356         }\r
1357 \r
1358         // Output Settings\r
1359         private void drop_format_SelectedIndexChanged(object sender, EventArgs e)\r
1360         {\r
1361             switch (drop_format.SelectedIndex)\r
1362             {\r
1363                 case 0:\r
1364                     if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked ||\r
1365                         AudioSettings.RequiresM4V() || Subtitles.RequiresM4V())\r
1366                         SetExtension(".m4v");\r
1367                     else\r
1368                         SetExtension(".mp4");\r
1369                     break;\r
1370                 case 1:\r
1371                     SetExtension(".mkv");\r
1372                     break;\r
1373             }\r
1374 \r
1375             AudioSettings.SetContainer(drop_format.Text);\r
1376             Subtitles.SetContainer(drop_format.SelectedIndex);\r
1377 \r
1378             if (drop_format.Text.Contains("MP4"))\r
1379             {\r
1380                 if (drp_videoEncoder.Items.Contains("VP3 (Theora)"))\r
1381                 {\r
1382                     drp_videoEncoder.Items.Remove("VP3 (Theora)");\r
1383                     drp_videoEncoder.SelectedIndex = 1;\r
1384                 }\r
1385             }\r
1386             else if (drop_format.Text.Contains("MKV"))\r
1387                 drp_videoEncoder.Items.Add("VP3 (Theora)");\r
1388         }\r
1389 \r
1390         public void SetExtension(string newExtension)\r
1391         {\r
1392             if (newExtension == ".mp4" || newExtension == ".m4v")\r
1393                 if (Properties.Settings.Default.useM4v || Check_ChapterMarkers.Checked || AudioSettings.RequiresM4V() ||\r
1394                     Subtitles.RequiresM4V())\r
1395                     newExtension = ".m4v";\r
1396                 else\r
1397                     newExtension = ".mp4";\r
1398 \r
1399             if (Path.HasExtension(newExtension))\r
1400                 text_destination.Text = Path.ChangeExtension(text_destination.Text, newExtension);\r
1401         }\r
1402 \r
1403         // Video Tab\r
1404         private void drp_videoEncoder_SelectedIndexChanged(object sender, EventArgs e)\r
1405         {\r
1406             setContainerOpts();\r
1407 \r
1408             // Turn off some options which are H.264 only when the user selects a non h.264 encoder\r
1409             if (drp_videoEncoder.Text.Contains("H.264"))\r
1410             {\r
1411                 if (check_2PassEncode.CheckState == CheckState.Checked)\r
1412                     check_turbo.Enabled = true;\r
1413 \r
1414                 tab_advanced.Enabled = true;\r
1415                 if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1416                     check_iPodAtom.Enabled = true;\r
1417                 else\r
1418                     check_iPodAtom.Enabled = false;\r
1419             }\r
1420             else\r
1421             {\r
1422                 check_turbo.CheckState = CheckState.Unchecked;\r
1423                 check_turbo.Enabled = false;\r
1424                 tab_advanced.Enabled = false;\r
1425                 x264Panel.X264Query = string.Empty;\r
1426                 check_iPodAtom.Enabled = false;\r
1427                 check_iPodAtom.Checked = false;\r
1428             }\r
1429 \r
1430             // Setup the CQ Slider\r
1431             switch (drp_videoEncoder.Text)\r
1432             {\r
1433                 case "MPEG-4 (FFmpeg)":\r
1434                     if (slider_videoQuality.Value > 31)\r
1435                         slider_videoQuality.Value = 20; // Just reset to 70% QP 10 on encode change.\r
1436                     slider_videoQuality.Minimum = 1;\r
1437                     slider_videoQuality.Maximum = 31;\r
1438                     break;\r
1439                 case "H.264 (x264)":\r
1440                     slider_videoQuality.Minimum = 0;\r
1441                     slider_videoQuality.TickFrequency = 1;\r
1442 \r
1443                     CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");\r
1444                     double cqStep = Properties.Settings.Default.x264cqstep;\r
1445                     double multiplier = 1.0 / cqStep;\r
1446                     double value = slider_videoQuality.Value * multiplier;\r
1447 \r
1448                     slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1449 \r
1450                     if (value < slider_videoQuality.Maximum)\r
1451                         slider_videoQuality.Value = slider_videoQuality.Maximum - (int)value;\r
1452 \r
1453                     break;\r
1454                 case "VP3 (Theora)":\r
1455                     if (slider_videoQuality.Value > 63)\r
1456                         slider_videoQuality.Value = 45; // Just reset to 70% QP 45 on encode change.\r
1457                     slider_videoQuality.Minimum = 0;\r
1458                     slider_videoQuality.Maximum = 63;\r
1459                     break;\r
1460             }\r
1461         }\r
1462 \r
1463         /// <summary>\r
1464         /// Set the container format options\r
1465         /// </summary>\r
1466         public void setContainerOpts()\r
1467         {\r
1468             if ((drop_format.Text.Contains("MP4")) || (drop_format.Text.Contains("M4V")))\r
1469             {\r
1470                 check_largeFile.Enabled = true;\r
1471                 check_optimiseMP4.Enabled = true;\r
1472                 check_iPodAtom.Enabled = true;\r
1473             }\r
1474             else\r
1475             {\r
1476                 check_largeFile.Enabled = false;\r
1477                 check_optimiseMP4.Enabled = false;\r
1478                 check_iPodAtom.Enabled = false;\r
1479                 check_largeFile.Checked = false;\r
1480                 check_optimiseMP4.Checked = false;\r
1481                 check_iPodAtom.Checked = false;\r
1482             }\r
1483         }\r
1484 \r
1485         private double _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1486 \r
1487         /// <summary>\r
1488         /// Update the CQ slider for x264 for a new CQ step. This is set from option\r
1489         /// </summary>\r
1490         public void setQualityFromSlider()\r
1491         {\r
1492             // Work out the current RF value.\r
1493             double cqStep = _cachedCqStep;\r
1494             double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1495 \r
1496             // Change the maximum value for the slider\r
1497             slider_videoQuality.Maximum = (int)(51 / Properties.Settings.Default.x264cqstep);\r
1498 \r
1499             // Reset the CQ slider to RF0\r
1500             slider_videoQuality.Value = slider_videoQuality.Maximum;\r
1501 \r
1502             // Reset the CQ slider back to the previous value as close as possible\r
1503             double cqStepNew = Properties.Settings.Default.x264cqstep;\r
1504             double rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1505             while (rfValueCurrent < rfValue)\r
1506             {\r
1507                 slider_videoQuality.Value--;\r
1508                 rfValueCurrent = 51.0 - slider_videoQuality.Value * cqStepNew;\r
1509             }\r
1510 \r
1511             // Cache the CQ step for the next calculation\r
1512             _cachedCqStep = Properties.Settings.Default.x264cqstep;\r
1513         }\r
1514 \r
1515         private void slider_videoQuality_Scroll(object sender, EventArgs e)\r
1516         {\r
1517             double cqStep = Properties.Settings.Default.x264cqstep;\r
1518             switch (drp_videoEncoder.Text)\r
1519             {\r
1520                 case "MPEG-4 (FFmpeg)":\r
1521                     lbl_SliderValue.Text = "QP:" + (32 - slider_videoQuality.Value);\r
1522                     break;\r
1523                 case "H.264 (x264)":\r
1524                     double rfValue = 51.0 - slider_videoQuality.Value * cqStep;\r
1525                     rfValue = Math.Round(rfValue, 2);\r
1526                     lbl_SliderValue.Text = "RF:" + rfValue.ToString(new CultureInfo("en-US"));\r
1527                     break;\r
1528                 case "VP3 (Theora)":\r
1529                     lbl_SliderValue.Text = "QP:" + slider_videoQuality.Value;\r
1530                     break;\r
1531             }\r
1532         }\r
1533 \r
1534         private void radio_targetFilesize_CheckedChanged(object sender, EventArgs e)\r
1535         {\r
1536             text_bitrate.Enabled = false;\r
1537             text_filesize.Enabled = true;\r
1538             slider_videoQuality.Enabled = false;\r
1539 \r
1540             check_2PassEncode.Enabled = true;\r
1541         }\r
1542 \r
1543         private void radio_avgBitrate_CheckedChanged(object sender, EventArgs e)\r
1544         {\r
1545             text_bitrate.Enabled = true;\r
1546             text_filesize.Enabled = false;\r
1547             slider_videoQuality.Enabled = false;\r
1548 \r
1549             check_2PassEncode.Enabled = true;\r
1550         }\r
1551 \r
1552         private void radio_cq_CheckedChanged(object sender, EventArgs e)\r
1553         {\r
1554             text_bitrate.Enabled = false;\r
1555             text_filesize.Enabled = false;\r
1556             slider_videoQuality.Enabled = true;\r
1557 \r
1558             check_2PassEncode.Enabled = false;\r
1559             check_2PassEncode.CheckState = CheckState.Unchecked;\r
1560         }\r
1561 \r
1562         private void check_2PassEncode_CheckedChanged(object sender, EventArgs e)\r
1563         {\r
1564             if (check_2PassEncode.CheckState.ToString() == "Checked")\r
1565             {\r
1566                 if (drp_videoEncoder.Text.Contains("H.264"))\r
1567                     check_turbo.Enabled = true;\r
1568             }\r
1569             else\r
1570             {\r
1571                 check_turbo.Enabled = false;\r
1572                 check_turbo.CheckState = CheckState.Unchecked;\r
1573             }\r
1574         }\r
1575 \r
1576         // Chapter Marker Tab\r
1577         private void Check_ChapterMarkers_CheckedChanged(object sender, EventArgs e)\r
1578         {\r
1579             if (Check_ChapterMarkers.Checked)\r
1580             {\r
1581                 if (drop_format.SelectedIndex != 1)\r
1582                     SetExtension(".m4v");\r
1583                 data_chpt.Enabled = true;\r
1584                 btn_importChapters.Enabled = true;\r
1585             }\r
1586             else\r
1587             {\r
1588                 if (drop_format.SelectedIndex != 1 && !Properties.Settings.Default.useM4v)\r
1589                     SetExtension(".mp4");\r
1590                 data_chpt.Enabled = false;\r
1591                 btn_importChapters.Enabled = false;\r
1592             }\r
1593         }\r
1594 \r
1595         private void btn_importChapters_Click(object sender, EventArgs e)\r
1596         {\r
1597             if (File_ChapterImport.ShowDialog() == DialogResult.OK)\r
1598             {\r
1599                 string filename = File_ChapterImport.FileName;\r
1600                 DataGridView imported = Main.ImportChapterNames(data_chpt, filename);\r
1601                 if (imported != null)\r
1602                     data_chpt = imported;\r
1603             }\r
1604         }\r
1605 \r
1606         private void btn_export_Click(object sender, EventArgs e)\r
1607         {\r
1608             SaveFileDialog saveFileDialog = new SaveFileDialog();\r
1609             saveFileDialog.Filter = "Csv File|*.csv";\r
1610             saveFileDialog.DefaultExt = "csv";\r
1611             if (saveFileDialog.ShowDialog() == DialogResult.OK)\r
1612             {\r
1613                 string filename = saveFileDialog.FileName;\r
1614 \r
1615                 Main.SaveChapterMarkersToCsv(this, filename);\r
1616             }\r
1617         }\r
1618 \r
1619         private void mnu_resetChapters_Click(object sender, EventArgs e)\r
1620         {\r
1621             data_chpt.Rows.Clear();\r
1622             DataGridView chapterGridView = Main.ChapterNaming(data_chpt, drop_chapterFinish.Text);\r
1623             if (chapterGridView != null)\r
1624             {\r
1625                 data_chpt = chapterGridView;\r
1626             }\r
1627         }\r
1628 \r
1629         // Query Editor Tab\r
1630         private void btn_generate_Query_Click(object sender, EventArgs e)\r
1631         {\r
1632             rtf_query.Text = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
1633         }\r
1634 \r
1635         private void btn_clear_Click(object sender, EventArgs e)\r
1636         {\r
1637             rtf_query.Clear();\r
1638         }\r
1639 \r
1640         #endregion\r
1641 \r
1642         // MainWindow Components, Actions and Functions ***********************\r
1643 \r
1644         #region Source Scan\r
1645 \r
1646         public bool isScanning { get; set; }\r
1647 \r
1648         private void StartScan(string filename, int title)\r
1649         {\r
1650             // Setup the GUI components for the scan.\r
1651             sourcePath = filename;\r
1652 \r
1653             this.DisableGUI();\r
1654 \r
1655             if (ActivityWindow != null)\r
1656                 ActivityWindow.SetMode(ActivityLogMode.Scan);\r
1657 \r
1658             // Start the Scan\r
1659             try\r
1660             {\r
1661                 isScanning = true;\r
1662                 SourceScan = new Scan();\r
1663                 SourceScan.ScanSource(sourcePath, title);\r
1664                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
1665                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
1666             }\r
1667             catch (Exception exc)\r
1668             {\r
1669                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1670             }\r
1671         }\r
1672 \r
1673         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
1674         {\r
1675             UpdateScanStatusLabel();\r
1676         }\r
1677 \r
1678         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
1679         {\r
1680             UpdateGuiAfterScan();\r
1681         }\r
1682 \r
1683         private void UpdateScanStatusLabel()\r
1684         {\r
1685             if (InvokeRequired)\r
1686             {\r
1687                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
1688                 return;\r
1689             }\r
1690             lbl_encode.Text = SourceScan.ScanStatus();\r
1691         }\r
1692 \r
1693         private void UpdateGuiAfterScan()\r
1694         {\r
1695             if (InvokeRequired)\r
1696             {\r
1697                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
1698                 return;\r
1699             }\r
1700 \r
1701             try\r
1702             {\r
1703                 currentSource = SourceScan.SouceData();\r
1704 \r
1705                 // Setup some GUI components\r
1706                 drp_dvdtitle.Items.Clear();\r
1707                 if (currentSource.Titles.Count != 0)\r
1708                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
1709 \r
1710                 foreach (Title title in currentSource.Titles)\r
1711                 {\r
1712                     if (title.MainTitle)\r
1713                     {\r
1714                         drp_dvdtitle.SelectedItem = title;\r
1715                     }\r
1716                 }\r
1717 \r
1718                 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)\r
1719                 {\r
1720                     drp_dvdtitle.SelectedIndex = 0;\r
1721                 }\r
1722 \r
1723                 // Enable the creation of chapter markers if the file is an image of a dvd.\r
1724                 int start, end;\r
1725                 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);\r
1726                 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);\r
1727                 if (end > start)\r
1728                     Check_ChapterMarkers.Enabled = true;\r
1729                 else\r
1730                 {\r
1731                     Check_ChapterMarkers.Enabled = false;\r
1732                     Check_ChapterMarkers.Checked = false;\r
1733                     data_chpt.Rows.Clear();\r
1734                 }\r
1735 \r
1736                 // If no titles were found, Display an error message\r
1737                 if (drp_dvdtitle.Items.Count == 0)\r
1738                 {\r
1739                     MessageBox.Show(\r
1740                         "No Title(s) found. \n\nYour Source may be copy protected, badly mastered or in a format which HandBrake does not support. \nPlease refer to the Documentation and FAQ (see Help Menu).",\r
1741                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
1742                     sourcePath = string.Empty;\r
1743                 }\r
1744                 UpdateSourceLabel();\r
1745 \r
1746                 // Enable the GUI components and enable any disabled components\r
1747                 EnableGUI();\r
1748             }\r
1749             catch (Exception exc)\r
1750             {\r
1751                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,\r
1752                                 MessageBoxIcon.Error);\r
1753                 EnableGUI();\r
1754             }\r
1755         }\r
1756 \r
1757         private void EnableGUI()\r
1758         {\r
1759             try\r
1760             {\r
1761                 if (InvokeRequired)\r
1762                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
1763                 lbl_encode.Text = "Scan Completed";\r
1764                 foreach (Control ctrl in Controls)\r
1765                     ctrl.Enabled = true;\r
1766                 btn_start.Enabled = true;\r
1767                 btn_showQueue.Enabled = true;\r
1768                 btn_add2Queue.Enabled = true;\r
1769                 tb_preview.Enabled = true;\r
1770                 btn_source.Enabled = true;\r
1771                 mnu_killCLI.Visible = false;\r
1772             }\r
1773             catch (Exception exc)\r
1774             {\r
1775                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1776             }\r
1777         }\r
1778 \r
1779         private void DisableGUI()\r
1780         {\r
1781             foreach (Control ctrl in Controls)\r
1782                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
1783                     ctrl.Enabled = false;\r
1784 \r
1785             lbl_encode.Visible = true;\r
1786             lbl_encode.Text = "Scanning ...";\r
1787             btn_source.Enabled = false;\r
1788             btn_start.Enabled = false;\r
1789             btn_showQueue.Enabled = false;\r
1790             btn_add2Queue.Enabled = false;\r
1791             tb_preview.Enabled = false;\r
1792             mnu_killCLI.Visible = true;\r
1793         }\r
1794 \r
1795         private void KillScan()\r
1796         {\r
1797             SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
1798             EnableGUI();\r
1799             ResetGUI();\r
1800 \r
1801             SourceScan.KillScan();\r
1802 \r
1803             lbl_encode.Text = "Scan Cancelled!";\r
1804         }\r
1805 \r
1806         private void ResetGUI()\r
1807         {\r
1808             drp_dvdtitle.Items.Clear();\r
1809             drop_chapterStart.Items.Clear();\r
1810             drop_chapterFinish.Items.Clear();\r
1811             lbl_duration.Text = "Select a Title";\r
1812             PictureSettings.lbl_src_res.Text = "Select a Title";\r
1813             sourcePath = String.Empty;\r
1814             text_destination.Text = String.Empty;\r
1815             selectedTitle = null;\r
1816             isScanning = false;\r
1817         }\r
1818 \r
1819         private void UpdateSourceLabel()\r
1820         {\r
1821             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
1822 \r
1823             if (selectedTitle != null)\r
1824                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1825                     // If it's one of multiple source files, make sure we don't use the folder name\r
1826                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1827         }\r
1828 \r
1829         public void RecievingJob(Job job)\r
1830         {\r
1831             string query = job.Query;\r
1832             StartScan(job.Source, job.Title);\r
1833 \r
1834             if (query != null)\r
1835             {\r
1836                 // Ok, Reset all the H264 widgets before changing the preset\r
1837                 x264Panel.Reset2Defaults();\r
1838 \r
1839                 // Send the query from the file to the Query Parser class\r
1840                 QueryParser presetQuery = QueryParser.Parse(query);\r
1841 \r
1842                 // Now load the preset\r
1843                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);\r
1844 \r
1845                 // The x264 widgets will need updated, so do this now:\r
1846                 x264Panel.X264_StandardizeOptString();\r
1847                 x264Panel.X264_SetCurrentSettingsInPanel();\r
1848 \r
1849                 // Finally, let this window have a copy of the preset settings.\r
1850                 CurrentlySelectedPreset = null;\r
1851                 PictureSettings.SetPresetCropWarningLabel(null);\r
1852             }\r
1853         }\r
1854 \r
1855         #endregion\r
1856 \r
1857         #region GUI Functions and Actions\r
1858 \r
1859         /// <summary>\r
1860         /// Set the GUI to it's finished encoding state.\r
1861         /// </summary>\r
1862         private void SetEncodeFinished()\r
1863         {\r
1864             try\r
1865             {\r
1866                 if (InvokeRequired)\r
1867                 {\r
1868                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
1869                     return;\r
1870                 }\r
1871 \r
1872                 lbl_encode.Text = "Encoding Finished";\r
1873                 btn_start.Text = "Start";\r
1874                 btn_start.ToolTipText = "Start the encoding process";\r
1875                 btn_start.Image = Properties.Resources.Play;\r
1876 \r
1877                 // If the window is minimized, display the notification in a popup.\r
1878                 if (Properties.Settings.Default.trayIconAlerts)\r
1879                     if (FormWindowState.Minimized == this.WindowState)\r
1880                     {\r
1881                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
1882                         notifyIcon.ShowBalloonTip(500);\r
1883                     }\r
1884             }\r
1885             catch (Exception exc)\r
1886             {\r
1887                 MessageBox.Show(exc.ToString());\r
1888             }\r
1889         }\r
1890 \r
1891         /// <summary>\r
1892         /// Set the GUI to it's started encoding state.\r
1893         /// </summary>\r
1894         private void SetEncodeStarted()\r
1895         {\r
1896             try\r
1897             {\r
1898                 if (InvokeRequired)\r
1899                 {\r
1900                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
1901                     return;\r
1902                 }\r
1903 \r
1904                 lbl_encode.Visible = true;\r
1905                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
1906                 btn_start.Text = "Stop";\r
1907                 btn_start.ToolTipText = "Stop the encoding process.";\r
1908                 btn_start.Image = Properties.Resources.stop;\r
1909             }\r
1910             catch (Exception exc)\r
1911             {\r
1912                 MessageBox.Show(exc.ToString());\r
1913             }\r
1914         }\r
1915 \r
1916         /// <summary>\r
1917         /// Set the DVD Drive selection in the "Source" Menu\r
1918         /// </summary>\r
1919         private void SetDriveSelectionMenuItem()\r
1920         {\r
1921             try\r
1922             {\r
1923                 if (InvokeRequired)\r
1924                 {\r
1925                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
1926                     return;\r
1927                 }\r
1928 \r
1929                 drives = Main.GetDrives();\r
1930 \r
1931                 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();\r
1932                 foreach (DriveInformation drive in drives)\r
1933                 {\r
1934                     ToolStripMenuItem menuItem = new ToolStripMenuItem();\r
1935                     menuItem.Name = drive.ToString();\r
1936                     menuItem.Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")";\r
1937                     menuItem.Image = Resources.disc_small;\r
1938                     menuItem.Click += new EventHandler(mnu_dvd_drive_Click);\r
1939                     menuItems.Add(menuItem);\r
1940                 }\r
1941 \r
1942                 foreach (ToolStripMenuItem item in menuItems)\r
1943                     btn_source.DropDownItems.Add(item);\r
1944             }\r
1945             catch (Exception exc)\r
1946             {\r
1947                 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);\r
1948             }\r
1949         }\r
1950 \r
1951         /// <summary>\r
1952         /// Access the preset Handler and setup the preset panel.\r
1953         /// </summary>\r
1954         private void LoadPresetPanel()\r
1955         {\r
1956             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
1957                 if (!Properties.Settings.Default.presetNotification)\r
1958                     MessageBox.Show(splash,\r
1959                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",\r
1960                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
1961 \r
1962             presetHandler.GetPresetPanel(ref treeView_presets);\r
1963             treeView_presets.Update();\r
1964         }\r
1965 \r
1966         /// <summary>\r
1967         /// Get the title from the selected item in the title dropdown.\r
1968         /// </summary>\r
1969         /// <returns>\r
1970         /// The title.\r
1971         /// </returns>\r
1972         private int getTitle()\r
1973         {\r
1974             int title = 0;\r
1975             if (drp_dvdtitle.SelectedItem != null)\r
1976             {\r
1977                 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');\r
1978                 int.TryParse(titleInfo[0], out title);\r
1979             }\r
1980 \r
1981             return title;\r
1982         }\r
1983 \r
1984         #endregion\r
1985 \r
1986         #region Overrides\r
1987 \r
1988         /// <summary>\r
1989         /// Handle GUI shortcuts\r
1990         /// </summary>\r
1991         /// <param name="msg">Message</param>\r
1992         /// <param name="keyData">Keys</param>\r
1993         /// <returns>Bool</returns>\r
1994         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
1995         {\r
1996             if (keyData == (Keys.Control | Keys.S))\r
1997             {\r
1998                 btn_start_Click(this, new EventArgs());\r
1999                 return true;\r
2000             }\r
2001 \r
2002             if (keyData == (Keys.Control | Keys.A))\r
2003             {\r
2004                 btn_add2Queue_Click(this, new EventArgs());\r
2005                 return true;\r
2006             }\r
2007             return base.ProcessCmdKey(ref msg, keyData);\r
2008         }\r
2009 \r
2010         /// <summary>\r
2011         /// If the queue is being processed, prompt the user to confirm application close.\r
2012         /// </summary>\r
2013         /// <param name="e">FormClosingEventArgs</param>\r
2014         protected override void OnFormClosing(FormClosingEventArgs e)\r
2015         {\r
2016             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
2017             if (encodeQueue.IsEncoding)\r
2018             {\r
2019                 DialogResult result =\r
2020                     MessageBox.Show(\r
2021                         "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",\r
2022                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
2023 \r
2024                 if (result == DialogResult.No)\r
2025                     e.Cancel = true;\r
2026 \r
2027                 // Try to safely close out if we can, or kill the cli if using in-gui status\r
2028                 if (Settings.Default.enocdeStatusInGui)\r
2029                     encodeQueue.Stop();\r
2030                 else\r
2031                     encodeQueue.SafelyClose();\r
2032             }\r
2033 \r
2034             if (SourceScan.IsScanning)\r
2035             {\r
2036                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2037                 SourceScan.KillScan();\r
2038             }\r
2039             base.OnFormClosing(e);\r
2040         }\r
2041 \r
2042         #endregion\r
2043 \r
2044         #region In-GUI Encode Status (Experimental)\r
2045 \r
2046         /// <summary>\r
2047         /// Starts a new thread to monitor and process the CLI encode status\r
2048         /// </summary>\r
2049         private void EncodeMonitorThread()\r
2050         {\r
2051             try\r
2052             {\r
2053                 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);\r
2054                 encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
2055                 while (!encode.EndOfStream)\r
2056                     encode.ReadEncodeStatus();\r
2057             }\r
2058             catch (Exception exc)\r
2059             {\r
2060                 MessageBox.Show(exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
2061             }\r
2062         }\r
2063 \r
2064         /// <summary>\r
2065         /// Displays the Encode status in the GUI\r
2066         /// </summary>\r
2067         /// <param name="Sender"></param>\r
2068         /// <param name="CurrentTask"></param>\r
2069         /// <param name="TaskCount"></param>\r
2070         /// <param name="PercentComplete"></param>\r
2071         /// <param name="CurrentFps"></param>\r
2072         /// <param name="AverageFps"></param>\r
2073         /// <param name="TimeRemaining"></param>\r
2074         private void EncodeOnEncodeProgress(object Sender, int CurrentTask, int TaskCount, float PercentComplete, float CurrentFps, float AverageFps, TimeSpan TimeRemaining)\r
2075         {\r
2076             if (this.InvokeRequired)\r
2077             {\r
2078                 this.BeginInvoke(\r
2079                     new EncodeProgressEventHandler(EncodeOnEncodeProgress),\r
2080                     new[] { Sender, CurrentTask, TaskCount, PercentComplete, CurrentFps, AverageFps, TimeRemaining });\r
2081                 return;\r
2082             }\r
2083             lbl_encode.Text =\r
2084                 string.Format("Encode Progress: {0}%,       FPS: {1},       Avg FPS: {2},       Time Remaining: {3} ", PercentComplete, CurrentFps, AverageFps, TimeRemaining);\r
2085         }\r
2086 \r
2087         #endregion\r
2088 \r
2089 \r
2090         // This is the END of the road ****************************************\r
2091     }\r
2092 }