diff options
author | John Stebbins <[email protected]> | 2019-07-12 14:06:18 -0700 |
---|---|---|
committer | John Stebbins <[email protected]> | 2019-09-10 09:09:52 -0700 |
commit | ed346b4659a7c353cc3f0aee745344e84c051e27 (patch) | |
tree | 7bb4b8f073704d4d42a20fd18e2d7dd29a1c48cf | |
parent | 53d6226c58e9f7bba23f1746bad1d8b61ec6338d (diff) |
Create separate fake iso639 "any" entry
Allows us to distinguish a selection of "any" which means match any
language from "und" which means the language is not known.
Fixes https://github.com/HandBrake/HandBrake/issues/731
-rw-r--r-- | gtk/src/hb-backend.c | 25 | ||||
-rw-r--r-- | libhb/lang.c | 73 | ||||
-rw-r--r-- | libhb/lang.h | 9 | ||||
-rw-r--r-- | libhb/preset.c | 32 | ||||
-rw-r--r-- | macosx/HBLanguagesSelection.m | 13 |
5 files changed, 94 insertions, 58 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 9f842ee89..e54b8964f 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -2000,16 +2000,16 @@ language_opts_set(signal_user_data_t *ud, const gchar *name, (void)data; // Silence "unused variable" warning GtkTreeIter iter; GtkListStore *store; - gint ii; GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, name)); store = GTK_LIST_STORE(gtk_combo_box_get_model (combo)); gtk_list_store_clear(store); const iso639_lang_t *iso639; - for (iso639 = lang_get_next(NULL), ii = 0; iso639 != NULL; - iso639 = lang_get_next(iso639), ii++) + for (iso639 = lang_get_next(NULL); iso639 != NULL; + iso639 = lang_get_next(iso639)) { - gchar *lang; + int index = lang_lookup_index(iso639->iso639_1); + gchar * lang; if (iso639->native_name[0] != 0) lang = g_strdup_printf("%s", iso639->native_name); @@ -2021,7 +2021,7 @@ language_opts_set(signal_user_data_t *ud, const gchar *name, 0, lang, 1, TRUE, 2, iso639->iso639_2, - 3, (gdouble)ii, + 3, (gdouble)index, -1); g_free(lang); } @@ -3050,22 +3050,17 @@ void ghb_init_lang_list(GtkTreeView *tv, signal_user_data_t *ud) { GtkTreeIter iter; GtkTreeStore * ts; - int ii; ghb_init_lang_list_model(tv); ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv)); const iso639_lang_t *iso639; - for (iso639 = lang_get_next(NULL), ii = 0; iso639 != NULL; - iso639 = lang_get_next(iso639), ii++) + for (iso639 = lang_get_any(); iso639 != NULL; + iso639 = lang_get_next(iso639)) { + int index = lang_lookup_index(iso639->iso639_2); const char * lang; - if (ii == 0) - { - lang = _("Any"); - } - else if (iso639->native_name != NULL && - iso639->native_name[0] != 0) + if (iso639->native_name != NULL && iso639->native_name[0] != 0) { lang = iso639->native_name; } @@ -3074,7 +3069,7 @@ void ghb_init_lang_list(GtkTreeView *tv, signal_user_data_t *ud) lang = iso639->eng_name; } gtk_tree_store_append(ts, &iter, NULL); - gtk_tree_store_set(ts, &iter, 0, lang, 1, ii, -1); + gtk_tree_store_set(ts, &iter, 0, lang, 1, index, -1); } } diff --git a/libhb/lang.c b/libhb/lang.c index c7a7e47e1..cd3c8887f 100644 --- a/libhb/lang.c +++ b/libhb/lang.c @@ -11,6 +11,10 @@ #include <string.h> #include <ctype.h> +// Fake iso639 entry to deal with selection of "any" language +static iso639_lang_t lang_any = + { "Any", "", "", "any" }; + static const iso639_lang_t languages[] = { { "Unknown", "", "", "und" }, { "Afar", "Qafar", "aa", "aar" }, @@ -207,21 +211,26 @@ const int lang_lookup_index( const char * str ) int ii = 0; const iso639_lang_t * lang; - // We use "Any" as a synonym for undefined - if (!strcasecmp("any", str)) + // We use fake lang_any iso639 to designate a match for "Any" language + if ((lang_any.iso639_1 && !strcasecmp(lang_any.iso639_1, str)) || + (lang_any.iso639 && !strcasecmp(lang_any.iso639, str)) || + (lang_any.iso639_2 && !strcasecmp(lang_any.iso639_2, str)) || + (lang_any.iso639_2b && !strcasecmp(lang_any.iso639_2b, str)) || + (lang_any.eng_name && !strcasecmp(lang_any.eng_name, str)) || + (lang_any.native_name && !strcasecmp(lang_any.native_name, str))) { - return 0; + return -1; } for (ii = 0; languages[ii].eng_name; ii++) { lang = &languages[ii]; - if ((lang->iso639_1 != NULL && !strcasecmp(lang->iso639_1, str)) || - (lang->iso639 != NULL && !strcasecmp(lang->iso639, str)) || - (lang->iso639_2 != NULL && !strcasecmp(lang->iso639_2, str)) || - (lang->iso639_2b != NULL && !strcasecmp(lang->iso639_2b, str)) || - (lang->eng_name != NULL && !strcasecmp(lang->eng_name, str)) || - (lang->native_name != NULL && !strcasecmp(lang->native_name, str))) + if ((lang->iso639_1 && !strcasecmp(lang->iso639_1, str)) || + (lang->iso639 && !strcasecmp(lang->iso639, str)) || + (lang->iso639_2 && !strcasecmp(lang->iso639_2, str)) || + (lang->iso639_2b && !strcasecmp(lang->iso639_2b, str)) || + (lang->eng_name && !strcasecmp(lang->eng_name, str)) || + (lang->native_name && !strcasecmp(lang->native_name, str))) { return ii; } @@ -237,6 +246,9 @@ const iso639_lang_t * lang_lookup( const char * str ) const iso639_lang_t * lang_for_index( int index ) { + if (index == -1) + return &lang_any; + if (index < 0 || index >= lang_count) return NULL; @@ -251,15 +263,21 @@ iso639_lang_t * lang_for_code( int code ) code_string[0] = tolower( ( code >> 8 ) & 0xFF ); code_string[1] = tolower( code & 0xFF ); - for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ ) + if ((lang_any.iso639_1 && !strncmp(lang_any.iso639_1, code_string, 2)) || + (lang_any.iso639 && !strncmp(lang_any.iso639, code_string, 2))) + { + return &lang_any; + } + for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++) { - if( !strncmp( lang->iso639_1, code_string, 2 ) || - (lang->iso639 != NULL && !strncmp(lang->iso639, code_string, 2)) ) + if ((lang->iso639_1 && !strncmp( lang->iso639_1, code_string, 2)) || + (lang->iso639 && !strncmp(lang->iso639, code_string, 2))) { return lang; } } + // Not found, return "Unknown" return (iso639_lang_t*) languages; } @@ -273,18 +291,22 @@ iso639_lang_t * lang_for_code2( const char *code ) code_string[2] = tolower( code[2] ); code_string[3] = 0; + if ((lang_any.iso639_2 && !strcmp(lang_any.iso639_2, code_string)) || + (lang_any.iso639_2b && !strcmp(lang_any.iso639_2b, code_string))) + { + return &lang_any; + } + for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ ) { - if( !strcmp( lang->iso639_2, code_string ) ) - { - return lang; - } - if( lang->iso639_2b && !strcmp( lang->iso639_2b, code_string ) ) + if ((lang->iso639_2 && !strcmp(lang->iso639_2, code_string)) || + (lang->iso639_2b && !strcmp(lang->iso639_2b, code_string))) { return lang; } } + // Not found, return "Unknown" return (iso639_lang_t*) languages; } @@ -302,20 +324,30 @@ iso639_lang_t * lang_for_english( const char * english ) { iso639_lang_t * lang; - for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ ) + if (!strcmp(lang_any.eng_name, english)) + { + return &lang_any; + } + for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++) { - if( !strcmp( lang->eng_name, english ) ) + if (!strcmp(lang->eng_name, english)) { return lang; } } + // Not found, return "Unknown" return (iso639_lang_t*) languages; } +const iso639_lang_t* lang_get_any(void) +{ + return &lang_any; +} + const iso639_lang_t* lang_get_next(const iso639_lang_t *last) { - if (last == NULL) + if (last == NULL || last == &lang_any) { return (const iso639_lang_t*)languages; } @@ -327,4 +359,3 @@ const iso639_lang_t* lang_get_next(const iso639_lang_t *last) return ++last; } - diff --git a/libhb/lang.h b/libhb/lang.h index ed3e08e5b..9017de066 100644 --- a/libhb/lang.h +++ b/libhb/lang.h @@ -44,6 +44,15 @@ int lang_to_code(const iso639_lang_t *lang); iso639_lang_t * lang_for_english( const char * english ); /* + * Get fake iso639 cooresponding to "Any" + * "Any" is used when a match for any language is desired. + * + * Calling lang_get_next() with pointer returned by lang_get_any() + * returns the first entry in the languages list + */ +const iso639_lang_t* lang_get_any(void); + +/* * Get the next language in the list. * Returns NULL if there are no more languages. * Pass NULL to get the first language in the list. diff --git a/libhb/preset.c b/libhb/preset.c index be4d773db..057de4ec0 100644 --- a/libhb/preset.c +++ b/libhb/preset.c @@ -11,6 +11,7 @@ #include "hb.h" #include "hb_dict.h" #include "plist.h" +#include "lang.h" #if HB_PROJECT_FEATURE_QSV #include "qsv_common.h" @@ -401,8 +402,9 @@ static hb_dict_t * source_audio_track_used(hb_dict_t *track_dict, int track) static int find_audio_track(const hb_title_t *title, const char *lang, int start, int behavior) { - hb_audio_config_t * audio; - int ii, count; + hb_audio_config_t * audio; + int ii, count; + const iso639_lang_t * lang_any = lang_get_any(); count = hb_list_count(title->list_audio); for (ii = start; ii < count; ii++) @@ -416,7 +418,8 @@ static int find_audio_track(const hb_title_t *title, if ((behavior == 2 || audio->lang.attributes == HB_AUDIO_ATTR_NONE || (audio->lang.attributes & HB_AUDIO_ATTR_REGULAR_MASK)) && - (!strcmp(lang, audio->lang.iso639_2) || !strcmp(lang, "und"))) + (!strcmp(lang, audio->lang.iso639_2) || + !strcmp(lang, lang_any->iso639_2))) { return ii; } @@ -861,11 +864,13 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index, add_audio_for_lang(list, preset, title, mux, copy_mask, fallback, lang, behavior, mode, track_dict); } - // If no audios found, try "und" language option + // If no audios found, try "any" language option + // This can happen if AudioLanguageList is empty or if no audio + // matches the users preferred languages in AudioLanguageList if (hb_value_array_len(list) <= 0) { add_audio_for_lang(list, preset, title, mux, copy_mask, fallback, - "und", behavior, mode, track_dict); + "any", behavior, mode, track_dict); } hb_dict_free(&track_dict); return 0; @@ -875,14 +880,16 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index, static int find_subtitle_track(const hb_title_t *title, const char *lang, int start) { - hb_subtitle_t * subtitle; - int ii, count; + hb_subtitle_t * subtitle; + int ii, count; + const iso639_lang_t * lang_any = lang_get_any(); count = hb_list_count(title->list_subtitle); for (ii = start; ii < count; ii++) { subtitle = hb_list_item(title->list_subtitle, ii); - if (!strcmp(lang, subtitle->iso639_2) || !strcmp(lang, "und")) + if (!strcmp(lang, subtitle->iso639_2) || + !strcmp(lang, lang_any->iso639_2)) { return ii; } @@ -1091,14 +1098,16 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, // Add tracks for all languages in the language list - hb_value_array_t *lang_list = hb_dict_get(preset, "SubtitleLanguageList"); + hb_value_array_t * lang_list = hb_dict_get(preset, "SubtitleLanguageList"); + const iso639_lang_t * lang_any = lang_get_any(); + const char * pref_lang = lang_any->iso639_2; + count = hb_value_array_len(lang_list); - const char *pref_lang = "und"; if (count > 0) { pref_lang = hb_value_get_string(hb_value_array_get(lang_list, 0)); } - if (!strcmp(pref_lang, "und")) + if (!strcmp(pref_lang, lang_any->iso639_2)) { if (first_audio_lang != NULL) { @@ -1163,6 +1172,7 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, } if (count <= 0) { + // No matching language. Try "Unknown" language add_subtitle_for_lang(list, title, mux, "und", &behavior); } } diff --git a/macosx/HBLanguagesSelection.m b/macosx/HBLanguagesSelection.m index 566d8266e..3fedddd6d 100644 --- a/macosx/HBLanguagesSelection.m +++ b/macosx/HBLanguagesSelection.m @@ -68,8 +68,8 @@ NSMutableArray<HBLang *> *internal = [[NSMutableArray alloc] init]; NSMutableArray<HBLang *> *selected = [[NSMutableArray alloc] init]; - const iso639_lang_t *lang = lang_get_next(NULL); - for (lang = lang_get_next(lang); lang != NULL; lang = lang_get_next(lang)) + const iso639_lang_t *lang; + for (lang = lang_get_any(); lang != NULL; lang = lang_get_next(lang)) { NSString *nativeLanguage = strlen(lang->native_name) ? @(lang->native_name) : @(lang->eng_name); @@ -87,15 +87,6 @@ } - // Add the (Any) item. - HBLang *item = [[HBLang alloc] initWithLanguage:NSLocalizedString(@"(Any)", @"Language selection") - iso639_2code:@"und"]; - if ([languages containsObject:item.iso639_2]) - { - item.isSelected = YES; - } - [internal insertObject:item atIndex:0]; - // Insert the selected items // in the original order. [selected sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { |