OSDN Git Service

LinGui: add audio-dub/add-subtitle radio buttons for preferred language control
[handbrake-jp/handbrake-jp-git.git] / gtk / src / subtitlehandler.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * subtitlehandler.c
4  * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
5  * 
6  * subtitlehandler.c is free software.
7  * 
8  * You may redistribute it and/or modify it under the terms of the
9  * GNU General Public License, as published by the Free Software
10  * Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  */
13
14 #include <gtk/gtk.h>
15 #include "hb.h"
16 #include "settings.h"
17 #include "hb-backend.h"
18 #include "values.h"
19 #include "callbacks.h"
20 #include "preview.h"
21 #include "presets.h"
22 #include "audiohandler.h"
23 #include "subtitlehandler.h"
24
25 static void add_to_subtitle_list(signal_user_data_t *ud, GValue *settings);
26
27 static void
28 free_subtitle_index_list(gpointer data)
29 {
30         g_free(data);
31 }
32
33 static void
34 free_subtitle_key(gpointer data)
35 {
36         if (data != NULL)
37                 g_free(data);
38 }
39
40 static gboolean
41 mustBurn(signal_user_data_t *ud, gint track)
42 {
43         gint mux;
44
45         mux = ghb_settings_combo_int(ud->settings, "FileFormat");
46         if (mux == HB_MUX_MP4)
47         {
48                 gint source;
49
50                 // MP4 can only handle burned vobsubs.  make sure there isn't
51                 // already something burned in the list
52                 source = ghb_subtitle_track_source(ud, track);
53                 if (source == VOBSUB)
54                 {
55                         return TRUE;
56                 }
57         }
58         return FALSE;
59 }
60
61 void
62 ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint index)
63 {
64         GValue *subtitle_list;
65         GValue *settings;
66         gint ii, count, tt;
67         GtkTreeView  *tv;
68         GtkTreeModel *tm;
69         GtkTreeIter   ti;
70         gboolean burned;
71
72         g_debug("ghb_subtitle_exclusive_burn");
73         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
74         count = ghb_array_len(subtitle_list);
75         for (ii = 0; ii < count; ii++)
76         {
77                 settings = ghb_array_get_nth(subtitle_list, ii);
78                 tt = ghb_settings_combo_int(settings, "SubtitleTrack");
79                 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
80
81                 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
82                 g_return_if_fail(tv != NULL);
83                 tm = gtk_tree_view_get_model(tv);
84                 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
85                 if (burned && ii != index && !mustBurn(ud, tt))
86                 {
87                         ghb_settings_set_boolean(settings, "SubtitleBurned", FALSE);
88                         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, FALSE, -1);
89                 }
90         }
91 }
92
93 void
94 ghb_subtitle_exclusive_default(signal_user_data_t *ud, gint index)
95 {
96         GValue *subtitle_list;
97         GValue *settings;
98         gint ii, count;
99         GtkTreeView  *tv;
100         GtkTreeModel *tm;
101         GtkTreeIter   ti;
102         gboolean def;
103
104         g_debug("ghb_subtitle_exclusive_default");
105         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
106         count = ghb_array_len(subtitle_list);
107         for (ii = 0; ii < count; ii++)
108         {
109                 settings = ghb_array_get_nth(subtitle_list, ii);
110                 def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
111
112                 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
113                 g_return_if_fail(tv != NULL);
114                 tm = gtk_tree_view_get_model(tv);
115                 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
116                 if (def && ii != index)
117                 {
118
119                         ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", FALSE);
120                         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, FALSE, -1);
121                 }
122         }
123 }
124
125 void
126 ghb_add_subtitle(signal_user_data_t *ud, GValue *settings)
127 {
128         // Add the current subtitle settings to the list.
129         GValue *subtitle_list;
130         gint count;
131         gboolean burned;
132         
133         g_debug("ghb_add_subtitle ()");
134
135         // Only allow up to 8 subtitle entries
136         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
137         if (subtitle_list == NULL)
138         {
139                 subtitle_list = ghb_array_value_new(8);
140                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
141         }
142         count = ghb_array_len(subtitle_list);
143         ghb_array_append(subtitle_list, settings);
144         add_to_subtitle_list(ud, settings);
145
146         burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
147         if (burned)
148                 ghb_subtitle_exclusive_burn(ud, count);
149 }
150
151 static void
152 add_all_pref_subtitles(signal_user_data_t *ud)
153 {
154         const GValue *pref_subtitle;
155         GValue *subtitle;
156         gint count, ii, track;
157         char *lang;
158
159         pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
160         count = ghb_array_len(pref_subtitle);
161         for (ii = 0; ii < count; ii++)
162         {
163                 subtitle = ghb_value_dup(ghb_array_get_nth(pref_subtitle, ii));
164                 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
165                 // If there are multiple subtitles using the same language, then
166                 // select sequential tracks for each.  The hash keeps track 
167                 // of the tracks used for each language.
168                 track = ghb_find_pref_subtitle_track(lang);
169                 g_free(lang);
170                 if (track >= -1)
171                 {
172                         // Add to subtitle list
173                         ghb_settings_set_int(subtitle, "SubtitleTrack", track);
174                         ghb_add_subtitle(ud, subtitle);
175                 }
176         }
177 }
178
179 void
180 ghb_set_pref_subtitle(gint titleindex, signal_user_data_t *ud)
181 {
182         gint track;
183         GHashTable *track_indices;
184         gchar *lang, *pref_lang = NULL;
185         gchar *audio_lang;
186         gint foreign_lang_index = -1;
187
188         const GValue *pref_subtitle;
189         GValue *subtitle;
190         gint count, ii, jj;
191         
192         g_debug("ghb_set_pref_subtitle %d", titleindex);
193
194         // Check to see if we need to add a subtitle track for foreign audio
195         // language films. A subtitle track will be added if:
196         //
197         // The first (default) audio track language does NOT match the users
198         // chosen Preferred Language AND the Preferred Language is NOT Any (und).
199         //
200         audio_lang = ghb_get_user_audio_lang(ud, titleindex, 0);
201         pref_lang = ghb_settings_get_string(ud->settings, "SourceAudioLang");
202
203         if (audio_lang != NULL && pref_lang != NULL &&
204                 (strcmp(audio_lang, pref_lang) == 0 || strcmp("und", pref_lang) == 0))
205         {
206                 g_free(pref_lang);
207                 pref_lang = NULL;
208         }
209
210         track_indices = g_hash_table_new_full(g_str_hash, g_str_equal, 
211                                                                                         free_subtitle_key, free_subtitle_index_list);
212
213         ghb_ui_update(ud, "SubtitleTrack", ghb_int_value(0));
214
215         // Clear the subtitle list
216         ghb_clear_subtitle_list(ud);
217         if (titleindex < 0)
218         {
219                 add_all_pref_subtitles(ud);
220                 return;
221         }
222
223         // Find "best" subtitle based on subtitle preferences
224         pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
225
226         count = ghb_array_len(pref_subtitle);
227         jj = 0;
228         for (ii = 0; ii < count; ii++)
229         {
230                 subtitle = ghb_array_get_nth(pref_subtitle, ii);
231                 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
232                 // If there are multiple subtitles using the same language, then
233                 // select sequential tracks for each.  The hash keeps track 
234                 // of the tracks used for each language.
235                 track = ghb_find_subtitle_track(titleindex, lang, track_indices);
236                 if (track >= -1)
237                 {
238                         GValue *dup = ghb_value_dup(subtitle);
239                         ghb_settings_set_int(dup, "SubtitleTrack", track);
240                         if (foreign_lang_index < 0 && pref_lang != NULL &&
241                                 strcmp(lang, pref_lang) == 0)
242                         {
243                                 foreign_lang_index = jj;
244                                 ghb_settings_take_value(dup, "SubtitleForced", 
245                                                                 ghb_boolean_value_new(FALSE));
246                                 ghb_settings_take_value(dup, "SubtitleDefaultTrack", 
247                                                                 ghb_boolean_value_new(TRUE));
248                         }
249                         ghb_add_subtitle(ud, dup);
250                         jj++;
251                 }
252                 g_free(lang);
253         }
254         if (foreign_lang_index < 0 && pref_lang != NULL)
255         {
256                 GValue *settings;
257                 gboolean burn;
258
259                 track = ghb_find_subtitle_track(titleindex, pref_lang, track_indices);
260                 if (track >= -1)
261                 {
262                         burn = mustBurn(ud, track);
263                         settings = ghb_dict_value_new();
264                         ghb_settings_set_int(settings, "SubtitleTrack", track);
265                         ghb_settings_take_value(settings, "SubtitleForced", 
266                                                         ghb_boolean_value_new(FALSE));
267                         ghb_settings_take_value(settings, "SubtitleBurned", 
268                                                         ghb_boolean_value_new(burn));
269                         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
270                                                         ghb_boolean_value_new(TRUE));
271
272                         ghb_add_subtitle(ud, settings);
273                         foreign_lang_index = jj;
274                 }
275         }
276         if (foreign_lang_index >= 0)
277         {
278                 GValue *subtitle_list;
279                 gboolean burn, def;
280
281                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
282                 subtitle = ghb_array_get_nth(subtitle_list, foreign_lang_index);
283
284                 burn = ghb_settings_get_boolean(subtitle, "SubtitleBurned");
285                 def = ghb_settings_get_boolean(subtitle, "SubtitleDefaultTrack");
286                 if (burn)
287                         ghb_subtitle_exclusive_burn(ud, foreign_lang_index);
288                 if (def)
289                         ghb_subtitle_exclusive_default(ud, foreign_lang_index);
290                 ghb_log("adding subtitle for foreign language audio: %s", audio_lang);
291         }
292         if (pref_lang != NULL)
293                 g_free(pref_lang);
294         if (audio_lang != NULL)
295                 g_free(audio_lang);
296         g_hash_table_destroy(track_indices);
297 }
298
299 gint
300 ghb_selected_subtitle_row(signal_user_data_t *ud)
301 {
302         GtkTreeView *treeview;
303         GtkTreePath *treepath;
304         GtkTreeSelection *selection;
305         GtkTreeModel *store;
306         GtkTreeIter iter;
307         gint *indices;
308         gint row = -1;
309         
310         g_debug("ghb_selected_subtitle_row ()");
311         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
312         selection = gtk_tree_view_get_selection (treeview);
313         if (gtk_tree_selection_get_selected(selection, &store, &iter))
314         {
315                 // Get the row number
316                 treepath = gtk_tree_model_get_path (store, &iter);
317                 indices = gtk_tree_path_get_indices (treepath);
318                 row = indices[0];
319                 gtk_tree_path_free(treepath);
320         }
321         return row;
322 }
323
324 GValue*
325 ghb_selected_subtitle_settings(signal_user_data_t *ud)
326 {
327         GtkTreeView *treeview;
328         GtkTreePath *treepath;
329         GtkTreeSelection *selection;
330         GtkTreeModel *store;
331         GtkTreeIter iter;
332         gint *indices;
333         gint row;
334         GValue *settings = NULL;
335         const GValue *subtitle_list;
336         
337         g_debug("get_selected_settings ()");
338         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
339         selection = gtk_tree_view_get_selection (treeview);
340         if (gtk_tree_selection_get_selected(selection, &store, &iter))
341         {
342                 // Get the row number
343                 treepath = gtk_tree_model_get_path (store, &iter);
344                 indices = gtk_tree_path_get_indices (treepath);
345                 row = indices[0];
346                 gtk_tree_path_free(treepath);
347                 // find subtitle settings
348                 if (row < 0) return NULL;
349                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
350                 if (row >= ghb_array_len(subtitle_list))
351                         return NULL;
352                 settings = ghb_array_get_nth(subtitle_list, row);
353         }
354         return settings;
355 }
356
357 G_MODULE_EXPORT void
358 subtitle_forced_toggled_cb(
359         GtkCellRendererToggle *cell, 
360         gchar                 *path,
361         signal_user_data_t    *ud)
362 {
363         GtkTreeView  *tv;
364         GtkTreeModel *tm;
365         GtkTreeIter   ti;
366         gboolean      active;
367         gint          row;
368         GtkTreePath  *tp;
369         gint *indices;
370         GValue *subtitle_list, *settings;
371         gint source, track;
372
373         g_debug("forced toggled");
374         tp = gtk_tree_path_new_from_string (path);
375         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
376         g_return_if_fail(tv != NULL);
377         tm = gtk_tree_view_get_model(tv);
378         g_return_if_fail(tm != NULL);
379         gtk_tree_model_get_iter(tm, &ti, tp);
380         gtk_tree_model_get(tm, &ti, 1, &active, -1);
381         active ^= 1;
382
383         // Get the row number
384         indices = gtk_tree_path_get_indices (tp);
385         row = indices[0];
386         gtk_tree_path_free(tp);
387
388         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
389
390         if (row < 0 || row >= ghb_array_len(subtitle_list))
391                 return;
392
393         settings = ghb_array_get_nth(subtitle_list, row);
394         track = ghb_settings_combo_int(settings, "SubtitleTrack");
395
396         source = ghb_subtitle_track_source(ud, track);
397         if (source != VOBSUB)
398                 return;
399
400         ghb_settings_set_boolean(settings, "SubtitleForced", active);
401         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 1, active, -1);
402 }
403
404 G_MODULE_EXPORT void
405 subtitle_burned_toggled_cb(
406         GtkCellRendererToggle *cell, 
407         gchar                 *path,
408         signal_user_data_t    *ud)
409 {
410         GtkTreeView  *tv;
411         GtkTreeModel *tm;
412         GtkTreeIter   ti;
413         GtkTreePath  *tp;
414         gboolean      active;
415         gint          row;
416         gint *indices;
417         GValue *subtitle_list;
418         gint count, track, source;
419         GValue *settings;
420
421         g_debug("burned toggled");
422         tp = gtk_tree_path_new_from_string (path);
423         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
424         g_return_if_fail(tv != NULL);
425         tm = gtk_tree_view_get_model(tv);
426         g_return_if_fail(tm != NULL);
427         gtk_tree_model_get_iter(tm, &ti, tp);
428         gtk_tree_model_get(tm, &ti, 2, &active, -1);
429         active ^= 1;
430
431         // Get the row number
432         indices = gtk_tree_path_get_indices (tp);
433         row = indices[0];
434         gtk_tree_path_free(tp);
435
436         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
437         count = ghb_array_len(subtitle_list);
438         if (row < 0 || row >= count)
439                 return;
440
441         settings = ghb_array_get_nth(subtitle_list, row);
442         track = ghb_settings_combo_int(settings, "SubtitleTrack");
443
444         source = ghb_subtitle_track_source(ud, track);
445         if (source != VOBSUB)
446                 return;
447
448         if (!active && mustBurn(ud, track))
449                 return;
450
451         ghb_settings_set_boolean(settings, "SubtitleBurned", active);
452
453         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, active, -1);
454         // Unburn the rest
455         if (active)
456                 ghb_subtitle_exclusive_burn(ud, row);
457 }
458
459 G_MODULE_EXPORT void
460 subtitle_default_toggled_cb(
461         GtkCellRendererToggle *cell, 
462         gchar                 *path,
463         signal_user_data_t    *ud)
464 {
465         GtkTreeView  *tv;
466         GtkTreeModel *tm;
467         GtkTreeIter   ti;
468         GtkTreePath  *tp;
469         gboolean      active;
470         gint          row;
471         gint *indices;
472         GValue *subtitle_list;
473         gint count, track;
474         GValue *settings;
475
476         g_debug("default toggled");
477         tp = gtk_tree_path_new_from_string (path);
478         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
479         g_return_if_fail(tv != NULL);
480         tm = gtk_tree_view_get_model(tv);
481         g_return_if_fail(tm != NULL);
482         gtk_tree_model_get_iter(tm, &ti, tp);
483         gtk_tree_model_get(tm, &ti, 3, &active, -1);
484         active ^= 1;
485
486         // Get the row number
487         indices = gtk_tree_path_get_indices (tp);
488         row = indices[0];
489         gtk_tree_path_free(tp);
490
491         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
492         count = ghb_array_len(subtitle_list);
493         if (row < 0 || row >= count)
494                 return;
495
496         settings = ghb_array_get_nth(subtitle_list, row);
497         track = ghb_settings_combo_int(settings, "SubtitleTrack");
498
499         ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", active);
500
501         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, active, -1);
502         // allow only one default
503         ghb_subtitle_exclusive_default(ud, row);
504 }
505
506 static void
507 subtitle_list_refresh_selected(signal_user_data_t *ud)
508 {
509         GtkTreeView *treeview;
510         GtkTreePath *treepath;
511         GtkTreeSelection *selection;
512         GtkTreeModel *store;
513         GtkTreeIter iter;
514         gint *indices;
515         gint row;
516         GValue *settings = NULL;
517         const GValue *subtitle_list;
518         
519         g_debug("subtitle_list_refresh_selected ()");
520         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
521         selection = gtk_tree_view_get_selection (treeview);
522         if (gtk_tree_selection_get_selected(selection, &store, &iter))
523         {
524                 const gchar *track, *source;
525                 gboolean forced, burned, def;
526                 gchar *s_track;
527                 gint i_track;
528         
529                 // Get the row number
530                 treepath = gtk_tree_model_get_path (store, &iter);
531                 indices = gtk_tree_path_get_indices (treepath);
532                 row = indices[0];
533                 gtk_tree_path_free(treepath);
534                 // find audio settings
535                 if (row < 0) return;
536                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
537                 if (row >= ghb_array_len(subtitle_list))
538                         return;
539                 settings = ghb_array_get_nth(subtitle_list, row);
540
541                 track = ghb_settings_combo_option(settings, "SubtitleTrack");
542                 forced = ghb_settings_get_boolean(settings, "SubtitleForced");
543                 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
544                 def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
545
546                 s_track = ghb_settings_get_string(settings, "SubtitleTrack");
547                 i_track = ghb_settings_get_int(settings, "SubtitleTrack");
548                 source = ghb_subtitle_track_source_name(ud, i_track);
549
550                 gint i_source;
551                 i_source = ghb_subtitle_track_source(ud, i_track);
552                 if (i_source != VOBSUB)
553                 {
554                         // Force and burn only apply to VOBSUBS
555                         forced = FALSE;
556                         burned = FALSE;
557                         ghb_settings_set_boolean(settings, "SubtitleForced", forced);
558                         ghb_settings_set_boolean(settings, "SubtitleBurned", burned);
559                 }
560
561                 gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
562                         // These are displayed in list
563                         0, track,
564                         1, forced,
565                         2, burned,
566                         3, def,
567                         4, source,
568                         // These are used to set combo box values when a list item is selected
569                         5, s_track,
570                         -1);
571                 g_free(s_track);
572                 if (burned)
573                         ghb_subtitle_exclusive_burn(ud, row);
574         }
575 }
576
577 G_MODULE_EXPORT void
578 subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
579 {
580         GValue *settings;
581
582         g_debug("subtitle_track_changed_cb ()");
583         ghb_check_dependency(ud, widget);
584         settings = ghb_selected_subtitle_settings(ud);
585         if (settings != NULL)
586         {
587                 ghb_widget_to_setting(settings, widget);
588                 subtitle_list_refresh_selected(ud);
589         }
590         ghb_live_reset(ud);
591 }
592
593 void
594 ghb_clear_subtitle_list(signal_user_data_t *ud)
595 {
596         GtkTreeView *treeview;
597         GtkListStore *store;
598         GValue *subtitle_list;
599         
600         g_debug("clear_subtitle_list ()");
601         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
602         if (subtitle_list == NULL)
603         {
604                 subtitle_list = ghb_array_value_new(8);
605                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
606         }
607         else
608                 ghb_array_value_reset(subtitle_list, 8);
609         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
610         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
611         gtk_list_store_clear (store);
612 }
613
614 static void
615 add_to_subtitle_list(
616         signal_user_data_t *ud, 
617         GValue *settings)
618 {
619         GtkTreeView *treeview;
620         GtkTreeIter iter;
621         GtkListStore *store;
622         GtkTreeSelection *selection;
623         const gchar *track, *source;
624         gboolean forced, burned, def;
625         gchar *s_track;
626         gint i_track;
627         
628         g_debug("add_to_subtitle_list ()");
629         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
630         selection = gtk_tree_view_get_selection (treeview);
631         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
632
633         track = ghb_settings_combo_option(settings, "SubtitleTrack");
634         forced = ghb_settings_get_boolean(settings, "SubtitleForced");
635         burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
636         def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
637
638         s_track = ghb_settings_get_string(settings, "SubtitleTrack");
639         i_track = ghb_settings_get_int(settings, "SubtitleTrack");
640         source = ghb_subtitle_track_source_name(ud, i_track);
641
642         gtk_list_store_append(store, &iter);
643         gtk_list_store_set(store, &iter, 
644                 // These are displayed in list
645                 0, track,
646                 1, forced,
647                 2, burned,
648                 3, def,
649                 4, source,
650                 // These are used to set combo box values when a list item is selected
651                 5, s_track,
652                 -1);
653         gtk_tree_selection_select_iter(selection, &iter);
654         g_free(s_track);
655 }
656
657 G_MODULE_EXPORT void
658 subtitle_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
659 {
660         GtkTreeModel *store;
661         GtkTreeIter iter;
662         GtkWidget *widget;
663         
664         g_debug("subtitle_list_selection_changed_cb ()");
665         if (gtk_tree_selection_get_selected(selection, &store, &iter))
666         {
667                 const gchar *track;
668
669                 gtk_tree_model_get(store, &iter, 5, &track, -1);
670                 ghb_ui_update(ud, "SubtitleTrack", ghb_string_value(track));
671
672                 widget = GHB_WIDGET (ud->builder, "subtitle_remove");
673                 gtk_widget_set_sensitive(widget, TRUE);
674         }
675 }
676
677 G_MODULE_EXPORT void
678 subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
679 {
680         // Add the current subtitle settings to the list.
681         GValue *settings;
682         gint count;
683         GValue *subtitle_list;
684         gboolean burned = FALSE;
685         gint track;
686         
687         g_debug("subtitle_add_clicked_cb ()");
688         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
689         if (subtitle_list == NULL)
690         {
691                 subtitle_list = ghb_array_value_new(8);
692                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
693         }
694         count = ghb_array_len(subtitle_list);
695         // Don't allow more than 99
696         // This is a had limit imposed by libhb/sync.c:GetFifoForId()
697         if (count >= 99)
698                 return;
699
700         track = ghb_settings_get_int(ud->settings, "SubtitleTrack");
701
702         if (mustBurn(ud, track))
703         {
704                 burned = TRUE;
705         }
706         settings = ghb_dict_value_new();
707         ghb_settings_set_int(settings, "SubtitleTrack", track);
708         ghb_settings_take_value(settings, "SubtitleForced", 
709                                                         ghb_boolean_value_new(FALSE));
710         ghb_settings_take_value(settings, "SubtitleBurned", 
711                                                         ghb_boolean_value_new(burned));
712         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
713                                                         ghb_boolean_value_new(FALSE));
714
715         ghb_array_append(subtitle_list, settings);
716         add_to_subtitle_list(ud, settings);
717         if (burned)
718                 ghb_subtitle_exclusive_burn(ud, count);
719         if (count == 98)
720         {
721                 GtkWidget *widget;
722                 widget = GHB_WIDGET (ud->builder, "subtitle_add");
723                 gtk_widget_set_sensitive(widget, FALSE);
724         }
725 }
726
727 G_MODULE_EXPORT void
728 subtitle_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
729 {
730         GtkTreeView *treeview;
731         GtkTreePath *treepath;
732         GtkTreeSelection *selection;
733         GtkTreeModel *store;
734         GtkTreeIter iter, nextIter;
735         gint *indices;
736         gint row;
737         GValue *subtitle_list;
738
739         g_debug("subtitle_remove_clicked_cb ()");
740         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
741         selection = gtk_tree_view_get_selection (treeview);
742         if (gtk_tree_selection_get_selected(selection, &store, &iter))
743         {
744                 nextIter = iter;
745                 if (!gtk_tree_model_iter_next(store, &nextIter))
746                 {
747                         nextIter = iter;
748                         if (gtk_tree_model_get_iter_first(store, &nextIter))
749                         {
750                                 gtk_tree_selection_select_iter (selection, &nextIter);
751                         }
752                 }
753                 else
754                 {
755                         gtk_tree_selection_select_iter (selection, &nextIter);
756                 }
757                 // Get the row number
758                 treepath = gtk_tree_model_get_path (store, &iter);
759                 indices = gtk_tree_path_get_indices (treepath);
760                 row = indices[0];
761                 gtk_tree_path_free(treepath);
762                 // Remove the selected item
763                 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
764                 // remove from subtitle settings list
765                 if (row < 0) return;
766                 widget = GHB_WIDGET (ud->builder, "subtitle_add");
767                 gtk_widget_set_sensitive(widget, TRUE);
768                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
769                 if (row >= ghb_array_len(subtitle_list))
770                         return;
771                 GValue *old = ghb_array_get_nth(subtitle_list, row);
772                 ghb_value_free(old);
773                 ghb_array_remove(subtitle_list, row);
774         }
775 }
776
777 void
778 ghb_subtitle_prune(signal_user_data_t *ud)
779 {
780         GtkTreeView  *tv;
781         GtkTreeModel *tm;
782         GtkTreeIter   ti;
783         GValue *subtitle_list, *settings;
784         gint count, ii, track;
785         gboolean burned;
786         gint first_track = 0, one_burned = 0;
787
788         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
789         if (subtitle_list == NULL)
790                 return;
791         count = ghb_array_len(subtitle_list);
792
793         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
794         g_return_if_fail(tv != NULL);
795         tm = gtk_tree_view_get_model(tv);
796         for (ii = count-1; ii >= 0; ii--)
797         {
798                 settings = ghb_array_get_nth(subtitle_list, ii);
799                 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
800                 track = ghb_settings_combo_int(settings, "SubtitleTrack");
801                 if (!burned && mustBurn(ud, track))
802                 {
803                         gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
804                         gtk_list_store_remove (GTK_LIST_STORE(tm), &ti);
805                         ghb_array_remove(subtitle_list, ii);
806                 }
807                 if (burned)
808                 {
809                         first_track = ii;
810                         one_burned++;
811                 }
812         }
813         if (one_burned)
814         {
815                 ghb_subtitle_exclusive_burn(ud, first_track);
816         }
817 }
818
819 void
820 ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings)
821 {
822         GValue *slist;
823         GValue *subtitle;
824         gint count, ii;
825         gint titleindex;
826         
827         g_debug("ghb_reset_subtitles");
828         ghb_clear_subtitle_list(ud);
829         titleindex = ghb_settings_combo_int(ud->settings, "title");
830         if (titleindex < 0)
831                 return;
832
833         slist = ghb_settings_get_value(settings, "subtitle_list");
834         count = ghb_array_len(slist);
835         for (ii = 0; ii < count; ii++)
836         {
837                 subtitle = ghb_value_dup(ghb_array_get_nth(slist, ii));
838                 ghb_add_subtitle(ud, subtitle);
839         }
840 }
841