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
6 namespace Handbrake.Controls
\r
9 using System.Collections.Generic;
\r
12 using System.Windows.Forms;
\r
15 using HandBrake.ApplicationServices.Model;
\r
20 /// The Subtitles Tab
\r
22 public partial class Subtitles : UserControl
\r
24 #region Priavate Variables and Collections
\r
27 /// Map of languages to language codes
\r
29 private readonly IDictionary<string, string> langMap = new Dictionary<string, string>();
\r
32 /// A List of SRT Files
\r
34 private readonly IDictionary<string, string> srtFiles = new Dictionary<string, string>();
\r
37 /// The Subtitle List
\r
39 private readonly List<SubtitleInfo> subList = new List<SubtitleInfo>();
\r
44 /// Initializes a new instance of the <see cref="Subtitles"/> class.
\r
48 InitializeComponent();
\r
50 langMap = Main.MapLanguages();
\r
51 foreach (string key in langMap.Keys)
\r
52 srt_lang.Items.Add(key);
\r
54 srt_charcode.SelectedIndex = 28;
\r
55 srt_lang.SelectedIndex = 40;
\r
58 #region Public Methods
\r
60 /// Gets the CLI Query for this panel
\r
62 /// <returns>A CliQuery string</returns>
\r
63 public string GetCliQuery
\r
67 string query = string.Empty;
\r
68 if (lv_subList.Items.Count != 0) // If we have subtitle tracks
\r
71 string subtitleTracks = String.Empty;
\r
72 string subtitleForced = String.Empty;
\r
73 string subtitleBurn = String.Empty;
\r
74 string subtitleDefault = String.Empty;
\r
77 string srtFile = String.Empty;
\r
78 string srtCodeset = String.Empty;
\r
79 string srtOffset = String.Empty;
\r
80 string srtLang = String.Empty;
\r
81 string srtDefault = String.Empty;
\r
85 foreach (SubtitleInfo item in subList)
\r
89 if (item.IsSrtSubtitle) // We have an SRT file
\r
91 srtCount++; // SRT track id.
\r
93 srtLang += srtLang == string.Empty ? langMap[item.SrtLang] : "," + langMap[item.SrtLang];
\r
94 srtCodeset += srtCodeset == string.Empty ? item.SrtCharCode : "," + item.SrtCharCode;
\r
97 srtDefault = srtCount.ToString();
\r
99 itemToAdd = item.SrtPath;
\r
100 srtFile += srtFile == string.Empty ? itemToAdd : "," + itemToAdd;
\r
102 itemToAdd = item.SrtOffset.ToString();
\r
103 srtOffset += srtOffset == string.Empty ? itemToAdd : "," + itemToAdd;
\r
105 else // We have Bitmap or CC
\r
109 // Find --subtitle <string>
\r
110 if (item.Track.Contains("Foreign Audio Search"))
\r
111 itemToAdd = "scan";
\r
114 string[] tempSub = item.Track.Split(' ');
\r
115 itemToAdd = tempSub[0];
\r
118 subtitleTracks += subtitleTracks == string.Empty ? itemToAdd : "," + itemToAdd;
\r
120 // Find --subtitle-forced
\r
122 subtitleForced += subtitleForced == string.Empty ? subCount.ToString() : "," + subCount;
\r
124 // Find --subtitle-burn
\r
126 subtitleBurn = subCount.ToString();
\r
128 // Find --subtitle-default
\r
130 subtitleDefault = subCount.ToString();
\r
134 // Build The CLI Subtitles Query
\r
135 if (subtitleTracks != string.Empty)
\r
137 query += " --subtitle " + subtitleTracks;
\r
139 if (subtitleForced != string.Empty)
\r
140 query += " --subtitle-forced=" + subtitleForced;
\r
141 if (subtitleBurn != string.Empty)
\r
142 query += " --subtitle-burn=" + subtitleBurn;
\r
143 if (subtitleDefault != string.Empty)
\r
144 query += " --subtitle-default=" + subtitleDefault;
\r
147 if (srtFile != string.Empty) // SRTs
\r
149 query += " --srt-file " + "\"" + srtFile + "\"";
\r
151 if (srtCodeset != string.Empty)
\r
152 query += " --srt-codeset " + srtCodeset;
\r
153 if (srtOffset != string.Empty)
\r
154 query += " --srt-offset " + srtOffset;
\r
155 if (srtLang != string.Empty)
\r
156 query += " --srt-lang " + srtLang;
\r
157 if (srtDefault != string.Empty)
\r
158 query += " --srt-default=" + srtDefault;
\r
166 /// Checks of the current settings will require the m4v file extension
\r
168 /// <returns>True if Yes</returns>
\r
169 public bool RequiresM4V()
\r
171 return this.subList.Any(track => track.SubtitleType != SubtitleType.VobSub);
\r
175 /// Automatically setup the subtitle tracks.
\r
176 /// This handles the automatic setup of subitles which the user can control from the program options
\r
178 /// <param name="subs">List of Subtitles</param>
\r
179 public void SetSubtitleTrackAuto(object[] subs)
\r
181 drp_subtitleTracks.Items.Clear();
\r
182 drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
183 drp_subtitleTracks.Items.AddRange(subs);
\r
184 drp_subtitleTracks.SelectedIndex = 0;
\r
187 this.AutomaticSubtitleSelection();
\r
191 /// Automatic Subtitle Selection based on user preferences.
\r
193 public void AutomaticSubtitleSelection()
\r
195 // Handle Native Language and "Dub Foreign language audio" and "Use Foreign language audio and Subtitles" Options
\r
196 if (Properties.Settings.Default.NativeLanguage != "Any")
\r
198 if (Properties.Settings.Default.DubMode != 1) // We need to add a subtitle track if this is false.
\r
200 foreach (object item in drp_subtitleTracks.Items)
\r
202 if (item.ToString().Contains(Properties.Settings.Default.NativeLanguage))
\r
204 drp_subtitleTracks.SelectedItem = item;
\r
205 BtnAddSubTrackClick(this, new EventArgs());
\r
209 if (drp_subtitleTracks.SelectedIndex == 0 && Properties.Settings.Default.useClosedCaption)
\r
211 foreach (object item in drp_subtitleTracks.Items)
\r
213 if (item.ToString().Contains("Closed"))
\r
215 drp_subtitleTracks.SelectedItem = item;
\r
216 BtnAddSubTrackClick(this, new EventArgs());
\r
225 /// Clear the Subtitle List
\r
227 public void Clear()
\r
229 lv_subList.Items.Clear();
\r
234 #region Primary Controls
\r
237 /// Add a Subtitle track.
\r
239 /// <param name="sender">
\r
242 /// <param name="e">
\r
245 private void BtnAddSubTrackClick(object sender, EventArgs e)
\r
248 string forcedVal = check_forced.CheckState == CheckState.Checked ? "Yes" : "No";
\r
249 string defaultSub = check_default.CheckState == CheckState.Checked ? "Yes" : "No";
\r
250 string burnedVal = check_burned.CheckState == CheckState.Checked &&
\r
251 (drp_subtitleTracks.Text.Contains("(VOBSUB)") || drp_subtitleTracks.Text.Contains("(SSA)"))
\r
254 string srtCode = "-", srtLangVal = "-", srtPath = "-", srtFile = "-";
\r
255 int srtOffsetMs = 0;
\r
257 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
259 srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath);
\r
260 srtFile = drp_subtitleTracks.SelectedItem.ToString();
\r
261 srtLangVal = srt_lang.SelectedItem.ToString();
\r
262 srtCode = srt_charcode.SelectedItem.ToString();
\r
263 srtOffsetMs = (int)srt_offset.Value;
\r
264 if (defaultSub == "Yes") this.SetDefaultToOffForAllSRTTracks();
\r
268 if (defaultSub == "Yes") this.SetDefaultToOffForAllTracks();
\r
269 if (burnedVal == "Yes") this.SetBurnedToOffForAllTracks();
\r
272 string trackName = (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
273 ? srtLangVal + " (" + srtFile + ")"
\r
274 : drp_subtitleTracks.SelectedItem.ToString();
\r
276 SubtitleInfo track = new SubtitleInfo
\r
279 Forced = check_forced.Checked,
\r
280 Burned = check_burned.Checked,
\r
281 Default = check_default.Checked,
\r
282 SrtLang = srtLangVal,
\r
283 SrtCharCode = srtCode,
\r
284 SrtOffset = srtOffsetMs,
\r
286 SrtFileName = srtFile
\r
289 lv_subList.Items.Add(track.ListView);
\r
290 subList.Add(track);
\r
294 /// Import an SRT Subtitle Track
\r
296 /// <param name="sender">
\r
299 /// <param name="e">
\r
302 private void BtnSrtAddClick(object sender, EventArgs e)
\r
304 if (openFileDialog.ShowDialog() != DialogResult.OK)
\r
307 if (srtFiles.ContainsKey(Path.GetFileName(openFileDialog.FileName)))
\r
310 "A Subtitle track with the same name has already been imported.",
\r
312 MessageBoxButtons.OK,
\r
313 MessageBoxIcon.Warning);
\r
317 drp_subtitleTracks.Items.Add(Path.GetFileName(openFileDialog.FileName));
\r
318 drp_subtitleTracks.SelectedItem = Path.GetFileName(openFileDialog.FileName);
\r
319 srtFiles.Add(Path.GetFileName(openFileDialog.FileName), openFileDialog.FileName);
\r
323 /// Remove a subtitle track
\r
325 /// <param name="sender">
\r
328 /// <param name="e">
\r
331 private void BtnRemoveSubTrackClick(object sender, EventArgs e)
\r
333 this.RemoveSelectedTrack();
\r
337 /// The Subtitle List selected index has changed
\r
339 /// <param name="sender">
\r
342 /// <param name="e">
\r
345 private void LbSubListSelectedIndexChanged(object sender, EventArgs e)
\r
347 // Set the dropdown controls based on the selected item in the List.
\r
348 if (lv_subList.Items.Count != 0 && lv_subList.SelectedIndices.Count != 0)
\r
350 SubtitleInfo track = subList[lv_subList.SelectedIndices[0]];
\r
353 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.ToLower().Contains(".srt"))
\r
356 foreach (var item in drp_subtitleTracks.Items)
\r
358 if (item.ToString() == track.SrtFileName)
\r
359 drp_subtitleTracks.SelectedIndex = c;
\r
362 srt_lang.SelectedItem = track.SrtLang;
\r
363 srt_offset.Value = track.SrtOffset;
\r
364 srt_charcode.SelectedItem = track.SrtCharCode;
\r
365 check_default.CheckState = track.Default ? CheckState.Checked : CheckState.Unchecked;
\r
366 SubGroupBox.Text = "Selected Track: " + track.Track;
\r
368 else // We have Bitmap/CC
\r
370 foreach (var item in drp_subtitleTracks.Items)
\r
372 if (item.ToString() == track.Track)
\r
373 drp_subtitleTracks.SelectedIndex = c;
\r
376 check_forced.CheckState = track.Forced ? CheckState.Checked : CheckState.Unchecked;
\r
377 check_burned.CheckState = track.Burned ? CheckState.Checked : CheckState.Unchecked;
\r
378 check_default.CheckState = track.Default ? CheckState.Checked : CheckState.Unchecked;
\r
379 SubGroupBox.Text = "Selected Track: " +
\r
380 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text;
\r
384 SubGroupBox.Text = "Selected Track: None (Click \"Add\" to add another track to the list)";
\r
389 #region Subtitle Controls
\r
392 /// Handle the Subtitle track dropdown changed event
\r
394 /// <param name="sender">
\r
397 /// <param name="e">
\r
400 private void DrpSubtitleTracksSelectedIndexChanged(object sender, EventArgs e)
\r
402 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
404 check_forced.Enabled = false;
\r
405 check_burned.Enabled = false;
\r
406 srt_lang.Enabled = true;
\r
407 srt_charcode.Enabled = true;
\r
408 srt_offset.Enabled = true;
\r
412 check_forced.Enabled = true;
\r
413 check_burned.Enabled = true;
\r
414 srt_lang.Enabled = false;
\r
415 srt_charcode.Enabled = false;
\r
416 srt_offset.Enabled = false;
\r
418 // Update an item in the list if required.
\r
419 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
421 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
423 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text = srt_lang.SelectedItem + "(" +
\r
424 drp_subtitleTracks.SelectedItem + ")";
\r
425 lv_subList.Select();
\r
428 srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath);
\r
429 subList[lv_subList.SelectedIndices[0]].SrtPath = srtPath;
\r
433 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text =
\r
434 drp_subtitleTracks.SelectedItem.ToString();
\r
435 lv_subList.Select();
\r
438 subList[lv_subList.SelectedIndices[0]].Track = drp_subtitleTracks.SelectedItem.ToString();
\r
442 /// Foreced Subtitles checkbox changed
\r
444 /// <param name="sender">
\r
447 /// <param name="e">
\r
450 private void CheckForcedCheckedChanged(object sender, EventArgs e)
\r
452 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
454 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[1].Text = check_forced.Checked ? "Yes" : "No";
\r
455 lv_subList.Select();
\r
457 subList[lv_subList.SelectedIndices[0]].Forced = check_forced.Checked;
\r
458 // Update SubList List<SubtitleInfo>
\r
462 /// Burned in subtitles checkbox changed
\r
464 /// <param name="sender">
\r
467 /// <param name="e">
\r
470 private void CheckBurnedCheckedChanged(object sender, EventArgs e)
\r
472 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
474 if (check_burned.Checked) // Make sure we only have 1 burned track
\r
475 this.SetBurnedToOffForAllTracks();
\r
477 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[2].Text = check_burned.Checked ? "Yes" : "No";
\r
478 lv_subList.Select();
\r
480 subList[lv_subList.SelectedIndices[0]].Burned = check_burned.Checked;
\r
481 // Update SubList List<SubtitleInfo>
\r
485 /// Default Subitle track check changed
\r
487 /// <param name="sender">
\r
490 /// <param name="e">
\r
493 private void CheckDefaultCheckedChanged(object sender, EventArgs e)
\r
495 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
497 if (check_default.Checked) // Make sure we only have 1 default track
\r
498 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.Contains(".srt"))
\r
499 this.SetDefaultToOffForAllSRTTracks();
\r
501 this.SetDefaultToOffForAllTracks();
\r
503 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[3].Text = check_default.Checked ? "Yes" : "No";
\r
504 lv_subList.Select();
\r
506 subList[lv_subList.SelectedIndices[0]].Default = check_default.Checked;
\r
507 // Update SubList List<SubtitleInfo>
\r
511 /// Srt Offset Numeric Control Changed
\r
513 /// <param name="sender">
\r
516 /// <param name="e">
\r
519 private void SrtOffsetValueChanged(object sender, EventArgs e)
\r
521 // Update an item in the list if required.
\r
522 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0)
\r
525 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[6].Text = srt_offset.Value.ToString();
\r
526 lv_subList.Select();
\r
528 subList[lv_subList.SelectedIndices[0]].SrtOffset = (int)srt_offset.Value;
\r
529 // Update SubList List<SubtitleInfo>
\r
533 /// The SRT Charcode changed
\r
535 /// <param name="sender">
\r
538 /// <param name="e">
\r
541 private void SrtCharcodeSelectedIndexChanged(object sender, EventArgs e)
\r
543 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
545 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[5].Text = srt_charcode.SelectedItem.ToString();
\r
546 lv_subList.Select();
\r
548 subList[lv_subList.SelectedIndices[0]].SrtCharCode = srt_charcode.SelectedItem.ToString();
\r
549 // Update SubList List<SubtitleInfo>
\r
553 /// The Srt Language code changed
\r
555 /// <param name="sender">
\r
558 /// <param name="e">
\r
561 private void SrtLangSelectedIndexChanged(object sender, EventArgs e)
\r
563 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
565 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[4].Text = srt_lang.SelectedItem.ToString();
\r
566 lv_subList.Select();
\r
568 subList[lv_subList.SelectedIndices[0]].SrtLang = srt_lang.SelectedItem.ToString();
\r
569 // Update SubList List<SubtitleInfo>
\r
574 #region Right Click Menu
\r
577 /// Move an item in the subtitle list up
\r
579 /// <param name="sender">
\r
582 /// <param name="e">
\r
585 private void MnuMoveupClick(object sender, EventArgs e)
\r
587 if (lv_subList.SelectedIndices.Count != 0)
\r
589 ListViewItem item = lv_subList.SelectedItems[0];
\r
590 int index = item.Index;
\r
593 if (lv_subList.Items.Count > index && index >= 0)
\r
595 lv_subList.Items.Remove(item);
\r
596 lv_subList.Items.Insert(index, item);
\r
597 item.Selected = true;
\r
598 lv_subList.Focus();
\r
604 /// Move an item in the subtitle list down
\r
606 /// <param name="sender">
\r
609 /// <param name="e">
\r
612 private void MnuMovedownClick(object sender, EventArgs e)
\r
614 if (lv_subList.SelectedIndices.Count != 0)
\r
616 ListViewItem item = lv_subList.SelectedItems[0];
\r
617 int index = item.Index;
\r
620 if (index < lv_subList.Items.Count)
\r
622 lv_subList.Items.Remove(item);
\r
623 lv_subList.Items.Insert(index, item);
\r
624 item.Selected = true;
\r
625 lv_subList.Focus();
\r
631 /// Remove a selected subtitle track.
\r
633 /// <param name="sender">
\r
636 /// <param name="e">
\r
639 private void MnuRemoveClick(object sender, EventArgs e)
\r
641 this.RemoveSelectedTrack();
\r
648 /// Set all Non SRT tracks to Default = NO
\r
650 private void SetDefaultToOffForAllTracks()
\r
653 foreach (ListViewItem item in lv_subList.Items)
\r
655 if (subList[c].SrtPath == "-")
\r
657 if (item.SubItems[3].Text == "Yes")
\r
659 item.SubItems[3].Text = "No";
\r
660 subList[c].Default = false;
\r
668 /// Set all subtitle tracks so that they have no default.
\r
670 private void SetDefaultToOffForAllSRTTracks()
\r
673 foreach (ListViewItem item in lv_subList.Items)
\r
675 if (!subList[c].IsSrtSubtitle)
\r
677 if (item.SubItems[3].Text == "Yes")
\r
679 item.SubItems[3].Text = "No";
\r
680 subList[c].Default = false;
\r
688 /// Set all tracks to Burned = No
\r
690 private void SetBurnedToOffForAllTracks()
\r
693 foreach (ListViewItem item in lv_subList.Items)
\r
695 if (item.SubItems[2].Text == "Yes")
\r
697 item.SubItems[2].Text = "No";
\r
698 subList[c].Burned = false;
\r
705 /// Remove a selected track
\r
707 private void RemoveSelectedTrack()
\r
709 // Remove the Item and reselect the control if the following conditions are met.
\r
710 if (lv_subList.SelectedItems.Count != 0)
\r
712 // Record the current selected index.
\r
713 int currentPosition = lv_subList.SelectedIndices[0];
\r
714 int selectedInd = lv_subList.SelectedIndices[0];
\r
716 lv_subList.Items.RemoveAt(selectedInd);
\r
717 subList.RemoveAt(selectedInd);
\r
719 // Now reslect the correct item and give focus to the list.
\r
720 if (lv_subList.Items.Count != 0)
\r
722 if (currentPosition <= (lv_subList.Items.Count - 1))
\r
723 lv_subList.Items[currentPosition].Selected = true;
\r
724 else if (currentPosition > (lv_subList.Items.Count - 1))
\r
725 lv_subList.Items[lv_subList.Items.Count - 1].Selected = true;
\r
727 lv_subList.Select();
\r