1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * subtitlehandler.c is free software.
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)
17 #include "hb-backend.h"
19 #include "callbacks.h"
21 #include "subtitlehandler.h"
23 static void add_to_subtitle_list(
24 signal_user_data_t *ud, GValue *settings, gboolean can_delete);
27 free_subtitle_index_list(gpointer data)
33 free_subtitle_key(gpointer data)
40 ghb_add_subtitle(signal_user_data_t *ud, GValue *settings, gboolean can_delete)
42 // Add the current subtitle settings to the list.
43 GValue *subtitle_list;
45 g_debug("ghb_add_subtitle ()");
47 // Only allow up to 8 subtitle entries
48 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
49 if (subtitle_list == NULL)
51 subtitle_list = ghb_array_value_new(8);
52 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
54 ghb_array_append(subtitle_list, settings);
55 add_to_subtitle_list(ud, settings, can_delete);
59 add_all_pref_subtitles(signal_user_data_t *ud)
61 const GValue *pref_subtitle;
63 gint count, ii, track;
66 pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
67 count = ghb_array_len(pref_subtitle);
68 for (ii = 0; ii < count; ii++)
70 subtitle = ghb_value_dup(ghb_array_get_nth(pref_subtitle, ii));
71 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
72 // If there are multiple subtitles using the same language, then
73 // select sequential tracks for each. The hash keeps track
74 // of the tracks used for each language.
75 track = ghb_find_pref_subtitle_track(lang);
79 // Add to subtitle list
80 ghb_settings_set_int(subtitle, "SubtitleTrack", track);
81 ghb_add_subtitle(ud, subtitle, TRUE);
87 ghb_set_pref_subtitle(gint titleindex, signal_user_data_t *ud)
90 GHashTable *track_indices;
93 const GValue *pref_subtitle;
97 g_debug("ghb_set_pref_subtitle %d", titleindex);
98 track_indices = g_hash_table_new_full(g_str_hash, g_str_equal,
99 NULL, free_subtitle_index_list);
100 // Clear the subtitle list
101 ghb_clear_subtitle_list(ud);
104 add_all_pref_subtitles(ud);
107 ghb_add_all_subtitles(ud, titleindex);
109 // Find "best" subtitle based on subtitle preferences
110 pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
112 count = ghb_array_len(pref_subtitle);
113 for (ii = 0; ii < count; ii++)
115 subtitle = ghb_array_get_nth(pref_subtitle, ii);
116 lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
117 // If there are multiple subtitles using the same language, then
118 // select sequential tracks for each. The hash keeps track
119 // of the tracks used for each language.
120 track = ghb_find_subtitle_track(titleindex, lang, track_indices);
124 ghb_set_subtitle(ud, track, subtitle);
127 g_hash_table_destroy(track_indices);
131 ghb_selected_subtitle_row(signal_user_data_t *ud)
133 GtkTreeView *treeview;
134 GtkTreePath *treepath;
135 GtkTreeSelection *selection;
141 g_debug("ghb_selected_subtitle_row ()");
142 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
143 selection = gtk_tree_view_get_selection (treeview);
144 if (gtk_tree_selection_get_selected(selection, &store, &iter))
146 // Get the row number
147 treepath = gtk_tree_model_get_path (store, &iter);
148 indices = gtk_tree_path_get_indices (treepath);
150 gtk_tree_path_free(treepath);
156 mustBurn(signal_user_data_t *ud, gint track)
160 mux = ghb_settings_combo_int(ud->settings, "FileFormat");
161 if (mux == HB_MUX_MP4)
165 // MP4 can only handle burned vobsubs. make sure there isn't
166 // already something burned in the list
167 source = ghb_subtitle_track_source(ud, track);
168 if (source == VOBSUB)
177 ghb_selected_subtitle_settings(signal_user_data_t *ud)
179 GtkTreeView *treeview;
180 GtkTreePath *treepath;
181 GtkTreeSelection *selection;
186 GValue *settings = NULL;
187 const GValue *subtitle_list;
189 g_debug("get_selected_settings ()");
190 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
191 selection = gtk_tree_view_get_selection (treeview);
192 if (gtk_tree_selection_get_selected(selection, &store, &iter))
194 // Get the row number
195 treepath = gtk_tree_model_get_path (store, &iter);
196 indices = gtk_tree_path_get_indices (treepath);
198 gtk_tree_path_free(treepath);
199 // find subtitle settings
200 if (row < 0) return NULL;
201 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
202 if (row >= ghb_array_len(subtitle_list))
204 settings = ghb_array_get_nth(subtitle_list, row);
210 ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint track)
212 GValue *subtitle_list;
220 g_debug("ghb_subtitle_exclusive_burn");
221 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
222 count = ghb_array_len(subtitle_list);
223 for (ii = 0; ii < count; ii++)
225 settings = ghb_array_get_nth(subtitle_list, ii);
226 tt = ghb_settings_combo_int(settings, "SubtitleTrack");
227 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
229 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
230 g_return_if_fail(tv != NULL);
231 tm = gtk_tree_view_get_model(tv);
232 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
233 if (burned && tt != track)
236 ghb_settings_set_boolean(settings, "SubtitleBurned", FALSE);
238 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, FALSE, -1);
240 if (!burned && mustBurn(ud, tt))
242 ghb_settings_set_boolean(settings, "SubtitleEnabled", FALSE);
243 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 0, FALSE, -1);
249 subtitle_enable_toggled_cb(
250 GtkCellRendererToggle *cell,
252 signal_user_data_t *ud)
261 GValue *subtitle_list, *settings;
264 g_debug("forced toggled");
265 tp = gtk_tree_path_new_from_string (path);
266 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
267 g_return_if_fail(tv != NULL);
268 tm = gtk_tree_view_get_model(tv);
269 g_return_if_fail(tm != NULL);
270 gtk_tree_model_get_iter(tm, &ti, tp);
271 gtk_tree_model_get(tm, &ti, 0, &active, -1);
274 // Get the row number
275 indices = gtk_tree_path_get_indices (tp);
277 gtk_tree_path_free(tp);
278 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
280 if (row < 0 || row >= ghb_array_len(subtitle_list))
283 settings = ghb_array_get_nth(subtitle_list, row);
284 track = ghb_settings_combo_int(settings, "SubtitleTrack");
286 if (active && mustBurn(ud, track))
288 ghb_settings_set_boolean(settings, "SubtitleBurned", TRUE);
289 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, TRUE, -1);
290 ghb_subtitle_exclusive_burn(ud, track);
293 ghb_settings_set_boolean(settings, "SubtitleEnabled", active);
294 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 0, active, -1);
298 subtitle_forced_toggled_cb(
299 GtkCellRendererToggle *cell,
301 signal_user_data_t *ud)
310 GValue *subtitle_list, *settings;
313 g_debug("forced toggled");
314 tp = gtk_tree_path_new_from_string (path);
315 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
316 g_return_if_fail(tv != NULL);
317 tm = gtk_tree_view_get_model(tv);
318 g_return_if_fail(tm != NULL);
319 gtk_tree_model_get_iter(tm, &ti, tp);
320 gtk_tree_model_get(tm, &ti, 2, &active, -1);
323 // Get the row number
324 indices = gtk_tree_path_get_indices (tp);
326 gtk_tree_path_free(tp);
328 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
330 if (row < 0 || row >= ghb_array_len(subtitle_list))
333 settings = ghb_array_get_nth(subtitle_list, row);
334 track = ghb_settings_combo_int(settings, "SubtitleTrack");
336 source = ghb_subtitle_track_source(ud, track);
337 if (source != VOBSUB)
340 ghb_settings_set_boolean(settings, "SubtitleForced", active);
341 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, active, -1);
345 subtitle_burned_toggled_cb(
346 GtkCellRendererToggle *cell,
348 signal_user_data_t *ud)
357 GValue *subtitle_list;
358 gint count, track, source;
361 g_debug("burned toggled");
362 tp = gtk_tree_path_new_from_string (path);
363 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
364 g_return_if_fail(tv != NULL);
365 tm = gtk_tree_view_get_model(tv);
366 g_return_if_fail(tm != NULL);
367 gtk_tree_model_get_iter(tm, &ti, tp);
368 gtk_tree_model_get(tm, &ti, 3, &active, -1);
371 // Get the row number
372 indices = gtk_tree_path_get_indices (tp);
374 gtk_tree_path_free(tp);
376 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
377 count = ghb_array_len(subtitle_list);
378 if (row < 0 || row >= count)
381 settings = ghb_array_get_nth(subtitle_list, row);
382 track = ghb_settings_combo_int(settings, "SubtitleTrack");
384 source = ghb_subtitle_track_source(ud, track);
385 if (source != VOBSUB)
388 if (!active && mustBurn(ud, track))
391 ghb_settings_set_boolean(settings, "SubtitleBurned", active);
393 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, active, -1);
395 ghb_subtitle_exclusive_burn(ud, track);
399 trackUsed(signal_user_data_t *ud, gint track)
402 GValue *settings, *subtitle_list;
404 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
405 count = ghb_array_len(subtitle_list);
406 for (ii = 0; ii < count; ii++)
408 settings = ghb_array_get_nth(subtitle_list, ii);
409 tt = ghb_settings_combo_int(settings, "SubtitleTrack");
419 subtitle_track_changed_cb(
420 GtkCellRendererCombo *combo,
423 signal_user_data_t *ud)
432 GValue *subtitle_list, *settings;
435 g_debug("subtitle_track_changed_cb ()");
436 gtk_tree_model_get(GTK_TREE_MODEL(ud->subtitle_track_model), iter,
439 if (trackUsed(ud, tt))
442 tp = gtk_tree_path_new_from_string (path);
443 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
444 g_return_if_fail(tv != NULL);
445 tm = gtk_tree_view_get_model(tv);
446 g_return_if_fail(tm != NULL);
447 gtk_tree_model_get_iter(tm, &ti, tp);
449 // Get the row number
450 indices = gtk_tree_path_get_indices (tp);
452 gtk_tree_path_free(tp);
454 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
455 if (row >= ghb_array_len(subtitle_list))
457 settings = ghb_array_get_nth(subtitle_list, row);
459 ghb_settings_set_int(settings, "SubtitleTrack", tt);
460 lang = ghb_settings_combo_string(settings, "SubtitleTrack");
461 if (mustBurn(ud, tt))
463 ghb_settings_set_boolean(settings, "SubtitleBurned", TRUE);
467 ghb_settings_set_boolean(settings, "SubtitleBurned", FALSE);
469 ghb_settings_set_string(settings, "SubtitleLanguage", lang);
471 const gchar *track, *source;
476 track = ghb_settings_combo_option(settings, "SubtitleTrack");
477 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
479 s_track = ghb_settings_get_string(settings, "SubtitleTrack");
480 i_track = ghb_settings_get_int(settings, "SubtitleTrack");
481 source = ghb_subtitle_track_source_name(ud, i_track);
483 gtk_list_store_set(GTK_LIST_STORE(tm), &ti,
484 // These are displayed in list
488 // These are used to set combo values when a list item is selected
497 ghb_subtitle_adjust_burn(signal_user_data_t *ud)
499 GValue *subtitle_list;
501 gint ii, count, track;
505 gboolean burned, enabled, found;
507 g_debug("ghb_subtitle_adjust_burn");
508 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
509 count = ghb_array_len(subtitle_list);
510 for (ii = 0; ii < count; ii++)
512 settings = ghb_array_get_nth(subtitle_list, ii);
513 enabled = ghb_settings_get_boolean(settings, "SubtitleEnabled");
514 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
515 if (enabled && burned)
521 for (ii = 0; ii < count; ii++)
523 settings = ghb_array_get_nth(subtitle_list, ii);
524 track = ghb_settings_combo_int(settings, "SubtitleTrack");
526 if (!mustBurn(ud, track))
529 enabled = ghb_settings_get_boolean(settings, "SubtitleEnabled");
530 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
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 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
539 if (enabled && !burned)
541 ghb_settings_set_boolean(settings, "SubtitleBurned", TRUE);
542 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, TRUE, -1);
548 if (enabled && !burned)
550 ghb_settings_set_boolean(settings, "SubtitleEnabled", FALSE);
551 gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 0, FALSE, -1);
558 ghb_clear_subtitle_list(signal_user_data_t *ud)
560 GtkTreeView *treeview;
562 GValue *subtitle_list;
564 g_debug("clear_subtitle_list ()");
565 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
566 if (subtitle_list == NULL)
568 subtitle_list = ghb_array_value_new(8);
569 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
572 ghb_array_value_reset(subtitle_list, 8);
573 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
574 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
575 gtk_list_store_clear (store);
579 add_to_subtitle_list(
580 signal_user_data_t *ud,
584 GtkTreeView *treeview;
587 GtkTreeSelection *selection;
588 const gchar *track, *source;
589 gboolean forced, burned, enabled;
593 g_debug("add_to_subtitle_list ()");
594 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
595 selection = gtk_tree_view_get_selection (treeview);
596 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
598 track = ghb_settings_combo_option(settings, "SubtitleTrack");
599 enabled = ghb_settings_get_boolean(settings, "SubtitleEnabled");
600 forced = ghb_settings_get_boolean(settings, "SubtitleForced");
601 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
603 s_track = ghb_settings_get_string(settings, "SubtitleTrack");
604 i_track = ghb_settings_get_int(settings, "SubtitleTrack");
605 source = ghb_subtitle_track_source_name(ud, i_track);
607 gtk_list_store_append(store, &iter);
608 gtk_list_store_set(store, &iter,
609 // These are displayed in list
615 // These are used to set combo box values when a list item is selected
619 gtk_tree_selection_select_iter(selection, &iter);
622 ghb_subtitle_exclusive_burn(ud, i_track);
626 subtitle_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
632 g_debug("subtitle_list_selection_changed_cb ()");
633 if (gtk_tree_selection_get_selected(selection, &store, &iter))
638 gtk_tree_model_get(store, &iter, 5, &track, 6, &can_delete, -1);
639 ghb_settings_set_string(ud->settings, "SubtitleTrack", track);
643 widget = GHB_WIDGET (ud->builder, "subtitle_remove");
644 gtk_widget_set_sensitive(widget, TRUE);
648 widget = GHB_WIDGET (ud->builder, "subtitle_remove");
649 gtk_widget_set_sensitive(widget, FALSE);
655 subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
657 // Add the current subtitle settings to the list.
660 GValue *subtitle_list;
661 gboolean burned = FALSE;
664 g_debug("subtitle_add_clicked_cb ()");
665 track = ghb_pick_subtitle_track(ud);
669 if (mustBurn(ud, track))
673 settings = ghb_dict_value_new();
674 // Only allow up to 8 subtitle entries
675 ghb_settings_set_int(settings, "SubtitleTrack", track);
676 ghb_settings_set_boolean(settings, "SubtitleEnabled", TRUE);
677 ghb_settings_take_value(settings, "SubtitleForced",
678 ghb_boolean_value_new(FALSE));
679 ghb_settings_take_value(settings, "SubtitleBurned",
680 ghb_boolean_value_new(burned));
682 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
683 if (subtitle_list == NULL)
685 subtitle_list = ghb_array_value_new(8);
686 ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
688 ghb_array_append(subtitle_list, settings);
689 add_to_subtitle_list(ud, settings, TRUE);
690 count = ghb_array_len(subtitle_list);
694 subtitle_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
696 GtkTreeView *treeview;
697 GtkTreePath *treepath;
698 GtkTreeSelection *selection;
700 GtkTreeIter iter, nextIter;
703 GValue *subtitle_list;
705 g_debug("subtitle_remove_clicked_cb ()");
706 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
707 selection = gtk_tree_view_get_selection (treeview);
708 if (gtk_tree_selection_get_selected(selection, &store, &iter))
711 if (!gtk_tree_model_iter_next(store, &nextIter))
714 if (gtk_tree_model_get_iter_first(store, &nextIter))
716 gtk_tree_selection_select_iter (selection, &nextIter);
721 gtk_tree_selection_select_iter (selection, &nextIter);
723 // Get the row number
724 treepath = gtk_tree_model_get_path (store, &iter);
725 indices = gtk_tree_path_get_indices (treepath);
727 gtk_tree_path_free(treepath);
728 // Remove the selected item
729 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
730 // remove from subtitle settings list
732 widget = GHB_WIDGET (ud->builder, "subtitle_add");
733 gtk_widget_set_sensitive(widget, TRUE);
734 subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
735 if (row >= ghb_array_len(subtitle_list))
737 GValue *old = ghb_array_get_nth(subtitle_list, row);
739 ghb_array_remove(subtitle_list, row);
744 ghb_set_subtitle(signal_user_data_t *ud, gint track, GValue *settings)
752 gboolean forced, burned, enabled;
754 g_debug("ghb_set_subtitle");
755 slist = ghb_settings_get_value(ud->settings, "subtitle_list");
757 count = ghb_array_len(slist);
758 for (ii = 0; ii < count; ii++)
760 subtitle = ghb_array_get_nth(slist, ii);
761 tt = ghb_settings_get_int(subtitle, "SubtitleTrack");
765 enabled = ghb_settings_get_boolean(settings, "SubtitleEnabled");
766 forced = ghb_settings_get_boolean(settings, "SubtitleForced");
767 burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
769 tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
770 g_return_if_fail(tv != NULL);
771 tm = gtk_tree_view_get_model(tv);
772 gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
774 ghb_settings_set_boolean(subtitle, "SubtitleEnabled", enabled);
775 ghb_settings_set_boolean(subtitle, "SubtitleForced", forced);
776 ghb_settings_set_boolean(subtitle, "SubtitleBurned", burned);
777 gtk_list_store_set(GTK_LIST_STORE(tm), &ti,
788 ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings)
792 gint count, ii, track;
795 g_debug("ghb_reset_subtitles");
796 ghb_clear_subtitle_list(ud);
797 titleindex = ghb_settings_combo_int(ud->settings, "title");
801 ghb_add_all_subtitles(ud, titleindex);
802 slist = ghb_settings_get_value(settings, "subtitle_list");
804 count = ghb_array_len(slist);
805 for (ii = 0; ii < count; ii++)
807 subtitle = ghb_array_get_nth(slist, ii);
808 track = ghb_settings_get_int(subtitle, "SubtitleTrack");
810 ghb_set_subtitle(ud, track, subtitle);