OSDN Git Service

LinGui: don't disable subme 10 when psy-rd is 0
[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 static void add_to_srt_list(signal_user_data_t *ud, GValue *settings);
27
28 static void
29 free_subtitle_index_list(gpointer data)
30 {
31         g_free(data);
32 }
33
34 static void
35 free_subtitle_key(gpointer data)
36 {
37         if (data != NULL)
38                 g_free(data);
39 }
40
41 static gboolean
42 mustBurn(signal_user_data_t *ud, gint track)
43 {
44         gint mux;
45
46         mux = ghb_settings_combo_int(ud->settings, "FileFormat");
47         if (mux == HB_MUX_MP4)
48         {
49                 gint source;
50
51                 // MP4 can only handle burned vobsubs.  make sure there isn't
52                 // already something burned in the list
53                 source = ghb_subtitle_track_source(ud, track);
54                 if (source == VOBSUB)
55                 {
56                         return TRUE;
57                 }
58         }
59         return FALSE;
60 }
61
62 void
63 ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint index)
64 {
65         GValue *subtitle_list;
66         GValue *settings;
67         gint ii, count, tt;
68         GtkTreeView  *tv;
69         GtkTreeModel *tm;
70         GtkTreeIter   ti;
71         gboolean burned;
72
73         g_debug("ghb_subtitle_exclusive_burn");
74         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
75         count = ghb_array_len(subtitle_list);
76         for (ii = 0; ii < count; ii++)
77         {
78                 settings = ghb_array_get_nth(subtitle_list, ii);
79                 tt = ghb_settings_combo_int(settings, "SubtitleTrack");
80                 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
81
82                 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
83                 g_return_if_fail(tv != NULL);
84                 tm = gtk_tree_view_get_model(tv);
85                 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
86                 if (burned && ii != index && !mustBurn(ud, tt))
87                 {
88                         ghb_settings_set_boolean(settings, "SubtitleBurned", FALSE);
89                         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, FALSE, -1);
90                 }
91         }
92 }
93
94 void
95 ghb_subtitle_exclusive_default(signal_user_data_t *ud, gint index)
96 {
97         GValue *subtitle_list;
98         GValue *settings;
99         gint ii, count;
100         GtkTreeView  *tv;
101         GtkTreeModel *tm;
102         GtkTreeIter   ti;
103         gboolean def;
104
105         g_debug("ghb_subtitle_exclusive_default");
106         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
107         count = ghb_array_len(subtitle_list);
108         for (ii = 0; ii < count; ii++)
109         {
110                 settings = ghb_array_get_nth(subtitle_list, ii);
111                 def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
112
113                 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
114                 g_return_if_fail(tv != NULL);
115                 tm = gtk_tree_view_get_model(tv);
116                 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
117                 if (def && ii != index)
118                 {
119
120                         ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", FALSE);
121                         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, FALSE, -1);
122                 }
123         }
124 }
125
126 void
127 ghb_add_srt(signal_user_data_t *ud, GValue *settings)
128 {
129         // Add the current subtitle settings to the list.
130         GValue *subtitle_list;
131         gint count;
132         const gchar *lang;
133         
134         g_debug("ghb_add_srt ()");
135
136         // Add the long track description so the queue can access it
137         // when a different title is selected.
138         lang = ghb_settings_combo_option(settings, "SrtLanguage");
139         ghb_settings_set_string(settings, "SubtitleTrackDescription", lang);
140
141         ghb_settings_set_int(settings, "SubtitleSource", SRTSUB);
142
143         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
144         if (subtitle_list == NULL)
145         {
146                 subtitle_list = ghb_array_value_new(8);
147                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
148         }
149         count = ghb_array_len(subtitle_list);
150
151         // Don't allow more than 99
152         // This is a had limit imposed by libhb/sync.c:GetFifoForId()
153         if (count >= 99)
154         {
155                 ghb_value_free(settings);
156                 return;
157         }
158
159         ghb_array_append(subtitle_list, settings);
160         add_to_srt_list(ud, settings);
161
162         if (count == 98)
163         {
164                 GtkWidget *widget;
165                 widget = GHB_WIDGET (ud->builder, "subtitle_add");
166                 gtk_widget_set_sensitive(widget, FALSE);
167                 widget = GHB_WIDGET (ud->builder, "srt_add");
168                 gtk_widget_set_sensitive(widget, FALSE);
169         }
170         ghb_live_reset(ud);
171 }
172
173 void
174 ghb_add_subtitle(signal_user_data_t *ud, GValue *settings)
175 {
176         // Add the current subtitle settings to the list.
177         GValue *subtitle_list;
178         gint count;
179         gboolean burned;
180         const gchar *track;
181         const gchar *lang;
182         gint tt, source;
183         
184         g_debug("ghb_add_subtitle ()");
185
186         // Add the long track description so the queue can access it
187         // when a different title is selected.
188         track = ghb_settings_combo_option(settings, "SubtitleTrack");
189         ghb_settings_set_string(settings, "SubtitleTrackDescription", track);
190
191         lang = ghb_settings_combo_string(settings, "SubtitleTrack");
192         ghb_settings_set_string(settings, "SubtitleLanguage", lang);
193
194         tt = ghb_settings_get_int(settings, "SubtitleTrack");
195         source = ghb_subtitle_track_source(ud, tt);
196         ghb_settings_set_int(settings, "SubtitleSource", source);
197
198         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
199         if (subtitle_list == NULL)
200         {
201                 subtitle_list = ghb_array_value_new(8);
202                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
203         }
204         count = ghb_array_len(subtitle_list);
205
206         // Don't allow more than 99
207         // This is a had limit imposed by libhb/sync.c:GetFifoForId()
208         if (count >= 99)
209         {
210                 ghb_value_free(settings);
211                 return;
212         }
213
214         ghb_array_append(subtitle_list, settings);
215         add_to_subtitle_list(ud, settings);
216
217         burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
218         if (burned)
219                 ghb_subtitle_exclusive_burn(ud, count);
220         if (count == 98)
221         {
222                 GtkWidget *widget;
223                 widget = GHB_WIDGET (ud->builder, "subtitle_add");
224                 gtk_widget_set_sensitive(widget, FALSE);
225                 widget = GHB_WIDGET (ud->builder, "srt_add");
226                 gtk_widget_set_sensitive(widget, FALSE);
227         }
228         ghb_live_reset(ud);
229 }
230
231 static void
232 add_all_pref_subtitles(signal_user_data_t *ud)
233 {
234         const GValue *pref_subtitle;
235         GValue *subtitle;
236         gint count, ii, track;
237         char *lang;
238
239         pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
240         count = ghb_array_len(pref_subtitle);
241         for (ii = 0; ii < count; ii++)
242         {
243                 subtitle = ghb_value_dup(ghb_array_get_nth(pref_subtitle, ii));
244                 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
245                 // If there are multiple subtitles using the same language, then
246                 // select sequential tracks for each.  The hash keeps track 
247                 // of the tracks used for each language.
248                 track = ghb_find_pref_subtitle_track(lang);
249                 g_free(lang);
250                 if (track >= -1)
251                 {
252                         // Add to subtitle list
253                         ghb_settings_set_int(subtitle, "SubtitleTrack", track);
254                         ghb_add_subtitle(ud, subtitle);
255                 }
256         }
257 }
258
259 void
260 ghb_set_pref_subtitle(gint titleindex, signal_user_data_t *ud)
261 {
262         gint track;
263         GHashTable *track_indices;
264         gchar *lang, *pref_lang = NULL;
265         gchar *audio_lang;
266         gint foreign_lang_index = -1;
267         gboolean found_cc = FALSE;
268
269         const GValue *pref_subtitle;
270         GValue *subtitle;
271         gint count, ii, jj;
272         
273         g_debug("ghb_set_pref_subtitle %d", titleindex);
274
275         // Check to see if we need to add a subtitle track for foreign audio
276         // language films. A subtitle track will be added if:
277         //
278         // The first (default) audio track language does NOT match the users
279         // chosen Preferred Language AND the Preferred Language is NOT Any (und).
280         //
281         audio_lang = ghb_get_user_audio_lang(ud, titleindex, 0);
282         pref_lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
283
284         if (audio_lang != NULL && pref_lang != NULL &&
285                 (strcmp(audio_lang, pref_lang) == 0 || strcmp("und", pref_lang) == 0))
286         {
287                 g_free(pref_lang);
288                 pref_lang = NULL;
289         }
290
291         track_indices = g_hash_table_new_full(g_str_hash, g_str_equal, 
292                                                                                         free_subtitle_key, free_subtitle_index_list);
293
294         ghb_ui_update(ud, "SubtitleTrack", ghb_int_value(0));
295
296         // Clear the subtitle list
297         ghb_clear_subtitle_list(ud);
298         if (titleindex < 0)
299         {
300                 add_all_pref_subtitles(ud);
301                 return;
302         }
303
304         // Find "best" subtitle based on subtitle preferences
305         pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
306
307         count = ghb_array_len(pref_subtitle);
308         jj = 0;
309         for (ii = 0; ii < count; ii++)
310         {
311                 subtitle = ghb_array_get_nth(pref_subtitle, ii);
312                 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
313                 // If there are multiple subtitles using the same language, then
314                 // select sequential tracks for each.  The hash keeps track 
315                 // of the tracks used for each language.
316                 track = ghb_find_subtitle_track(titleindex, lang, track_indices);
317                 g_free(lang);
318                 if (track >= -1)
319                 {
320                         gint source;
321                         GValue *dup = ghb_value_dup(subtitle);
322                         lang = ghb_subtitle_track_lang(ud, track);
323                         ghb_settings_set_int(dup, "SubtitleTrack", track);
324                         if (foreign_lang_index < 0 && pref_lang != NULL &&
325                                 strcmp(lang, pref_lang) == 0)
326                         {
327                                 foreign_lang_index = jj;
328                                 ghb_settings_take_value(dup, "SubtitleForced", 
329                                                                 ghb_boolean_value_new(FALSE));
330                                 ghb_settings_take_value(dup, "SubtitleDefaultTrack", 
331                                                                 ghb_boolean_value_new(TRUE));
332                         }
333                         source = ghb_subtitle_track_source(ud, track);
334                         if (source == CC608SUB || source == CC708SUB)
335                                 found_cc = TRUE;
336                         ghb_add_subtitle(ud, dup);
337                         jj++;
338                         g_free(lang);
339                 }
340         }
341         if (foreign_lang_index < 0 && pref_lang != NULL)
342         {
343                 // Subtitle for foreign language audio not added yet
344                 GValue *settings;
345                 gboolean burn;
346
347                 track = ghb_find_subtitle_track(titleindex, pref_lang, track_indices);
348                 if (track >= -1)
349                 {
350                         burn = mustBurn(ud, track);
351                         settings = ghb_dict_value_new();
352                         ghb_settings_set_int(settings, "SubtitleTrack", track);
353                         ghb_settings_take_value(settings, "SubtitleForced", 
354                                                         ghb_boolean_value_new(FALSE));
355                         ghb_settings_take_value(settings, "SubtitleBurned", 
356                                                         ghb_boolean_value_new(burn));
357                         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
358                                                         ghb_boolean_value_new(TRUE));
359
360                         ghb_add_subtitle(ud, settings);
361                         foreign_lang_index = jj;
362                 }
363         }
364         if (foreign_lang_index >= 0)
365         {
366                 GValue *subtitle_list;
367                 gboolean burn, def;
368
369                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
370                 subtitle = ghb_array_get_nth(subtitle_list, foreign_lang_index);
371
372                 burn = ghb_settings_get_boolean(subtitle, "SubtitleBurned");
373                 def = ghb_settings_get_boolean(subtitle, "SubtitleDefaultTrack");
374                 if (burn)
375                         ghb_subtitle_exclusive_burn(ud, foreign_lang_index);
376                 if (def)
377                         ghb_subtitle_exclusive_default(ud, foreign_lang_index);
378                 ghb_log("adding subtitle for foreign language audio: %s", audio_lang);
379         }
380         if (ghb_settings_get_boolean(ud->settings, "AddCC") && !found_cc)
381         {
382                 // Subtitle for foreign language audio not added yet
383                 GValue *settings;
384
385                 track = ghb_find_cc_track(titleindex);
386                 if (track >= 0)
387                 {
388                         settings = ghb_dict_value_new();
389                         ghb_settings_set_int(settings, "SubtitleTrack", track);
390                         ghb_settings_take_value(settings, "SubtitleForced", 
391                                                         ghb_boolean_value_new(FALSE));
392                         ghb_settings_take_value(settings, "SubtitleBurned", 
393                                                         ghb_boolean_value_new(FALSE));
394                         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
395                                                         ghb_boolean_value_new(FALSE));
396
397                         ghb_add_subtitle(ud, settings);
398                         ghb_log("adding Closed Captions: %s", audio_lang);
399                 }
400         }
401         if (pref_lang != NULL)
402                 g_free(pref_lang);
403         if (audio_lang != NULL)
404                 g_free(audio_lang);
405         g_hash_table_destroy(track_indices);
406 }
407
408 gint
409 ghb_selected_subtitle_row(signal_user_data_t *ud)
410 {
411         GtkTreeView *treeview;
412         GtkTreePath *treepath;
413         GtkTreeSelection *selection;
414         GtkTreeModel *store;
415         GtkTreeIter iter;
416         gint *indices;
417         gint row = -1;
418         
419         g_debug("ghb_selected_subtitle_row ()");
420         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
421         selection = gtk_tree_view_get_selection (treeview);
422         if (gtk_tree_selection_get_selected(selection, &store, &iter))
423         {
424                 // Get the row number
425                 treepath = gtk_tree_model_get_path (store, &iter);
426                 indices = gtk_tree_path_get_indices (treepath);
427                 row = indices[0];
428                 gtk_tree_path_free(treepath);
429         }
430         return row;
431 }
432
433 GValue*
434 ghb_selected_subtitle_settings(signal_user_data_t *ud)
435 {
436         GtkTreeView *treeview;
437         GtkTreePath *treepath;
438         GtkTreeSelection *selection;
439         GtkTreeModel *store;
440         GtkTreeIter iter;
441         gint *indices;
442         gint row;
443         GValue *settings = NULL;
444         const GValue *subtitle_list;
445         
446         g_debug("get_selected_settings ()");
447         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
448         selection = gtk_tree_view_get_selection (treeview);
449         if (gtk_tree_selection_get_selected(selection, &store, &iter))
450         {
451                 // Get the row number
452                 treepath = gtk_tree_model_get_path (store, &iter);
453                 indices = gtk_tree_path_get_indices (treepath);
454                 row = indices[0];
455                 gtk_tree_path_free(treepath);
456                 // find subtitle settings
457                 if (row < 0) return NULL;
458                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
459                 if (row >= ghb_array_len(subtitle_list))
460                         return NULL;
461                 settings = ghb_array_get_nth(subtitle_list, row);
462         }
463         return settings;
464 }
465
466 G_MODULE_EXPORT void
467 subtitle_forced_toggled_cb(
468         GtkCellRendererToggle *cell, 
469         gchar                 *path,
470         signal_user_data_t    *ud)
471 {
472         GtkTreeView  *tv;
473         GtkTreeModel *tm;
474         GtkTreeIter   ti;
475         gboolean      active;
476         gint          row;
477         GtkTreePath  *tp;
478         gint *indices;
479         GValue *subtitle_list, *settings;
480         gint source;
481
482         g_debug("forced toggled");
483         tp = gtk_tree_path_new_from_string (path);
484         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
485         g_return_if_fail(tv != NULL);
486         tm = gtk_tree_view_get_model(tv);
487         g_return_if_fail(tm != NULL);
488         gtk_tree_model_get_iter(tm, &ti, tp);
489         gtk_tree_model_get(tm, &ti, 1, &active, -1);
490         active ^= 1;
491
492         // Get the row number
493         indices = gtk_tree_path_get_indices (tp);
494         row = indices[0];
495         gtk_tree_path_free(tp);
496
497         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
498
499         if (row < 0 || row >= ghb_array_len(subtitle_list))
500                 return;
501
502         settings = ghb_array_get_nth(subtitle_list, row);
503
504         source = ghb_settings_get_int(settings, "SubtitleSource");
505         if (source != VOBSUB)
506                 return;
507
508         ghb_settings_set_boolean(settings, "SubtitleForced", active);
509         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 1, active, -1);
510         ghb_live_reset(ud);
511 }
512
513 G_MODULE_EXPORT void
514 subtitle_burned_toggled_cb(
515         GtkCellRendererToggle *cell, 
516         gchar                 *path,
517         signal_user_data_t    *ud)
518 {
519         GtkTreeView  *tv;
520         GtkTreeModel *tm;
521         GtkTreeIter   ti;
522         GtkTreePath  *tp;
523         gboolean      active;
524         gint          row;
525         gint *indices;
526         GValue *subtitle_list;
527         gint count, track, source;
528         GValue *settings;
529
530         g_debug("burned toggled");
531         tp = gtk_tree_path_new_from_string (path);
532         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
533         g_return_if_fail(tv != NULL);
534         tm = gtk_tree_view_get_model(tv);
535         g_return_if_fail(tm != NULL);
536         gtk_tree_model_get_iter(tm, &ti, tp);
537         gtk_tree_model_get(tm, &ti, 2, &active, -1);
538         active ^= 1;
539
540         // Get the row number
541         indices = gtk_tree_path_get_indices (tp);
542         row = indices[0];
543         gtk_tree_path_free(tp);
544
545         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
546         count = ghb_array_len(subtitle_list);
547         if (row < 0 || row >= count)
548                 return;
549
550         settings = ghb_array_get_nth(subtitle_list, row);
551
552         source = ghb_settings_get_int(settings, "SubtitleSource");
553         if (source != VOBSUB)
554                 return;
555
556         track = ghb_settings_combo_int(settings, "SubtitleTrack");
557         if (!active && mustBurn(ud, track))
558                 return;
559
560         ghb_settings_set_boolean(settings, "SubtitleBurned", active);
561
562         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, active, -1);
563         // Unburn the rest
564         if (active)
565                 ghb_subtitle_exclusive_burn(ud, row);
566         ghb_live_reset(ud);
567 }
568
569 G_MODULE_EXPORT void
570 subtitle_default_toggled_cb(
571         GtkCellRendererToggle *cell, 
572         gchar                 *path,
573         signal_user_data_t    *ud)
574 {
575         GtkTreeView  *tv;
576         GtkTreeModel *tm;
577         GtkTreeIter   ti;
578         GtkTreePath  *tp;
579         gboolean      active;
580         gint          row;
581         gint *indices;
582         GValue *subtitle_list;
583         gint count;
584         GValue *settings;
585
586         g_debug("default toggled");
587         tp = gtk_tree_path_new_from_string (path);
588         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
589         g_return_if_fail(tv != NULL);
590         tm = gtk_tree_view_get_model(tv);
591         g_return_if_fail(tm != NULL);
592         gtk_tree_model_get_iter(tm, &ti, tp);
593         gtk_tree_model_get(tm, &ti, 3, &active, -1);
594         active ^= 1;
595
596         // Get the row number
597         indices = gtk_tree_path_get_indices (tp);
598         row = indices[0];
599         gtk_tree_path_free(tp);
600
601         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
602         count = ghb_array_len(subtitle_list);
603         if (row < 0 || row >= count)
604                 return;
605
606         settings = ghb_array_get_nth(subtitle_list, row);
607
608         ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", active);
609
610         gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, active, -1);
611         // allow only one default
612         ghb_subtitle_exclusive_default(ud, row);
613         ghb_live_reset(ud);
614 }
615
616 static const char*
617 subtitle_source_name(gint source)
618 {
619         const gchar * name;
620
621         switch (source)
622         {
623                 case VOBSUB:
624                         name = "Bitmap";
625                         break;
626                 case CC708SUB:
627                 case CC608SUB:
628                         name = "Text";
629                         break;
630                 case SRTSUB:
631                         name = "SRT";
632                         break;
633                 default:
634                         name = "Unknown";
635                         break;
636         }
637         return name;
638 }
639
640 static void
641 subtitle_list_refresh_selected(signal_user_data_t *ud)
642 {
643         GtkTreeView *treeview;
644         GtkTreePath *treepath;
645         GtkTreeSelection *selection;
646         GtkTreeModel *store;
647         GtkTreeIter iter;
648         gint *indices;
649         gint row;
650         GValue *settings = NULL;
651         const GValue *subtitle_list;
652         
653         g_debug("subtitle_list_refresh_selected ()");
654         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
655         selection = gtk_tree_view_get_selection (treeview);
656         if (gtk_tree_selection_get_selected(selection, &store, &iter))
657         {
658                 gchar *track, *source;
659                 gboolean forced, burned, def;
660                 gchar *s_track;
661                 gint offset = 0;
662         
663                 // Get the row number
664                 treepath = gtk_tree_model_get_path (store, &iter);
665                 indices = gtk_tree_path_get_indices (treepath);
666                 row = indices[0];
667                 gtk_tree_path_free(treepath);
668                 // find audio settings
669                 if (row < 0) return;
670                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
671                 if (row >= ghb_array_len(subtitle_list))
672                         return;
673                 settings = ghb_array_get_nth(subtitle_list, row);
674
675                 def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
676
677                 gint i_source;
678                 i_source = ghb_settings_get_int(settings, "SubtitleSource");
679                 if (i_source != VOBSUB)
680                 {
681                         // Force and burn only apply to VOBSUBS
682                         forced = FALSE;
683                         burned = FALSE;
684                         ghb_settings_set_boolean(settings, "SubtitleForced", forced);
685                         ghb_settings_set_boolean(settings, "SubtitleBurned", burned);
686                 }
687
688                 if (i_source == SRTSUB)
689                 {
690                         const gchar *lang;
691                         gchar *code;
692
693                         lang = ghb_settings_combo_option(settings, "SrtLanguage");
694                         code = ghb_settings_get_string(settings, "SrtCodeset");
695                         track = g_strdup_printf("%s (%s)", lang, code);
696                         g_free(code);
697
698                         s_track = ghb_settings_get_string(settings, "SrtFile");
699                         if (g_file_test(s_track, G_FILE_TEST_IS_REGULAR))
700                         {
701                                 gchar *basename;
702
703                                 basename = g_path_get_basename(s_track);
704                                 source = g_strdup_printf("SRT (%s)", basename);
705                                 g_free(basename);
706                         }
707                         else
708                         {
709                                 source = g_strdup_printf("SRT (none)");
710                         }
711                         offset = ghb_settings_get_int(settings, "SrtOffset");
712
713                         forced = FALSE;
714                         burned = FALSE;
715                 }
716                 else
717                 {
718                         track = g_strdup(
719                                 ghb_settings_combo_option(settings, "SubtitleTrack"));
720                         source = g_strdup(subtitle_source_name(i_source));
721                         s_track = ghb_settings_get_string(settings, "SubtitleTrack");
722
723                         forced = ghb_settings_get_boolean(settings, "SubtitleForced");
724                         burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
725                 }
726
727                 gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
728                         // These are displayed in list
729                         0, track,
730                         1, forced,
731                         2, burned,
732                         3, def,
733                         4, source,
734                         5, offset,
735                         // These are used to set combo box values when a list item is selected
736                         6, s_track,
737                         7, i_source,
738                         -1);
739                 g_free(track);
740                 g_free(source);
741                 g_free(s_track);
742                 if (burned)
743                         ghb_subtitle_exclusive_burn(ud, row);
744         }
745 }
746
747 G_MODULE_EXPORT void
748 subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
749 {
750         GValue *settings;
751
752         g_debug("subtitle_track_changed_cb ()");
753         ghb_check_dependency(ud, widget);
754         ghb_widget_to_setting(ud->settings, widget);
755         settings = ghb_selected_subtitle_settings(ud);
756         if (settings != NULL)
757         {
758                 const gchar *track, *lang;
759                 gint tt, source;
760
761                 ghb_widget_to_setting(settings, widget);
762                 subtitle_list_refresh_selected(ud);
763                 track = ghb_settings_combo_option(settings, "SubtitleTrack");
764                 ghb_settings_set_string(settings, "SubtitleTrackDescription", track);
765                 tt = ghb_settings_get_int(settings, "SubtitleTrack");
766                 source = ghb_subtitle_track_source(ud, tt);
767                 ghb_settings_set_int(settings, "SubtitleSource", source);
768                 lang = ghb_settings_combo_string(settings, "SubtitleTrack");
769                 ghb_settings_set_string(settings, "SubtitleLanguage", lang);
770                 ghb_live_reset(ud);
771         }
772         ghb_live_reset(ud);
773 }
774
775 G_MODULE_EXPORT void
776 srt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
777 {
778         GValue *settings;
779
780         g_debug("srt_changed_cb ()");
781         ghb_check_dependency(ud, widget);
782         ghb_widget_to_setting(ud->settings, widget);
783         settings = ghb_selected_subtitle_settings(ud);
784         if (settings != NULL)
785         {
786                 ghb_widget_to_setting(settings, widget);
787                 subtitle_list_refresh_selected(ud);
788
789                 ghb_live_reset(ud);
790         }
791 }
792
793 G_MODULE_EXPORT void
794 srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
795 {
796         GValue *settings;
797
798         g_debug("srt_changed_cb ()");
799         ghb_check_dependency(ud, widget);
800         ghb_widget_to_setting(ud->settings, widget);
801         settings = ghb_selected_subtitle_settings(ud);
802         if (settings != NULL)
803         {
804                 gchar *filename, *dirname;
805
806                 ghb_widget_to_setting(settings, widget);
807                 subtitle_list_refresh_selected(ud);
808
809                 ghb_live_reset(ud);
810
811                 filename = ghb_settings_get_string(settings, "SrtFile");
812                 if (g_file_test(filename, G_FILE_TEST_IS_DIR))
813                 {
814                         ghb_settings_set_string(ud->settings, "SrtDir", filename);
815                 }
816                 else
817                 {
818                         dirname = g_path_get_dirname(filename);
819                         ghb_settings_set_string(ud->settings, "SrtDir", dirname);
820                         g_free(dirname);
821                 }
822                 ghb_pref_save(ud->settings, "SrtDir");
823                 g_free(filename);
824         }
825 }
826
827 G_MODULE_EXPORT void
828 srt_lang_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
829 {
830         GValue *settings;
831
832         g_debug("srt_lang_changed_cb ()");
833         ghb_check_dependency(ud, widget);
834         ghb_widget_to_setting(ud->settings, widget);
835         settings = ghb_selected_subtitle_settings(ud);
836         if (settings != NULL)
837         {
838                 const gchar *lang;
839
840                 ghb_widget_to_setting(settings, widget);
841                 subtitle_list_refresh_selected(ud);
842
843                 ghb_live_reset(ud);
844
845                 lang = ghb_settings_combo_option(settings, "SrtLanguage");
846                 ghb_settings_set_string(settings, "SubtitleTrackDescription", lang);
847         }
848 }
849
850 void
851 ghb_clear_subtitle_list(signal_user_data_t *ud)
852 {
853         GtkTreeView *treeview;
854         GtkListStore *store;
855         GValue *subtitle_list;
856         
857         g_debug("clear_subtitle_list ()");
858         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
859         if (subtitle_list == NULL)
860         {
861                 subtitle_list = ghb_array_value_new(8);
862                 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
863         }
864         else
865                 ghb_array_value_reset(subtitle_list, 8);
866         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
867         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
868         gtk_list_store_clear (store);
869 }
870
871 static void
872 add_to_subtitle_list(
873         signal_user_data_t *ud, 
874         GValue *settings)
875 {
876         GtkTreeView *treeview;
877         GtkTreeIter iter;
878         GtkListStore *store;
879         GtkTreeSelection *selection;
880         const gchar *track, *source;
881         gboolean forced, burned, def;
882         gchar *s_track;
883         gint i_source;
884         
885         g_debug("add_to_subtitle_list ()");
886         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
887         selection = gtk_tree_view_get_selection (treeview);
888         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
889
890         track = ghb_settings_combo_option(settings, "SubtitleTrack");
891         forced = ghb_settings_get_boolean(settings, "SubtitleForced");
892         burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
893         def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
894
895         s_track = ghb_settings_get_string(settings, "SubtitleTrack");
896         i_source = ghb_settings_get_int(settings, "SubtitleSource");
897         source = subtitle_source_name(i_source);
898
899         gtk_list_store_append(store, &iter);
900         gtk_list_store_set(store, &iter, 
901                 // These are displayed in list
902                 0, track,
903                 1, forced,
904                 2, burned,
905                 3, def,
906                 4, source,
907                 // These are used to set combo box values when a list item is selected
908                 6, s_track,
909                 7, i_source,
910                 8, TRUE,
911                 9, TRUE,
912                 10, FALSE,
913                 -1);
914         gtk_tree_selection_select_iter(selection, &iter);
915         g_free(s_track);
916 }
917
918 static void
919 add_to_srt_list(
920         signal_user_data_t *ud, 
921         GValue *settings)
922 {
923         GtkTreeView *treeview;
924         GtkTreeIter iter;
925         GtkListStore *store;
926         GtkTreeSelection *selection;
927         const gchar *lang;
928         gboolean forced, burned, def;
929         gchar *filename, *code, *track, *source;
930         gint i_source, offset;
931         
932         g_debug("add_to_srt_list ()");
933         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
934         selection = gtk_tree_view_get_selection (treeview);
935         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
936
937         lang = ghb_settings_combo_option(settings, "SrtLanguage");
938         code = ghb_settings_get_string(settings, "SrtCodeset");
939         track = g_strdup_printf("%s (%s)", lang, code);
940         forced = FALSE;
941         burned = FALSE;
942         def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
943
944         filename = ghb_settings_get_string(settings, "SrtFile");
945         if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
946         {
947                 gchar *basename;
948
949                 basename = g_path_get_basename(filename);
950                 source = g_strdup_printf("SRT (%s)", basename);
951                 g_free(basename);
952         }
953         else
954         {
955                 source = g_strdup_printf("SRT (none)");
956         }
957         i_source = SRTSUB;
958         offset = ghb_settings_get_int(settings, "SrtOffset");
959
960         gtk_list_store_append(store, &iter);
961         gtk_list_store_set(store, &iter, 
962                 // These are displayed in list
963                 0, track,
964                 1, forced,
965                 2, burned,
966                 3, def,
967                 4, source,
968                 5, offset,
969                 // These are used to set combo box values when a list item is selected
970                 6, filename,
971                 7, i_source,
972                 8, FALSE,
973                 9, FALSE,
974                 10, TRUE,
975                 -1);
976         gtk_tree_selection_select_iter(selection, &iter);
977         g_free(code);
978         g_free(track);
979         g_free(filename);
980         g_free(source);
981 }
982
983 G_MODULE_EXPORT void
984 subtitle_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
985 {
986         GtkTreeModel *store;
987         GtkTreeIter iter;
988         GtkWidget *widget;
989         
990         g_debug("subtitle_list_selection_changed_cb ()");
991         if (gtk_tree_selection_get_selected(selection, &store, &iter))
992         {
993                 gint source;
994                 GtkTreePath *treepath;
995                 gint *indices, row;
996                 GValue *subtitle_list, *settings;
997
998                 treepath = gtk_tree_model_get_path (store, &iter);
999                 indices = gtk_tree_path_get_indices (treepath);
1000                 row = indices[0];
1001                 gtk_tree_path_free(treepath);
1002
1003                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
1004                 if (row >= ghb_array_len(subtitle_list))
1005                         return;
1006
1007                 settings = ghb_array_get_nth(subtitle_list, row);
1008
1009                 source = ghb_settings_get_int(settings, "SubtitleSource");
1010                 if (source == SRTSUB)
1011                 {
1012                         gchar *str;
1013                         gint offset;
1014
1015                         str = ghb_settings_get_string(settings, "SrtLanguage");
1016                         ghb_ui_update(ud, "SrtLanguage", ghb_string_value(str));
1017                         g_free(str);
1018
1019                         str = ghb_settings_get_string(settings, "SrtCodeset");
1020                         ghb_ui_update(ud, "SrtCodeset", ghb_string_value(str));
1021                         g_free(str);
1022
1023                         str = ghb_settings_get_string(settings, "SrtFile");
1024                         ghb_ui_update(ud, "SrtFile", ghb_string_value(str));
1025                         g_free(str);
1026
1027                         offset = ghb_settings_get_int(settings, "SrtOffset");
1028                         ghb_ui_update(ud, "SrtOffset", ghb_int_value(offset));
1029
1030                         widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
1031                         gtk_widget_hide(widget);
1032                         widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
1033                         gtk_widget_hide(widget);
1034                         widget = GHB_WIDGET(ud->builder, "srt_lang_label");
1035                         gtk_widget_show(widget);
1036                         widget = GHB_WIDGET(ud->builder, "srt_code_label");
1037                         gtk_widget_show(widget);
1038                         widget = GHB_WIDGET(ud->builder, "srt_file_label");
1039                         gtk_widget_show(widget);
1040                         widget = GHB_WIDGET(ud->builder, "srt_offset_label");
1041                         gtk_widget_show(widget);
1042                         widget = GHB_WIDGET(ud->builder, "SrtLanguage");
1043                         gtk_widget_show(widget);
1044                         widget = GHB_WIDGET(ud->builder, "SrtCodeset");
1045                         gtk_widget_show(widget);
1046                         widget = GHB_WIDGET(ud->builder, "SrtFile");
1047                         gtk_widget_show(widget);
1048                         widget = GHB_WIDGET(ud->builder, "SrtOffset");
1049                         gtk_widget_show(widget);
1050                 }
1051                 else
1052                 {
1053                         gchar *track;
1054
1055                         track = ghb_settings_get_string(settings, "SubtitleTrack");
1056                         ghb_ui_update(ud, "SubtitleTrack", ghb_string_value(track));
1057                         g_free(track);
1058
1059                         widget = GHB_WIDGET(ud->builder, "srt_lang_label");
1060                         gtk_widget_hide(widget);
1061                         widget = GHB_WIDGET(ud->builder, "srt_code_label");
1062                         gtk_widget_hide(widget);
1063                         widget = GHB_WIDGET(ud->builder, "srt_file_label");
1064                         gtk_widget_hide(widget);
1065                         widget = GHB_WIDGET(ud->builder, "srt_offset_label");
1066                         gtk_widget_hide(widget);
1067                         widget = GHB_WIDGET(ud->builder, "SrtLanguage");
1068                         gtk_widget_hide(widget);
1069                         widget = GHB_WIDGET(ud->builder, "SrtCodeset");
1070                         gtk_widget_hide(widget);
1071                         widget = GHB_WIDGET(ud->builder, "SrtFile");
1072                         gtk_widget_hide(widget);
1073                         widget = GHB_WIDGET(ud->builder, "SrtOffset");
1074                         gtk_widget_hide(widget);
1075                         widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
1076                         gtk_widget_show(widget);
1077                         widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
1078                         gtk_widget_show(widget);
1079                 }
1080                 widget = GHB_WIDGET (ud->builder, "subtitle_remove");
1081                 gtk_widget_set_sensitive(widget, TRUE);
1082         }
1083         else
1084         {
1085                 widget = GHB_WIDGET(ud->builder, "srt_lang_label");
1086                 gtk_widget_hide(widget);
1087                 widget = GHB_WIDGET(ud->builder, "srt_code_label");
1088                 gtk_widget_hide(widget);
1089                 widget = GHB_WIDGET(ud->builder, "srt_file_label");
1090                 gtk_widget_hide(widget);
1091                 widget = GHB_WIDGET(ud->builder, "srt_offset_label");
1092                 gtk_widget_hide(widget);
1093                 widget = GHB_WIDGET(ud->builder, "SrtLanguage");
1094                 gtk_widget_hide(widget);
1095                 widget = GHB_WIDGET(ud->builder, "SrtCodeset");
1096                 gtk_widget_hide(widget);
1097                 widget = GHB_WIDGET(ud->builder, "SrtFile");
1098                 gtk_widget_hide(widget);
1099                 widget = GHB_WIDGET(ud->builder, "SrtOffset");
1100                 gtk_widget_hide(widget);
1101                 widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
1102                 gtk_widget_show(widget);
1103                 widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
1104                 gtk_widget_show(widget);
1105         }
1106 }
1107
1108 G_MODULE_EXPORT void
1109 srt_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1110 {
1111         // Add the current subtitle settings to the list.
1112         GValue *settings;
1113         gboolean burned = FALSE;
1114         gint track;
1115         gchar *dir, *filename;
1116         
1117         g_debug("subtitle_add_clicked_cb ()");
1118
1119         track = ghb_settings_get_int(ud->settings, "SubtitleTrack");
1120         if (mustBurn(ud, track))
1121         {
1122                 burned = TRUE;
1123         }
1124         settings = ghb_dict_value_new();
1125         ghb_settings_set_string(settings, "SrtLanguage", "und");
1126         ghb_settings_set_string(settings, "SrtCodeset", "UTF-8");
1127
1128         dir = ghb_settings_get_string(ud->settings, "SrtDir");
1129         filename = g_strdup_printf("%s/none", dir);
1130         ghb_settings_set_string(settings, "SrtFile", filename);
1131         g_free(dir);
1132         g_free(filename);
1133
1134         ghb_settings_set_int(settings, "SrtOffset", 0);
1135         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
1136                                                         ghb_boolean_value_new(FALSE));
1137
1138         ghb_add_srt(ud, settings);
1139 }
1140
1141 G_MODULE_EXPORT void
1142 subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1143 {
1144         // Add the current subtitle settings to the list.
1145         GValue *settings;
1146         gboolean burned = FALSE;
1147         gint track;
1148         
1149         g_debug("subtitle_add_clicked_cb ()");
1150
1151         track = ghb_settings_get_int(ud->settings, "SubtitleTrack");
1152         if (mustBurn(ud, track))
1153         {
1154                 burned = TRUE;
1155         }
1156         settings = ghb_dict_value_new();
1157         ghb_settings_set_int(settings, "SubtitleTrack", track);
1158         ghb_settings_take_value(settings, "SubtitleForced", 
1159                                                         ghb_boolean_value_new(FALSE));
1160         ghb_settings_take_value(settings, "SubtitleBurned", 
1161                                                         ghb_boolean_value_new(burned));
1162         ghb_settings_take_value(settings, "SubtitleDefaultTrack", 
1163                                                         ghb_boolean_value_new(FALSE));
1164
1165         ghb_add_subtitle(ud, settings);
1166 }
1167
1168 G_MODULE_EXPORT void
1169 subtitle_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
1170 {
1171         GtkTreeView *treeview;
1172         GtkTreePath *treepath;
1173         GtkTreeSelection *selection;
1174         GtkTreeModel *store;
1175         GtkTreeIter iter, nextIter;
1176         gint *indices;
1177         gint row;
1178         GValue *subtitle_list;
1179
1180         g_debug("subtitle_remove_clicked_cb ()");
1181         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
1182         selection = gtk_tree_view_get_selection (treeview);
1183         if (gtk_tree_selection_get_selected(selection, &store, &iter))
1184         {
1185                 nextIter = iter;
1186                 if (!gtk_tree_model_iter_next(store, &nextIter))
1187                 {
1188                         nextIter = iter;
1189                         if (gtk_tree_model_get_iter_first(store, &nextIter))
1190                         {
1191                                 gtk_tree_selection_select_iter (selection, &nextIter);
1192                         }
1193                 }
1194                 else
1195                 {
1196                         gtk_tree_selection_select_iter (selection, &nextIter);
1197                 }
1198                 // Get the row number
1199                 treepath = gtk_tree_model_get_path (store, &iter);
1200                 indices = gtk_tree_path_get_indices (treepath);
1201                 row = indices[0];
1202                 gtk_tree_path_free(treepath);
1203                 // Remove the selected item
1204                 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
1205                 // remove from subtitle settings list
1206                 if (row < 0) return;
1207                 widget = GHB_WIDGET (ud->builder, "subtitle_add");
1208                 gtk_widget_set_sensitive(widget, TRUE);
1209                 widget = GHB_WIDGET (ud->builder, "srt_add");
1210                 gtk_widget_set_sensitive(widget, TRUE);
1211                 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
1212                 if (row >= ghb_array_len(subtitle_list))
1213                         return;
1214                 GValue *old = ghb_array_get_nth(subtitle_list, row);
1215                 ghb_value_free(old);
1216                 ghb_array_remove(subtitle_list, row);
1217                 ghb_live_reset(ud);
1218         }
1219 }
1220
1221 void
1222 ghb_subtitle_prune(signal_user_data_t *ud)
1223 {
1224         GtkTreeView  *tv;
1225         GtkTreeModel *tm;
1226         GtkTreeIter   ti;
1227         GValue *subtitle_list, *settings;
1228         gint count, ii, track;
1229         gboolean burned;
1230         gint first_track = 0, one_burned = 0;
1231
1232         subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
1233         if (subtitle_list == NULL)
1234                 return;
1235         count = ghb_array_len(subtitle_list);
1236
1237         tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
1238         g_return_if_fail(tv != NULL);
1239         tm = gtk_tree_view_get_model(tv);
1240         for (ii = count-1; ii >= 0; ii--)
1241         {
1242                 settings = ghb_array_get_nth(subtitle_list, ii);
1243                 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
1244                 track = ghb_settings_combo_int(settings, "SubtitleTrack");
1245                 if (!burned && mustBurn(ud, track))
1246                 {
1247                         gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
1248                         gtk_list_store_remove (GTK_LIST_STORE(tm), &ti);
1249                         ghb_array_remove(subtitle_list, ii);
1250                 }
1251                 if (burned)
1252                 {
1253                         first_track = ii;
1254                         one_burned++;
1255                 }
1256         }
1257         if (one_burned)
1258         {
1259                 ghb_subtitle_exclusive_burn(ud, first_track);
1260         }
1261 }
1262
1263 void
1264 ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings)
1265 {
1266         GValue *slist;
1267         GValue *subtitle;
1268         gint count, ii;
1269         gint titleindex;
1270         
1271         g_debug("ghb_reset_subtitles");
1272         ghb_clear_subtitle_list(ud);
1273         titleindex = ghb_settings_combo_int(ud->settings, "title");
1274         if (titleindex < 0)
1275                 return;
1276
1277         slist = ghb_settings_get_value(settings, "subtitle_list");
1278         count = ghb_array_len(slist);
1279         for (ii = 0; ii < count; ii++)
1280         {
1281                 subtitle = ghb_value_dup(ghb_array_get_nth(slist, ii));
1282                 ghb_add_subtitle(ud, subtitle);
1283         }
1284 }
1285