static GhbValue* subtitle_get_selected_settings(signal_user_data_t *ud, int *index) { GtkTreeView *tv; GtkTreePath *tp; GtkTreeSelection *ts; GtkTreeModel *tm; GtkTreeIter iter; gint *indices; gint row; GhbValue *subsettings = NULL; const GhbValue *subtitle_list; g_debug("get_selected_settings ()"); tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list_view")); ts = gtk_tree_view_get_selection(tv); if (gtk_tree_selection_get_selected(ts, &tm, &iter)) { // Get the row number tp = gtk_tree_model_get_path(tm, &iter); indices = gtk_tree_path_get_indices(tp); row = indices[0]; gtk_tree_path_free(tp); if (row < 0) return NULL; subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); if (row >= ghb_array_len(subtitle_list)) return NULL; subsettings = ghb_array_get(subtitle_list, row); if (index != NULL) *index = row; } return subsettings; }
void ghb_subtitle_list_refresh_selected(signal_user_data_t *ud) { GtkTreeView *tv; GtkTreeModel *tm; GtkTreePath *tp; GtkTreeSelection *ts; GtkTreeIter ti; gint *indices; gint row; GhbValue *subsettings = NULL; const GhbValue *subtitle_list; g_debug("subtitle_list_refresh_selected()"); tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list_view")); ts = gtk_tree_view_get_selection(tv); if (gtk_tree_selection_get_selected(ts, &tm, &ti)) { // Get the row number tp = gtk_tree_model_get_path(tm, &ti); indices = gtk_tree_path_get_indices(tp); row = indices[0]; gtk_tree_path_free(tp); if (row < 0) return; subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); if (row >= ghb_array_len(subtitle_list)) return; subsettings = ghb_array_get(subtitle_list, row); subtitle_refresh_list_row_ui(tm, &ti, subsettings); } }
void ghb_reset_subtitles(signal_user_data_t *ud, GhbValue *settings) { GhbValue *slist; GhbValue *subtitle; gint count, ii; gint title_id, titleindex; const hb_title_t *title; g_debug("ghb_reset_subtitles"); ghb_clear_subtitle_list_settings(ud->settings); ghb_clear_subtitle_list_ui(ud->builder); title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL) return; slist = ghb_dict_get_value(settings, "subtitle_list"); count = ghb_array_len(slist); for (ii = 0; ii < count; ii++) { subtitle = ghb_value_dup(ghb_array_get(slist, ii)); subtitle_add_to_settings(ud->settings, subtitle); } subtitle_refresh_list_ui(ud); }
static void subtitle_refresh_list_ui_from_settings(signal_user_data_t *ud, GhbValue *settings) { GhbValue *subtitle_list; GhbValue *subsettings; gint ii, count, tm_count; GtkTreeView *tv; GtkTreeModel *tm; GtkTreeIter ti; tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list_view")); tm = gtk_tree_view_get_model(tv); tm_count = gtk_tree_model_iter_n_children(tm, NULL); subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); count = ghb_array_len(subtitle_list); if (count != tm_count) { ghb_clear_subtitle_list_ui(ud->builder); for (ii = 0; ii < count; ii++) { gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL); } } for (ii = 0; ii < count; ii++) { g_return_if_fail(tv != NULL); gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii); subsettings = ghb_array_get(subtitle_list, ii); subtitle_refresh_list_row_ui(tm, &ti, subsettings); } }
static void subtitle_def_lang_list_init(signal_user_data_t *ud) { GhbValue *lang_list; // Clear selected languages. subtitle_def_selected_lang_list_clear(ud); lang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); if (lang_list == NULL) { lang_list = ghb_array_new(); ghb_dict_set(ud->settings, "SubtitleLanguageList", lang_list); } int ii, count; count = ghb_array_len(lang_list); for (ii = 0; ii < count; ) { GhbValue *lang_val = ghb_array_get(lang_list, ii); int idx = ghb_lookup_audio_lang(lang_val); if (ii == 0) { const iso639_lang_t *lang; lang = ghb_iso639_lookup_by_int(idx); subtitle_update_pref_lang(ud, lang); } GtkListBox *avail, *selected; GtkListBoxRow *row; avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); row = ghb_find_lang_row(avail, idx); if (row) { GtkWidget *label = gtk_bin_get_child(GTK_BIN(row)); g_object_ref(G_OBJECT(label)); gtk_widget_destroy(GTK_WIDGET(row)); gtk_widget_show(label); gtk_list_box_insert(selected, label, -1); ii++; } else { // Error in list. Probably duplicate languages. Remove // this item from the list. ghb_array_remove(lang_list, ii); count--; } } if (count == 0) { subtitle_update_pref_lang(ud, NULL); } }
void ghb_subtitle_exclusive_burn_settings(GhbValue *settings, gint index) { GhbValue *subtitle_list; GhbValue *subsettings; gint ii, count; subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); subsettings = ghb_array_get(subtitle_list, index); if (subsettings != NULL) { int track = ghb_dict_get_int(subsettings, "SubtitleTrack"); if (track == -1) { // Allow 2 tracks to be marked burned when one is // foreign audio search. Extra burned track will be // sanitized away if foreign audio search actually finds // something. return; } } count = ghb_array_len(subtitle_list); for (ii = 0; ii < count; ii++) { if (ii != index) { subsettings = ghb_array_get(subtitle_list, ii); int track = ghb_dict_get_int(subsettings, "SubtitleTrack"); if (track != -1) { // Allow 2 tracks to be marked burned when one is // foreign audio search. Extra burned track will be // sanitized away if foreign audio search actually finds // something. ghb_dict_set_bool(subsettings, "SubtitleBurned", FALSE); } } } }
G_MODULE_EXPORT void subtitle_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud) { GtkTreeModel *tm; GtkTreeIter iter; GhbValue *subsettings = NULL; int row; g_debug("subtitle_list_selection_changed_cb()"); if (gtk_tree_selection_get_selected(ts, &tm, &iter)) { GtkTreeIter piter; if (gtk_tree_model_iter_parent(tm, &piter, &iter)) { GtkTreePath *path; GtkTreeView *tv; gtk_tree_selection_select_iter(ts, &piter); path = gtk_tree_model_get_path(tm, &piter); tv = gtk_tree_selection_get_tree_view(ts); // Make the parent visible in scroll window if it is not. gtk_tree_view_scroll_to_cell(tv, path, NULL, FALSE, 0, 0); gtk_tree_path_free(path); return; } GtkTreePath *tp; gint *indices; GhbValue *subtitle_list; tp = gtk_tree_model_get_path(tm, &iter); indices = gtk_tree_path_get_indices(tp); row = indices[0]; gtk_tree_path_free(tp); subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); if (row >= 0 && row < ghb_array_len(subtitle_list)) subsettings = ghb_array_get(subtitle_list, row); } subtitle_update_dialog_widgets(ud, subsettings); if (subsettings) { if (ghb_dict_get_bool(subsettings, "SubtitleBurned")) { ghb_subtitle_exclusive_burn(ud, row); } } }
G_MODULE_EXPORT void subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) { GtkListBox *avail, *selected; GtkListBoxRow *row; GtkWidget *label; avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); row = gtk_list_box_get_selected_row(selected); if (row != NULL) { gint index; GhbValue *lang_list; index = gtk_list_box_row_get_index(row); // Remove from UI selected language list box label = gtk_bin_get_child(GTK_BIN(row)); g_object_ref(G_OBJECT(label)); int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); gtk_widget_destroy(GTK_WIDGET(row)); gtk_widget_show(label); // Add to UI available language list box gtk_list_box_insert(avail, label, idx); // Remove from preset language list lang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); ghb_array_remove(lang_list, index); ghb_clear_presets_selection(ud); if (ghb_array_len(lang_list) > 0) { const iso639_lang_t *lang; GhbValue *entry = ghb_array_get(lang_list, 0); lang = ghb_iso639_lookup_by_int(ghb_lookup_audio_lang(entry)); subtitle_update_pref_lang(ud, lang); } else { subtitle_update_pref_lang(ud, NULL); } } }
void ghb_subtitle_exclusive_default_settings(GhbValue *settings, gint index) { GhbValue *subtitle_list; GhbValue *subtitle; gint ii, count; subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); count = ghb_array_len(subtitle_list); for (ii = 0; ii < count; ii++) { if (ii != index) { subtitle = ghb_array_get(subtitle_list, ii); ghb_dict_set_bool(subtitle, "SubtitleDefaultTrack", FALSE); } } }
void ghb_subtitle_prune(signal_user_data_t *ud) { GhbValue *subtitle_list; GhbValue *subsettings; gint ii; gboolean one_burned = FALSE; subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); if (subtitle_list == NULL) return; const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(ud->settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); for (ii = 0; ii < ghb_array_len(subtitle_list); ) { gboolean burned; int source; subsettings = ghb_array_get(subtitle_list, ii); burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); source = ghb_dict_get_bool(subsettings, "SubtitleSource"); burned = burned || !hb_subtitle_can_pass(source, mux->format); if (burned && one_burned) { ghb_array_remove(subtitle_list, ii); continue; } one_burned = one_burned || burned; ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); ii++; } subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { subtitle_update_dialog_widgets(ud, subsettings); } }
static gboolean subtitle_is_one_burned(GhbValue *settings) { GhbValue *subtitle_list, *subsettings; int count, ii; subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); if (subtitle_list == NULL) return FALSE; count = ghb_array_len(subtitle_list); for (ii = 0; ii < count; ii++) { subsettings = ghb_array_get(subtitle_list, ii); if (ghb_dict_get_bool(subsettings, "SubtitleBurned")) { return TRUE; } } return FALSE; }
void ghb_subtitle_set_pref_lang(GhbValue *settings) { GhbValue *lang_list; gboolean set = FALSE; lang_list = ghb_dict_get_value(settings, "SubtitleLanguageList"); if (ghb_array_len(lang_list) > 0) { GhbValue *glang = ghb_array_get(lang_list, 0); if (glang != NULL) { ghb_dict_set_string(settings, "PreferredLanguage", ghb_value_get_string(glang)); set = TRUE; } } if (!set) { ghb_dict_set_string(settings, "PreferredLanguage", "und"); } }
static void gval_write(FILE *file, GhbValue *gval) { static gint indent = 0; gint ii; GhbType gtype; if (gval == NULL) return; gtype = ghb_value_type(gval); if (gtype == GHB_ARRAY) { GhbValue *val; gint count; indent_fprintf(file, indent, "<array>\n"); indent++; count = ghb_array_len(gval); for (ii = 0; ii < count; ii++) { val = ghb_array_get(gval, ii); gval_write(file, val); } indent--; indent_fprintf(file, indent, "</array>\n"); } else if (gtype == GHB_DICT) { const char *key; GhbValue *val; GhbDictIter iter; indent_fprintf(file, indent, "<dict>\n"); indent++; iter = ghb_dict_iter_init(gval); while (ghb_dict_iter_next(gval, &iter, &key, &val)) { indent_fprintf(file, indent, "<key>%s</key>\n", key); gval_write(file, val); } indent--; indent_fprintf(file, indent, "</dict>\n"); } else if (gtype == GHB_BOOL) { gchar *tag; if (ghb_value_get_bool(gval)) { tag = "true"; } else { tag = "false"; } indent_fprintf(file, indent, "<%s />\n", tag); } else if (gtype == GHB_DOUBLE) { gdouble val = ghb_value_get_double(gval); indent_fprintf(file, indent, "<real>%.17g</real>\n", val); } else if (gtype == GHB_INT) { gint64 val = ghb_value_get_int(gval); indent_fprintf(file, indent, "<integer>%"PRId64"</integer>\n", val); } else if (gtype == GHB_STRING) { const gchar *str = ghb_value_get_string(gval); gchar *esc = g_markup_escape_text(str, -1); indent_fprintf(file, indent, "<string>%s</string>\n", esc); g_free(esc); } else { // Try to make anything thats unrecognized into a string g_warning("Unhandled data type %d", gtype); } }
void ghb_set_pref_subtitle_settings(signal_user_data_t *ud, const hb_title_t *title, GhbValue *settings) { gint track; gboolean *used; const gchar *audio_lang, *pref_lang = NULL; gboolean foreign_audio_search, foreign_audio_subs; gboolean burn_foreign, burn_first, burn_dvd, burn_bd; gboolean one_burned = FALSE; const GhbValue *lang_list; gint lang_count, sub_count, ii; int behavior; behavior = ghb_settings_combo_int(settings, "SubtitleTrackSelectionBehavior"); // Clear the subtitle list ghb_clear_subtitle_list_settings(settings); if (title == NULL) { // no source title return; } sub_count = hb_list_count(title->list_subtitle); if (sub_count == 0) { // No source subtitles return; } const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); // Check to see if we need to add a subtitle track for foreign audio // language films. A subtitle track will be added if: // // The first (default) audio track language does NOT match the users // chosen Preferred Language AND the Preferred Language is NOT Any (und). // audio_lang = ghb_get_user_audio_lang(settings, title, 0); foreign_audio_search = ghb_dict_get_bool( settings, "SubtitleAddForeignAudioSearch"); foreign_audio_subs = ghb_dict_get_bool( settings, "SubtitleAddForeignAudioSubtitle"); lang_list = ghb_dict_get_value(settings, "SubtitleLanguageList"); lang_count = ghb_array_len(lang_list); if (lang_count > 0) { GhbValue *glang = ghb_array_get(lang_list, 0); pref_lang = ghb_value_get_string(glang); } if (pref_lang == NULL || !strncmp(pref_lang, "und", 4)) { foreign_audio_search = foreign_audio_subs = FALSE; pref_lang = NULL; } used = g_malloc0(sub_count * sizeof(gboolean)); int burn_behavior; burn_behavior = ghb_settings_combo_int(settings, "SubtitleBurnBehavior"); burn_foreign = burn_behavior == 1 || burn_behavior == 3; burn_first = burn_behavior == 2 || burn_behavior == 3; burn_dvd = ghb_dict_get_bool(settings, "SubtitleBurnDVDSub"); burn_bd = ghb_dict_get_bool(settings, "SubtitleBurnBDSub"); if (foreign_audio_subs && (audio_lang == NULL || strncmp(audio_lang, pref_lang, 4))) { // Add preferred language subtitle since first audio track // is foreign language. foreign_audio_search = FALSE; track = ghb_find_subtitle_track(title, pref_lang, 0); if (track >= 0) { gboolean burn; hb_subtitle_t *subtitle; subtitle = hb_list_item(title->list_subtitle, track); burn = (subtitle->source == VOBSUB && burn_dvd) || (subtitle->source == PGSSUB && burn_bd) || burn_foreign || burn_first; used[track] = TRUE; subtitle_add_track(ud, settings, title, track, mux->format, !burn, FALSE, burn, &one_burned); burn_first &= !burn; } } if (foreign_audio_search && (audio_lang != NULL && !strncmp(audio_lang, pref_lang, 4))) { // Add search for foreign audio segments gboolean burn = burn_foreign || burn_first; subtitle_add_track(ud, settings, title, -1, mux->format, !burn, FALSE, burn, &one_burned); burn_first &= !burn; } if (behavior != 0) { // Find "best" subtitle based on subtitle preferences for (ii = 0; ii < lang_count; ii++) { GhbValue *glang = ghb_array_get(lang_list, ii); const gchar *lang = ghb_value_get_string(glang); int next_track = 0; track = ghb_find_subtitle_track(title, lang, next_track); while (track >= 0) { if (!used[track]) { gboolean burn; hb_subtitle_t *subtitle; subtitle = hb_list_item(title->list_subtitle, track); burn = (subtitle->source == VOBSUB && burn_dvd) || (subtitle->source == PGSSUB && burn_bd) || burn_first; used[track] = TRUE; subtitle_add_track(ud, settings, title, track, mux->format, FALSE, FALSE, burn, &one_burned); burn_first &= !burn; } next_track = track + 1; if (behavior == 2) { track = ghb_find_subtitle_track(title, lang, next_track); } else { break; } } } } if (ghb_dict_get_bool(settings, "SubtitleAddCC")) { for (track = 0; track < sub_count; track++) { hb_subtitle_t *subtitle = hb_list_item(title->list_subtitle, track); if (subtitle->source == CC608SUB || subtitle->source == CC708SUB) break; } if (track < sub_count && !used[track]) { used[track] = TRUE; subtitle_add_track(ud, settings, title, track, mux->format, FALSE, FALSE, burn_first, &one_burned); } } g_free(used); }