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
17 /// The Subtitles Tab
\r
19 public partial class Subtitles : UserControl
\r
22 /// Map of languages to language codes
\r
24 private readonly IDictionary<string, string> langMap = new Dictionary<string, string>();
\r
27 /// A List of SRT Files
\r
29 private readonly IDictionary<string, string> srtFiles = new Dictionary<string, string>();
\r
32 /// The Subtitle List
\r
34 private readonly List<SubtitleInfo> subList = new List<SubtitleInfo>();
\r
37 /// Initializes a new instance of the <see cref="Subtitles"/> class.
\r
41 InitializeComponent();
\r
43 langMap = Main.MapLanguages();
\r
44 foreach (string key in langMap.Keys)
\r
45 srt_lang.Items.Add(key);
\r
47 srt_charcode.SelectedIndex = 28;
\r
48 srt_lang.SelectedIndex = 40;
\r
52 /// Gets the CLI Query for this panel
\r
54 /// <returns>A CliQuery string</returns>
\r
55 public string GetCliQuery
\r
59 string query = string.Empty;
\r
60 if (lv_subList.Items.Count != 0) // If we have subtitle tracks
\r
63 string subtitleTracks = String.Empty;
\r
64 string subtitleForced = String.Empty;
\r
65 string subtitleBurn = String.Empty;
\r
66 string subtitleDefault = String.Empty;
\r
69 string srtFile = String.Empty;
\r
70 string srtCodeset = String.Empty;
\r
71 string srtOffset = String.Empty;
\r
72 string srtLang = String.Empty;
\r
73 string srtDefault = String.Empty;
\r
76 foreach (SubtitleInfo item in subList)
\r
78 string itemToAdd, trackId;
\r
80 if (item.IsSrtSubtitle) // We have an SRT file
\r
82 srtCount++; // SRT track id.
\r
84 srtLang += srtLang == string.Empty ? langMap[item.SrtLang] : "," + langMap[item.SrtLang];
\r
85 srtCodeset += srtCodeset == string.Empty ? item.SrtCharCode : "," + item.SrtCharCode;
\r
87 if (item.Default == "Yes")
\r
88 srtDefault = srtCount.ToString();
\r
90 itemToAdd = item.SrtPath;
\r
91 srtFile += srtFile == string.Empty ? itemToAdd : "," + itemToAdd;
\r
93 itemToAdd = item.SrtOffset.ToString();
\r
94 srtOffset += srtOffset == string.Empty ? itemToAdd : "," + itemToAdd;
\r
96 else // We have Bitmap or CC
\r
100 // Find --subtitle <string>
\r
101 if (item.Track.Contains("Foreign Audio Search"))
\r
102 itemToAdd = "scan";
\r
105 tempSub = item.Track.Split(' ');
\r
106 itemToAdd = tempSub[0];
\r
109 subtitleTracks += subtitleTracks == string.Empty ? itemToAdd : "," + itemToAdd;
\r
111 // Find --subtitle-forced
\r
112 itemToAdd = string.Empty;
\r
113 tempSub = item.Track.Split(' ');
\r
114 trackId = tempSub[0];
\r
116 if (item.Forced == "Yes")
\r
117 itemToAdd = trackId;
\r
119 if (itemToAdd != string.Empty)
\r
120 subtitleForced += subtitleForced == string.Empty ? itemToAdd : "," + itemToAdd;
\r
122 // Find --subtitle-burn and --subtitle-default
\r
123 trackId = tempSub[0];
\r
125 if (trackId.Trim() == "Foreign") // foreign audio search
\r
128 if (item.Burned == "Yes") // burn
\r
129 subtitleBurn = trackId;
\r
131 if (item.Default == "Yes") // default
\r
132 subtitleDefault = trackId;
\r
136 // Build The CLI Subtitles Query
\r
137 if (subtitleTracks != string.Empty)
\r
139 query += " --subtitle " + subtitleTracks;
\r
141 if (subtitleForced != string.Empty)
\r
142 query += " --subtitle-forced=" + subtitleForced;
\r
143 if (subtitleBurn != string.Empty)
\r
144 query += " --subtitle-burn=" + subtitleBurn;
\r
145 if (subtitleDefault != string.Empty)
\r
146 query += " --subtitle-default=" + subtitleDefault;
\r
149 if (srtFile != string.Empty) // SRTs
\r
151 query += " --srt-file " + "\"" + srtFile + "\"";
\r
153 if (srtCodeset != string.Empty)
\r
154 query += " --srt-codeset " + srtCodeset;
\r
155 if (srtOffset != string.Empty)
\r
156 query += " --srt-offset " + srtOffset;
\r
157 if (srtLang != string.Empty)
\r
158 query += " --srt-lang " + srtLang;
\r
159 if (srtDefault != string.Empty)
\r
160 query += " --srt-default=" + srtDefault;
\r
167 /* Primary Controls */
\r
170 /// Add a Subtitle track.
\r
172 /// <param name="sender">
\r
175 /// <param name="e">
\r
178 private void BtnAddSubTrackClick(object sender, EventArgs e)
\r
181 string forcedVal = check_forced.CheckState == CheckState.Checked ? "Yes" : "No";
\r
182 string defaultSub = check_default.CheckState == CheckState.Checked ? "Yes" : "No";
\r
183 string burnedVal = check_burned.CheckState == CheckState.Checked &&
\r
184 (!drp_subtitleTracks.Text.Contains("Text"))
\r
187 string srtCode = "-", srtLangVal = "-", srtPath = "-", srtFile = "-";
\r
188 int srtOffsetMs = 0;
\r
190 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
194 srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath);
\r
195 srtFile = drp_subtitleTracks.SelectedItem.ToString();
\r
196 srtLangVal = srt_lang.SelectedItem.ToString();
\r
197 srtCode = srt_charcode.SelectedItem.ToString();
\r
198 srtOffsetMs = (int)srt_offset.Value;
\r
199 if (defaultSub == "Yes") SetNoSrtDefault();
\r
203 if (defaultSub == "Yes") SetNoDefault();
\r
204 if (burnedVal == "Yes") SetNoBurned();
\r
207 string trackName = (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
208 ? srtLangVal + " (" + srtFile + ")"
\r
209 : drp_subtitleTracks.SelectedItem.ToString();
\r
211 SubtitleInfo track = new SubtitleInfo
\r
214 Forced = forcedVal,
\r
215 Burned = burnedVal,
\r
216 Default = defaultSub,
\r
217 SrtLang = srtLangVal,
\r
218 SrtCharCode = srtCode,
\r
219 SrtOffset = srtOffsetMs,
\r
221 SrtFileName = srtFile
\r
224 lv_subList.Items.Add(track.ListView);
\r
225 subList.Add(track);
\r
229 /// Import an SRT Subtitle Track
\r
231 /// <param name="sender">
\r
234 /// <param name="e">
\r
237 private void BtnSrtAddClick(object sender, EventArgs e)
\r
239 if (openFileDialog.ShowDialog() != DialogResult.OK)
\r
242 if (srtFiles.ContainsKey(Path.GetFileName(openFileDialog.FileName)))
\r
245 "A Subtitle track with the same name has already been imported.",
\r
247 MessageBoxButtons.OK,
\r
248 MessageBoxIcon.Warning);
\r
252 drp_subtitleTracks.Items.Add(Path.GetFileName(openFileDialog.FileName));
\r
253 drp_subtitleTracks.SelectedItem = Path.GetFileName(openFileDialog.FileName);
\r
254 srtFiles.Add(Path.GetFileName(openFileDialog.FileName), openFileDialog.FileName);
\r
258 /// Remove a subtitle track
\r
260 /// <param name="sender">
\r
263 /// <param name="e">
\r
266 private void BtnRemoveSubTrackClick(object sender, EventArgs e)
\r
272 /// The Subtitle List selected index has changed
\r
274 /// <param name="sender">
\r
277 /// <param name="e">
\r
280 private void LbSubListSelectedIndexChanged(object sender, EventArgs e)
\r
282 // Set the dropdown controls based on the selected item in the List.
\r
283 if (lv_subList.Items.Count != 0 && lv_subList.SelectedIndices.Count != 0)
\r
285 SubtitleInfo track = subList[lv_subList.SelectedIndices[0]];
\r
288 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.ToLower().Contains(".srt"))
\r
291 foreach (var item in drp_subtitleTracks.Items)
\r
293 if (item.ToString() == track.SrtFileName)
\r
294 drp_subtitleTracks.SelectedIndex = c;
\r
297 srt_lang.SelectedItem = track.SrtLang;
\r
298 srt_offset.Value = track.SrtOffset;
\r
299 srt_charcode.SelectedItem = track.SrtCharCode;
\r
300 check_default.CheckState = track.Default == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
301 SubGroupBox.Text = "Selected Track: " + track.Track;
\r
303 else // We have Bitmap/CC
\r
305 foreach (var item in drp_subtitleTracks.Items)
\r
307 if (item.ToString() == track.Track)
\r
308 drp_subtitleTracks.SelectedIndex = c;
\r
311 check_forced.CheckState = track.Forced == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
312 check_burned.CheckState = track.Burned == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
313 check_default.CheckState = track.Default == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
314 SubGroupBox.Text = "Selected Track: " +
\r
315 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text;
\r
319 SubGroupBox.Text = "Selected Track: None (Click \"Add\" to add another track to the list)";
\r
322 /* Bitmap / CC / SRT Controls */
\r
325 /// Handle the Subtitle track dropdown changed event
\r
327 /// <param name="sender">
\r
330 /// <param name="e">
\r
333 private void DrpSubtitleTracksSelectedIndexChanged(object sender, EventArgs e)
\r
335 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
337 check_forced.Enabled = false;
\r
338 check_burned.Enabled = false;
\r
339 srt_lang.Enabled = true;
\r
340 srt_charcode.Enabled = true;
\r
341 srt_offset.Enabled = true;
\r
345 check_forced.Enabled = true;
\r
346 check_burned.Enabled = true;
\r
347 srt_lang.Enabled = false;
\r
348 srt_charcode.Enabled = false;
\r
349 srt_offset.Enabled = false;
\r
351 // Update an item in the list if required.
\r
352 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
354 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
356 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text = srt_lang.SelectedItem + "(" +
\r
357 drp_subtitleTracks.SelectedItem + ")";
\r
358 lv_subList.Select();
\r
361 srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath);
\r
362 subList[lv_subList.SelectedIndices[0]].SrtPath = srtPath;
\r
366 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text =
\r
367 drp_subtitleTracks.SelectedItem.ToString();
\r
368 lv_subList.Select();
\r
371 subList[lv_subList.SelectedIndices[0]].Track = drp_subtitleTracks.SelectedItem.ToString();
\r
375 /// Foreced Subtitles checkbox changed
\r
377 /// <param name="sender">
\r
380 /// <param name="e">
\r
383 private void CheckForcedCheckedChanged(object sender, EventArgs e)
\r
385 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
387 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[1].Text = check_forced.Checked ? "Yes" : "No";
\r
388 lv_subList.Select();
\r
390 subList[lv_subList.SelectedIndices[0]].Forced = check_forced.Checked ? "Yes" : "No";
\r
391 // Update SubList List<SubtitleInfo>
\r
395 /// Burned in subtitles checkbox changed
\r
397 /// <param name="sender">
\r
400 /// <param name="e">
\r
403 private void CheckBurnedCheckedChanged(object sender, EventArgs e)
\r
405 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
407 if (check_burned.Checked) // Make sure we only have 1 burned track
\r
410 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[2].Text = check_burned.Checked ? "Yes" : "No";
\r
411 lv_subList.Select();
\r
413 subList[lv_subList.SelectedIndices[0]].Burned = check_burned.Checked ? "Yes" : "No";
\r
414 // Update SubList List<SubtitleInfo>
\r
418 /// Default Subitle track check changed
\r
420 /// <param name="sender">
\r
423 /// <param name="e">
\r
426 private void CheckDefaultCheckedChanged(object sender, EventArgs e)
\r
428 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
430 if (check_default.Checked) // Make sure we only have 1 default track
\r
431 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.Contains(".srt"))
\r
436 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[3].Text = check_default.Checked ? "Yes" : "No";
\r
437 lv_subList.Select();
\r
439 subList[lv_subList.SelectedIndices[0]].Default = check_default.Checked ? "Yes" : "No";
\r
440 // Update SubList List<SubtitleInfo>
\r
444 /// Srt Offset Numeric Control Changed
\r
446 /// <param name="sender">
\r
449 /// <param name="e">
\r
452 private void SrtOffsetValueChanged(object sender, EventArgs e)
\r
454 // Update an item in the list if required.
\r
455 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0)
\r
458 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[6].Text = srt_offset.Value.ToString();
\r
459 lv_subList.Select();
\r
461 subList[lv_subList.SelectedIndices[0]].SrtOffset = (int)srt_offset.Value;
\r
462 // Update SubList List<SubtitleInfo>
\r
466 /// The SRT Charcode changed
\r
468 /// <param name="sender">
\r
471 /// <param name="e">
\r
474 private void SrtCharcodeSelectedIndexChanged(object sender, EventArgs e)
\r
476 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
478 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[5].Text = srt_charcode.SelectedItem.ToString();
\r
479 lv_subList.Select();
\r
481 subList[lv_subList.SelectedIndices[0]].SrtCharCode = srt_charcode.SelectedItem.ToString();
\r
482 // Update SubList List<SubtitleInfo>
\r
486 /// The Srt Language code changed
\r
488 /// <param name="sender">
\r
491 /// <param name="e">
\r
494 private void SrtLangSelectedIndexChanged(object sender, EventArgs e)
\r
496 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
498 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[4].Text = srt_lang.SelectedItem.ToString();
\r
499 lv_subList.Select();
\r
501 subList[lv_subList.SelectedIndices[0]].SrtLang = srt_lang.SelectedItem.ToString();
\r
502 // Update SubList List<SubtitleInfo>
\r
505 /* Right Click Menu */
\r
508 /// Move an item in the subtitle list up
\r
510 /// <param name="sender">
\r
513 /// <param name="e">
\r
516 private void MnuMoveupClick(object sender, EventArgs e)
\r
518 if (lv_subList.SelectedIndices.Count != 0)
\r
520 ListViewItem item = lv_subList.SelectedItems[0];
\r
521 int index = item.Index;
\r
524 if (lv_subList.Items.Count > index && index >= 0)
\r
526 lv_subList.Items.Remove(item);
\r
527 lv_subList.Items.Insert(index, item);
\r
528 item.Selected = true;
\r
529 lv_subList.Focus();
\r
535 /// Move an item in the subtitle list down
\r
537 /// <param name="sender">
\r
540 /// <param name="e">
\r
543 private void MnuMovedownClick(object sender, EventArgs e)
\r
545 if (lv_subList.SelectedIndices.Count != 0)
\r
547 ListViewItem item = lv_subList.SelectedItems[0];
\r
548 int index = item.Index;
\r
551 if (index < lv_subList.Items.Count)
\r
553 lv_subList.Items.Remove(item);
\r
554 lv_subList.Items.Insert(index, item);
\r
555 item.Selected = true;
\r
556 lv_subList.Focus();
\r
562 /// Remove a selected subtitle track.
\r
564 /// <param name="sender">
\r
567 /// <param name="e">
\r
570 private void MnuRemoveClick(object sender, EventArgs e)
\r
578 /// Set all Non SRT tracks to Default = NO
\r
580 private void SetNoDefault()
\r
583 foreach (ListViewItem item in lv_subList.Items)
\r
585 if (subList[c].SrtPath == "-")
\r
587 if (item.SubItems[3].Text == "Yes")
\r
589 item.SubItems[3].Text = "No";
\r
590 subList[c].Default = "No";
\r
598 /// Set all subtitle tracks so that they have no default.
\r
600 private void SetNoSrtDefault()
\r
603 foreach (ListViewItem item in lv_subList.Items)
\r
605 if (!subList[c].IsSrtSubtitle)
\r
607 if (item.SubItems[3].Text == "Yes")
\r
609 item.SubItems[3].Text = "No";
\r
610 subList[c].Default = "No";
\r
618 /// Set all tracks to Burned = No
\r
620 private void SetNoBurned()
\r
623 foreach (ListViewItem item in lv_subList.Items)
\r
625 if (item.SubItems[2].Text == "Yes")
\r
627 item.SubItems[2].Text = "No";
\r
628 subList[c].Burned = "No";
\r
635 /// Remove a selected track
\r
637 private void RemoveTrack()
\r
639 // Remove the Item and reselect the control if the following conditions are met.
\r
640 if (lv_subList.SelectedItems.Count != 0)
\r
642 // Record the current selected index.
\r
643 int currentPosition = lv_subList.SelectedIndices[0];
\r
644 int selectedInd = lv_subList.SelectedIndices[0];
\r
646 lv_subList.Items.RemoveAt(selectedInd);
\r
647 subList.RemoveAt(selectedInd);
\r
649 // Now reslect the correct item and give focus to the list.
\r
650 if (lv_subList.Items.Count != 0)
\r
652 if (currentPosition <= (lv_subList.Items.Count - 1))
\r
653 lv_subList.Items[currentPosition].Selected = true;
\r
654 else if (currentPosition > (lv_subList.Items.Count - 1))
\r
655 lv_subList.Items[lv_subList.Items.Count - 1].Selected = true;
\r
657 lv_subList.Select();
\r
663 /// Clear the Subtitle List
\r
665 public void Clear()
\r
667 lv_subList.Items.Clear();
\r
672 /// Checks of the current settings will require the m4v file extension
\r
674 /// <returns>True if Yes</returns>
\r
675 public bool RequiresM4V()
\r
677 return this.lv_subList.Items.Cast<ListViewItem>().Any(item => item.SubItems.Count != 5 || item.SubItems[1].Text.Contains("(Text)"));
\r
681 /// Automatically setup the subtitle tracks.
\r
682 /// This handles the automatic setup of subitles which the user can control from the program options
\r
684 /// <param name="subs">List of Subtitles</param>
\r
685 public void SetSubtitleTrackAuto(object[] subs)
\r
687 drp_subtitleTracks.Items.Clear();
\r
688 drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
689 drp_subtitleTracks.Items.AddRange(subs);
\r
690 drp_subtitleTracks.SelectedIndex = 0;
\r
693 this.AutomaticSubtitleSelection();
\r
697 /// Automatic Subtitle Selection based on user preferences.
\r
699 public void AutomaticSubtitleSelection()
\r
701 // Handle Native Language and "Dub Foreign language audio" and "Use Foreign language audio and Subtitles" Options
\r
702 if (Properties.Settings.Default.NativeLanguage != "Any")
\r
704 if (Properties.Settings.Default.DubMode != 1) // We need to add a subtitle track if this is false.
\r
706 foreach (object item in drp_subtitleTracks.Items)
\r
708 if (item.ToString().Contains(Properties.Settings.Default.NativeLanguage))
\r
710 drp_subtitleTracks.SelectedItem = item;
\r
711 BtnAddSubTrackClick(this, new EventArgs());
\r
715 if (drp_subtitleTracks.SelectedIndex == 0 && Properties.Settings.Default.useClosedCaption)
\r
717 foreach (object item in drp_subtitleTracks.Items)
\r
719 if (item.ToString().Contains("Closed"))
\r
721 drp_subtitleTracks.SelectedItem = item;
\r
722 BtnAddSubTrackClick(this, new EventArgs());
\r
731 /// Get the list of subtitles.
\r
733 /// <returns>A List of SubtitleInfo Object</returns>
\r
734 public List<SubtitleInfo> GetSubtitleInfoList()
\r