diff options
-rw-r--r-- | gtk/src/audiohandler.c | 302 | ||||
-rw-r--r-- | gtk/src/audiohandler.h | 2 | ||||
-rw-r--r-- | gtk/src/ghb.m4 | 16 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 36 | ||||
-rw-r--r-- | gtk/src/hb-backend.h | 3 | ||||
-rw-r--r-- | gtk/src/subtitlehandler.c | 294 |
6 files changed, 451 insertions, 202 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c index d4994463f..68a45ebe8 100644 --- a/gtk/src/audiohandler.c +++ b/gtk/src/audiohandler.c @@ -1986,70 +1986,154 @@ audio_def_setting_update(signal_user_data_t *ud, GtkWidget *widget) } } +void +audio_add_lang_iter(GtkTreeModel *tm, GtkTreeIter *iter, signal_user_data_t *ud) +{ + GtkTreeView * selected; + GtkTreeStore * selected_ts; + GtkTreeIter pos; + GtkTreePath * tp; + char * lang; + int index; + const iso639_lang_t * iso_lang; + GhbValue * glang, * alang_list; + GtkTreeSelection * tsel; + + selected = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_selected_lang")); + selected_ts = GTK_TREE_STORE(gtk_tree_view_get_model(selected)); + tsel = gtk_tree_view_get_selection(selected); + + // Add to UI selected language list box + gtk_tree_model_get(tm, iter, 0, &lang, 1, &index, -1); + gtk_tree_store_append(selected_ts, &pos, NULL); + gtk_tree_store_set(selected_ts, &pos, 0, lang, 1, index, -1); + g_free(lang); + + // Select the item added to the selected list and make it + // visible in the scrolled window + tp = gtk_tree_model_get_path(GTK_TREE_MODEL(selected_ts), &pos); + gtk_tree_selection_select_iter(tsel, &pos); + gtk_tree_view_scroll_to_cell(selected, tp, NULL, FALSE, 0, 0); + gtk_tree_path_free(tp); + + // Remove from UI available language list box + gtk_tree_store_remove(GTK_TREE_STORE(tm), iter); + + // Add to preset language list + iso_lang = ghb_iso639_lookup_by_int(index); + glang = ghb_string_value_new(iso_lang->iso639_2); + alang_list = ghb_dict_get_value(ud->settings, "AudioLanguageList"); + ghb_array_append(alang_list, glang); + ghb_clear_presets_selection(ud); +} + +G_MODULE_EXPORT void +audio_avail_lang_activated_cb(GtkTreeView *tv, GtkTreePath *tp, + GtkTreeViewColumn *column, signal_user_data_t *ud) +{ + GtkTreeIter iter; + GtkTreeModel * tm = gtk_tree_view_get_model(tv); + + if (gtk_tree_model_get_iter(tm, &iter, tp)) + { + audio_add_lang_iter(tm, &iter, ud); + } +} + G_MODULE_EXPORT void audio_add_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) { - GtkListBox *avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang")); - GtkListBox *selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang")); - GtkListBoxRow *row; - GtkWidget *label; + GtkTreeView * avail; + GtkTreeModel * avail_tm; + GtkTreeSelection * tsel; + GtkTreeIter iter; - row = gtk_list_box_get_selected_row(avail); - if (row != NULL) + avail = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_avail_lang")); + avail_tm = gtk_tree_view_get_model(avail); + tsel = gtk_tree_view_get_selection(avail); + if (gtk_tree_selection_get_selected(tsel, NULL, &iter)) { - int idx; - const iso639_lang_t *lang; - GhbValue *glang, *alang_list; + audio_add_lang_iter(avail_tm, &iter, ud); + } +} - // Remove from UI available language list box - label = gtk_bin_get_child(GTK_BIN(row)); - g_object_ref(G_OBJECT(label)); - gtk_widget_destroy(GTK_WIDGET(row)); - gtk_widget_show(label); - // Add to UI selected language list box - gtk_list_box_insert(selected, label, -1); +void +audio_remove_lang_iter(GtkTreeModel *tm, GtkTreeIter *iter, + signal_user_data_t *ud) +{ + GtkTreeView * avail; + GtkTreeStore * avail_ts; + GtkTreeIter pos, sibling; + char * lang; + int index; + GtkTreePath * tp = gtk_tree_model_get_path(tm, iter); + int * ind = gtk_tree_path_get_indices(tp); + int row = ind[0]; + GhbValue * alang_list; + GtkTreeSelection * tsel; + + gtk_tree_path_free(tp); + avail = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_avail_lang")); + avail_ts = GTK_TREE_STORE(gtk_tree_view_get_model(avail)); + tsel = gtk_tree_view_get_selection(avail); - // Add to preset language list - idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); - lang = ghb_iso639_lookup_by_int(idx); - glang = ghb_string_value_new(lang->iso639_2); - alang_list = ghb_dict_get_value(ud->settings, "AudioLanguageList"); - ghb_array_append(alang_list, glang); - ghb_clear_presets_selection(ud); + // Add to UI available language list box + gtk_tree_model_get(tm, iter, 0, &lang, 1, &index, -1); + if (ghb_find_lang_row(GTK_TREE_MODEL(avail_ts), &sibling, index)) + { + gtk_tree_store_insert_before(avail_ts, &pos, NULL, &sibling); } + else + { + gtk_tree_store_append(avail_ts, &pos, NULL); + } + gtk_tree_store_set(avail_ts, &pos, 0, lang, 1, index, -1); + g_free(lang); + + // Select the item added to the available list and make it + // visible in the scrolled window + tp = gtk_tree_model_get_path(GTK_TREE_MODEL(avail_ts), &pos); + gtk_tree_selection_select_iter(tsel, &pos); + gtk_tree_view_scroll_to_cell(avail, tp, NULL, FALSE, 0, 0); + gtk_tree_path_free(tp); + + // Remove from UI selected language list box + gtk_tree_store_remove(GTK_TREE_STORE(tm), iter); + + // Remove from preset language list + alang_list = ghb_dict_get_value(ud->settings, "AudioLanguageList"); + ghb_array_remove(alang_list, row); + ghb_clear_presets_selection(ud); } G_MODULE_EXPORT void -audio_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +audio_selected_lang_activated_cb(GtkTreeView *tv, GtkTreePath *tp, + GtkTreeViewColumn *column, + signal_user_data_t *ud) { + GtkTreeIter iter; + GtkTreeModel * tm = gtk_tree_view_get_model(tv); - GtkListBox *avail, *selected; - GtkListBoxRow *row; - GtkWidget *label; - - avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang")); - selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang")); - row = gtk_list_box_get_selected_row(selected); - if (row != NULL) + if (gtk_tree_model_get_iter(tm, &iter, tp)) { - gint index; - GhbValue *alang_list; - - index = gtk_list_box_row_get_index(row); + audio_remove_lang_iter(tm, &iter, ud); + } +} - // 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); +G_MODULE_EXPORT void +audio_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + GtkTreeView * selected; + GtkTreeModel * selected_tm; + GtkTreeSelection * tsel; + GtkTreeIter iter; - // Remove from preset language list - alang_list = ghb_dict_get_value(ud->settings, "AudioLanguageList"); - ghb_array_remove(alang_list, index); - ghb_clear_presets_selection(ud); + selected = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_selected_lang")); + selected_tm = gtk_tree_view_get_model(selected); + tsel = gtk_tree_view_get_selection(selected); + if (gtk_tree_selection_get_selected(tsel, NULL, &iter)) + { + audio_remove_lang_iter(selected_tm, &iter, ud); } } @@ -2297,54 +2381,73 @@ audio_def_encode_setting_changed_cb(GtkWidget *widget, signal_user_data_t *ud) ghb_clear_presets_selection(ud); } -GtkListBoxRow* ghb_find_lang_row(GtkListBox *list_box, int lang_idx) +gboolean ghb_find_lang_row(GtkTreeModel *model, GtkTreeIter *iter, int lang_idx) { - GList *list, *link; - GtkListBoxRow *result = NULL; - - list = link = gtk_container_get_children(GTK_CONTAINER(list_box)); - while (link != NULL) + if (gtk_tree_model_get_iter_first(model, iter)) { - GtkListBoxRow *row = (GtkListBoxRow*)link->data; - GtkWidget *label = gtk_bin_get_child(GTK_BIN(row)); - int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); - if (idx == lang_idx) + do { - result = row; - break; - } - link = link->next; - } - g_list_free(list); - - return result; -} + gint index; -static void audio_def_lang_list_clear_cb(GtkWidget *row, gpointer data) -{ - GtkListBox *avail = (GtkListBox*)data; - 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); - int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); - gtk_list_box_insert(avail, label, idx); + gtk_tree_model_get(model, iter, 1, &index, -1); + if (index >= lang_idx) + { + return TRUE; + } + } while (gtk_tree_model_iter_next(model, iter)); + } + return FALSE; } static void audio_def_selected_lang_list_clear(signal_user_data_t *ud) { - GtkListBox *avail, *selected; - avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang")); - selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang")); - gtk_container_foreach(GTK_CONTAINER(selected), - audio_def_lang_list_clear_cb, (gpointer)avail); + GtkTreeView * tv; + GtkTreeModel * selected_tm; + GtkTreeStore * avail_ts; + GtkTreeIter iter; + + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_avail_lang")); + avail_ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv)); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_selected_lang")); + selected_tm = gtk_tree_view_get_model(tv); + if (gtk_tree_model_get_iter_first(selected_tm, &iter)) + { + do + { + gchar * lang; + gint index; + GtkTreeIter pos, sibling; + + gtk_tree_model_get(selected_tm, &iter, 0, &lang, 1, &index, -1); + if (ghb_find_lang_row(GTK_TREE_MODEL(avail_ts), &sibling, index)) + { + gtk_tree_store_insert_before(avail_ts, &pos, NULL, &sibling); + } + else + { + gtk_tree_store_append(avail_ts, &pos, NULL); + } + gtk_tree_store_set(avail_ts, &pos, 0, lang, 1, index, -1); + g_free(lang); + } while (gtk_tree_model_iter_next(selected_tm, &iter)); + } + gtk_tree_store_clear(GTK_TREE_STORE(selected_tm)); } static void audio_def_lang_list_init(signal_user_data_t *ud) { - GhbValue *lang_list; + GhbValue * lang_list; + GtkTreeView * tv; + GtkTreeModel * avail; + GtkTreeStore * selected; + int ii, count; + + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_avail_lang")); + avail = gtk_tree_view_get_model(tv); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_selected_lang")); + selected = GTK_TREE_STORE(gtk_tree_view_get_model(tv)); // Clear selected languages. audio_def_selected_lang_list_clear(ud); @@ -2356,25 +2459,24 @@ audio_def_lang_list_init(signal_user_data_t *ud) ghb_dict_set(ud->settings, "AudioLanguageList", 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_lang(lang_val); + GhbValue * lang_val = ghb_array_get(lang_list, ii); + int idx = ghb_lookup_lang(lang_val); + GtkTreeIter iter; - GtkListBox *avail, *selected; - GtkListBoxRow *row; - avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang")); - selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang")); - row = ghb_find_lang_row(avail, idx); - if (row) + if (ghb_find_lang_row(avail, &iter, idx)) { - 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); + gchar * lang; + gint index; + GtkTreeIter pos; + + gtk_tree_model_get(avail, &iter, 0, &lang, 1, &index, -1); + gtk_tree_store_append(selected, &pos, NULL); + gtk_tree_store_set(selected, &pos, 0, lang, 1, index, -1); + g_free(lang); + gtk_tree_store_remove(GTK_TREE_STORE(avail), &iter); ii++; } else @@ -2427,10 +2529,12 @@ void ghb_audio_defaults_to_ui(signal_user_data_t *ud) void ghb_init_audio_defaults_ui(signal_user_data_t *ud) { - GtkListBox *list_box; + GtkTreeView * tv; - list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang")); - ghb_init_lang_list_box(list_box); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_avail_lang")); + ghb_init_lang_list(tv, ud); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_selected_lang")); + ghb_init_lang_list_model(tv); } G_MODULE_EXPORT void diff --git a/gtk/src/audiohandler.h b/gtk/src/audiohandler.h index 45be4df0d..8c60f9e34 100644 --- a/gtk/src/audiohandler.h +++ b/gtk/src/audiohandler.h @@ -40,7 +40,7 @@ void ghb_audio_list_refresh_all(signal_user_data_t *ud); char * ghb_format_quality( const char *prefix, int codec, double quality ); void ghb_init_audio_defaults_ui(signal_user_data_t *ud); void ghb_audio_defaults_to_ui(signal_user_data_t *ud); -GtkListBoxRow* ghb_find_lang_row(GtkListBox *list_box, int lang_idx); +gboolean ghb_find_lang_row(GtkTreeModel *model, GtkTreeIter *iter, int idx); void ghb_audio_title_change(signal_user_data_t *ud, gboolean title_valid); void ghb_clear_audio_selection(GtkBuilder *builder); gboolean ghb_audio_quality_enabled(const GhbValue *asettings); diff --git a/gtk/src/ghb.m4 b/gtk/src/ghb.m4 index c38eb13a3..c3d061f9a 100644 --- a/gtk/src/ghb.m4 +++ b/gtk/src/ghb.m4 @@ -4265,10 +4265,12 @@ filter_output([ <property name="min_content_height">84</property> <property name="vexpand">True</property> <child> - <object class="GtkListBox" id="audio_avail_lang"> + <object class="GtkTreeView" id="audio_avail_lang"> <property name="visible">True</property> + <property name="headers-visible">False</property> <property name="can_focus">True</property> <property name="vexpand">True</property> + <signal name="row-activated" handler="audio_avail_lang_activated_cb" swapped="no"/> </object> </child> </object> @@ -4286,11 +4288,13 @@ filter_output([ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <child> - <object class="GtkListBox" id="audio_selected_lang"> + <object class="GtkTreeView" id="audio_selected_lang"> <property name="visible">True</property> + <property name="headers-visible">False</property> <property name="can_focus">True</property> <property name="tooltip_text" translatable="yes">Create a list of languages you would like to select audio for. Tracks matching these languages will be selected using the chosen Selection Behavior.</property> + <signal name="row-activated" handler="audio_selected_lang_activated_cb" swapped="no"/> </object> </child> </object> @@ -5078,11 +5082,13 @@ filter_output([ <property name="vexpand">True</property> <property name="halign">GTK_ALIGN_FILL</property> <child> - <object class="GtkListBox" id="subtitle_avail_lang"> + <object class="GtkTreeView" id="subtitle_avail_lang"> <property name="visible">True</property> + <property name="headers-visible">False</property> <property name="can_focus">True</property> <property name="vexpand">True</property> <property name="halign">GTK_ALIGN_FILL</property> + <signal name="row-activated" handler="subtitle_avail_lang_activated_cb" swapped="no"/> </object> </child> </object> @@ -5102,8 +5108,9 @@ filter_output([ <property name="vexpand">True</property> <property name="halign">GTK_ALIGN_FILL</property> <child> - <object class="GtkListBox" id="subtitle_selected_lang"> + <object class="GtkTreeView" id="subtitle_selected_lang"> <property name="visible">True</property> + <property name="headers-visible">False</property> <property name="can_focus">True</property> <property name="tooltip_text" translatable="yes">Create a list of languages you would like to select subtitles for. Tracks matching these languages will be selected using the chosen Selection Behavior. @@ -5112,6 +5119,7 @@ The first language in this list is your "preferred" language and will be used for determining subtitle selection settings when there is foreign audio.</property> <property name="vexpand">True</property> <property name="halign">GTK_ALIGN_FILL</property> + <signal name="row-activated" handler="subtitle_selected_lang_activated_cb" swapped="no"/> </object> </child> </object> diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 433e21bfc..8a9ed99b0 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -2899,15 +2899,39 @@ ghb_lookup_combo_option(const gchar *name, const GhbValue *gval) return result; } -void ghb_init_lang_list_box(GtkListBox *list_box) +void ghb_init_lang_list_model(GtkTreeView *tv) { - int ii; + GtkTreeViewColumn * column; + GtkTreeStore * ts; + GtkCellRenderer * lang_cell; + + // Store contains: + // 0 - Language string to display + // 1 - Index of language in the libhb language list + ts = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_INT); + gtk_tree_view_set_model(tv, GTK_TREE_MODEL(ts)); + + lang_cell = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new(); + gtk_tree_view_column_pack_start(column, lang_cell, FALSE); + gtk_tree_view_column_add_attribute(column, lang_cell, "markup", 0); + gtk_tree_view_append_column(tv, GTK_TREE_VIEW_COLUMN(column)); +} + +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++) { - const char *lang; + const char * lang; if (ii == 0) { lang = _("Any"); @@ -2921,10 +2945,8 @@ void ghb_init_lang_list_box(GtkListBox *list_box) { lang = iso639->eng_name; } - GtkWidget *label = gtk_label_new(lang); - g_object_set_data(G_OBJECT(label), "lang_idx", (gpointer)(intptr_t)ii); - gtk_widget_show(label); - gtk_list_box_insert(list_box, label, -1); + gtk_tree_store_append(ts, &iter, NULL); + gtk_tree_store_set(ts, &iter, 0, lang, 1, ii, -1); } } diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h index 481aafbb2..7ebec5c1a 100644 --- a/gtk/src/hb-backend.h +++ b/gtk/src/hb-backend.h @@ -169,7 +169,8 @@ const char* ghb_lookup_filter_name(int filter_id, const char *short_name, int pr gchar* ghb_get_tmp_dir(); gint ghb_find_closest_audio_samplerate(gint rate); -void ghb_init_lang_list_box(GtkListBox *list_box); +void ghb_init_lang_list_model(GtkTreeView *tv); +void ghb_init_lang_list(GtkTreeView *tv, signal_user_data_t *ud); void ghb_init_combo_box(GtkComboBox *combo); void ghb_audio_encoder_opts_set(GtkComboBox *combo); diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c index 3cf44689f..9297c0968 100644 --- a/gtk/src/subtitlehandler.c +++ b/gtk/src/subtitlehandler.c @@ -1329,80 +1329,137 @@ ghb_subtitle_set_pref_lang(GhbValue *settings) } } -G_MODULE_EXPORT void -subtitle_add_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +void +subtitle_add_lang_iter(GtkTreeModel *tm, GtkTreeIter *iter, + signal_user_data_t *ud) { - GtkListBox *avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); - GtkListBox *selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); - GtkListBoxRow *row; - GtkWidget *label; - - row = gtk_list_box_get_selected_row(avail); - if (row != NULL) - { - int idx; - const iso639_lang_t *lang; - GhbValue *glang, *lang_list; - - // Remove from UI available language list box - label = gtk_bin_get_child(GTK_BIN(row)); - g_object_ref(G_OBJECT(label)); - gtk_widget_destroy(GTK_WIDGET(row)); - gtk_widget_show(label); - // Add to UI selected language list box - gtk_list_box_insert(selected, label, -1); - - // Add to preset language list - idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); - lang = ghb_iso639_lookup_by_int(idx); - glang = ghb_string_value_new(lang->iso639_2); - lang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); - if (ghb_array_len(lang_list) == 0) - { - subtitle_update_pref_lang(ud, lang); - } - ghb_array_append(lang_list, glang); - ghb_clear_presets_selection(ud); + GtkTreeView * selected; + GtkTreeStore * selected_ts; + GtkTreeIter pos; + GtkTreePath * tp; + char * lang; + int index; + const iso639_lang_t * iso_lang; + GhbValue * glang, * slang_list; + GtkTreeSelection * tsel; + + selected = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); + selected_ts = GTK_TREE_STORE(gtk_tree_view_get_model(selected)); + tsel = gtk_tree_view_get_selection(selected); + + // Add to UI selected language list box + gtk_tree_model_get(tm, iter, 0, &lang, 1, &index, -1); + gtk_tree_store_append(selected_ts, &pos, NULL); + gtk_tree_store_set(selected_ts, &pos, 0, lang, 1, index, -1); + g_free(lang); + + // Select the item added to the selected list and make it + // visible in the scrolled window + tp = gtk_tree_model_get_path(GTK_TREE_MODEL(selected_ts), &pos); + gtk_tree_selection_select_iter(tsel, &pos); + gtk_tree_view_scroll_to_cell(selected, tp, NULL, FALSE, 0, 0); + gtk_tree_path_free(tp); + + // Remove from UI available language list box + gtk_tree_store_remove(GTK_TREE_STORE(tm), iter); + + // Add to preset language list + iso_lang = ghb_iso639_lookup_by_int(index); + glang = ghb_string_value_new(iso_lang->iso639_2); + slang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); + if (ghb_array_len(slang_list) == 0) + { + subtitle_update_pref_lang(ud, iso_lang); } + ghb_array_append(slang_list, glang); + ghb_clear_presets_selection(ud); } G_MODULE_EXPORT void -subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +subtitle_avail_lang_activated_cb(GtkTreeView *tv, GtkTreePath *tp, + GtkTreeViewColumn *column, + signal_user_data_t *ud) { + GtkTreeIter iter; + GtkTreeModel * tm = gtk_tree_view_get_model(tv); - GtkListBox *avail, *selected; - GtkListBoxRow *row; - GtkWidget *label; + if (gtk_tree_model_get_iter(tm, &iter, tp)) + { + subtitle_add_lang_iter(tm, &iter, ud); + } +} - 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) +G_MODULE_EXPORT void +subtitle_add_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + GtkTreeView * avail; + GtkTreeModel * avail_tm; + GtkTreeSelection * tsel; + GtkTreeIter iter; + + avail = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); + avail_tm = gtk_tree_view_get_model(avail); + tsel = gtk_tree_view_get_selection(avail); + if (gtk_tree_selection_get_selected(tsel, NULL, &iter)) { - gint index; - GhbValue *lang_list; + subtitle_add_lang_iter(avail_tm, &iter, ud); + } +} + +void +subtitle_remove_lang_iter(GtkTreeModel *tm, GtkTreeIter *iter, + signal_user_data_t *ud) +{ + GtkTreeView * avail; + GtkTreeStore * avail_ts; + GtkTreeIter pos, sibling; + char * lang; + int index; + GtkTreePath * tp = gtk_tree_model_get_path(tm, iter); + int * ind = gtk_tree_path_get_indices(tp); + int row = ind[0]; + GhbValue * slang_list; + GtkTreeSelection * tsel; + + gtk_tree_path_free(tp); + avail = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); + avail_ts = GTK_TREE_STORE(gtk_tree_view_get_model(avail)); + tsel = gtk_tree_view_get_selection(avail); - index = gtk_list_box_row_get_index(row); + // Add to UI available language list box + gtk_tree_model_get(tm, iter, 0, &lang, 1, &index, -1); + if (ghb_find_lang_row(GTK_TREE_MODEL(avail_ts), &sibling, index)) + { + gtk_tree_store_insert_before(avail_ts, &pos, NULL, &sibling); + } + else + { + gtk_tree_store_append(avail_ts, &pos, NULL); + } + gtk_tree_store_set(avail_ts, &pos, 0, lang, 1, index, -1); + g_free(lang); - // 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); + // Select the item added to the available list and make it + // visible in the scrolled window + tp = gtk_tree_model_get_path(GTK_TREE_MODEL(avail_ts), &pos); + gtk_tree_selection_select_iter(tsel, &pos); + gtk_tree_view_scroll_to_cell(avail, tp, NULL, FALSE, 0, 0); + gtk_tree_path_free(tp); - // Remove from preset language list - lang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); - ghb_array_remove(lang_list, index); + // Remove from UI selected language list box + gtk_tree_store_remove(GTK_TREE_STORE(tm), iter); - ghb_clear_presets_selection(ud); + // Remove from preset language list + slang_list = ghb_dict_get_value(ud->settings, "SubtitleLanguageList"); + ghb_array_remove(slang_list, row); + ghb_clear_presets_selection(ud); - if (ghb_array_len(lang_list) > 0) + if (row == 0) + { + if (ghb_array_len(slang_list) > 0) { const iso639_lang_t *lang; - GhbValue *entry = ghb_array_get(lang_list, 0); + GhbValue *entry = ghb_array_get(slang_list, 0); lang = ghb_iso639_lookup_by_int(ghb_lookup_lang(entry)); subtitle_update_pref_lang(ud, lang); } @@ -1413,29 +1470,85 @@ subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) } } -static void subtitle_def_lang_list_clear_cb(GtkWidget *row, gpointer data) +G_MODULE_EXPORT void +subtitle_selected_lang_activated_cb(GtkTreeView *tv, GtkTreePath *tp, + GtkTreeViewColumn *column, + signal_user_data_t *ud) { - GtkListBox *avail = (GtkListBox*)data; - 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); - int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx"); - gtk_list_box_insert(avail, label, idx); + GtkTreeIter iter; + GtkTreeModel * tm = gtk_tree_view_get_model(tv); + + if (gtk_tree_model_get_iter(tm, &iter, tp)) + { + subtitle_remove_lang_iter(tm, &iter, ud); + } +} + +G_MODULE_EXPORT void +subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + GtkTreeView * selected; + GtkTreeModel * selected_tm; + GtkTreeSelection * tsel; + GtkTreeIter iter; + + selected = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, + "subtitle_selected_lang")); + selected_tm = gtk_tree_view_get_model(selected); + tsel = gtk_tree_view_get_selection(selected); + if (gtk_tree_selection_get_selected(tsel, NULL, &iter)) + { + subtitle_remove_lang_iter(selected_tm, &iter, ud); + } } static void subtitle_def_selected_lang_list_clear(signal_user_data_t *ud) { - GtkListBox *avail, *selected; - avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); - selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); - gtk_container_foreach(GTK_CONTAINER(selected), - subtitle_def_lang_list_clear_cb, (gpointer)avail); + GtkTreeView * tv; + GtkTreeModel * selected_tm; + GtkTreeStore * avail_ts; + GtkTreeIter iter; + + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); + avail_ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv)); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, + "subtitle_selected_lang")); + selected_tm = gtk_tree_view_get_model(tv); + if (gtk_tree_model_get_iter_first(selected_tm, &iter)) + { + do + { + char * lang; + gint index; + GtkTreeIter pos, sibling; + + gtk_tree_model_get(selected_tm, &iter, 0, &lang, 1, &index, -1); + if (ghb_find_lang_row(GTK_TREE_MODEL(avail_ts), &sibling, index)) + { + gtk_tree_store_insert_before(avail_ts, &pos, NULL, &sibling); + } + else + { + gtk_tree_store_append(avail_ts, &pos, NULL); + } + gtk_tree_store_set(avail_ts, &pos, 0, lang, 1, index, -1); + } while (gtk_tree_model_iter_next(selected_tm, &iter)); + } + gtk_tree_store_clear(GTK_TREE_STORE(selected_tm)); } static void subtitle_def_lang_list_init(signal_user_data_t *ud) { - GhbValue *lang_list; + GhbValue * lang_list; + GtkTreeView * tv; + GtkTreeModel * avail; + GtkTreeStore * selected; + int ii, count; + + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); + avail = gtk_tree_view_get_model(tv); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); + selected = GTK_TREE_STORE(gtk_tree_view_get_model(tv)); // Clear selected languages. subtitle_def_selected_lang_list_clear(ud); @@ -1447,31 +1560,30 @@ static void subtitle_def_lang_list_init(signal_user_data_t *ud) 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_lang(lang_val); + GhbValue * lang_val = ghb_array_get(lang_list, ii); + int idx = ghb_lookup_lang(lang_val); + GtkTreeIter iter; + 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) + if (ghb_find_lang_row(avail, &iter, idx)) { - 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); + gchar * lang; + gint index; + GtkTreeIter pos; + + gtk_tree_model_get(avail, &iter, 0, &lang, 1, &index, -1); + gtk_tree_store_append(selected, &pos, NULL); + gtk_tree_store_set(selected, &pos, 0, lang, 1, index, -1); + g_free(lang); + gtk_tree_store_remove(GTK_TREE_STORE(avail), &iter); ii++; } else @@ -1495,10 +1607,12 @@ void ghb_subtitle_defaults_to_ui(signal_user_data_t *ud) void ghb_init_subtitle_defaults_ui(signal_user_data_t *ud) { - GtkListBox *list_box; + GtkTreeView * tv; - list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); - ghb_init_lang_list_box(list_box); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_avail_lang")); + ghb_init_lang_list(tv, ud); + tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_selected_lang")); + ghb_init_lang_list_model(tv); } G_MODULE_EXPORT void |