3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Collections.Generic;
\r
10 using System.Windows.Forms;
\r
11 using Handbrake.Functions;
\r
12 using Handbrake.Model;
\r
14 namespace Handbrake.Controls
\r
18 public partial class Subtitles : UserControl
\r
20 readonly IDictionary<string, string> langMap = new Dictionary<string, string>();
\r
21 readonly List<SubtitleInfo> subList = new List<SubtitleInfo>();
\r
22 private int fileContainer;
\r
26 InitializeComponent();
\r
28 langMap = Main.MapLanguages();
\r
29 foreach (string key in langMap.Keys)
\r
30 srt_lang.Items.Add(key);
\r
32 srt_charcode.SelectedIndex = 28;
\r
33 srt_lang.SelectedIndex = 40;
\r
37 private void BtnAddSubTrackClick(object sender, EventArgs e)
\r
40 string forcedVal = check_forced.CheckState == CheckState.Checked ? "Yes" : "No";
\r
41 string defaultSub = check_default.CheckState == CheckState.Checked ? "Yes" : "No";
\r
42 string burnedVal = check_burned.CheckState == CheckState.Checked && (!drp_subtitleTracks.Text.Contains("Text")) ? "Yes" : "No";
\r
43 string srtCode = "-", srtLangVal = "-", srtPath = "-", srtFile = "-";
\r
44 int srtOffsetMs = 0;
\r
46 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
50 srtPath = openFileDialog.FileName;
\r
51 srtFile = Path.GetFileName(openFileDialog.FileName);
\r
52 srtLangVal = srt_lang.SelectedItem.ToString();
\r
53 srtCode = srt_charcode.SelectedItem.ToString();
\r
54 srtOffsetMs = (int)srt_offset.Value;
\r
55 if (defaultSub == "Yes") SetNoSrtDefault();
\r
58 if (defaultSub == "Yes") SetNoDefault();
\r
59 if (burnedVal == "Yes") SetNoBurned();
\r
61 if (fileContainer == 0)
\r
62 burnedVal = "Yes"; // MP4 must have bitmap subs burned in.
\r
65 if (fileContainer == 0) // MP4 and M4V file extension
\r
67 // Make sure we only have 1 bitmap track.
\r
68 if (drp_subtitleTracks.SelectedItem != null && drp_subtitleTracks.SelectedItem.ToString().Contains("Bitmap"))
\r
70 if (lv_subList.Items.Cast<ListViewItem>().Any(item => item.SubItems[0].Text.Contains("Bitmap")))
\r
72 MessageBox.Show(this, "More than one vobsub is not supported in mp4... Your first vobsub track will now be used.",
\r
73 "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
79 string trackName = (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
80 ? srtLangVal + " (" + srtFile + ")"
\r
81 : drp_subtitleTracks.SelectedItem.ToString();
\r
84 SubtitleInfo track = new SubtitleInfo
\r
89 Default = defaultSub,
\r
90 SrtLang = srtLangVal,
\r
91 SrtCharCode = srtCode,
\r
92 SrtOffset = srtOffsetMs,
\r
94 SrtFileName = srtFile
\r
97 lv_subList.Items.Add(track.ListView);
\r
101 private void BtnSrtAddClick(object sender, EventArgs e)
\r
103 if (openFileDialog.ShowDialog() != DialogResult.OK)
\r
105 drp_subtitleTracks.Items.Add(Path.GetFileName(openFileDialog.FileName));
\r
106 drp_subtitleTracks.SelectedItem = Path.GetFileName(openFileDialog.FileName);
\r
108 private void BtnRemoveSubTrackClick(object sender, EventArgs e)
\r
113 // Secondary Controls
\r
114 private void LbSubListSelectedIndexChanged(object sender, EventArgs e)
\r
116 // Set the dropdown controls based on the selected item in the List.
\r
117 if (lv_subList.Items.Count != 0 && lv_subList.SelectedIndices.Count != 0)
\r
119 SubtitleInfo track = subList[lv_subList.SelectedIndices[0]];
\r
122 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.ToLower().Contains(".srt")) // We have an SRT
\r
124 foreach (var item in drp_subtitleTracks.Items)
\r
126 if (item.ToString() == track.SrtFileName)
\r
127 drp_subtitleTracks.SelectedIndex = c;
\r
130 srt_lang.SelectedItem = track.SrtLang;
\r
131 srt_offset.Value = track.SrtOffset;
\r
132 srt_charcode.SelectedItem = track.SrtCharCode;
\r
133 check_default.CheckState = track.Default == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
134 SubGroupBox.Text = "Selected Track: " + track.Track;
\r
136 else // We have Bitmap/CC
\r
138 foreach (var item in drp_subtitleTracks.Items)
\r
140 if (item.ToString() == track.Track)
\r
141 drp_subtitleTracks.SelectedIndex = c;
\r
144 check_forced.CheckState = track.Forced == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
145 check_burned.CheckState = track.Burned == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
146 check_default.CheckState = track.Default == "Yes" ? CheckState.Checked : CheckState.Unchecked;
\r
147 SubGroupBox.Text = "Selected Track: " + lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text;
\r
151 SubGroupBox.Text = "Selected Track: None (Click \"Add\" to add another track to the list)";
\r
154 // Bitmap / CC / SRT Controls
\r
155 private void DrpSubtitleTracksSelectedIndexChanged(object sender, EventArgs e)
\r
157 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
159 check_forced.Enabled = false;
\r
160 check_burned.Enabled = false;
\r
161 srt_lang.Enabled = true;
\r
162 srt_charcode.Enabled = true;
\r
163 srt_offset.Enabled = true;
\r
167 check_forced.Enabled = true;
\r
168 check_burned.Enabled = true;
\r
169 srt_lang.Enabled = false;
\r
170 srt_charcode.Enabled = false;
\r
171 srt_offset.Enabled = false;
\r
173 // Update an item in the list if required.
\r
174 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
176 if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt"))
\r
178 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text = srt_lang.SelectedItem + "(" +
\r
179 drp_subtitleTracks.SelectedItem + ")";
\r
180 lv_subList.Select();
\r
183 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text =
\r
184 drp_subtitleTracks.SelectedItem.ToString();
\r
185 lv_subList.Select();
\r
188 subList[lv_subList.SelectedIndices[0]].Track = drp_subtitleTracks.SelectedItem.ToString(); // Update SubList List<SubtitleInfo>
\r
190 private void CheckForcedCheckedChanged(object sender, EventArgs e)
\r
192 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
194 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[1].Text = check_forced.Checked ? "Yes" : "No";
\r
195 lv_subList.Select();
\r
197 subList[lv_subList.SelectedIndices[0]].Forced = check_forced.Checked ? "Yes" : "No"; // Update SubList List<SubtitleInfo>
\r
199 private void CheckBurnedCheckedChanged(object sender, EventArgs e)
\r
201 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
203 if (check_burned.Checked) // Make sure we only have 1 burned track
\r
206 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[2].Text = check_burned.Checked ? "Yes" : "No";
\r
207 lv_subList.Select();
\r
209 subList[lv_subList.SelectedIndices[0]].Burned = check_burned.Checked ? "Yes" : "No"; // Update SubList List<SubtitleInfo>
\r
211 private void CheckDefaultCheckedChanged(object sender, EventArgs e)
\r
213 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
215 if (check_default.Checked) // Make sure we only have 1 default track
\r
216 if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.Contains(".srt"))
\r
221 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[3].Text = check_default.Checked ? "Yes" : "No";
\r
222 lv_subList.Select();
\r
224 subList[lv_subList.SelectedIndices[0]].Default = check_default.Checked ? "Yes" : "No"; // Update SubList List<SubtitleInfo>
\r
226 private void SrtOffsetValueChanged(object sender, EventArgs e)
\r
228 // Update an item in the list if required.
\r
229 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0)
\r
232 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[6].Text = srt_offset.Value.ToString();
\r
233 lv_subList.Select();
\r
235 subList[lv_subList.SelectedIndices[0]].SrtOffset = (int)srt_offset.Value; // Update SubList List<SubtitleInfo>
\r
237 private void SrtCharcodeSelectedIndexChanged(object sender, EventArgs e)
\r
239 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
241 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[5].Text = srt_charcode.SelectedItem.ToString();
\r
242 lv_subList.Select();
\r
244 subList[lv_subList.SelectedIndices[0]].SrtCharCode = srt_charcode.SelectedItem.ToString(); // Update SubList List<SubtitleInfo>
\r
246 private void SrtLangSelectedIndexChanged(object sender, EventArgs e)
\r
248 if (lv_subList.Items.Count == 0 || lv_subList.SelectedIndices.Count == 0) return;
\r
250 lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[4].Text = srt_lang.SelectedItem.ToString();
\r
251 lv_subList.Select();
\r
253 subList[lv_subList.SelectedIndices[0]].SrtLang = srt_lang.SelectedItem.ToString(); // Update SubList List<SubtitleInfo>
\r
256 // Right Click Menu
\r
257 private void MnuMoveupClick(object sender, EventArgs e)
\r
259 if (lv_subList.SelectedIndices.Count != 0)
\r
261 ListViewItem item = lv_subList.SelectedItems[0];
\r
262 int index = item.Index;
\r
265 if (lv_subList.Items.Count > index && index >= 0)
\r
267 lv_subList.Items.Remove(item);
\r
268 lv_subList.Items.Insert(index, item);
\r
269 item.Selected = true;
\r
270 lv_subList.Focus();
\r
274 private void MnuMovedownClick(object sender, EventArgs e)
\r
276 if (lv_subList.SelectedIndices.Count != 0)
\r
278 ListViewItem item = lv_subList.SelectedItems[0];
\r
279 int index = item.Index;
\r
282 if (index < lv_subList.Items.Count)
\r
284 lv_subList.Items.Remove(item);
\r
285 lv_subList.Items.Insert(index, item);
\r
286 item.Selected = true;
\r
287 lv_subList.Focus();
\r
291 private void MnuRemoveClick(object sender, EventArgs e)
\r
297 private void SetNoDefault()
\r
300 foreach (ListViewItem item in lv_subList.Items)
\r
302 if (subList[c].SrtPath == "-")
\r
304 if (item.SubItems[3].Text == "Yes")
\r
306 item.SubItems[3].Text = "No";
\r
307 subList[c].Default = "No";
\r
315 /// Set all subtitle tracks so that they have no default.
\r
317 private void SetNoSrtDefault()
\r
320 foreach (ListViewItem item in lv_subList.Items)
\r
322 if (!subList[c].IsSrtSubtitle)
\r
324 if (item.SubItems[3].Text == "Yes")
\r
326 item.SubItems[3].Text = "No";
\r
327 subList[c].Default = "No";
\r
333 private void SetNoBurned()
\r
336 foreach (ListViewItem item in lv_subList.Items)
\r
338 if (item.SubItems[2].Text == "Yes")
\r
340 item.SubItems[2].Text = "No";
\r
341 subList[c].Burned = "No";
\r
346 private void RemoveTrack()
\r
348 // Remove the Item and reselect the control if the following conditions are met.
\r
349 if (lv_subList.SelectedItems.Count != 0)
\r
351 // Record the current selected index.
\r
352 int currentPosition = lv_subList.SelectedIndices[0];
\r
353 int selectedInd = lv_subList.SelectedIndices[0];
\r
355 lv_subList.Items.RemoveAt(selectedInd);
\r
356 subList.RemoveAt(selectedInd);
\r
358 // Now reslect the correct item and give focus to the list.
\r
359 if (lv_subList.Items.Count != 0)
\r
361 if (currentPosition <= (lv_subList.Items.Count - 1))
\r
362 lv_subList.Items[currentPosition].Selected = true;
\r
363 else if (currentPosition > (lv_subList.Items.Count - 1))
\r
364 lv_subList.Items[lv_subList.Items.Count - 1].Selected = true;
\r
366 lv_subList.Select();
\r
372 /// Clear the Subtitle List
\r
374 public void Clear()
\r
376 lv_subList.Items.Clear();
\r
381 /// Cleverly Clear the subtitle list. Only remove tracks that are not available for the current source.
\r
383 public void SmartClear()
\r
385 /* Smart clear will only remove subtitle tracks that do not have an equivlent
\r
386 for the new source / title which the user has selected. */
\r
387 throw new NotImplementedException();
\r
391 /// Checks of the current settings will require the m4v file extension
\r
393 /// <returns>True if Yes</returns>
\r
394 public Boolean RequiresM4V()
\r
396 foreach (ListViewItem item in lv_subList.Items)
\r
398 if (item.SubItems.Count != 5)
\r
401 if (item.SubItems[1].Text.Contains("(Text)"))
\r
408 /// Automatically setup the subtitle tracks.
\r
409 /// This handles the automatic setup of subitles which the user can control from the program options
\r
411 /// <param name="subs"></param>
\r
412 public void SetSubtitleTrackAuto(object[] subs)
\r
414 drp_subtitleTracks.Items.Clear();
\r
415 drp_subtitleTracks.Items.Add("Foreign Audio Search (Bitmap)");
\r
416 drp_subtitleTracks.Items.AddRange(subs);
\r
417 drp_subtitleTracks.SelectedIndex = 0;
\r
420 // Handle Native Language and "Dub Foreign language audio" and "Use Foreign language audio and Subtitles" Options
\r
421 if (Properties.Settings.Default.NativeLanguage != "Any")
\r
423 if (!Properties.Settings.Default.DubAudio) // We need to add a subtitle track if this is false.
\r
426 foreach (object item in drp_subtitleTracks.Items)
\r
428 if (item.ToString().Contains(Properties.Settings.Default.NativeLanguage))
\r
429 drp_subtitleTracks.SelectedIndex = i;
\r
434 BtnAddSubTrackClick(this, new EventArgs());
\r
440 /// Set the file container which is currently in use.
\r
442 /// <param name="value"></param>
\r
443 public void SetContainer(int value)
\r
445 fileContainer = value;
\r
446 Boolean trigger = false;
\r
447 if (fileContainer != 1)
\r
448 foreach (ListViewItem item in lv_subList.Items)
\r
450 if (item.SubItems[1].Text.Contains("Bitmap"))
\r
453 lv_subList.Items.Remove(item);
\r
460 /// Get the list of subtitles.
\r
462 /// <returns></returns>
\r
463 public List<SubtitleInfo> GetSubtitleInfoList()
\r
469 /// Get the CLI Query for this panel
\r
471 /// <returns></returns>
\r
472 public string GetCliQuery
\r
476 string query = string.Empty;
\r
477 if (lv_subList.Items.Count != 0) // If we have subtitle tracks
\r
480 string subtitleTracks = String.Empty;
\r
481 string subtitleForced = String.Empty;
\r
482 string subtitleBurn = String.Empty;
\r
483 string subtitleDefault = String.Empty;
\r
486 string srtFile = String.Empty;
\r
487 string srtCodeset = String.Empty;
\r
488 string srtOffset = String.Empty;
\r
489 string srtLang = String.Empty;
\r
490 string srtDefault = String.Empty;
\r
493 foreach (SubtitleInfo item in subList)
\r
495 string itemToAdd, trackId;
\r
497 if (item.IsSrtSubtitle) // We have an SRT file
\r
499 srtCount++; // SRT track id.
\r
501 srtLang += srtLang == "" ? langMap[item.SrtLang] : "," + langMap[item.SrtLang];
\r
502 srtCodeset += srtCodeset == "" ? item.SrtCharCode : "," + item.SrtCharCode;
\r
504 if (item.Default == "Yes")
\r
505 srtDefault = srtCount.ToString();
\r
507 itemToAdd = item.SrtPath;
\r
508 srtFile += srtFile == "" ? itemToAdd : "," + itemToAdd;
\r
510 itemToAdd = item.SrtOffset.ToString();
\r
511 srtOffset += srtOffset == "" ? itemToAdd : "," + itemToAdd;
\r
513 else // We have Bitmap or CC
\r
517 // Find --subtitle <string>
\r
518 if (item.Track.Contains("Foreign Audio Search"))
\r
519 itemToAdd = "scan";
\r
522 tempSub = item.Track.Split(' ');
\r
523 itemToAdd = tempSub[0];
\r
526 subtitleTracks += subtitleTracks == "" ? itemToAdd : "," + itemToAdd;
\r
528 // Find --subtitle-forced
\r
530 tempSub = item.Track.Split(' ');
\r
531 trackId = tempSub[0];
\r
533 if (item.Forced == "Yes")
\r
534 itemToAdd = "scan";
\r
536 if (itemToAdd != "")
\r
537 subtitleForced += subtitleForced == "" ? itemToAdd : "," + itemToAdd;
\r
539 // Find --subtitle-burn and --subtitle-default
\r
540 trackId = tempSub[0];
\r
542 if (trackId.Trim() == "Foreign") // foreign audio search
\r
545 if (item.Burned == "Yes") // burn
\r
546 subtitleBurn = trackId;
\r
548 if (item.Default == "Yes") // default
\r
549 subtitleDefault = trackId;
\r
553 // Build The CLI Subtitles Query
\r
554 if (subtitleTracks != "")
\r
556 query += " --subtitle " + subtitleTracks;
\r
558 if (subtitleForced != "")
\r
559 query += " --subtitle-forced=" + subtitleForced;
\r
560 if (subtitleBurn != "")
\r
561 query += " --subtitle-burn=" + subtitleBurn;
\r
562 if (subtitleDefault != "")
\r
563 query += " --subtitle-default=" + subtitleDefault;
\r
566 if (srtFile != "") // SRTs
\r
568 query += " --srt-file " + "\"" + srtFile + "\"";
\r
570 if (srtCodeset != "")
\r
571 query += " --srt-codeset " + srtCodeset;
\r
572 if (srtOffset != "")
\r
573 query += " --srt-offset " + srtOffset;
\r
575 query += " --srt-lang " + srtLang;
\r
576 if (srtDefault != "")
\r
577 query += " --srt-default=" + srtDefault;
\r