OSDN Git Service

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