OSDN Git Service

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