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 SourceType selectedSourceType;\r
39         private string dvdDrivePath;\r
40         private string dvdDriveLabel;\r
41         private Preset CurrentlySelectedPreset;\r
42         private DVD currentSource;\r
43         private ScanService SourceScan = new ScanService();\r
44         private List<DriveInformation> drives;\r
45         private Thread encodeMonitor;\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             SetEncodeStarted();\r
351 \r
352             // Experimental HBProc Process Monitoring.\r
353             if (Properties.Settings.Default.enocdeStatusInGui)\r
354             {\r
355                 encodeMonitor = new Thread(EncodeMonitorThread);\r
356                 encodeMonitor.Start();\r
357             }\r
358         }\r
359 \r
360         private void encodeEnded(object sender, EventArgs e)\r
361         {\r
362             SetEncodeFinished();\r
363         }\r
364 \r
365         private void encodePaused(object sender, EventArgs e)\r
366         {\r
367             SetEncodeFinished();\r
368         }\r
369 \r
370         #endregion\r
371 \r
372         // User Interface Menus / Tool Strips *********************************\r
373 \r
374         #region File Menu\r
375 \r
376         private void mnu_killCLI_Click(object sender, EventArgs e)\r
377         {\r
378             KillScan();\r
379         }\r
380 \r
381         private void mnu_exit_Click(object sender, EventArgs e)\r
382         {\r
383             Application.Exit();\r
384         }\r
385 \r
386         #endregion\r
387 \r
388         #region Tools Menu\r
389 \r
390         private void mnu_encode_Click(object sender, EventArgs e)\r
391         {\r
392             queueWindow.Show();\r
393         }\r
394 \r
395         private void mnu_encodeLog_Click(object sender, EventArgs e)\r
396         {\r
397             frmActivityWindow dvdInfoWindow = new frmActivityWindow(encodeQueue, SourceScan);\r
398             dvdInfoWindow.Show();\r
399         }\r
400 \r
401         private void mnu_options_Click(object sender, EventArgs e)\r
402         {\r
403             Form options = new frmOptions(this);\r
404             options.ShowDialog();\r
405         }\r
406 \r
407         #endregion\r
408 \r
409         #region Presets Menu\r
410 \r
411         private void mnu_presetReset_Click(object sender, EventArgs e)\r
412         {\r
413             presetHandler.UpdateBuiltInPresets();\r
414             LoadPresetPanel();\r
415             if (treeView_presets.Nodes.Count == 0)\r
416                 MessageBox.Show(\r
417                     "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
418                     "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
419             else\r
420                 MessageBox.Show("Presets have been updated!", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
421 \r
422             treeView_presets.ExpandAll();\r
423         }\r
424 \r
425         private void mnu_delete_preset_Click(object sender, EventArgs e)\r
426         {\r
427             presetHandler.RemoveBuiltInPresets();\r
428             LoadPresetPanel(); // Reload the preset panel\r
429         }\r
430 \r
431         private void mnu_SelectDefault_Click(object sender, EventArgs e)\r
432         {\r
433             loadNormalPreset();\r
434         }\r
435 \r
436         private void mnu_importMacPreset_Click(object sender, EventArgs e)\r
437         {\r
438             ImportPreset();\r
439         }\r
440 \r
441         private void mnu_exportMacPreset_Click(object sender, EventArgs e)\r
442         {\r
443             ExportPreset();\r
444         }\r
445 \r
446 \r
447         private void btn_new_preset_Click(object sender, EventArgs e)\r
448         {\r
449             Form preset = new frmAddPreset(this, QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
450                                            presetHandler);\r
451             preset.ShowDialog();\r
452         }\r
453 \r
454         #endregion\r
455 \r
456         #region Help Menu\r
457 \r
458         private void mnu_user_guide_Click(object sender, EventArgs e)\r
459         {\r
460             Process.Start("http://trac.handbrake.fr/wiki/HandBrakeGuide");\r
461         }\r
462 \r
463         private void mnu_handbrake_home_Click(object sender, EventArgs e)\r
464         {\r
465             Process.Start("http://handbrake.fr");\r
466         }\r
467 \r
468         private void mnu_UpdateCheck_Click(object sender, EventArgs e)\r
469         {\r
470             lbl_updateCheck.Visible = true;\r
471             Main.BeginCheckForUpdates(new AsyncCallback(updateCheckDoneMenu), false);\r
472         }\r
473 \r
474         private void updateCheckDoneMenu(IAsyncResult result)\r
475         {\r
476             // Make sure it's running on the calling thread\r
477             if (InvokeRequired)\r
478             {\r
479                 Invoke(new MethodInvoker(() => updateCheckDoneMenu(result)));\r
480                 return;\r
481             }\r
482             UpdateCheckInformation info;\r
483             try\r
484             {\r
485                 // Get the information about the new build, if any, and close the window\r
486                 info = Main.EndCheckForUpdates(result);\r
487 \r
488                 if (info.NewVersionAvailable && info.BuildInformation != null)\r
489                 {\r
490                     frmUpdater updateWindow = new frmUpdater(info.BuildInformation);\r
491                     updateWindow.ShowDialog();\r
492                 }\r
493                 else\r
494                     MessageBox.Show("There are no new updates at this time.", "Update Check", MessageBoxButtons.OK,\r
495                                     MessageBoxIcon.Information);\r
496                 lbl_updateCheck.Visible = false;\r
497                 return;\r
498             }\r
499             catch (Exception ex)\r
500             {\r
501                 if ((bool)result.AsyncState)\r
502                     MessageBox.Show(\r
503                         "Unable to check for updates, Please try again later.\n\nDetailed Error Information:\n" + ex,\r
504                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
505             }\r
506         }\r
507 \r
508         private void mnu_about_Click(object sender, EventArgs e)\r
509         {\r
510             using (frmAbout About = new frmAbout())\r
511             {\r
512                 About.ShowDialog();\r
513             }\r
514         }\r
515 \r
516         #endregion\r
517 \r
518         #region Preset Bar\r
519 \r
520         // Right Click Menu Code\r
521         private void pmnu_expandAll_Click(object sender, EventArgs e)\r
522         {\r
523             treeView_presets.ExpandAll();\r
524         }\r
525 \r
526         private void pmnu_collapse_Click(object sender, EventArgs e)\r
527         {\r
528             treeView_presets.CollapseAll();\r
529         }\r
530 \r
531         private void pmnu_import_Click(object sender, EventArgs e)\r
532         {\r
533             ImportPreset();\r
534         }\r
535 \r
536         private void pmnu_saveChanges_Click(object sender, EventArgs e)\r
537         {\r
538             DialogResult result =\r
539                 MessageBox.Show(\r
540                     "Do you wish to include picture settings when updating the preset: " +\r
541                     treeView_presets.SelectedNode.Text, "Update Preset", MessageBoxButtons.YesNoCancel,\r
542                     MessageBoxIcon.Question);\r
543             if (result == DialogResult.Yes)\r
544                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
545                                      QueryGenerator.GenerateTabbedComponentsQuery(this), true);\r
546             else if (result == DialogResult.No)\r
547                 presetHandler.Update(treeView_presets.SelectedNode.Text,\r
548                                      QueryGenerator.GenerateTabbedComponentsQuery(this), false);\r
549         }\r
550 \r
551         private void pmnu_delete_click(object sender, EventArgs e)\r
552         {\r
553             if (treeView_presets.SelectedNode != null)\r
554             {\r
555                 presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
556                 treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
557             }\r
558             treeView_presets.Select();\r
559         }\r
560 \r
561         private void presets_menu_Opening(object sender, CancelEventArgs e)\r
562         {\r
563             // Make sure that the save menu is always disabled by default\r
564             pmnu_saveChanges.Enabled = false;\r
565 \r
566             // Now enable the save menu if the selected preset is a user preset\r
567             if (treeView_presets.SelectedNode != null)\r
568                 if (presetHandler.CheckIfUserPresetExists(treeView_presets.SelectedNode.Text))\r
569                     pmnu_saveChanges.Enabled = true;\r
570 \r
571             treeView_presets.Select();\r
572         }\r
573 \r
574         // Presets Management\r
575         private void btn_addPreset_Click(object sender, EventArgs e)\r
576         {\r
577             Form preset = new frmAddPreset(this, QueryGenerator.GenerateTabbedComponentsQuery(this), presetHandler);\r
578             preset.ShowDialog();\r
579         }\r
580 \r
581         private void btn_removePreset_Click(object sender, EventArgs e)\r
582         {\r
583             DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
584                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
585             if (result == DialogResult.Yes)\r
586             {\r
587                 if (treeView_presets.SelectedNode != null)\r
588                 {\r
589                     presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
590                     treeView_presets.Nodes.Remove(treeView_presets.SelectedNode);\r
591                 }\r
592             }\r
593             treeView_presets.Select();\r
594         }\r
595 \r
596         private void btn_setDefault_Click(object sender, EventArgs e)\r
597         {\r
598             if (treeView_presets.SelectedNode != null)\r
599             {\r
600                 DialogResult result = MessageBox.Show("Are you sure you wish to set this preset as the default?",\r
601                                                       "Preset", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
602                 if (result == DialogResult.Yes)\r
603                 {\r
604                     Properties.Settings.Default.defaultPreset = treeView_presets.SelectedNode.Text;\r
605                     Properties.Settings.Default.Save();\r
606                     MessageBox.Show("New default preset set.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
607                 }\r
608             }\r
609             else\r
610                 MessageBox.Show("Please select a preset first.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
611         }\r
612 \r
613         private void treeview_presets_mouseUp(object sender, MouseEventArgs e)\r
614         {\r
615             if (e.Button == MouseButtons.Right)\r
616                 treeView_presets.SelectedNode = treeView_presets.GetNodeAt(e.Location);\r
617             else if (e.Button == MouseButtons.Left)\r
618             {\r
619                 if (treeView_presets.GetNodeAt(e.Location) != null)\r
620                 {\r
621                     if (labelPreset.Text.Contains(treeView_presets.GetNodeAt(e.Location).Text))\r
622                         selectPreset();\r
623                 }\r
624             }\r
625 \r
626             treeView_presets.Select();\r
627         }\r
628 \r
629         private void treeView_presets_AfterSelect(object sender, TreeViewEventArgs e)\r
630         {\r
631             selectPreset();\r
632         }\r
633 \r
634         private void treeView_presets_deleteKey(object sender, KeyEventArgs e)\r
635         {\r
636             if (e.KeyCode == Keys.Delete)\r
637             {\r
638                 DialogResult result = MessageBox.Show("Are you sure you wish to delete the selected preset?", "Preset",\r
639                                                       MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
640                 if (result == DialogResult.Yes)\r
641                 {\r
642                     if (treeView_presets.SelectedNode != null)\r
643                         presetHandler.Remove(treeView_presets.SelectedNode.Text);\r
644 \r
645                     // Remember each nodes expanded status so we can reload it\r
646                     List<bool> nodeStatus = new List<bool>();\r
647                     foreach (TreeNode node in treeView_presets.Nodes)\r
648                         nodeStatus.Add(node.IsExpanded);\r
649 \r
650                     // Now reload the preset panel\r
651                     LoadPresetPanel();\r
652 \r
653                     // And finally, re-expand any of the nodes if required\r
654                     int i = 0;\r
655                     foreach (TreeNode node in treeView_presets.Nodes)\r
656                     {\r
657                         if (nodeStatus[i])\r
658                             node.Expand();\r
659 \r
660                         i++;\r
661                     }\r
662                 }\r
663             }\r
664         }\r
665 \r
666         private void selectPreset()\r
667         {\r
668             if (treeView_presets.SelectedNode != null)\r
669             {\r
670                 // Ok, so, we've selected a preset. Now we want to load it.\r
671                 string presetName = treeView_presets.SelectedNode.Text;\r
672                 Preset preset = presetHandler.GetPreset(presetName);\r
673                 if (preset != null)\r
674                 {\r
675                     string query = presetHandler.GetPreset(presetName).Query;\r
676                     bool loadPictureSettings = presetHandler.GetPreset(presetName).PictureSettings;\r
677 \r
678                     if (query != null)\r
679                     {\r
680                         // Ok, Reset all the H264 widgets before changing the preset\r
681                         x264Panel.Reset2Defaults();\r
682 \r
683                         // Send the query from the file to the Query Parser class\r
684                         QueryParser presetQuery = QueryParser.Parse(query);\r
685 \r
686                         // Now load the preset\r
687                         PresetLoader.LoadPreset(this, presetQuery, presetName, loadPictureSettings);\r
688 \r
689                         // The x264 widgets will need updated, so do this now:\r
690                         x264Panel.X264_StandardizeOptString();\r
691                         x264Panel.X264_SetCurrentSettingsInPanel();\r
692 \r
693                         // Finally, let this window have a copy of the preset settings.\r
694                         CurrentlySelectedPreset = preset;\r
695                         PictureSettings.SetPresetCropWarningLabel(preset);\r
696                     }\r
697                 }\r
698             }\r
699         }\r
700 \r
701         private void loadNormalPreset()\r
702         {\r
703             foreach (TreeNode treenode in treeView_presets.Nodes)\r
704             {\r
705                 foreach (TreeNode node in treenode.Nodes)\r
706                 {\r
707                     if (node.Text.Equals("Normal"))\r
708                         treeView_presets.SelectedNode = treeView_presets.Nodes[treenode.Index].Nodes[0];\r
709                 }\r
710             }\r
711         }\r
712 \r
713         private void ImportPreset()\r
714         {\r
715             if (openPreset.ShowDialog() == DialogResult.OK)\r
716             {\r
717                 QueryParser parsed = PlistPresetHandler.Import(openPreset.FileName);\r
718                 if (presetHandler.CheckIfUserPresetExists(parsed.PresetName + " (Imported)"))\r
719                 {\r
720                     DialogResult result =\r
721                         MessageBox.Show("This preset appears to already exist. Would you like to overwrite it?",\r
722                                         "Overwrite preset?",\r
723                                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
724                     if (result == DialogResult.Yes)\r
725                     {\r
726                         PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
727                         presetHandler.Update(parsed.PresetName + " (Imported)",\r
728                                              QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
729                                              parsed.UsesPictureSettings);\r
730                     }\r
731                 }\r
732                 else\r
733                 {\r
734                     PresetLoader.LoadPreset(this, parsed, parsed.PresetName, parsed.UsesPictureSettings);\r
735                     if (presetHandler.Add(parsed.PresetName + " (Imported)",\r
736                                           QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null),\r
737                                           parsed.UsesPictureSettings))\r
738                     {\r
739                         TreeNode preset_treeview = new TreeNode(parsed.PresetName + " (Imported)")\r
740                                                        {\r
741                                                            ForeColor = Color.Black\r
742                                                        };\r
743                         treeView_presets.Nodes.Add(preset_treeview);\r
744                     }\r
745                 }\r
746             }\r
747         }\r
748 \r
749         private void ExportPreset()\r
750         {\r
751             MessageBox.Show("This feature has not been implimented yet.", "Not Implimented", MessageBoxButtons.OK, MessageBoxIcon.Warning);\r
752             return;\r
753 \r
754             SaveFileDialog savefiledialog = new SaveFileDialog();\r
755             savefiledialog.Filter = "plist|*.plist";\r
756 \r
757             if (savefiledialog.ShowDialog() == DialogResult.OK)\r
758             {\r
759                 QueryParser parsed = QueryParser.Parse(QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null));\r
760                 PlistPresetHandler.Export(savefiledialog.FileName, parsed);\r
761             }\r
762         }\r
763 \r
764         #endregion\r
765 \r
766         #region ToolStrip\r
767 \r
768         private void btn_source_Click(object sender, EventArgs e)\r
769         {\r
770             // Remove old Drive Menu Items.\r
771             List<ToolStripMenuItem> itemsToRemove = new List<ToolStripMenuItem>();\r
772             foreach (var item in btn_source.DropDownItems)\r
773             {\r
774                 if (item.GetType() == typeof(ToolStripMenuItem))\r
775                 {\r
776                     ToolStripMenuItem menuItem = (ToolStripMenuItem)item;\r
777                     if (menuItem.Name.StartsWith("Drive"))\r
778                     {\r
779                         itemsToRemove.Add(menuItem);\r
780                     }\r
781                 }\r
782             }\r
783 \r
784             foreach (ToolStripMenuItem item in itemsToRemove)\r
785                 btn_source.DropDownItems.Remove(item);\r
786 \r
787             Thread driveInfoThread = new Thread(SetDriveSelectionMenuItem);\r
788             driveInfoThread.Start();\r
789         }\r
790 \r
791         private void btn_start_Click(object sender, EventArgs e)\r
792         {\r
793             if (btn_start.Text == "Stop")\r
794             {\r
795                 DialogResult result;\r
796                 if (Properties.Settings.Default.enocdeStatusInGui &&\r
797                     !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
798                 {\r
799                     result = MessageBox.Show(\r
800                         "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
801                         "Cancel Encode?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
802                 }\r
803                 else\r
804                 {\r
805                     result = MessageBox.Show("Are you sure you wish to cancel the encode?", "Cancel Encode?",\r
806                                              MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
807                 }\r
808 \r
809                 if (result == DialogResult.Yes)\r
810                 {\r
811                     // Pause The Queue\r
812                     encodeQueue.Pause();\r
813 \r
814                     if (Properties.Settings.Default.enocdeStatusInGui &&\r
815                         !Properties.Settings.Default.showCliForInGuiEncodeStatus)\r
816                     {\r
817                         encodeQueue.Stop();\r
818                         if (encodeQueue.HbProcess != null)\r
819                             encodeQueue.HbProcess.WaitForExit();\r
820                     }\r
821                     else\r
822                     {\r
823                         encodeQueue.SafelyClose();\r
824                     }\r
825                 }\r
826             }\r
827             else\r
828             {\r
829                 if (encodeQueue.Count != 0 ||\r
830                     (!string.IsNullOrEmpty(sourcePath) && !string.IsNullOrEmpty(text_destination.Text)))\r
831                 {\r
832                     string generatedQuery = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
833                     string specifiedQuery = rtf_query.Text != string.Empty\r
834                                                 ? rtf_query.Text\r
835                                                 : QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
836                     string query = string.Empty;\r
837 \r
838                     // Check to make sure the generated query matches the GUI settings\r
839                     if (Properties.Settings.Default.PromptOnUnmatchingQueries && !string.IsNullOrEmpty(specifiedQuery) &&\r
840                         generatedQuery != specifiedQuery)\r
841                     {\r
842                         DialogResult result = MessageBox.Show("The query under the \"Query Editor\" tab " +\r
843                                                               "does not match the current GUI settings.\n\nBecause the manual query takes " +\r
844                                                               "priority over the GUI, your recently updated settings will not be taken " +\r
845                                                               "into account when encoding this job." +\r
846                                                               Environment.NewLine + Environment.NewLine +\r
847                                                               "Do you want to replace the manual query with the updated GUI-generated query?",\r
848                                                               "Manual Query does not Match GUI",\r
849                                                               MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk,\r
850                                                               MessageBoxDefaultButton.Button3);\r
851 \r
852                         switch (result)\r
853                         {\r
854                             case DialogResult.Yes:\r
855                                 // Replace the manual query with the generated one\r
856                                 query = generatedQuery;\r
857                                 rtf_query.Text = generatedQuery;\r
858                                 break;\r
859                             case DialogResult.No:\r
860                                 // Use the manual query\r
861                                 query = specifiedQuery;\r
862                                 break;\r
863                             case DialogResult.Cancel:\r
864                                 // Don't start the encode\r
865                                 return;\r
866                         }\r
867                     }\r
868                     else\r
869                     {\r
870                         query = specifiedQuery;\r
871                     }\r
872 \r
873                     DialogResult overwrite = DialogResult.Yes;\r
874                     if (text_destination.Text != string.Empty)\r
875                         if (File.Exists(text_destination.Text))\r
876                             overwrite =\r
877                                 MessageBox.Show(\r
878                                     "The destination file already exists. Are you sure you want to overwrite it?",\r
879                                     "Overwrite File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
880 \r
881                     if (overwrite == DialogResult.Yes)\r
882                     {\r
883                         if (encodeQueue.Count == 0)\r
884                             encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
885 \r
886                         queueWindow.SetQueue();\r
887                         if (encodeQueue.Count > 1)\r
888                             queueWindow.Show(false);\r
889 \r
890                         SetEncodeStarted(); // Encode is running, so setup the GUI appropriately\r
891                         encodeQueue.Start(); // Start The Queue Encoding Process\r
892                     }\r
893 \r
894                     this.Focus();\r
895                 }\r
896                 else if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
897                     MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
898                                     MessageBoxIcon.Warning);\r
899             }\r
900         }\r
901 \r
902         private void btn_add2Queue_Click(object sender, EventArgs e)\r
903         {\r
904             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
905                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
906                                 MessageBoxIcon.Warning);\r
907             else\r
908             {\r
909                 string query = QueryGenerator.GenerateCliQuery(this, drop_mode.SelectedIndex, 0, null);\r
910                 if (rtf_query.Text != string.Empty)\r
911                     query = rtf_query.Text;\r
912 \r
913                 if (encodeQueue.CheckForDestinationDuplicate(text_destination.Text))\r
914                 {\r
915                     DialogResult result =\r
916                         MessageBox.Show(\r
917                             "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
918                             "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);\r
919                     if (result == DialogResult.Yes)\r
920                         encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
921                 }\r
922                 else\r
923                     encodeQueue.Add(query, getTitle(), sourcePath, text_destination.Text, (rtf_query.Text != string.Empty));\r
924 \r
925                 lbl_encode.Text = encodeQueue.Count + " encode(s) pending in the queue";\r
926 \r
927                 queueWindow.Show();\r
928             }\r
929         }\r
930 \r
931         private void btn_showQueue_Click(object sender, EventArgs e)\r
932         {\r
933             queueWindow.Show();\r
934             queueWindow.Activate();\r
935         }\r
936 \r
937         private void tb_preview_Click(object sender, EventArgs e)\r
938         {\r
939             if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(text_destination.Text))\r
940                 MessageBox.Show("No source or destination selected.", "Warning", MessageBoxButtons.OK,\r
941                                 MessageBoxIcon.Warning);\r
942             else\r
943             {\r
944                 if (qtpreview == null)\r
945                 {\r
946                     qtpreview = new frmPreview(this);\r
947                     qtpreview.Show();\r
948                 }\r
949                 else if (qtpreview.IsDisposed)\r
950                 {\r
951                     qtpreview = new frmPreview(this);\r
952                     qtpreview.Show();\r
953                 }\r
954                 else\r
955                     MessageBox.Show(qtpreview, "The preview window is already open!", "Warning", MessageBoxButtons.OK,\r
956                                     MessageBoxIcon.Warning);\r
957             }\r
958         }\r
959 \r
960         private void btn_ActivityWindow_Click(object sender, EventArgs e)\r
961         {\r
962             if (ActivityWindow == null || !ActivityWindow.IsHandleCreated)\r
963                 ActivityWindow = new frmActivityWindow(encodeQueue, SourceScan);\r
964 \r
965             ActivityWindow.Show();\r
966             ActivityWindow.Activate();\r
967         }\r
968 \r
969         #endregion\r
970 \r
971         #region System Tray Icon\r
972 \r
973         private void frmMain_Resize(object sender, EventArgs e)\r
974         {\r
975             if (FormWindowState.Minimized == this.WindowState)\r
976             {\r
977                 notifyIcon.Visible = true;\r
978                 this.Hide();\r
979             }\r
980             else if (FormWindowState.Normal == this.WindowState)\r
981                 notifyIcon.Visible = false;\r
982         }\r
983 \r
984         private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)\r
985         {\r
986             this.Visible = true;\r
987             this.Activate();\r
988             this.WindowState = FormWindowState.Normal;\r
989             notifyIcon.Visible = false;\r
990         }\r
991 \r
992         private void btn_restore_Click(object sender, EventArgs e)\r
993         {\r
994             this.Visible = true;\r
995             this.Activate();\r
996             this.WindowState = FormWindowState.Normal;\r
997             notifyIcon.Visible = false;\r
998         }\r
999 \r
1000         #endregion\r
1001 \r
1002         #region Tab Control\r
1003 \r
1004         // Source\r
1005         private void btn_dvd_source_Click(object sender, EventArgs e)\r
1006         {\r
1007             if (DVD_Open.ShowDialog() == DialogResult.OK)\r
1008             {\r
1009                 this.selectedSourceType = SourceType.Folder;\r
1010                 SelectSource(DVD_Open.SelectedPath);\r
1011             }\r
1012             else\r
1013                 UpdateSourceLabel();\r
1014         }\r
1015 \r
1016         private void btn_file_source_Click(object sender, EventArgs e)\r
1017         {\r
1018             if (ISO_Open.ShowDialog() == DialogResult.OK)\r
1019             {\r
1020                 this.selectedSourceType = SourceType.VideoFile;\r
1021                 SelectSource(ISO_Open.FileName);\r
1022             }\r
1023             else\r
1024                 UpdateSourceLabel();\r
1025         }\r
1026 \r
1027         private void mnu_dvd_drive_Click(object sender, EventArgs e)\r
1028         {\r
1029             ToolStripMenuItem item = sender as ToolStripMenuItem;\r
1030             if (item != null)\r
1031             {\r
1032                 string driveId = item.Name.Replace("Drive", string.Empty);\r
1033                 int id;\r
1034                 if (int.TryParse(driveId, out id))\r
1035                 {\r
1036 \r
1037                     this.dvdDrivePath = drives[id].RootDirectory;\r
1038                     this.dvdDriveLabel = drives[id].VolumeLabel;\r
1039 \r
1040                     if (this.dvdDrivePath == null) return;\r
1041                     this.selectedSourceType = SourceType.DvdDrive;\r
1042                     SelectSource(this.dvdDrivePath);\r
1043                 }\r
1044             }\r
1045         }\r
1046 \r
1047         private void SelectSource(string file)\r
1048         {\r
1049             Check_ChapterMarkers.Enabled = true;\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             // Start the Scan\r
1656             try\r
1657             {\r
1658                 isScanning = true;\r
1659                 SourceScan.Scan(sourcePath, title);\r
1660                 SourceScan.ScanStatusChanged += new EventHandler(SourceScan_ScanStatusChanged);\r
1661                 SourceScan.ScanCompleted += new EventHandler(SourceScan_ScanCompleted);\r
1662             }\r
1663             catch (Exception exc)\r
1664             {\r
1665                 MessageBox.Show("frmMain.cs - StartScan " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1666             }\r
1667         }\r
1668 \r
1669         private void SourceScan_ScanStatusChanged(object sender, EventArgs e)\r
1670         {\r
1671             UpdateScanStatusLabel();\r
1672         }\r
1673 \r
1674         private void SourceScan_ScanCompleted(object sender, EventArgs e)\r
1675         {\r
1676             UpdateGuiAfterScan();\r
1677         }\r
1678 \r
1679         private void UpdateScanStatusLabel()\r
1680         {\r
1681             if (InvokeRequired)\r
1682             {\r
1683                 BeginInvoke(new UpdateWindowHandler(UpdateScanStatusLabel));\r
1684                 return;\r
1685             }\r
1686             lbl_encode.Text = SourceScan.ScanStatus;\r
1687         }\r
1688 \r
1689         private void UpdateGuiAfterScan()\r
1690         {\r
1691             if (InvokeRequired)\r
1692             {\r
1693                 BeginInvoke(new UpdateWindowHandler(UpdateGuiAfterScan));\r
1694                 return;\r
1695             }\r
1696 \r
1697             try\r
1698             {\r
1699                 currentSource = SourceScan.SouceData;\r
1700 \r
1701                 // Setup some GUI components\r
1702                 drp_dvdtitle.Items.Clear();\r
1703                 if (currentSource.Titles.Count != 0)\r
1704                     drp_dvdtitle.Items.AddRange(currentSource.Titles.ToArray());\r
1705 \r
1706                 foreach (Title title in currentSource.Titles)\r
1707                 {\r
1708                     if (title.MainTitle)\r
1709                     {\r
1710                         drp_dvdtitle.SelectedItem = title;\r
1711                     }\r
1712                 }\r
1713 \r
1714                 if (drp_dvdtitle.SelectedItem == null && drp_dvdtitle.Items.Count > 0)\r
1715                 {\r
1716                     drp_dvdtitle.SelectedIndex = 0;\r
1717                 }\r
1718 \r
1719                 // Enable the creation of chapter markers if the file is an image of a dvd.\r
1720                 int start, end;\r
1721                 int.TryParse(drop_chapterStart.Items[0].ToString(), out start);\r
1722                 int.TryParse(drop_chapterFinish.Items[drop_chapterFinish.Items.Count - 1].ToString(), out end);\r
1723                 if (end > start)\r
1724                     Check_ChapterMarkers.Enabled = true;\r
1725                 else\r
1726                 {\r
1727                     Check_ChapterMarkers.Enabled = false;\r
1728                     Check_ChapterMarkers.Checked = false;\r
1729                     data_chpt.Rows.Clear();\r
1730                 }\r
1731 \r
1732                 // If no titles were found, Display an error message\r
1733                 if (drp_dvdtitle.Items.Count == 0)\r
1734                 {\r
1735                     MessageBox.Show(\r
1736                         "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
1737                         "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);\r
1738                     sourcePath = string.Empty;\r
1739                 }\r
1740                 UpdateSourceLabel();\r
1741 \r
1742                 // Enable the GUI components and enable any disabled components\r
1743                 EnableGUI();\r
1744             }\r
1745             catch (Exception exc)\r
1746             {\r
1747                 MessageBox.Show("frmMain.cs - updateUIafterScan " + exc, "Error", MessageBoxButtons.OK,\r
1748                                 MessageBoxIcon.Error);\r
1749                 EnableGUI();\r
1750             }\r
1751         }\r
1752 \r
1753         private void EnableGUI()\r
1754         {\r
1755             try\r
1756             {\r
1757                 if (InvokeRequired)\r
1758                     BeginInvoke(new UpdateWindowHandler(EnableGUI));\r
1759                 lbl_encode.Text = "Scan Completed";\r
1760                 foreach (Control ctrl in Controls)\r
1761                     ctrl.Enabled = true;\r
1762                 btn_start.Enabled = true;\r
1763                 btn_showQueue.Enabled = true;\r
1764                 btn_add2Queue.Enabled = true;\r
1765                 tb_preview.Enabled = true;\r
1766                 btn_source.Enabled = true;\r
1767                 mnu_killCLI.Visible = false;\r
1768             }\r
1769             catch (Exception exc)\r
1770             {\r
1771                 MessageBox.Show("frmMain.cs - EnableGUI() " + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
1772             }\r
1773         }\r
1774 \r
1775         private void DisableGUI()\r
1776         {\r
1777             foreach (Control ctrl in Controls)\r
1778                 if (!(ctrl is StatusStrip || ctrl is MenuStrip || ctrl is ToolStrip))\r
1779                     ctrl.Enabled = false;\r
1780 \r
1781             lbl_encode.Visible = true;\r
1782             lbl_encode.Text = "Scanning ...";\r
1783             btn_source.Enabled = false;\r
1784             btn_start.Enabled = false;\r
1785             btn_showQueue.Enabled = false;\r
1786             btn_add2Queue.Enabled = false;\r
1787             tb_preview.Enabled = false;\r
1788             mnu_killCLI.Visible = true;\r
1789         }\r
1790 \r
1791         private void KillScan()\r
1792         {\r
1793             SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
1794             EnableGUI();\r
1795             ResetGUI();\r
1796 \r
1797             SourceScan.Stop();\r
1798 \r
1799             lbl_encode.Text = "Scan Cancelled!";\r
1800         }\r
1801 \r
1802         private void ResetGUI()\r
1803         {\r
1804             drp_dvdtitle.Items.Clear();\r
1805             drop_chapterStart.Items.Clear();\r
1806             drop_chapterFinish.Items.Clear();\r
1807             lbl_duration.Text = "Select a Title";\r
1808             PictureSettings.lbl_src_res.Text = "Select a Title";\r
1809             sourcePath = String.Empty;\r
1810             text_destination.Text = String.Empty;\r
1811             selectedTitle = null;\r
1812             isScanning = false;\r
1813         }\r
1814 \r
1815         private void UpdateSourceLabel()\r
1816         {\r
1817             labelSource.Text = string.IsNullOrEmpty(sourcePath) ? "Select \"Source\" to continue." : this.SourceName;\r
1818 \r
1819             if (selectedTitle != null)\r
1820                 if (!string.IsNullOrEmpty(selectedTitle.SourceName))\r
1821                     // If it's one of multiple source files, make sure we don't use the folder name\r
1822                     labelSource.Text = Path.GetFileName(selectedTitle.SourceName);\r
1823         }\r
1824 \r
1825         public void RecievingJob(Job job)\r
1826         {\r
1827             string query = job.Query;\r
1828             StartScan(job.Source, job.Title);\r
1829 \r
1830             if (query != null)\r
1831             {\r
1832                 // Ok, Reset all the H264 widgets before changing the preset\r
1833                 x264Panel.Reset2Defaults();\r
1834 \r
1835                 // Send the query from the file to the Query Parser class\r
1836                 QueryParser presetQuery = QueryParser.Parse(query);\r
1837 \r
1838                 // Now load the preset\r
1839                 PresetLoader.LoadPreset(this, presetQuery, "Load Back From Queue", true);\r
1840 \r
1841                 // The x264 widgets will need updated, so do this now:\r
1842                 x264Panel.X264_StandardizeOptString();\r
1843                 x264Panel.X264_SetCurrentSettingsInPanel();\r
1844 \r
1845                 // Finally, let this window have a copy of the preset settings.\r
1846                 CurrentlySelectedPreset = null;\r
1847                 PictureSettings.SetPresetCropWarningLabel(null);\r
1848             }\r
1849         }\r
1850 \r
1851         #endregion\r
1852 \r
1853         #region GUI Functions and Actions\r
1854 \r
1855         /// <summary>\r
1856         /// Set the GUI to it's finished encoding state.\r
1857         /// </summary>\r
1858         private void SetEncodeFinished()\r
1859         {\r
1860             try\r
1861             {\r
1862                 if (InvokeRequired)\r
1863                 {\r
1864                     BeginInvoke(new UpdateWindowHandler(SetEncodeFinished));\r
1865                     return;\r
1866                 }\r
1867 \r
1868                 lbl_encode.Text = "Encoding Finished";\r
1869                 ProgressBarStatus.Visible = false;\r
1870                 btn_start.Text = "Start";\r
1871                 btn_start.ToolTipText = "Start the encoding process";\r
1872                 btn_start.Image = Properties.Resources.Play;\r
1873 \r
1874                 // If the window is minimized, display the notification in a popup.\r
1875                 if (Properties.Settings.Default.trayIconAlerts)\r
1876                     if (FormWindowState.Minimized == this.WindowState)\r
1877                     {\r
1878                         notifyIcon.BalloonTipText = lbl_encode.Text;\r
1879                         notifyIcon.ShowBalloonTip(500);\r
1880                     }\r
1881             }\r
1882             catch (Exception exc)\r
1883             {\r
1884                 MessageBox.Show(exc.ToString());\r
1885             }\r
1886         }\r
1887 \r
1888         /// <summary>\r
1889         /// Set the GUI to it's started encoding state.\r
1890         /// </summary>\r
1891         private void SetEncodeStarted()\r
1892         {\r
1893             try\r
1894             {\r
1895                 if (InvokeRequired)\r
1896                 {\r
1897                     BeginInvoke(new UpdateWindowHandler(SetEncodeStarted));\r
1898                     return;\r
1899                 }\r
1900                 lbl_encode.Visible = true;\r
1901                 ProgressBarStatus.Value = 0;\r
1902                 ProgressBarStatus.Visible = true;\r
1903                 lbl_encode.Text = "Encoding with " + encodeQueue.Count + " encode(s) pending";\r
1904                 btn_start.Text = "Stop";\r
1905                 btn_start.ToolTipText = "Stop the encoding process.";\r
1906                 btn_start.Image = Properties.Resources.stop;\r
1907             }\r
1908             catch (Exception exc)\r
1909             {\r
1910                 MessageBox.Show(exc.ToString());\r
1911             }\r
1912         }\r
1913 \r
1914         /// <summary>\r
1915         /// Set the DVD Drive selection in the "Source" Menu\r
1916         /// </summary>\r
1917         private void SetDriveSelectionMenuItem()\r
1918         {\r
1919             try\r
1920             {\r
1921                 if (InvokeRequired)\r
1922                 {\r
1923                     BeginInvoke(new UpdateWindowHandler(SetDriveSelectionMenuItem));\r
1924                     return;\r
1925                 }\r
1926 \r
1927                 drives = Main.GetDrives();\r
1928 \r
1929                 List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();\r
1930                 foreach (DriveInformation drive in drives)\r
1931                 {\r
1932                     ToolStripMenuItem menuItem = new ToolStripMenuItem();\r
1933                     menuItem.Name = drive.ToString();\r
1934                     menuItem.Text = drive.RootDirectory + " (" + drive.VolumeLabel + ")";\r
1935                     menuItem.Image = Resources.disc_small;\r
1936                     menuItem.Click += new EventHandler(mnu_dvd_drive_Click);\r
1937                     menuItems.Add(menuItem);\r
1938                 }\r
1939 \r
1940                 foreach (ToolStripMenuItem item in menuItems)\r
1941                     btn_source.DropDownItems.Add(item);\r
1942             }\r
1943             catch (Exception exc)\r
1944             {\r
1945                 MessageBox.Show("Error in SetDriveSelectionMenuItem" + exc);\r
1946             }\r
1947         }\r
1948 \r
1949         /// <summary>\r
1950         /// Access the preset Handler and setup the preset panel.\r
1951         /// </summary>\r
1952         private void LoadPresetPanel()\r
1953         {\r
1954             if (presetHandler.CheckIfPresetsAreOutOfDate())\r
1955                 if (!Properties.Settings.Default.presetNotification)\r
1956                     MessageBox.Show(splash,\r
1957                                     "HandBrake has determined your built-in presets are out of date... These presets will now be updated.",\r
1958                                     "Preset Update", MessageBoxButtons.OK, MessageBoxIcon.Information);\r
1959 \r
1960             presetHandler.GetPresetPanel(ref treeView_presets);\r
1961             treeView_presets.Update();\r
1962         }\r
1963 \r
1964         /// <summary>\r
1965         /// Get the title from the selected item in the title dropdown.\r
1966         /// </summary>\r
1967         /// <returns>\r
1968         /// The title.\r
1969         /// </returns>\r
1970         private int getTitle()\r
1971         {\r
1972             int title = 0;\r
1973             if (drp_dvdtitle.SelectedItem != null)\r
1974             {\r
1975                 string[] titleInfo = drp_dvdtitle.SelectedItem.ToString().Split(' ');\r
1976                 int.TryParse(titleInfo[0], out title);\r
1977             }\r
1978 \r
1979             return title;\r
1980         }\r
1981 \r
1982         #endregion\r
1983 \r
1984         #region Overrides\r
1985 \r
1986         /// <summary>\r
1987         /// Handle GUI shortcuts\r
1988         /// </summary>\r
1989         /// <param name="msg">Message</param>\r
1990         /// <param name="keyData">Keys</param>\r
1991         /// <returns>Bool</returns>\r
1992         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
1993         {\r
1994             if (keyData == (Keys.Control | Keys.S))\r
1995             {\r
1996                 btn_start_Click(this, new EventArgs());\r
1997                 return true;\r
1998             }\r
1999 \r
2000             if (keyData == (Keys.Control | Keys.A))\r
2001             {\r
2002                 btn_add2Queue_Click(this, new EventArgs());\r
2003                 return true;\r
2004             }\r
2005             return base.ProcessCmdKey(ref msg, keyData);\r
2006         }\r
2007 \r
2008         /// <summary>\r
2009         /// If the queue is being processed, prompt the user to confirm application close.\r
2010         /// </summary>\r
2011         /// <param name="e">FormClosingEventArgs</param>\r
2012         protected override void OnFormClosing(FormClosingEventArgs e)\r
2013         {\r
2014             // If currently encoding, the queue isn't paused, and there are queue items to process, prompt to confirm close.\r
2015             if (encodeQueue.IsEncoding)\r
2016             {\r
2017                 DialogResult result =\r
2018                     MessageBox.Show(\r
2019                         "HandBrake has queue items to process. Closing HandBrake will stop the current encoding.\n\nDo you want to close HandBrake?",\r
2020                         "Close HandBrake?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);\r
2021 \r
2022                 if (result == DialogResult.No)\r
2023                     e.Cancel = true;\r
2024 \r
2025                 // Try to safely close out if we can, or kill the cli if using in-gui status\r
2026                 if (Settings.Default.enocdeStatusInGui)\r
2027                     encodeQueue.Stop();\r
2028                 else\r
2029                     encodeQueue.SafelyClose();\r
2030             }\r
2031 \r
2032             if (SourceScan.IsScanning)\r
2033             {\r
2034                 SourceScan.ScanCompleted -= new EventHandler(SourceScan_ScanCompleted);\r
2035                 SourceScan.Stop();\r
2036             }\r
2037             base.OnFormClosing(e);\r
2038         }\r
2039 \r
2040         #endregion\r
2041 \r
2042         #region In-GUI Encode Status (Experimental)\r
2043 \r
2044         /// <summary>\r
2045         /// Starts a new thread to monitor and process the CLI encode status\r
2046         /// </summary>\r
2047         private void EncodeMonitorThread()\r
2048         {\r
2049             try\r
2050             {\r
2051                 Parser encode = new Parser(encodeQueue.HbProcess.StandardOutput.BaseStream);\r
2052                 encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
2053                 while (!encode.EndOfStream)\r
2054                     encode.ReadEncodeStatus();\r
2055 \r
2056                 SetEncodeFinished();\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(\r
2085                 "{0:00.00}%,    FPS: {1:000.0},    Avg FPS: {2:000.0},    Time Remaining: {3}", \r
2086                 PercentComplete, \r
2087                 CurrentFps, \r
2088                 AverageFps, \r
2089                 TimeRemaining);\r
2090 \r
2091             ProgressBarStatus.Value = (int)Math.Round(PercentComplete);\r
2092         }\r
2093 \r
2094         #endregion\r
2095 \r
2096         // This is the END of the road ****************************************\r
2097     }\r
2098 }