diff options
-rw-r--r-- | gtk/src/ghb-3.12.ui | 23 | ||||
-rw-r--r-- | gtk/src/ghb-3.14.ui | 23 | ||||
-rw-r--r-- | gtk/src/ghb.ui | 23 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 167 | ||||
-rw-r--r-- | gtk/src/internal_defaults.json | 7 | ||||
-rw-r--r-- | gtk/src/queuehandler.c | 58 | ||||
-rw-r--r-- | gtk/src/subtitlehandler.c | 791 | ||||
-rw-r--r-- | gtk/src/subtitlehandler.h | 4 |
8 files changed, 582 insertions, 514 deletions
diff --git a/gtk/src/ghb-3.12.ui b/gtk/src/ghb-3.12.ui index 0f34d43f3..95cc6521d 100644 --- a/gtk/src/ghb-3.12.ui +++ b/gtk/src/ghb-3.12.ui @@ -5062,6 +5062,23 @@ Only one subtitle track can be burned! Since conflicts can occur, the first chos </packing> </child> <child> + <object class="GtkToolButton" id="subtitle_add_fas"> + <property name="visible">True</property> + <property name="sensitive">True</property> + <property name="can_focus">False</property> + <property name="is_important">True</property> + <property name="label" translatable="yes">Foreign Audio Search</property> + <property name="icon_name">list-add</property> + <property name="tooltip_text" translatable="yes">Add an extra pass to the encode which searches +for subtitle candidates that provide subtitles for +segments of the audio that are in a foreign language.</property> + <signal name="clicked" handler="subtitle_add_fas_clicked_cb" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> <object class="GtkToolButton" id="subtitle_reset"> <property name="visible">True</property> <property name="sensitive">True</property> @@ -8651,6 +8668,7 @@ Setting this to 0 means there is no maximum height.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> @@ -8849,7 +8867,7 @@ SRTs come in all flavours of character sets. We translate the character set to UTF-8. The source's character code is needed in order to perform this translation.</property> <property name="has_entry">True</property> - <signal name="changed" handler="srt_changed_cb" swapped="no"/> + <signal name="changed" handler="srt_codeset_changed_cb" swapped="no"/> <child internal-child="entry"> <object class="GtkEntry" id="combobox-entry1"> <property name="can_focus">True</property> @@ -8889,7 +8907,7 @@ The source's character code is needed in order to perform this translation.</pro <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> <property name="adjustment">adjustment31</property> - <signal name="value-changed" handler="srt_changed_cb" swapped="no"/> + <signal name="value-changed" handler="srt_offset_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">1</property> @@ -9041,6 +9059,7 @@ in your output.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> diff --git a/gtk/src/ghb-3.14.ui b/gtk/src/ghb-3.14.ui index aeeed8b0b..738075217 100644 --- a/gtk/src/ghb-3.14.ui +++ b/gtk/src/ghb-3.14.ui @@ -5066,6 +5066,23 @@ Only one subtitle track can be burned! Since conflicts can occur, the first chos </packing> </child> <child> + <object class="GtkToolButton" id="subtitle_add_fas"> + <property name="visible">True</property> + <property name="sensitive">True</property> + <property name="can_focus">False</property> + <property name="is_important">True</property> + <property name="label" translatable="yes">Foreign Audio Search</property> + <property name="icon_name">list-add</property> + <property name="tooltip_text" translatable="yes">Add an extra pass to the encode which searches +for subtitle candidates that provide subtitles for +segments of the audio that are in a foreign language.</property> + <signal name="clicked" handler="subtitle_add_fas_clicked_cb" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> <object class="GtkToolButton" id="subtitle_reset"> <property name="visible">True</property> <property name="sensitive">True</property> @@ -8638,6 +8655,7 @@ Setting this to 0 means there is no maximum height.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> @@ -8836,7 +8854,7 @@ SRTs come in all flavours of character sets. We translate the character set to UTF-8. The source's character code is needed in order to perform this translation.</property> <property name="has_entry">True</property> - <signal name="changed" handler="srt_changed_cb" swapped="no"/> + <signal name="changed" handler="srt_codeset_changed_cb" swapped="no"/> <child internal-child="entry"> <object class="GtkEntry" id="combobox-entry1"> <property name="can_focus">True</property> @@ -8876,7 +8894,7 @@ The source's character code is needed in order to perform this translation.</pro <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> <property name="adjustment">adjustment31</property> - <signal name="value-changed" handler="srt_changed_cb" swapped="no"/> + <signal name="value-changed" handler="srt_offset_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">1</property> @@ -9029,6 +9047,7 @@ in your output.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui index 40529c727..413d1637a 100644 --- a/gtk/src/ghb.ui +++ b/gtk/src/ghb.ui @@ -5062,6 +5062,23 @@ Only one subtitle track can be burned! Since conflicts can occur, the first chos </packing> </child> <child> + <object class="GtkToolButton" id="subtitle_add_fas"> + <property name="visible">True</property> + <property name="sensitive">True</property> + <property name="can_focus">False</property> + <property name="is_important">True</property> + <property name="label" translatable="yes">Foreign Audio Search</property> + <property name="icon_name">list-add</property> + <property name="tooltip_text" translatable="yes">Add an extra pass to the encode which searches +for subtitle candidates that provide subtitles for +segments of the audio that are in a foreign language.</property> + <signal name="clicked" handler="subtitle_add_fas_clicked_cb" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> <object class="GtkToolButton" id="subtitle_reset"> <property name="visible">True</property> <property name="sensitive">True</property> @@ -8650,6 +8667,7 @@ Setting this to 0 means there is no maximum height.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> @@ -8848,7 +8866,7 @@ SRTs come in all flavours of character sets. We translate the character set to UTF-8. The source's character code is needed in order to perform this translation.</property> <property name="has_entry">True</property> - <signal name="changed" handler="srt_changed_cb" swapped="no"/> + <signal name="changed" handler="srt_codeset_changed_cb" swapped="no"/> <child internal-child="entry"> <object class="GtkEntry" id="combobox-entry1"> <property name="can_focus">True</property> @@ -8888,7 +8906,7 @@ The source's character code is needed in order to perform this translation.</pro <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> <property name="adjustment">adjustment31</property> - <signal name="value-changed" handler="srt_changed_cb" swapped="no"/> + <signal name="value-changed" handler="srt_offset_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">1</property> @@ -9040,6 +9058,7 @@ in your output.</property> <property name="can_focus">False</property> <property name="border_width">5</property> <property name="modal">True</property> + <property name="resizable">False</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <property name="skip_taskbar_hint">True</property> diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index b0223106d..3d8cdab7b 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -2225,39 +2225,27 @@ subtitle_track_opts_set( { count = hb_list_count( title->list_subtitle ); } - if (count > 0) + for (ii = 0; ii < count; ii++) { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - 0, _("Foreign Audio Search"), - 1, TRUE, - 2, "-1", - 3, -1.0, - 4, "auto", - -1); - - for (ii = 0; ii < count; ii++) - { - gchar *opt; - char idx[4]; + gchar *opt; + char idx[4]; - subtitle = hb_list_item(title->list_subtitle, ii); - opt = g_strdup_printf("%d - %s (%s)", ii+1, subtitle->lang, - hb_subsource_name(subtitle->source)); - snprintf(idx, 4, "%d", ii); + subtitle = hb_list_item(title->list_subtitle, ii); + opt = g_strdup_printf("%d - %s (%s)", ii+1, subtitle->lang, + hb_subsource_name(subtitle->source)); + snprintf(idx, 4, "%d", ii); - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - 0, opt, - 1, TRUE, - 2, idx, - 3, (gdouble)ii, - 4, idx, - -1); - g_free(opt); - } + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, opt, + 1, TRUE, + 2, idx, + 3, (gdouble)ii, + 4, idx, + -1); + g_free(opt); } - else + if (count <= 0) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, @@ -3777,15 +3765,14 @@ ghb_validate_subtitles(GhbValue *settings, GtkWindow *parent) gint count, ii, source, track; gboolean burned, one_burned = FALSE; - slist = ghb_dict_get_value(settings, "subtitle_list"); + slist = ghb_get_subtitle_list(settings); count = ghb_array_len(slist); for (ii = 0; ii < count; ii++) { subtitle = ghb_array_get(slist, ii); - track = ghb_dict_get_int(subtitle, "SubtitleTrack"); - source = ghb_dict_get_int(subtitle, "SubtitleSource"); - burned = track != -1 && - ghb_dict_get_bool(subtitle, "SubtitleBurned"); + track = ghb_dict_get_int(subtitle, "Track"); + source = ghb_dict_get_int(subtitle, "Source"); + burned = track != -1 && ghb_dict_get_bool(subtitle, "Burn"); if (burned && one_burned) { // MP4 can only handle burned vobsubs. make sure there isn't @@ -3810,12 +3797,13 @@ ghb_validate_subtitles(GhbValue *settings, GtkWindow *parent) if (source == SRTSUB) { const gchar *filename; + GhbValue *srt = ghb_dict_get(subtitle, "SRT"); - filename = ghb_dict_get_string(subtitle, "SrtFile"); + filename = ghb_dict_get_string(srt, "Filename"); if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { message = g_strdup_printf( - _("Srt file does not exist or not a regular file.\n\n" + _("SRT file does not exist or not a regular file.\n\n" "You should choose a valid file.\n" "If you continue, this subtitle will be ignored.")); if (!ghb_message_dialog(parent, GTK_MESSAGE_WARNING, message, @@ -3967,7 +3955,6 @@ add_job(hb_handle_t *h, GhbValue *js, gint unique_id) { hb_dict_t * dict; json_error_t error; - int ii, count; // Assumes that the UI has reduced geometry settings to only the // necessary PAR value @@ -4462,110 +4449,8 @@ add_job(hb_handle_t *h, GhbValue *js, gint unique_id) hb_dict_set(audios_dict, "AudioList", ghb_value_dup(ghb_dict_get(js, "audio_list"))); - // Create subtitle list - hb_dict_t *subtitles_dict = hb_dict_get(dict, "Subtitle"); - hb_value_array_t *json_subtitle_list = hb_dict_get(subtitles_dict, "SubtitleList"); - const GhbValue *subtitle_list; - - subtitle_list = ghb_dict_get_value(js, "subtitle_list"); - count = ghb_array_len(subtitle_list); - for (ii = 0; ii < count; ii++) - { - hb_dict_t *subtitle_dict; - gint track; - gboolean force, burned, def, one_burned = FALSE; - GhbValue *ssettings; - gint source; - - ssettings = ghb_array_get(subtitle_list, ii); - - force = ghb_dict_get_bool(ssettings, "SubtitleForced"); - burned = ghb_dict_get_bool(ssettings, "SubtitleBurned"); - def = ghb_dict_get_bool(ssettings, "SubtitleDefaultTrack"); - source = ghb_dict_get_int(ssettings, "SubtitleSource"); - - if (source == SRTSUB) - { - const gchar *filename, *lang, *code; - int offset; - filename = ghb_dict_get_string(ssettings, "SrtFile"); - if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) - { - continue; - } - offset = ghb_dict_get_int(ssettings, "SrtOffset"); - lang = ghb_dict_get_string(ssettings, "SrtLanguage"); - code = ghb_dict_get_string(ssettings, "SrtCodeset"); - if (burned && !one_burned && hb_subtitle_can_burn(SRTSUB)) - { - // Only allow one subtitle to be burned into the video - one_burned = TRUE; - } - else - { - burned = FALSE; - } - subtitle_dict = json_pack_ex(&error, 0, - "{s:o, s:o, s:o, s:{s:o, s:o, s:o}}", - "Default", hb_value_bool(def), - "Burn", hb_value_bool(burned), - "Offset", hb_value_int(offset), - "SRT", - "Filename", hb_value_string(filename), - "Language", hb_value_string(lang), - "Codeset", hb_value_string(code)); - if (subtitle_dict == NULL) - { - g_warning("json pack srt failure: %s", error.text); - return; - } - hb_value_array_append(json_subtitle_list, subtitle_dict); - } - - track = ghb_dict_get_int(ssettings, "SubtitleTrack"); - if (track == -1) - { - hb_dict_t *search = hb_dict_get(subtitles_dict, "Search"); - if (burned && !one_burned) - { - // Only allow one subtitle to be burned into the video - one_burned = TRUE; - } - else - { - burned = FALSE; - } - hb_dict_set(search, "Enable", hb_value_bool(TRUE)); - hb_dict_set(search, "Forced", hb_value_bool(force)); - hb_dict_set(search, "Default", hb_value_bool(def)); - hb_dict_set(search, "Burn", hb_value_bool(burned)); - } - else if (track >= 0) - { - if (burned && !one_burned && hb_subtitle_can_burn(source)) - { - // Only allow one subtitle to be burned into the video - one_burned = TRUE; - } - else - { - burned = FALSE; - } - - subtitle_dict = json_pack_ex(&error, 0, - "{s:o, s:o, s:o, s:o}", - "Track", hb_value_int(track), - "Default", hb_value_bool(def), - "Forced", hb_value_bool(force), - "Burn", hb_value_bool(burned)); - if (subtitle_dict == NULL) - { - g_warning("json pack subtitle failure: %s", error.text); - return; - } - hb_value_array_append(json_subtitle_list, subtitle_dict); - } - } + GhbValue *subtitle_dict = ghb_get_subtitle_settings(js); + hb_dict_set(dict, "Subtitle", ghb_value_dup(subtitle_dict)); char *json_job = hb_value_get_json(dict); hb_value_free(&dict); diff --git a/gtk/src/internal_defaults.json b/gtk/src/internal_defaults.json index d4a24ab15..4803c49a4 100644 --- a/gtk/src/internal_defaults.json +++ b/gtk/src/internal_defaults.json @@ -55,7 +55,12 @@ "volume_label": "New Video", "audio_list": [], "chapter_list": [], - "subtitle_list": [], + "Subtitle": { + "Search": { + "Enable": false + }, + "SubtitleList": [] + }, "vquality_type_bitrate": false, "vquality_type_constant": false, "SrtLanguage": "und", diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c index dcac384f0..19fce60d1 100644 --- a/gtk/src/queuehandler.c +++ b/gtk/src/queuehandler.c @@ -22,6 +22,7 @@ #include "callbacks.h" #include "presets.h" #include "audiohandler.h" +#include "subtitlehandler.h" #include "ghb-dvd.h" #include "plist.h" @@ -597,17 +598,38 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter // Subtitle Tracks: count // Subtitle description(Subtitle options) // ... - const GhbValue *sub_list; + const GhbValue *sub_settings, *sub_list, *sub_search; + gboolean search; - sub_list = ghb_dict_get_value(settings, "subtitle_list"); + sub_settings = ghb_get_subtitle_settings(settings); + sub_list = ghb_dict_get(sub_settings, "SubtitleList"); + sub_search = ghb_dict_get(sub_settings, "Search"); + search = ghb_dict_get_bool(sub_search, "Enable"); count = ghb_array_len(sub_list); - if (count == 1) + if (count + search == 1) { XPRINT(_("<b>Subtitle:</b> ")); } - else if (count > 1) + else if (count + search > 1) { - XPRINT(_("<b>Subtitle Tracks: %d</b>\n"), count); + XPRINT(_("<b>Subtitle Tracks: %d</b>\n"), count + search); + } + if (search) + { + const gchar *track; + gboolean force, burn, def; + + track = ghb_dict_get_string(sub_search, "Description"); + force = ghb_dict_get_bool(sub_search, "Forced"); + burn = ghb_dict_get_bool(sub_search, "Burn"); + def = ghb_dict_get_bool(sub_search, "Default"); + if (count + search > 1) + XPRINT("\t"); + XPRINT("<small>%s%s%s%s</small>\n", track, + force ? _(" (Forced Only)") : "", + burn ? _(" (Burn)") : "", + def ? _(" (Default)") : "" + ); } for (ii = 0; ii < count; ii++) { @@ -617,32 +639,34 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter gint source; settings = ghb_array_get(sub_list, ii); - track = ghb_dict_get_string(settings, "SubtitleTrackDescription"); - source = ghb_dict_get_int(settings, "SubtitleSource"); - force = ghb_dict_get_bool(settings, "SubtitleForced"); - burn = ghb_dict_get_bool(settings, "SubtitleBurned"); - def = ghb_dict_get_bool(settings, "SubtitleDefaultTrack"); - if (count > 1) + track = ghb_dict_get_string(settings, "Description"); + source = ghb_dict_get_int(settings, "Source"); + force = ghb_dict_get_bool(settings, "Forced"); + burn = ghb_dict_get_bool(settings, "Burn"); + def = ghb_dict_get_bool(settings, "Default"); + if (count + search > 1) XPRINT("\t"); if (source != SRTSUB) { XPRINT("<small>%s%s%s%s</small>\n", track, - force ? _(" (Force)"):"", - burn ? _(" (Burn)"):"", - def ? _(" (Default)"):"" + force ? _(" (Forced Only)") : "", + burn ? _(" (Burn)") : "", + def ? _(" (Default)") : "" ); } else { + GhbValue *srt; gint offset; const gchar *filename, *code; gchar *basename; - offset = ghb_dict_get_int(settings, "SrtOffset"); - filename = ghb_dict_get_string(settings, "SrtFile"); + srt = ghb_dict_get(settings, "SRT"); + offset = ghb_dict_get_int(settings, "Offset"); + filename = ghb_dict_get_string(srt, "File"); basename = g_path_get_basename(filename); - code = ghb_dict_get_string(settings, "SrtCodeset"); + code = ghb_dict_get_string(srt, "Codeset"); XPRINT(_("<small> %s (%s), %s, Offset (ms) %d%s</small>\n"), track, code, basename, offset, def ? " (Default)":""); diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c index 33e9e106a..6d137757b 100644 --- a/gtk/src/subtitlehandler.c +++ b/gtk/src/subtitlehandler.c @@ -23,11 +23,63 @@ #include "audiohandler.h" #include "subtitlehandler.h" +static void subtitle_list_refresh_selected(signal_user_data_t *ud, + GhbValue *subsettings); static void subtitle_add_to_settings(GhbValue *settings, GhbValue *subsettings); -static void ghb_add_subtitle_to_ui(signal_user_data_t *ud, GhbValue *subsettings); +static void add_subtitle_to_ui(signal_user_data_t *ud, GhbValue *subsettings); static void add_to_subtitle_list_ui(signal_user_data_t *ud, GhbValue *settings); -static void ghb_clear_subtitle_list_settings(GhbValue *settings); -static void ghb_clear_subtitle_list_ui(GtkBuilder *builder); +static void clear_subtitle_list_settings(GhbValue *settings); +static void clear_subtitle_list_ui(GtkBuilder *builder); + +static GhbValue *get_sub_settings(GhbValue *settings) +{ + GhbValue *sub; + sub = ghb_dict_get(settings, "Subtitle"); + if (sub == NULL) + { + sub = ghb_dict_new(); + ghb_dict_set(settings, "Subtitle", sub); + } + return sub; +} + +GhbValue *ghb_get_subtitle_settings(GhbValue *settings) +{ + return get_sub_settings(settings); +} + + +static GhbValue *get_sub_list(GhbValue *settings) +{ + GhbValue *sub_dict, *sub_list = NULL; + sub_dict = get_sub_settings(settings); + sub_list = ghb_dict_get(sub_dict, "SubtitleList"); + if (sub_list == NULL) + { + sub_list = ghb_array_new(); + ghb_dict_set(sub_dict, "SubtitleList", sub_list); + } + return sub_list; +} + +GhbValue *ghb_get_subtitle_list(GhbValue *settings) +{ + return get_sub_list(settings); +} + +static GhbValue *get_sub_search(GhbValue *settings) +{ + GhbValue *sub_dict, *sub_search = NULL; + sub_dict = get_sub_settings(settings); + sub_search = ghb_dict_get(sub_dict, "Search"); + if (sub_search == NULL) + { + sub_search = ghb_dict_new(); + ghb_dict_set(sub_dict, "Search", sub_search); + ghb_dict_set_bool(sub_search, "Enable", 0); + } + return sub_search; +} static void subtitle_refresh_list_row_ui( @@ -44,15 +96,15 @@ subtitle_refresh_list_row_ui( info_src_2 = NULL; info_dst_2 = NULL; - forced = ghb_dict_get_bool(subsettings, "SubtitleForced"); - burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); - def = ghb_dict_get_bool(subsettings, "SubtitleDefaultTrack"); + forced = ghb_dict_get_bool(subsettings, "Forced"); + burned = ghb_dict_get_bool(subsettings, "Burn"); + def = ghb_dict_get_bool(subsettings, "Default"); info_src = g_strdup_printf("<small>%s</small>", - ghb_dict_get_string(subsettings, "SubtitleTrackDescription")); - if (ghb_dict_get_int(subsettings, "SubtitleSource") == SRTSUB) + ghb_dict_get_string(subsettings, "Description")); + if (ghb_dict_get_int(subsettings, "Source") == SRTSUB) { gint offset; - offset = ghb_dict_get_int(subsettings, "SrtOffset"); + offset = ghb_dict_get_int(subsettings, "Offset"); if (offset != 0) { info_dst_2 = g_strdup_printf("Offset: %dms", offset); @@ -119,32 +171,43 @@ subtitle_refresh_list_row_ui( 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; + GhbValue *subtitle_list, *subtitle_search; + GhbValue *subsettings; + gint ii, count, tm_count; + gboolean search; 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"); + subtitle_list = get_sub_list(settings); + subtitle_search = get_sub_search(settings); + search = ghb_dict_get_bool(subtitle_search, "Enable"); count = ghb_array_len(subtitle_list); - if (count != tm_count) + if (count + search != tm_count) { - ghb_clear_subtitle_list_ui(ud->builder); - for (ii = 0; ii < count; ii++) + clear_subtitle_list_ui(ud->builder); + for (ii = 0; ii < count + search; ii++) { gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL); } } + // Enable or Disabel FAS button + GtkWidget *w = GHB_WIDGET(ud->builder, "subtitle_add_fas"); + gtk_widget_set_sensitive(w, !search); + if (search) + { + + gtk_tree_model_iter_nth_child(tm, &ti, NULL, 0); + subtitle_refresh_list_row_ui(tm, &ti, subtitle_search); + } for (ii = 0; ii < count; ii++) { - g_return_if_fail(tv != NULL); - gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii); + gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii + search); subsettings = ghb_array_get(subtitle_list, ii); subtitle_refresh_list_row_ui(tm, &ti, subsettings); } @@ -156,81 +219,60 @@ subtitle_refresh_list_ui(signal_user_data_t *ud) subtitle_refresh_list_ui_from_settings(ud, ud->settings); } -void -ghb_subtitle_exclusive_burn_settings(GhbValue *settings, gint index) +static void +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; - } - } + subtitle_list = get_sub_list(settings); 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); - } + ghb_dict_set_bool(subsettings, "Burn", FALSE); } } } -void -ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint index) +static void +subtitle_exclusive_burn(signal_user_data_t *ud, gint index) { - ghb_subtitle_exclusive_burn_settings(ud->settings, index); + subtitle_exclusive_burn_settings(ud->settings, index); subtitle_refresh_list_ui(ud); } -void -ghb_subtitle_exclusive_default_settings(GhbValue *settings, gint index) +static void +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"); + subtitle_list = get_sub_list(settings); 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); + ghb_dict_set_bool(subtitle, "Default", FALSE); } } } -void -ghb_subtitle_exclusive_default(signal_user_data_t *ud, gint index) +static void +subtitle_exclusive_default(signal_user_data_t *ud, gint index) { - ghb_subtitle_exclusive_default_settings(ud->settings, index); + subtitle_exclusive_default_settings(ud->settings, index); subtitle_refresh_list_ui(ud); } static void -ghb_add_subtitle_to_ui(signal_user_data_t *ud, GhbValue *subsettings) +add_subtitle_to_ui(signal_user_data_t *ud, GhbValue *subsettings) { if (subsettings == NULL) return; @@ -246,14 +288,14 @@ subtitle_add_to_settings(GhbValue *settings, GhbValue *subsettings) // Add the current subtitle settings to the list. GhbValue *subtitle_list; gint count; - gboolean burned, forced, def; + gboolean burn, forced, def; gint source; - subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); + subtitle_list = get_sub_list(settings); if (subtitle_list == NULL) { - subtitle_list = ghb_array_new(); - ghb_dict_set(settings, "subtitle_list", subtitle_list); + g_warning("No subtitle list!"); + return; } // Validate some settings @@ -263,35 +305,35 @@ subtitle_add_to_settings(GhbValue *settings, GhbValue *subsettings) mux_id = ghb_dict_get_string(settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); - source = ghb_dict_get_int(subsettings, "SubtitleSource"); - burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); - if (burned && !hb_subtitle_can_burn(source)) + source = ghb_dict_get_int(subsettings, "Source"); + burn = ghb_dict_get_bool(subsettings, "Burn"); + if (burn && !hb_subtitle_can_burn(source)) { - burned = FALSE; - ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); + burn = FALSE; + ghb_dict_set_bool(subsettings, "Burn", burn); } - if (!burned && !hb_subtitle_can_pass(source, mux->format)) + if (!burn && !hb_subtitle_can_pass(source, mux->format)) { - burned = TRUE; - ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); - ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", FALSE); + burn = TRUE; + ghb_dict_set_bool(subsettings, "Burn", burn); + ghb_dict_set_bool(subsettings, "Default", FALSE); } - def = ghb_dict_get_bool(subsettings, "SubtitleDefaultTrack"); - forced = ghb_dict_get_bool(subsettings, "SubtitleForced"); + def = ghb_dict_get_bool(subsettings, "Default"); + forced = ghb_dict_get_bool(subsettings, "Forced"); if (forced && !hb_subtitle_can_force(source)) { forced = FALSE; - ghb_dict_set_bool(subsettings, "SubtitleForced", forced); + ghb_dict_set_bool(subsettings, "Forced", forced); } ghb_array_append(subtitle_list, subsettings); // Check consistancy of exclusive flags count = ghb_array_len(subtitle_list); - if (burned) - ghb_subtitle_exclusive_burn_settings(settings, count-1); + if (burn) + subtitle_exclusive_burn_settings(settings, count-1); if (def) - ghb_subtitle_exclusive_default_settings(settings, count-1); + subtitle_exclusive_default_settings(settings, count-1); } static void @@ -299,15 +341,27 @@ subtitle_set_track_description(GhbValue *settings, GhbValue *subsettings) { char *desc = NULL; - if (ghb_dict_get_int(subsettings, "SubtitleSource") == SRTSUB) + if (ghb_dict_get_int(subsettings, "Source") == SRTSUB) { + GhbValue *srt; const gchar *filename, *code; const gchar *lang; + const iso639_lang_t *iso; - lang = ghb_settings_combo_option(subsettings, "SrtLanguage"); - code = ghb_dict_get_string(subsettings, "SrtCodeset"); + srt = ghb_dict_get(subsettings, "SRT"); + lang = ghb_dict_get_string(srt, "Language"); + code = ghb_dict_get_string(srt, "Codeset"); + filename = ghb_dict_get_string(srt, "Filename"); + + iso = lang_lookup(lang); + if (iso != NULL) + { + if (iso->native_name != NULL) + lang = iso->native_name; + else + lang = iso->eng_name; + } - filename = ghb_dict_get_string(subsettings, "SrtFile"); if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { gchar *basename; @@ -327,11 +381,13 @@ subtitle_set_track_description(GhbValue *settings, GhbValue *subsettings) const hb_title_t *title; int track; hb_subtitle_t *subtitle; + GhbValue *val; title_id = ghb_dict_get_int(settings, "title"); title = ghb_lookup_title(title_id, &titleindex); - track = ghb_dict_get_int(subsettings, "SubtitleTrack"); - if (track < 0) + val = ghb_dict_get(subsettings, "Track"); + track = ghb_dict_get_int(subsettings, "Track"); + if (val == NULL || track < 0) { desc = g_strdup(_("Foreign Audio Search")); } @@ -349,13 +405,11 @@ subtitle_set_track_description(GhbValue *settings, GhbValue *subsettings) if (desc != NULL) { - ghb_dict_set_string( - subsettings, "SubtitleTrackDescription", desc); + ghb_dict_set_string(subsettings, "Description", desc); } else { - ghb_dict_set_string( - subsettings, "SubtitleTrackDescription", "Error!"); + ghb_dict_set_string(subsettings, "Description", "Error!"); } g_free(desc); @@ -393,60 +447,43 @@ static GhbValue* subtitle_add_track( } GhbValue *subsettings = ghb_dict_new(); - ghb_dict_set_int(subsettings, "SubtitleTrack", track); - ghb_dict_set_int(subsettings, "SubtitleSource", source); - - // Set default SRT settings - const gchar *pref_lang, *dir; - gchar *filename; + if (srt) + { + // Set default SRT settings + GhbValue *srt_dict; + const gchar *pref_lang, *dir; + gchar *filename; - pref_lang = ghb_dict_get_string(settings, "PreferredLanguage"); - ghb_dict_set_string(subsettings, "SrtLanguage", pref_lang); + srt_dict = ghb_dict_new(); + hb_dict_set(subsettings, "SRT", srt_dict); - ghb_dict_set_string(subsettings, "SrtCodeset", "UTF-8"); + pref_lang = ghb_dict_get_string(settings, "PreferredLanguage"); + ghb_dict_set_string(srt_dict, "Language", pref_lang); + ghb_dict_set_string(srt_dict, "Codeset", "UTF-8"); - dir = ghb_dict_get_string(ud->prefs, "SrtDir"); - filename = g_strdup_printf("%s/none", dir); - ghb_dict_set_string(subsettings, "SrtFile", filename); - g_free(filename); + dir = ghb_dict_get_string(ud->prefs, "SrtDir"); + filename = g_strdup_printf("%s/none", dir); + ghb_dict_set_string(srt_dict, "Filename", filename); + g_free(filename); + } - ghb_dict_set_int(subsettings, "SrtOffset", 0); + ghb_dict_set_int(subsettings, "Track", track); + ghb_dict_set_int(subsettings, "Source", source); + ghb_dict_set_int(subsettings, "Offset", 0); + ghb_dict_set_bool(subsettings, "Forced", track == -1); + ghb_dict_set_bool(subsettings, "Default", default_track); + ghb_dict_set_bool(subsettings, "Burn", burn); + if (burn && 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. + *burned = TRUE; + } subtitle_set_track_description(settings, subsettings); - if (burn) - { - ghb_dict_set_bool(subsettings, "SubtitleBurned", TRUE); - 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. - *burned = TRUE; - } - } - else - { - ghb_dict_set_bool(subsettings, "SubtitleBurned", FALSE); - } - if (track == -1) - { - // Foreign audio search "track" - ghb_dict_set_bool(subsettings, "SubtitleForced", TRUE); - } - else - { - ghb_dict_set_bool(subsettings, "SubtitleForced", FALSE); - } - if (default_track) - { - ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", TRUE); - } - else - { - ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", FALSE); - } subtitle_add_to_settings(settings, subsettings); return subsettings; @@ -489,7 +526,7 @@ ghb_set_pref_subtitle_settings(signal_user_data_t *ud, const hb_title_t *title, behavior = ghb_settings_combo_int(settings, "SubtitleTrackSelectionBehavior"); // Clear the subtitle list - ghb_clear_subtitle_list_settings(settings); + clear_subtitle_list_settings(settings); if (title == NULL) { @@ -570,8 +607,13 @@ ghb_set_pref_subtitle_settings(signal_user_data_t *ud, const hb_title_t *title, { // 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); + GhbValue *subtitle_search = get_sub_search(settings); + + ghb_dict_set_bool(subtitle_search, "Enable", 1); + ghb_dict_set_bool(subtitle_search, "Forced", 1); + ghb_dict_set_bool(subtitle_search, "Default", !burn); + ghb_dict_set_bool(subtitle_search, "Burn", burn); + subtitle_set_track_description(settings, subtitle_search); burn_first &= !burn; } @@ -638,11 +680,11 @@ ghb_set_pref_subtitle(const hb_title_t *title, signal_user_data_t *ud) int sub_count; GtkWidget *widget; - ghb_clear_subtitle_list_ui(ud->builder); + clear_subtitle_list_ui(ud->builder); if (title == NULL) { // Clear the subtitle list - ghb_clear_subtitle_list_settings(ud->settings); + clear_subtitle_list_settings(ud->settings); return; } sub_count = hb_list_count(title->list_subtitle); @@ -672,7 +714,6 @@ ghb_selected_subtitle_row(signal_user_data_t *ud) gint *indices; gint row = -1; - g_debug("ghb_selected_subtitle_row ()"); 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)) @@ -690,29 +731,41 @@ 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)) { + GhbValue *subtitle_list, *subtitle_search; + gboolean search; + gint row, *indices; + GtkTreePath *tp; + // 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)) + subtitle_search = get_sub_search(ud->settings); + search = ghb_dict_get_bool(subtitle_search, "Enable"); + if (search) + { + if (row == 0) + { + if (index != NULL) + *index = -1; + return subtitle_search; + } + row--; + } + + subtitle_list = get_sub_list(ud->settings); + if (row < 0 || row >= ghb_array_len(subtitle_list)) return NULL; subsettings = ghb_array_get(subtitle_list, row); @@ -730,6 +783,7 @@ subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) if (subsettings != NULL) { // Update widgets with subsettings + GhbValue *val; gboolean burn, force, def; const char *mux_id; @@ -738,17 +792,52 @@ subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) mux_id = ghb_dict_get_string(ud->settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); - int source = ghb_dict_get_int(subsettings, "SubtitleSource"); + int source = ghb_dict_get_int(subsettings, "Source"); + + val = ghb_dict_get(subsettings, "Track"); + if (val != NULL) + { + ghb_ui_update(ud, "SubtitleTrack", val); + + // Hide regular subtitle widgets + widget = GHB_WIDGET(ud->builder, "subtitle_track_box"); + gtk_widget_set_visible(widget, source != SRTSUB); + + // Show SRT subitle widgets + widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid"); + gtk_widget_set_visible(widget, source == SRTSUB); + + widget = GHB_WIDGET(ud->builder, "subtitle_srt_switch_box"); + gtk_widget_set_visible(widget, TRUE); + } + else + { + // Hide widgets not needed for "Foreign audio search" + widget = GHB_WIDGET(ud->builder, "subtitle_track_box"); + gtk_widget_set_visible(widget, FALSE); + + widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid"); + gtk_widget_set_visible(widget, FALSE); - ghb_ui_update_from_settings(ud, "SubtitleTrack", subsettings); - ghb_ui_update_from_settings(ud, "SrtLanguage", subsettings); - ghb_ui_update_from_settings(ud, "SrtCodeset", subsettings); - ghb_ui_update_from_settings(ud, "SrtFile", subsettings); - ghb_ui_update_from_settings(ud, "SrtOffset", subsettings); + widget = GHB_WIDGET(ud->builder, "subtitle_srt_switch_box"); + gtk_widget_set_visible(widget, FALSE); + } if (source == SRTSUB) { + GhbValue *srt; + + srt = ghb_dict_get(subsettings, "SRT"); + ghb_ui_update(ud, "SubtitleSrtEnable", ghb_boolean_value(TRUE)); + val = ghb_dict_get(srt, "Language"); + ghb_ui_update(ud, "SrtLanguage", val); + val = ghb_dict_get(srt, "Codeset"); + ghb_ui_update(ud, "SrtCodeset", val); + val = ghb_dict_get(srt, "Filename"); + ghb_ui_update(ud, "SrtFile", val); + val = ghb_dict_get(subsettings, "Offset"); + ghb_ui_update(ud, "SrtOffset", val); } else { @@ -757,16 +846,18 @@ subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) widget = GHB_WIDGET(ud->builder, "SubtitleBurned"); gtk_widget_set_sensitive(widget, hb_subtitle_can_burn(source) && - hb_subtitle_can_pass(source, mux->format)); + hb_subtitle_can_pass(source, mux->format)); + widget = GHB_WIDGET(ud->builder, "SubtitleForced"); gtk_widget_set_sensitive(widget, hb_subtitle_can_force(source)); + widget = GHB_WIDGET(ud->builder, "SubtitleDefaultTrack"); gtk_widget_set_sensitive(widget, - hb_subtitle_can_pass(source, mux->format)); + hb_subtitle_can_pass(source, mux->format)); - burn = ghb_dict_get_int(subsettings, "SubtitleBurned"); - force = ghb_dict_get_int(subsettings, "SubtitleForced"); - def = ghb_dict_get_int(subsettings, "SubtitleDefaultTrack"); + burn = ghb_dict_get_bool(subsettings, "Burn"); + force = ghb_dict_get_bool(subsettings, "Forced"); + def = ghb_dict_get_bool(subsettings, "Default"); if (!hb_subtitle_can_burn(source)) { @@ -781,20 +872,13 @@ subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) def = FALSE; burn = TRUE; } - ghb_dict_set_bool(subsettings, "SubtitleBurned", burn); + ghb_dict_set_bool(subsettings, "Burn", burn); + ghb_dict_set_bool(subsettings, "Forced", force); + ghb_dict_set_bool(subsettings, "Default", def); ghb_ui_update(ud, "SubtitleBurned", ghb_boolean_value(burn)); - ghb_dict_set_bool(subsettings, "SubtitleForced", force); ghb_ui_update(ud, "SubtitleForced", ghb_boolean_value(force)); - ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", def); ghb_ui_update(ud, "SubtitleDefaultTrack", ghb_boolean_value(def)); - // Hide regular subtitle widgets - widget = GHB_WIDGET(ud->builder, "subtitle_track_box"); - gtk_widget_set_visible(widget, source != SRTSUB); - - // Show SRT subitle widgets - widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid"); - gtk_widget_set_visible(widget, source == SRTSUB); } else { @@ -809,16 +893,16 @@ subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) } static GhbValue* -subtitle_update_setting(GtkWidget *widget, signal_user_data_t *ud) +subtitle_update_setting(GhbValue *val, const char *name, signal_user_data_t *ud) { GhbValue *subsettings; - ghb_widget_to_setting(ud->settings, widget); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { - ghb_widget_to_setting(subsettings, widget); - ghb_subtitle_list_refresh_selected(ud); + ghb_dict_set(subsettings, name, val); + subtitle_set_track_description(ud->settings, subsettings); + subtitle_list_refresh_selected(ud, subsettings); ghb_live_reset(ud); } return subsettings; @@ -829,28 +913,26 @@ subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { GhbValue *subsettings; - g_debug("subtitle_track_changed_cb()"); ghb_widget_to_setting(ud->settings, widget); - subsettings = subtitle_get_selected_settings(ud, NULL); + + int track = ghb_dict_get_int(ud->settings, "SubtitleTrack"); + subsettings = subtitle_update_setting(ghb_int_value_new(track), + "Track", ud); if (subsettings != NULL) { - gint track, source; - - ghb_widget_to_setting(subsettings, widget); - track = ghb_dict_get_int(subsettings, "SubtitleTrack"); - source = ghb_subtitle_track_source(ud->settings, track); - ghb_dict_set_int(subsettings, "SubtitleSource", source); + int source = ghb_subtitle_track_source(ud->settings, track); + ghb_dict_set_int(subsettings, "Source", source); subtitle_set_track_description(ud->settings, subsettings); subtitle_update_dialog_widgets(ud, subsettings); - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); } } G_MODULE_EXPORT void subtitle_forced_toggled_cb(GtkWidget *widget, signal_user_data_t *ud) { - subtitle_update_setting(widget, ud); + ghb_widget_to_setting(ud->settings, widget); + GhbValue *val = ghb_widget_value(widget); + subtitle_update_setting(ghb_value_dup(val), "Forced", ud); } G_MODULE_EXPORT void @@ -860,17 +942,16 @@ subtitle_burned_toggled_cb(GtkWidget *widget, signal_user_data_t *ud) int index; ghb_widget_to_setting(ud->settings, widget); + GhbValue *val = ghb_widget_value(widget); + subtitle_update_setting(ghb_value_dup(val), "Burn", ud); subsettings = subtitle_get_selected_settings(ud, &index); if (subsettings != NULL) { - ghb_widget_to_setting(subsettings, widget); - if (ghb_dict_get_bool(subsettings, "SubtitleBurned")) + if (ghb_dict_get_bool(subsettings, "Burn")) { ghb_ui_update(ud, "SubtitleDefaultTrack", ghb_boolean_value(FALSE)); - ghb_subtitle_exclusive_burn(ud, index); + subtitle_exclusive_burn(ud, index); } - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); } } @@ -881,17 +962,16 @@ subtitle_default_toggled_cb(GtkWidget *widget, signal_user_data_t *ud) int index; ghb_widget_to_setting(ud->settings, widget); + GhbValue *val = ghb_widget_value(widget); + subtitle_update_setting(ghb_value_dup(val), "Default", ud); subsettings = subtitle_get_selected_settings(ud, &index); if (subsettings != NULL) { - ghb_widget_to_setting(subsettings, widget); - if (ghb_dict_get_bool(subsettings, "SubtitleDefaultTrack")) + if (ghb_dict_get_bool(subsettings, "Default")) { ghb_ui_update(ud, "SubtitleBurned", ghb_boolean_value(FALSE)); - ghb_subtitle_exclusive_default(ud, index); + subtitle_exclusive_default(ud, index); } - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); } } @@ -906,53 +986,51 @@ subtitle_srt_radio_toggled_cb(GtkWidget *widget, signal_user_data_t *ud) { if (ghb_dict_get_bool(ud->settings, "SubtitleSrtEnable")) { - ghb_dict_set_int(subsettings, "SubtitleSource", SRTSUB); + const gchar *pref_lang, *dir; + gchar *filename; + GhbValue *srt = ghb_dict_new(); + + ghb_dict_set(subsettings, "SRT", srt); + pref_lang = ghb_dict_get_string(ud->settings, "PreferredLanguage"); + ghb_dict_set_string(srt, "Language", pref_lang); + ghb_dict_set_string(srt, "Codeset", "UTF-8"); + + dir = ghb_dict_get_string(ud->prefs, "SrtDir"); + filename = g_strdup_printf("%s/none", dir); + ghb_dict_set_string(srt, "Filename", filename); + g_free(filename); + + ghb_dict_set_int(subsettings, "Source", SRTSUB); } else { int track, source; - track = ghb_dict_get_int(subsettings, "SubtitleTrack"); + ghb_dict_remove(subsettings, "SRT"); + + track = ghb_dict_get_int(subsettings, "Track"); source = ghb_subtitle_track_source(ud->settings, track); - ghb_dict_set_int(subsettings, "SubtitleSource", source); + ghb_dict_set_int(subsettings, "Source", source); } subtitle_set_track_description(ud->settings, subsettings); subtitle_update_dialog_widgets(ud, subsettings); - ghb_subtitle_list_refresh_selected(ud); + subtitle_list_refresh_selected(ud, subsettings); ghb_live_reset(ud); } } void -ghb_subtitle_list_refresh_selected(signal_user_data_t *ud) +subtitle_list_refresh_selected(signal_user_data_t *ud, GhbValue *subsettings) { GtkTreeView *tv; - GtkTreeModel *tm; - GtkTreePath *tp; GtkTreeSelection *ts; + GtkTreeModel *tm; 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); } } @@ -964,89 +1042,90 @@ ghb_subtitle_list_refresh_all(signal_user_data_t *ud) } G_MODULE_EXPORT void -srt_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +srt_setting_update(GhbValue *val, const char *name, signal_user_data_t *ud) { GhbValue *subsettings; - - g_debug("srt_changed_cb()"); - ghb_check_dependency(ud, widget, NULL); - ghb_widget_to_setting(ud->settings, widget); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { - ghb_widget_to_setting(subsettings, widget); - subtitle_set_track_description(ud->settings, subsettings); - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); + GhbValue *srt; + srt = ghb_dict_get(subsettings, "SRT"); + if (srt != NULL) + { + ghb_dict_set(srt, name, val); + subtitle_set_track_description(ud->settings, subsettings); + subtitle_list_refresh_selected(ud, subsettings); + ghb_live_reset(ud); + } } } G_MODULE_EXPORT void -srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +srt_offset_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { - GhbValue *subsettings; + ghb_widget_to_setting(ud->settings, widget); + ghb_check_dependency(ud, widget, NULL); + + int64_t offset = ghb_dict_get_int(ud->settings, "SrtOffset"); + srt_setting_update(ghb_int_value_new(offset), "Offset", ud); +} - g_debug("srt_file_changed_cb()"); +G_MODULE_EXPORT void +srt_codeset_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + ghb_widget_to_setting(ud->settings, widget); ghb_check_dependency(ud, widget, NULL); + + GhbValue *val = ghb_dict_get(ud->settings, "SrtCodeset"); + srt_setting_update(ghb_value_dup(val), "Codeset", ud); +} + +G_MODULE_EXPORT void +srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ ghb_widget_to_setting(ud->settings, widget); - subsettings = subtitle_get_selected_settings(ud, NULL); - if (subsettings != NULL) - { - const gchar *filename; - gchar *dirname; + ghb_check_dependency(ud, widget, NULL); - ghb_widget_to_setting(subsettings, widget); - subtitle_set_track_description(ud->settings, subsettings); - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); + GhbValue *val = ghb_dict_get(ud->settings, "SrtFile"); + srt_setting_update(ghb_value_dup(val), "Filename", ud); - // Update SrtDir preference - filename = ghb_dict_get_string(subsettings, "SrtFile"); - if (g_file_test(filename, G_FILE_TEST_IS_DIR)) - { - ghb_dict_set_string(ud->prefs, "SrtDir", filename); - } - else - { - dirname = g_path_get_dirname(filename); - ghb_dict_set_string(ud->prefs, "SrtDir", dirname); - g_free(dirname); - } - ghb_pref_save(ud->prefs, "SrtDir"); + // Update SrtDir preference + const gchar *filename; + gchar *dirname; + + filename = ghb_value_get_string(val); + if (g_file_test(filename, G_FILE_TEST_IS_DIR)) + { + ghb_dict_set_string(ud->prefs, "SrtDir", filename); } + else + { + dirname = g_path_get_dirname(filename); + ghb_dict_set_string(ud->prefs, "SrtDir", dirname); + g_free(dirname); + } + ghb_pref_save(ud->prefs, "SrtDir"); } G_MODULE_EXPORT void srt_lang_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { - GhbValue *subsettings; - - g_debug("srt_lang_changed_cb()"); - ghb_check_dependency(ud, widget, NULL); ghb_widget_to_setting(ud->settings, widget); - subsettings = subtitle_get_selected_settings(ud, NULL); - if (subsettings != NULL) - { - ghb_widget_to_setting(subsettings, widget); - subtitle_set_track_description(ud->settings, subsettings); - ghb_subtitle_list_refresh_selected(ud); - ghb_live_reset(ud); - } + ghb_check_dependency(ud, widget, NULL); + + GhbValue *val = ghb_dict_get(ud->settings, "SrtLanguage"); + srt_setting_update(ghb_value_dup(val), "Language", ud); } static void -ghb_clear_subtitle_list_settings(GhbValue *settings) +clear_subtitle_list_settings(GhbValue *settings) { - GhbValue *subtitle_list; + GhbValue *subtitle_list, *subtitle_search; - subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); - if (subtitle_list == NULL) - { - subtitle_list = ghb_array_new(); - ghb_dict_set(settings, "subtitle_list", subtitle_list); - } - else - ghb_array_reset(subtitle_list); + subtitle_list = get_sub_list(settings); + subtitle_search = get_sub_search(settings); + ghb_array_reset(subtitle_list); + ghb_dict_set_bool(subtitle_search, "Enable", 0); } void @@ -1063,7 +1142,7 @@ ghb_clear_subtitle_selection(GtkBuilder *builder) } static void -ghb_clear_subtitle_list_ui(GtkBuilder *builder) +clear_subtitle_list_ui(GtkBuilder *builder) { GtkTreeView *tv; GtkTreeStore *ts; @@ -1101,14 +1180,11 @@ subtitle_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud) { GtkTreeModel *tm; GtkTreeIter iter; - GhbValue *subsettings = NULL; - int row; + GhbValue *subsettings; - 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; @@ -1122,28 +1198,9 @@ subtitle_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud) 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); } + subsettings = subtitle_get_selected_settings(ud, NULL); subtitle_update_dialog_widgets(ud, subsettings); - if (subsettings) - { - if (ghb_dict_get_bool(subsettings, "SubtitleBurned")) - { - ghb_subtitle_exclusive_burn(ud, row); - } - } } static gboolean subtitle_is_one_burned(GhbValue *settings) @@ -1151,7 +1208,7 @@ static gboolean subtitle_is_one_burned(GhbValue *settings) GhbValue *subtitle_list, *subsettings; int count, ii; - subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); + subtitle_list = get_sub_list(settings); if (subtitle_list == NULL) return FALSE; @@ -1159,7 +1216,7 @@ static gboolean subtitle_is_one_burned(GhbValue *settings) for (ii = 0; ii < count; ii++) { subsettings = ghb_array_get(subtitle_list, ii); - if (ghb_dict_get_bool(subsettings, "SubtitleBurned")) + if (ghb_dict_get_bool(subsettings, "Burn")) { return TRUE; } @@ -1186,9 +1243,7 @@ subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) } // Back up settings in case we need to revert. - backup = ghb_value_dup( - ghb_dict_get_value(ud->settings, "subtitle_list")); - + backup = ghb_value_dup(get_sub_settings(ud->settings)); one_burned = subtitle_is_one_burned(ud->settings); const char *mux_id; @@ -1209,10 +1264,10 @@ subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) subsettings = subtitle_add_track(ud, ud->settings, title, 0, mux->format, FALSE, TRUE, FALSE, &one_burned); } - ghb_add_subtitle_to_ui(ud, subsettings); - if (subsettings != NULL) { + add_subtitle_to_ui(ud, subsettings); + // Pop up the edit dialog GtkResponseType response; GtkWidget *dialog = GHB_WIDGET(ud->builder, "subtitle_dialog"); @@ -1220,12 +1275,8 @@ subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) gtk_widget_hide(dialog); if (response != GTK_RESPONSE_OK) { - ghb_dict_set(ud->settings, "subtitle_list", backup); - subsettings = subtitle_get_selected_settings(ud, NULL); - if (subsettings != NULL) - { - subtitle_update_dialog_widgets(ud, subsettings); - } + ghb_clear_subtitle_selection(ud->builder); + ghb_dict_set(ud->settings, "Subtitle", backup); subtitle_refresh_list_ui(ud); } else @@ -1236,6 +1287,62 @@ subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) } G_MODULE_EXPORT void +subtitle_add_fas_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) +{ + GhbValue *subtitle_search, *backup; + + subtitle_search = get_sub_search(ud->settings); + if (ghb_dict_get_bool(subtitle_search, "Enable")) + { + // Foreign audio search is already enabled + return; + } + + backup = ghb_value_dup(get_sub_settings(ud->settings)); + + ghb_dict_set_bool(subtitle_search, "Enable", 1); + ghb_dict_set_bool(subtitle_search, "Forced", 1); + ghb_dict_set_bool(subtitle_search, "Default", 1); + ghb_dict_set_bool(subtitle_search, "Burn", 0); + + subtitle_set_track_description(ud->settings, subtitle_search); + + GtkTreeView *tv; + GtkTreeIter ti; + GtkTreeModel *tm; + GtkTreeSelection *ts; + + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list_view")); + ts = gtk_tree_view_get_selection(tv); + tm = gtk_tree_view_get_model(tv); + + gtk_tree_store_prepend(GTK_TREE_STORE(tm), &ti, NULL); + subtitle_refresh_list_row_ui(tm, &ti, subtitle_search); + + gtk_tree_selection_select_iter(ts, &ti); + ghb_live_reset(ud); + + GtkResponseType response; + GtkWidget *dialog = GHB_WIDGET(ud->builder, "subtitle_dialog"); + response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_hide(dialog); + if (response != GTK_RESPONSE_OK) + { + ghb_clear_subtitle_selection(ud->builder); + ghb_dict_set(ud->settings, "Subtitle", backup); + subtitle_refresh_list_ui(ud); + } + else + { + // Disabel FAS button + GtkWidget *w = GHB_WIDGET(ud->builder, "subtitle_add_fas"); + gtk_widget_set_sensitive(w, 0); + + ghb_value_free(&backup); + } +} + +G_MODULE_EXPORT void subtitle_add_all_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { // Add the current subtitle settings to the list. @@ -1251,8 +1358,8 @@ subtitle_add_all_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) return; } - ghb_clear_subtitle_list_settings(ud->settings); - ghb_clear_subtitle_list_ui(ud->builder); + clear_subtitle_list_settings(ud->settings); + clear_subtitle_list_ui(ud->builder); const char *mux_id; const hb_container_t *mux; @@ -1281,6 +1388,9 @@ subtitle_reset_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) ghb_set_pref_subtitle(title, ud); } +// When the container changes, it may be necessary to burn additional +// subtitles. Since only one can be burned, some subtitles may be +// removed from the list. void ghb_subtitle_prune(signal_user_data_t *ud) { @@ -1289,7 +1399,7 @@ ghb_subtitle_prune(signal_user_data_t *ud) gint ii; gboolean one_burned = FALSE; - subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); + subtitle_list = get_sub_list(ud->settings); if (subtitle_list == NULL) return; @@ -1305,8 +1415,8 @@ ghb_subtitle_prune(signal_user_data_t *ud) int source; subsettings = ghb_array_get(subtitle_list, ii); - burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); - source = ghb_dict_get_bool(subsettings, "SubtitleSource"); + burned = ghb_dict_get_bool(subsettings, "Burn"); + source = ghb_dict_get_bool(subsettings, "Source"); burned = burned || !hb_subtitle_can_pass(source, mux->format); if (burned && one_burned) { @@ -1314,7 +1424,7 @@ ghb_subtitle_prune(signal_user_data_t *ud) continue; } one_burned = one_burned || burned; - ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); + ghb_dict_set_bool(subsettings, "Burn", burned); ii++; } subsettings = subtitle_get_selected_settings(ud, NULL); @@ -1324,33 +1434,6 @@ ghb_subtitle_prune(signal_user_data_t *ud) } } -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); -} - G_MODULE_EXPORT void subtitle_def_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { @@ -1615,8 +1698,7 @@ subtitle_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud) gtk_tree_selection_select_iter(ts, &ti); // Back up settings in case we need to revert. - backup = ghb_value_dup( - ghb_dict_get_value(ud->settings, "subtitle_list")); + backup = ghb_value_dup(get_sub_settings(ud->settings)); // Pop up the edit dialog GtkResponseType response; @@ -1625,7 +1707,7 @@ subtitle_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud) gtk_widget_hide(dialog); if (response != GTK_RESPONSE_OK) { - ghb_dict_set(ud->settings, "subtitle_list", backup); + ghb_dict_set(ud->settings, "Subtitle", backup); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { @@ -1650,7 +1732,7 @@ subtitle_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *u GtkTreeIter ti, nextIter; gint row; gint *indices; - GhbValue *subtitle_list; + GhbValue *subtitle_list, *subtitle_search; tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list_view")); ts = gtk_tree_view_get_selection(tv); @@ -1673,11 +1755,26 @@ subtitle_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *u gtk_tree_selection_select_iter(ts, &nextIter); } - subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); + subtitle_search = get_sub_search(ud->settings); + subtitle_list = get_sub_list(ud->settings); // Get the row number - indices = gtk_tree_path_get_indices (tp); + indices = gtk_tree_path_get_indices(tp); row = indices[0]; + if (ghb_dict_get_bool(subtitle_search, "Enable")) + { + if (row == 0) + { + ghb_dict_set_bool(subtitle_search, "Enable", 0); + gtk_tree_store_remove(GTK_TREE_STORE(tm), &ti); + + // Enable FAS button + GtkWidget *w = GHB_WIDGET(ud->builder, "subtitle_add_fas"); + gtk_widget_set_sensitive(w, 1); + return; + } + row--; + } if (row < 0 || row >= ghb_array_len(subtitle_list)) { gtk_tree_path_free(tp); diff --git a/gtk/src/subtitlehandler.h b/gtk/src/subtitlehandler.h index df3d22694..9235270af 100644 --- a/gtk/src/subtitlehandler.h +++ b/gtk/src/subtitlehandler.h @@ -30,14 +30,14 @@ void ghb_set_pref_subtitle_settings(signal_user_data_t *ud, const hb_title_t *title, GhbValue *settings); void ghb_set_subtitle(signal_user_data_t *ud, gint track, GhbValue *settings); -void ghb_reset_subtitles(signal_user_data_t *ud, GhbValue *settings); void ghb_subtitle_prune(signal_user_data_t *ud); -void ghb_subtitle_list_refresh_selected(signal_user_data_t *ud); void ghb_subtitle_list_refresh_all(signal_user_data_t *ud); void ghb_init_subtitle_defaults_ui(signal_user_data_t *ud); void ghb_subtitle_defaults_to_ui(signal_user_data_t *ud); void ghb_subtitle_title_change(signal_user_data_t *ud, gboolean show); void ghb_subtitle_set_pref_lang(GhbValue *settings); void ghb_clear_subtitle_selection(GtkBuilder *builder); +GhbValue *ghb_get_subtitle_list(GhbValue *settings); +GhbValue *ghb_get_subtitle_settings(GhbValue *settings); #endif // _SUBTITLEHANDLER_H_ |