Tue, 06 Aug 2019 04:51:53 +0000
Merged in default (pull request #533)
Convert more of the prefs window to Glade
Approved-by: Gary Kramlich
| pidgin/resources/Prefs/prefs.ui | file | annotate | diff | comparison | revisions |
--- a/pidgin/gtkprefs.c Tue Aug 06 01:16:36 2019 +0000 +++ b/pidgin/gtkprefs.c Tue Aug 06 04:51:53 2019 +0000 @@ -210,6 +210,31 @@ GtkWidget *password; } proxy; + /* Keyrings page */ + struct { + PidginPrefCombo active; + GtkWidget *vbox; + PurpleRequestFields *settings; + GtkWidget *settings_box; + GtkWidget *apply; + } keyring; + + /* Sounds page */ + struct { + PidginPrefCombo method; + GtkWidget *method_vbox; + GtkWidget *command; + GtkWidget *command_hbox; + GtkWidget *mute; + GtkWidget *conv_focus; + PidginPrefCombo while_status; + struct { + GtkWidget *view; + GtkListStore *store; + } event; + GtkWidget *entry; + } sound; + /* Away page */ struct { PidginPrefCombo idle_reporting; @@ -221,6 +246,31 @@ GtkWidget *startup_hbox; GtkWidget *startup_label; } away; + + /* Themes page */ + struct { + GtkWidget *blist; + GtkWidget *status; + GtkWidget *sound; + GtkWidget *smiley; + } theme; + +#ifdef USE_VV + /* Voice/Video page */ + struct { + struct { + GtkWidget *level; + GtkWidget *threshold; + GtkWidget *volume; + GstElement *pipeline; + } voice; + + struct { + GtkWidget *drawing_area; + GstElement *pipeline; + } video; + } vv; +#endif }; /* Main dialog */ @@ -233,16 +283,7 @@ static GtkWidget *prefs_smiley_themes_combo_box; static PurpleHttpConnection *prefs_themes_running_request = NULL; -/* Keyrings page */ -static GtkWidget *keyring_page_instance = NULL; -static GtkComboBox *keyring_combo = NULL; -static GtkBox *keyring_vbox = NULL; -static PurpleRequestFields *keyring_settings = NULL; -static GList *keyring_settings_fields = NULL; -static GtkWidget *keyring_apply = NULL; - /* Sound theme specific */ -static GtkWidget *sound_entry = NULL; static int sound_row_sel = 0; static gboolean prefs_sound_themes_loading; @@ -252,18 +293,6 @@ static GtkListStore *prefs_status_icon_themes; static GtkListStore *prefs_smiley_themes; -#ifdef USE_VV - -static GtkWidget *voice_level; -static GtkWidget *voice_threshold; -static GtkWidget *voice_volume; -static GstElement *voice_pipeline; - -static GtkWidget *video_drawing_area; -static GstElement *video_pipeline; - -#endif - /* * PROTOTYPES */ @@ -432,18 +461,15 @@ cb(combo_box, active); } -static void pidgin_prefs_dropdown_revert_active(GtkComboBox *combo_box) +static void +pidgin_prefs_bind_dropdown_revert_active(PidginPrefCombo *combo) { - gint previously_active; - - g_return_if_fail(combo_box != NULL); - - previously_active = GPOINTER_TO_INT(g_object_get_data( - G_OBJECT(combo_box), "previously_active")); - g_object_set_data(G_OBJECT(combo_box), "current_active", - GINT_TO_POINTER(previously_active)); - - gtk_combo_box_set_active(combo_box, previously_active); + g_return_if_fail(combo != NULL); + + combo->current_active = combo->previously_active; + + gtk_combo_box_set_active(GTK_COMBO_BOX(combo->combo), + combo->previously_active); } static GtkWidget * @@ -858,7 +884,7 @@ G_CALLBACK(set_bool_pref), (char *)key); } -static void keyring_page_cleanup(void); +static void keyring_page_cleanup(PidginPrefsWindow *win); static void delete_prefs(GtkWidget *asdf, void *gdsa) @@ -872,7 +898,6 @@ purple_prefs_disconnect_by_handle(prefs); /* NULL-ify globals */ - sound_entry = NULL; sound_row_sel = 0; prefs_sound_themes_loading = FALSE; @@ -881,14 +906,8 @@ prefs_status_themes_combo_box = NULL; prefs_smiley_themes_combo_box = NULL; - keyring_page_cleanup(); - -#ifdef USE_VV - voice_level = NULL; - voice_threshold = NULL; - voice_volume = NULL; - video_drawing_area = NULL; -#endif + keyring_page_cleanup(prefs); + g_free(prefs->proxy.gnome_program_path); g_free(prefs->browser.gnome_program_path); prefs = NULL; @@ -1455,43 +1474,32 @@ } /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */ -static GtkWidget * -prefs_build_theme_combo_box(GtkListStore *store, const char *current_theme, const char *type) +static void +prefs_build_theme_combo_box(GtkWidget *combo_box, GtkListStore *store, + const char *current_theme, const char *type) { - GtkCellRenderer *cell_rend; - GtkWidget *combo_box; GtkTargetEntry te[3] = { {"text/plain", 0, 0}, {"text/uri-list", 0, 1}, {"STRING", 0, 2} }; - g_return_val_if_fail(store != NULL && current_theme != NULL, NULL); - - combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); - - cell_rend = gtk_cell_renderer_pixbuf_new(); - gtk_cell_renderer_set_fixed_size(cell_rend, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL); - - cell_rend = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, TRUE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL); - g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_return_if_fail(store != NULL && current_theme != NULL); + + gtk_combo_box_set_model(GTK_COMBO_BOX(combo_box), + GTK_TREE_MODEL(store)); gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te, sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE); g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), (gpointer) type); - - return combo_box; } /* sets the current sound theme */ static void prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(user_data); gint i; gchar *pref; gchar *new_theme; @@ -1514,7 +1522,7 @@ /* gets rid of the "(Custom)" from the last selection */ pref_sound_generate_markup(); - gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + gtk_entry_set_text(GTK_ENTRY(win->sound.entry), _("(default)")); g_free(new_theme); } @@ -1616,95 +1624,36 @@ } } -static GtkWidget * -add_theme_prefs_combo(GtkWidget *vbox, - GtkSizeGroup *combo_sg, GtkSizeGroup *label_sg, - GtkListStore *theme_store, - GCallback combo_box_cb, gpointer combo_box_cb_user_data, - const char *label_str, const char *prefs_path, - const char *theme_type) +static void +bind_theme_page(PidginPrefsWindow *win) { - GtkWidget *label; - GtkWidget *combo_box = NULL; - GtkWidget *themesel_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BOX_SPACE); - - label = gtk_label_new(label_str); - gtk_label_set_xalign(GTK_LABEL(label), 0.0); - gtk_label_set_yalign(GTK_LABEL(label), 0.5); - gtk_size_group_add_widget(label_sg, label); - gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0); - - combo_box = prefs_build_theme_combo_box(theme_store, - purple_prefs_get_string(prefs_path), - theme_type); - g_signal_connect(G_OBJECT(combo_box), "changed", - (GCallback)combo_box_cb, combo_box_cb_user_data); - gtk_size_group_add_widget(combo_sg, combo_box); - gtk_box_pack_start(GTK_BOX(themesel_hbox), combo_box, TRUE, TRUE, 0); - - gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0); - - return combo_box; -} - -static GtkWidget * -theme_page(void) -{ - GtkWidget *label; - GtkWidget *ret, *vbox; - GtkSizeGroup *label_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkSizeGroup *combo_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_CAT_SPACE); - gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); - - vbox = pidgin_make_frame(ret, _("Theme Selections")); - - /* Instructions */ - label = gtk_label_new(_("Select a theme that you would like to use from " - "the lists below.\nNew themes can be installed by " - "dragging and dropping them onto the theme list.")); - - gtk_label_set_xalign(GTK_LABEL(label), 0.0); - gtk_label_set_yalign(GTK_LABEL(label), 0.5); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); - - gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); - gtk_widget_show(label); - /* Buddy List Themes */ - prefs_blist_themes_combo_box = add_theme_prefs_combo( - vbox, combo_sg, label_sg, prefs_blist_themes, - (GCallback)prefs_set_blist_theme_cb, NULL, - _("Buddy List Theme:"), PIDGIN_PREFS_ROOT "/blist/theme", "blist"); + prefs_build_theme_combo_box(win->theme.blist, prefs_blist_themes, + PIDGIN_PREFS_ROOT "/blist/theme", "blist"); + prefs_blist_themes_combo_box = win->theme.blist; /* Status Icon Themes */ - prefs_status_themes_combo_box = add_theme_prefs_combo( - vbox, combo_sg, label_sg, prefs_status_icon_themes, - (GCallback)prefs_set_status_icon_theme_cb, NULL, - _("Status Icon Theme:"), PIDGIN_PREFS_ROOT "/status/icon-theme", "icon"); + prefs_build_theme_combo_box(win->theme.status, prefs_status_icon_themes, + PIDGIN_PREFS_ROOT "/status/icon-theme", + "icon"); + prefs_status_themes_combo_box = win->theme.status; /* Sound Themes */ - prefs_sound_themes_combo_box = add_theme_prefs_combo( - vbox, combo_sg, label_sg, prefs_sound_themes, - (GCallback)prefs_set_sound_theme_cb, NULL, - _("Sound Theme:"), PIDGIN_PREFS_ROOT "/sound/theme", "sound"); + prefs_build_theme_combo_box(win->theme.sound, prefs_sound_themes, + PIDGIN_PREFS_ROOT "/sound/theme", "sound"); + prefs_sound_themes_combo_box = win->theme.sound; /* Smiley Themes */ - prefs_smiley_themes_combo_box = add_theme_prefs_combo( - vbox, combo_sg, label_sg, prefs_smiley_themes, - (GCallback)prefs_set_smiley_theme_cb, NULL, - _("Smiley Theme:"), PIDGIN_PREFS_ROOT "/smileys/theme", "smiley"); + prefs_build_theme_combo_box(win->theme.smiley, prefs_smiley_themes, + PIDGIN_PREFS_ROOT "/smileys/theme", + "smiley"); + prefs_smiley_themes_combo_box = win->theme.smiley; /* Custom sort so "none" theme is at top of list */ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(prefs_smiley_themes), 2, pidgin_sort_smileys, NULL, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(prefs_smiley_themes), 2, GTK_SORT_ASCENDING); - - gtk_widget_show_all(ret); - - return ret; } static void @@ -2187,11 +2136,20 @@ gtk_widget_set_sensitive(hbox, purple_strequal(browser, "custom")); } +#endif /* _WIN32 */ static void bind_browser_page(PidginPrefsWindow *win) { - if (purple_running_gnome()) { +#ifdef _WIN32 + /* We use the registered default browser in windows */ + gtk_widget_hide(win->browser.page); + return; +#else + /* if the user is running Mac OS X, hide the browsers tab */ + if (purple_running_osx()) { + gtk_widget_hide(win->browser.page); + } else if (purple_running_gnome()) { gchar *path; gtk_stack_set_visible_child_name(GTK_STACK(win->browser.stack), @@ -2252,8 +2210,8 @@ FALSE); } } +#endif /* _WIN32 */ } -#endif /*_WIN32*/ static void bind_proxy_page(PidginPrefsWindow *win) @@ -2356,7 +2314,7 @@ PurpleRequestField *setting = _setting; PurpleRequestFieldType field_type; - gtk_widget_set_sensitive(keyring_apply, TRUE); + gtk_widget_set_sensitive(prefs->keyring.apply, TRUE); field_type = purple_request_field_get_field_type(setting); @@ -2375,11 +2333,11 @@ g_return_if_reached(); } -static GtkWidget * +static void keyring_page_add_settings_field(GtkBox *vbox, PurpleRequestField *setting, GtkSizeGroup *sg) { - GtkWidget *widget, *hbox; + GtkWidget *widget; PurpleRequestFieldType field_type; const gchar *label; @@ -2411,25 +2369,26 @@ G_CALLBACK(keyring_page_settings_changed), setting); } else { purple_debug_error("gtkprefs", "Unsupported field type\n"); - return NULL; + return; } - hbox = pidgin_add_widget_to_vbox(vbox, label, sg, widget, - FALSE, NULL); - return ((void*)hbox == (void*)vbox) ? widget : hbox; + pidgin_add_widget_to_vbox(vbox, label, sg, widget, FALSE, NULL); } /* XXX: it could be available for all plugins, not keyrings only */ -static GList * -keyring_page_add_settings(PurpleRequestFields *settings) +static void +keyring_page_add_settings(PidginPrefsWindow *win) { - GList *it, *groups, *added_fields; + GtkWidget *box; + GList *it, *groups; GtkSizeGroup *sg; + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_BOX_SPACE); + gtk_box_pack_start(GTK_BOX(win->keyring.vbox), box, FALSE, FALSE, 0); + sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - added_fields = NULL; - groups = purple_request_fields_get_groups(settings); + groups = purple_request_fields_get_groups(win->keyring.settings); for (it = g_list_first(groups); it != NULL; it = g_list_next(it)) { GList *it2, *fields; GtkBox *vbox; @@ -2439,74 +2398,71 @@ group = it->data; group_title = purple_request_field_group_get_title(group); if (group_title) { - vbox = GTK_BOX(pidgin_make_frame( - GTK_WIDGET(keyring_vbox), group_title)); - added_fields = g_list_prepend(added_fields, - g_object_get_data(G_OBJECT(vbox), "main-vbox")); - } else - vbox = keyring_vbox; + vbox = GTK_BOX(pidgin_make_frame(box, group_title)); + } else { + vbox = GTK_BOX(box); + } fields = purple_request_field_group_get_fields(group); for (it2 = g_list_first(fields); it2 != NULL; it2 = g_list_next(it2)) { - GtkWidget *added = keyring_page_add_settings_field(vbox, - it2->data, sg); - if (added == NULL || vbox != keyring_vbox) - continue; - added_fields = g_list_prepend(added_fields, added); + keyring_page_add_settings_field(vbox, it2->data, sg); } } g_object_unref(sg); - return added_fields; + win->keyring.settings_box = box; } static void -keyring_page_settings_apply(GtkButton *button, gpointer _unused) +keyring_page_settings_apply(GtkButton *button, gpointer data) { - if (!purple_keyring_apply_settings(prefs, keyring_settings)) + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + + if (!purple_keyring_apply_settings(win, win->keyring.settings)) { return; - - gtk_widget_set_sensitive(keyring_apply, FALSE); + } + + gtk_widget_set_sensitive(win->keyring.apply, FALSE); } static void -keyring_page_update_settings() +keyring_page_update_settings(PidginPrefsWindow *win) { - if (keyring_settings != NULL) - purple_request_fields_destroy(keyring_settings); - keyring_settings = purple_keyring_read_settings(); - if (!keyring_settings) + g_clear_pointer(&win->keyring.settings, purple_request_fields_destroy); + win->keyring.settings = purple_keyring_read_settings(); + if (!win->keyring.settings) { return; - - keyring_settings_fields = keyring_page_add_settings(keyring_settings); - - keyring_apply = gtk_button_new_with_mnemonic(_("_Apply")); - gtk_box_pack_start(keyring_vbox, keyring_apply, FALSE, FALSE, 1); - gtk_widget_set_sensitive(keyring_apply, FALSE); - keyring_settings_fields = g_list_prepend(keyring_settings_fields, - keyring_apply); - g_signal_connect(G_OBJECT(keyring_apply), "clicked", - G_CALLBACK(keyring_page_settings_apply), NULL); - - gtk_widget_show_all(keyring_page_instance); + } + + keyring_page_add_settings(win); + + win->keyring.apply = gtk_button_new_with_mnemonic(_("_Apply")); + gtk_box_pack_start(GTK_BOX(win->keyring.settings_box), + win->keyring.apply, FALSE, FALSE, 1); + gtk_widget_set_sensitive(win->keyring.apply, FALSE); + g_signal_connect(G_OBJECT(win->keyring.apply), "clicked", + G_CALLBACK(keyring_page_settings_apply), win); + + gtk_widget_show_all(win->keyring.settings_box); } static void -keyring_page_pref_set_inuse(GError *error, gpointer _keyring_page_instance) +keyring_page_pref_set_inuse(GError *error, G_GNUC_UNUSED gpointer unused) { PurpleKeyring *in_use = purple_keyring_get_inuse(); - if (_keyring_page_instance != keyring_page_instance) { + if (prefs == NULL) { purple_debug_info("gtkprefs", "pref window already closed\n"); return; } - gtk_widget_set_sensitive(GTK_WIDGET(keyring_combo), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(prefs->keyring.active.combo), TRUE); if (error != NULL) { - pidgin_prefs_dropdown_revert_active(keyring_combo); + pidgin_prefs_bind_dropdown_revert_active( + &prefs->keyring.active); purple_notify_error(NULL, _("Keyring"), _("Failed to set new keyring"), error->message, NULL); return; @@ -2516,23 +2472,21 @@ purple_prefs_set_string("/purple/keyring/active", purple_keyring_get_id(in_use)); - keyring_page_update_settings(); + keyring_page_update_settings(prefs); } static void -keyring_page_pref_changed(GtkComboBox *combo_box, PidginPrefValue value) +keyring_page_pref_changed(GtkComboBox *combo_box, PidginPrefCombo *combo) { const char *keyring_id; PurpleKeyring *keyring; - GList *it; g_return_if_fail(combo_box != NULL); - g_return_if_fail(value.type == PURPLE_PREF_STRING); - - keyring_id = value.value.string; + + keyring_id = combo->value.string; keyring = purple_keyring_find_keyring_by_id(keyring_id); if (keyring == NULL) { - pidgin_prefs_dropdown_revert_active(keyring_combo); + pidgin_prefs_bind_dropdown_revert_active(combo); purple_notify_error(NULL, _("Keyring"), _("Selected keyring is disabled"), NULL, NULL); return; @@ -2540,70 +2494,71 @@ gtk_widget_set_sensitive(GTK_WIDGET(combo_box), FALSE); - for (it = keyring_settings_fields; it != NULL; it = g_list_next(it)) - { - GtkWidget *widget = it->data; - gtk_container_remove( - GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); - } - gtk_widget_show_all(keyring_page_instance); - g_list_free(keyring_settings_fields); - keyring_settings_fields = NULL; - if (keyring_settings) - purple_request_fields_destroy(keyring_settings); - keyring_settings = NULL; + g_clear_pointer(&prefs->keyring.settings_box, gtk_widget_destroy); + g_clear_pointer(&prefs->keyring.settings, + purple_request_fields_destroy); purple_keyring_set_inuse(keyring, FALSE, keyring_page_pref_set_inuse, - keyring_page_instance); + NULL); +} + +static void +keyring_page_cleanup(PidginPrefsWindow *win) +{ + g_clear_pointer(&win->keyring.settings, purple_request_fields_destroy); } static void -keyring_page_cleanup(void) -{ - keyring_page_instance = NULL; - keyring_combo = NULL; - keyring_vbox = NULL; - g_list_free(keyring_settings_fields); - keyring_settings_fields = NULL; - if (keyring_settings) - purple_request_fields_destroy(keyring_settings); - keyring_settings = NULL; - keyring_apply = NULL; -} - -static GtkWidget * -keyring_page(void) +bind_keyring_page(PidginPrefsWindow *win) { GList *names; - PidginPrefValue initial; - - g_return_val_if_fail(keyring_page_instance == NULL, - keyring_page_instance); - - keyring_page_instance = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_CAT_SPACE); - gtk_container_set_border_width(GTK_CONTAINER(keyring_page_instance), - PIDGIN_HIG_BORDER); /* Keyring selection */ - keyring_vbox = GTK_BOX(pidgin_make_frame(keyring_page_instance, - _("Keyring"))); names = purple_keyring_get_options(); - initial.type = PURPLE_PREF_STRING; - initial.value.string = purple_prefs_get_string("/purple/keyring/active"); - pidgin_prefs_dropdown_from_list_with_cb(GTK_WIDGET(keyring_vbox), - _("Keyring:"), &keyring_combo, names, initial, - keyring_page_pref_changed); + win->keyring.active.type = PURPLE_PREF_STRING; + win->keyring.active.key = "/purple/keyring/active"; + pidgin_prefs_bind_dropdown_from_list(&win->keyring.active, names); + /* Override the usual callback to defer changing the pref. */ + win->keyring.active.cb = keyring_page_pref_changed; g_list_free(names); - keyring_page_update_settings(); - - gtk_widget_show_all(keyring_page_instance); - - return keyring_page_instance; + keyring_page_update_settings(win); } /*** keyring page - end *************************************************/ +static gboolean +sound_method_filter(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) +{ + gboolean any = FALSE; + gboolean gstreamer = FALSE; + gboolean win32 = FALSE; + + gtk_tree_model_get(model, iter, 2, &any, 3, &gstreamer, 4, &win32, -1); + + if (any) { + return TRUE; + } + + if (gstreamer) { +#ifdef USE_GSTREAMER +#ifdef _WIN32 + return win32; +#else + return !win32; +#endif +#else + return FALSE; +#endif + } + +#ifdef _WIN32 + return win32; +#else + return !win32; +#endif +} + static gint sound_cmd_yeah(GtkEntry *entry, gpointer d) { @@ -2684,8 +2639,9 @@ * Resets a sound file back to default. */ static void -reset_sound(GtkWidget *button, gpointer i_am_also_NULL) +reset_sound(GtkWidget *button, gpointer data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); gchar *pref; pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", @@ -2693,7 +2649,7 @@ purple_prefs_set_path(pref, ""); g_free(pref); - gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + gtk_entry_set_text(GTK_ENTRY(win->sound.entry), _("(default)")); pref_sound_generate_markup(); } @@ -2717,7 +2673,7 @@ * sound, then update the box showing the file name. */ if (sound == sound_row_sel) - gtk_entry_set_text(GTK_ENTRY(sound_entry), filename); + gtk_entry_set_text(GTK_ENTRY(prefs->sound.entry), filename); pref_sound_generate_markup(); } @@ -2742,8 +2698,10 @@ } static void -prefs_sound_sel(GtkTreeSelection *sel, GtkTreeModel *model) +prefs_sound_sel(GtkTreeSelection *sel, gpointer data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + GtkTreeModel *model; GtkTreeIter iter; GValue val; const char *file; @@ -2760,147 +2718,81 @@ pidgin_sound_get_event_option(sound_row_sel)); file = purple_prefs_get_path(pref); g_free(pref); - if (sound_entry) - gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)")); + if (win->sound.entry) { + gtk_entry_set_text(GTK_ENTRY(win->sound.entry), + (file && *file != '\0') ? file + : _("(default)")); + } g_value_unset (&val); pref_sound_generate_markup(); } - static void -mute_changed_cb(const char *pref_name, - PurplePrefType pref_type, - gconstpointer val, - gpointer data) +bind_sound_page(PidginPrefsWindow *win) { - GtkToggleButton *button = data; - gboolean muted = GPOINTER_TO_INT(val); - - g_return_if_fail(purple_strequal (pref_name, PIDGIN_PREFS_ROOT "/sound/mute")); - - /* Block the handler that re-sets the preference. */ - g_signal_handlers_block_matched(button, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer)pref_name); - gtk_toggle_button_set_active (button, muted); - g_signal_handlers_unblock_matched(button, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer)pref_name); -} - - -static GtkWidget * -sound_page(void) -{ - GtkWidget *ret; - GtkWidget *vbox, *vbox2, *button, *parent, *parent_parent, *parent_parent_parent; - GtkSizeGroup *sg; - GtkTreeIter iter; - GtkWidget *event_view; - GtkListStore *event_store; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; + GtkTreeModel *model; GtkTreeSelection *sel; GtkTreePath *path; - GtkWidget *hbox; int j; const char *file; char *pref; - GtkWidget *dd; - GtkWidget *entry; const char *cmd; - ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_CAT_SPACE); - gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); - - sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - vbox2 = pidgin_make_frame(ret, _("Sound Options")); - - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(vbox2), vbox, FALSE, FALSE, 0); - - dd = pidgin_prefs_dropdown(vbox2, _("_Method:"), PURPLE_PREF_STRING, - PIDGIN_PREFS_ROOT "/sound/method", - _("Automatic"), "automatic", -#ifdef USE_GSTREAMER -#ifdef _WIN32 -/* "WaveForm", "waveform", */ - "DirectSound", "directsound", -#else - "ESD", "esd", - "ALSA", "alsa", -#endif /* _WIN32 */ -#endif /* USE_GSTREAMER */ -#ifdef _WIN32 - "PlaySound", "playsoundw", -#else - _("Console beep"), "beep", - _("Command"), "custom", -#endif /* _WIN32 */ - _("No sounds"), "none", - NULL); - gtk_size_group_add_widget(sg, dd); - gtk_label_set_xalign(GTK_LABEL(dd), 0.0); - gtk_label_set_yalign(GTK_LABEL(dd), 0.5); - - entry = gtk_entry_new(); - gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); + win->sound.method.type = PURPLE_PREF_STRING; + win->sound.method.key = PIDGIN_PREFS_ROOT "/sound/method"; + pidgin_prefs_bind_dropdown(&win->sound.method); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(win->sound.method.combo)); + gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model), sound_method_filter, NULL, NULL); + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(model)); + + gtk_widget_set_sensitive( + win->sound.method_vbox, + !purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT + "/sound/method"), + "none")); + purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", + sound_changed2_cb, + win->sound.method_vbox); + + gtk_widget_set_sensitive( + win->sound.command_hbox, + purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT + "/sound/method"), + "custom")); + purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", + sound_changed1_cb, + win->sound.command_hbox); + cmd = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/sound/command"); - if(cmd) - gtk_entry_set_text(GTK_ENTRY(entry), cmd); - g_signal_connect(G_OBJECT(entry), "changed", - G_CALLBACK(sound_cmd_yeah), NULL); - - hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Sound c_ommand:\n(%s for filename)"), sg, entry, TRUE, NULL); - purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", - sound_changed1_cb, hbox); - gtk_widget_set_sensitive(hbox, - purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), - "custom")); - - button = pidgin_prefs_checkbox(_("M_ute sounds"), PIDGIN_PREFS_ROOT "/sound/mute", vbox); - purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/mute", mute_changed_cb, button); - - pidgin_prefs_checkbox(_("Sounds when conversation has _focus"), - PIDGIN_PREFS_ROOT "/sound/conv_focus", vbox); - pidgin_prefs_dropdown(vbox, _("_Enable sounds:"), - PURPLE_PREF_INT, "/purple/sound/while_status", - _("Only when available"), PURPLE_SOUND_STATUS_AVAILABLE, - _("Only when not available"), PURPLE_SOUND_STATUS_AWAY, - _("Always"), PURPLE_SOUND_STATUS_ALWAYS, - NULL); - - gtk_widget_set_sensitive(vbox, - !purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none")); - purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", - sound_changed2_cb, vbox); - vbox = pidgin_make_frame(ret, _("Sound Events")); - - /* The following is an ugly hack to make the frame expand so the - * sound events list is big enough to be usable */ - parent = gtk_widget_get_parent(vbox); - parent_parent = gtk_widget_get_parent(parent); - parent_parent_parent = gtk_widget_get_parent(parent_parent); - gtk_box_set_child_packing(GTK_BOX(parent), vbox, TRUE, TRUE, 0, - GTK_PACK_START); - gtk_box_set_child_packing(GTK_BOX(parent_parent), - parent, TRUE, TRUE, 0, GTK_PACK_START); - gtk_box_set_child_packing(GTK_BOX(parent_parent_parent), - parent_parent, TRUE, TRUE, 0, GTK_PACK_START); + if (cmd) { + gtk_entry_set_text(GTK_ENTRY(win->sound.command), cmd); + } + + pidgin_prefs_bind_checkbox(PIDGIN_PREFS_ROOT "/sound/mute", + win->sound.mute); + + pidgin_prefs_bind_checkbox(PIDGIN_PREFS_ROOT "/sound/conv_focus", + win->sound.conv_focus); + + win->sound.while_status.type = PURPLE_PREF_INT; + win->sound.while_status.key = "/purple/sound/while_status"; + pidgin_prefs_bind_dropdown(&win->sound.while_status); /* SOUND SELECTION */ - event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); - for (j=0; j < PURPLE_NUM_SOUNDS; j++) { char *pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/enabled/%s", pidgin_sound_get_event_option(j)); const char *label = pidgin_sound_get_event_label(j); + GtkTreeIter iter; if (label == NULL) { g_free(pref); continue; } - gtk_list_store_append (event_store, &iter); - gtk_list_store_set(event_store, &iter, + gtk_list_store_append(win->sound.event.store, &iter); + gtk_list_store_set(win->sound.event.store, &iter, 0, purple_prefs_get_bool(pref), 1, _(label), 2, pref, @@ -2909,63 +2801,17 @@ g_free(pref); } - event_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(event_store)); - - rend = gtk_cell_renderer_toggle_new(); - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_view)); - g_signal_connect (G_OBJECT (sel), "changed", - G_CALLBACK (prefs_sound_sel), - NULL); - g_signal_connect (G_OBJECT(rend), "toggled", - G_CALLBACK(event_toggled), event_store); + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(win->sound.event.view)); path = gtk_tree_path_new_first(); gtk_tree_selection_select_path(sel, path); gtk_tree_path_free(path); - col = gtk_tree_view_column_new_with_attributes (_("Play"), - rend, - "active", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col); - - rend = gtk_cell_renderer_text_new(); - col = gtk_tree_view_column_new_with_attributes (_("Event"), - rend, - "text", 1, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col); - g_object_unref(G_OBJECT(event_store)); - gtk_box_pack_start(GTK_BOX(vbox), - pidgin_make_scrollable(event_view, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 100), - TRUE, TRUE, 0); - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); - sound_entry = gtk_entry_new(); pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", pidgin_sound_get_event_option(0)); file = purple_prefs_get_path(pref); g_free(pref); - gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)")); - gtk_editable_set_editable(GTK_EDITABLE(sound_entry), FALSE); - gtk_box_pack_start(GTK_BOX(hbox), sound_entry, FALSE, FALSE, PIDGIN_HIG_BOX_SPACE); - - button = gtk_button_new_with_mnemonic(_("_Browse...")); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(select_sound), NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); - - button = gtk_button_new_with_mnemonic(_("Pre_view")); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(test_sound), NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); - - button = gtk_button_new_with_mnemonic(_("_Reset")); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(reset_sound), NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); - - gtk_widget_show_all(ret); - g_object_unref(sg); - - return ret; + gtk_entry_set_text(GTK_ENTRY(win->sound.entry), + (file && *file != '\0') ? file : _("(default)")); } @@ -3099,12 +2945,14 @@ static void on_volume_change_cb(GtkWidget *w, gdouble value, gpointer data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); GstElement *volume; - if (!voice_pipeline) + if (!win->vv.voice.pipeline) { return; - - volume = gst_bin_get_by_name(GST_BIN(voice_pipeline), "volume"); + } + + volume = gst_bin_get_by_name(GST_BIN(win->vv.voice.pipeline), "volume"); g_object_set(volume, "volume", gtk_scale_button_get_value(GTK_SCALE_BUTTON(w)) * 10.0, NULL); } @@ -3133,6 +2981,8 @@ static gboolean gst_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT && gst_structure_has_name(gst_message_get_structure(msg), "level")) { @@ -3145,14 +2995,18 @@ GstElement *valve; percent = gst_msg_db_to_percent(msg, "rms"); - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(voice_level), percent); + gtk_progress_bar_set_fraction( + GTK_PROGRESS_BAR(win->vv.voice.level), percent); percent = gst_msg_db_to_percent(msg, "decay"); - threshold = gtk_range_get_value(GTK_RANGE(voice_threshold)) / 100.0; + threshold = gtk_range_get_value(GTK_RANGE( + win->vv.voice.threshold)) / + 100.0; valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve"); g_object_set(valve, "drop", (percent < threshold), NULL); - g_object_set(voice_level, "text", - (percent < threshold) ? _("DROP") : " ", NULL); + g_object_set(win->vv.voice.level, "text", + (percent < threshold) ? _("DROP") : " ", + NULL); } g_free(name); @@ -3164,23 +3018,25 @@ static void voice_test_destroy_cb(GtkWidget *w, gpointer data) { - if (!voice_pipeline) + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + + if (!win->vv.voice.pipeline) { return; - - gst_element_set_state(voice_pipeline, GST_STATE_NULL); - gst_object_unref(voice_pipeline); - voice_pipeline = NULL; + } + + gst_element_set_state(win->vv.voice.pipeline, GST_STATE_NULL); + g_clear_pointer(&win->vv.voice.pipeline, gst_object_unref); } static void -enable_voice_test(void) +enable_voice_test(PidginPrefsWindow *win) { GstBus *bus; - voice_pipeline = create_voice_pipeline(); - bus = gst_pipeline_get_bus(GST_PIPELINE(voice_pipeline)); + win->vv.voice.pipeline = create_voice_pipeline(); + bus = gst_pipeline_get_bus(GST_PIPELINE(win->vv.voice.pipeline)); gst_bus_add_signal_watch(bus); - g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), NULL); + g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), win); gst_object_unref(bus); } @@ -3190,28 +3046,29 @@ PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); if (gtk_toggle_button_get_active(test)) { - gtk_widget_set_sensitive(voice_level, TRUE); - enable_voice_test(); - - g_signal_connect(voice_volume, "value-changed", - G_CALLBACK(on_volume_change_cb), NULL); + gtk_widget_set_sensitive(win->vv.voice.level, TRUE); + enable_voice_test(win); + + g_signal_connect(win->vv.voice.volume, "value-changed", + G_CALLBACK(on_volume_change_cb), win); g_signal_connect(test, "destroy", - G_CALLBACK(voice_test_destroy_cb), NULL); + G_CALLBACK(voice_test_destroy_cb), win); g_signal_connect(win->notebook, "switch-page", G_CALLBACK(vv_test_switch_page_cb), test); } else { - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(voice_level), 0.0); - gtk_widget_set_sensitive(voice_level, FALSE); - g_object_disconnect(voice_volume, "any-signal::value-changed", - G_CALLBACK(on_volume_change_cb), NULL, - NULL); + gtk_progress_bar_set_fraction( + GTK_PROGRESS_BAR(win->vv.voice.level), 0.0); + gtk_widget_set_sensitive(win->vv.voice.level, FALSE); + g_object_disconnect(win->vv.voice.volume, + "any-signal::value-changed", + G_CALLBACK(on_volume_change_cb), win, NULL); g_object_disconnect(test, "any-signal::destroy", - G_CALLBACK(voice_test_destroy_cb), NULL, + G_CALLBACK(voice_test_destroy_cb), win, NULL); g_object_disconnect(win->notebook, "any-signal::switch-page", G_CALLBACK(vv_test_switch_page_cb), test, NULL); - voice_test_destroy_cb(NULL, NULL); + voice_test_destroy_cb(NULL, win); } } @@ -3283,9 +3140,9 @@ gtk_box_pack_start(GTK_BOX(vbox), level, FALSE, FALSE, 0); gtk_widget_set_sensitive(level, FALSE); - voice_volume = volume; - voice_level = level; - voice_threshold = threshold; + win->vv.voice.volume = volume; + win->vv.voice.level = level; + win->vv.voice.threshold = threshold; g_signal_connect(test, "toggled", G_CALLBACK(toggle_voice_test_cb), win); } @@ -3316,12 +3173,14 @@ static void video_test_destroy_cb(GtkWidget *w, gpointer data) { - if (!video_pipeline) + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + + if (!win->vv.video.pipeline) { return; - - gst_element_set_state(video_pipeline, GST_STATE_NULL); - gst_object_unref(video_pipeline); - video_pipeline = NULL; + } + + gst_element_set_state(win->vv.video.pipeline, GST_STATE_NULL); + g_clear_pointer(&win->vv.video.pipeline, gst_object_unref); } static void @@ -3354,10 +3213,10 @@ } static void -enable_video_test(void) +enable_video_test(PidginPrefsWindow *win) { GstBus *bus; - GdkWindow *window = gtk_widget_get_window(video_drawing_area); + GdkWindow *window = gtk_widget_get_window(win->vv.video.drawing_area); gulong window_id = 0; #ifdef GDK_WINDOWING_WIN32 @@ -3382,8 +3241,8 @@ # error "Unsupported GDK windowing system" #endif - video_pipeline = create_video_pipeline(); - bus = gst_pipeline_get_bus(GST_PIPELINE(video_pipeline)); + win->vv.video.pipeline = create_video_pipeline(); + bus = gst_pipeline_get_bus(GST_PIPELINE(win->vv.video.pipeline)); #if GST_CHECK_VERSION(1,0,0) gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL); #else @@ -3393,7 +3252,8 @@ G_CALLBACK(window_id_cb), (gpointer)window_id); gst_object_unref(bus); - gst_element_set_state(GST_ELEMENT(video_pipeline), GST_STATE_PLAYING); + gst_element_set_state(GST_ELEMENT(win->vv.video.pipeline), + GST_STATE_PLAYING); } static void @@ -3402,19 +3262,19 @@ PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); if (gtk_toggle_button_get_active(test)) { - enable_video_test(); + enable_video_test(win); g_signal_connect(test, "destroy", - G_CALLBACK(video_test_destroy_cb), NULL); + G_CALLBACK(video_test_destroy_cb), win); g_signal_connect(win->notebook, "switch-page", G_CALLBACK(vv_test_switch_page_cb), test); } else { g_object_disconnect(test, "any-signal::destroy", - G_CALLBACK(video_test_destroy_cb), NULL, + G_CALLBACK(video_test_destroy_cb), win, NULL); g_object_disconnect(win->notebook, "any-signal::switch-page", G_CALLBACK(vv_test_switch_page_cb), test, NULL); - video_test_destroy_cb(NULL, NULL); + video_test_destroy_cb(NULL, win); } } @@ -3424,7 +3284,7 @@ GtkWidget *test; GtkWidget *video; - video_drawing_area = video = pidgin_create_video_widget(); + win->vv.video.drawing_area = video = pidgin_create_video_widget(); gtk_box_pack_start(GTK_BOX(vbox), video, TRUE, TRUE, 0); gtk_widget_set_size_request(GTK_WIDGET(video), 240, 180); @@ -3439,6 +3299,8 @@ vv_device_changed_cb(const gchar *name, PurplePrefType type, gconstpointer value, gpointer data) { + PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data); + PurpleMediaManager *manager; PurpleMediaElementInfo *info; @@ -3447,12 +3309,12 @@ purple_media_manager_set_active_element(manager, info); /* Refresh test viewers */ - if (strstr(name, "audio") && voice_pipeline) { - voice_test_destroy_cb(NULL, NULL); - enable_voice_test(); - } else if(strstr(name, "video") && video_pipeline) { - video_test_destroy_cb(NULL, NULL); - enable_video_test(); + if (strstr(name, "audio") && win->vv.voice.pipeline) { + voice_test_destroy_cb(NULL, win); + enable_voice_test(win); + } else if (strstr(name, "video") && win->vv.video.pipeline) { + video_test_destroy_cb(NULL, win); + enable_video_test(win); } } @@ -3510,7 +3372,7 @@ } static GtkWidget * -make_vv_frame(GtkWidget *parent, GtkSizeGroup *sg, +make_vv_frame(PidginPrefsWindow *win, GtkWidget *parent, GtkSizeGroup *sg, const gchar *name, PurpleMediaElementType type) { GtkWidget *vbox; @@ -3521,8 +3383,8 @@ dropdown = make_vv_dropdown(vbox, sg, type); purple_prefs_connect_callback(vbox, - purple_media_type_to_preference_key(type), - vv_device_changed_cb, vbox); + purple_media_type_to_preference_key(type), + vv_device_changed_cb, win); g_signal_connect_swapped(vbox, "destroy", G_CALLBACK(purple_prefs_disconnect_by_handle), vbox); @@ -3571,26 +3433,30 @@ manager = purple_media_manager_get(); vbox = pidgin_make_frame(ret, _("Audio")); - frame = make_vv_frame(vbox, sg, _("Input"), - PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SRC); + frame = make_vv_frame(win, vbox, sg, _("Input"), + PURPLE_MEDIA_ELEMENT_AUDIO | + PURPLE_MEDIA_ELEMENT_SRC); g_signal_connect_object(manager, "elements-changed::audiosrc", G_CALLBACK(device_list_changed_cb), frame, 0); - frame = make_vv_frame(vbox, sg, _("Output"), - PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SINK); + frame = make_vv_frame(win, vbox, sg, _("Output"), + PURPLE_MEDIA_ELEMENT_AUDIO | + PURPLE_MEDIA_ELEMENT_SINK); g_signal_connect_object(manager, "elements-changed::audiosink", G_CALLBACK(device_list_changed_cb), frame, 0); make_voice_test(win, vbox); vbox = pidgin_make_frame(ret, _("Video")); - frame = make_vv_frame(vbox, sg, _("Input"), - PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SRC); + frame = make_vv_frame(win, vbox, sg, _("Input"), + PURPLE_MEDIA_ELEMENT_VIDEO | + PURPLE_MEDIA_ELEMENT_SRC); g_signal_connect_object(manager, "elements-changed::videosrc", G_CALLBACK(device_list_changed_cb), frame, 0); - frame = make_vv_frame(vbox, sg, _("Output"), - PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SINK); + frame = make_vv_frame(win, vbox, sg, _("Output"), + PURPLE_MEDIA_ELEMENT_VIDEO | + PURPLE_MEDIA_ELEMENT_SINK); g_signal_connect_object(manager, "elements-changed::videosink", G_CALLBACK(device_list_changed_cb), frame, 0); @@ -3602,51 +3468,26 @@ } #endif -static int -prefs_notebook_add_page(GtkNotebook *notebook, const char *text, - GtkWidget *page, int ind) -{ - return gtk_notebook_insert_page(notebook, page, gtk_label_new(text), ind); -} - static void prefs_notebook_init(PidginPrefsWindow *win) { +#ifdef USE_VV GtkNotebook *notebook = GTK_NOTEBOOK(win->notebook); - int notebook_page = 0; +#endif bind_interface_page(win); - notebook_page++; - -#ifdef _WIN32 - /* We use the registered default browser in windows */ - gtk_widget_hide(win->browser.page); -#else - /* if the user is running Mac OS X, hide the browsers tab */ - if (purple_running_osx()) { - gtk_widget_hide(win->browser.page); - } else { - bind_browser_page(win); - notebook_page++; - } -#endif - + bind_browser_page(win); bind_conv_page(win); - notebook_page++; bind_logging_page(win); - notebook_page++; bind_network_page(win); - notebook_page++; bind_proxy_page(win); - notebook_page++; - prefs_notebook_add_page(notebook, _("Password Storage"), keyring_page(), notebook_page++); - - prefs_notebook_add_page(notebook, _("Sounds"), sound_page(), notebook_page++); + bind_keyring_page(win); + bind_sound_page(win); bind_away_page(win); - notebook_page++; - prefs_notebook_add_page(notebook, _("Themes"), theme_page(), notebook_page++); + bind_theme_page(win); #ifdef USE_VV - prefs_notebook_add_page(notebook, _("Voice/Video"), vv_page(win), notebook_page++); + gtk_notebook_append_page(notebook, vv_page(win), + gtk_label_new(_("Voice/Video"))); #endif } @@ -3862,6 +3703,40 @@ gtk_widget_class_bind_template_callback(widget_class, proxy_print_option); + /* Keyrings page */ + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, keyring.active.combo); + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, keyring.vbox); + + /* Sounds page */ + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.method.combo); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.method_vbox); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.command); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.command_hbox); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.mute); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.conv_focus); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.while_status.combo); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.event.view); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.event.store); + gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow, + sound.entry); + gtk_widget_class_bind_template_callback(widget_class, sound_cmd_yeah); + gtk_widget_class_bind_template_callback(widget_class, prefs_sound_sel); + gtk_widget_class_bind_template_callback(widget_class, event_toggled); + gtk_widget_class_bind_template_callback(widget_class, select_sound); + gtk_widget_class_bind_template_callback(widget_class, test_sound); + gtk_widget_class_bind_template_callback(widget_class, reset_sound); + /* Away page */ gtk_widget_class_bind_template_child( widget_class, PidginPrefsWindow, @@ -3883,6 +3758,24 @@ widget_class, PidginPrefsWindow, away.startup_hbox); gtk_widget_class_bind_template_child( widget_class, PidginPrefsWindow, away.startup_label); + + /* Themes page */ + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, theme.blist); + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, theme.status); + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, theme.sound); + gtk_widget_class_bind_template_child( + widget_class, PidginPrefsWindow, theme.smiley); + gtk_widget_class_bind_template_callback(widget_class, + prefs_set_blist_theme_cb); + gtk_widget_class_bind_template_callback(widget_class, + prefs_set_status_icon_theme_cb); + gtk_widget_class_bind_template_callback(widget_class, + prefs_set_sound_theme_cb); + gtk_widget_class_bind_template_callback(widget_class, + prefs_set_smiley_theme_cb); } static void
--- a/pidgin/resources/Prefs/prefs.ui Tue Aug 06 01:16:36 2019 +0000 +++ b/pidgin/resources/Prefs/prefs.ui Tue Aug 06 04:51:53 2019 +0000 @@ -212,6 +212,14 @@ </row> </data> </object> + <object class="GtkListStore" id="keyring.active.store"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name value --> + <column type="gchararray"/> + </columns> + </object> <object class="GtkListStore" id="logging.format.store"> <columns> <!-- column-name text --> @@ -279,6 +287,115 @@ </row> </data> </object> + <object class="GtkListStore" id="sound.event.store"> + <columns> + <!-- column-name active --> + <column type="gboolean"/> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name pref --> + <column type="gchararray"/> + <!-- column-name id --> + <column type="guint"/> + </columns> + </object> + <object class="GtkListStore" id="sound.method.store_raw"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name value --> + <column type="gchararray"/> + <!-- column-name any --> + <column type="gboolean"/> + <!-- column-name gstreamer --> + <column type="gboolean"/> + <!-- column-name win32 --> + <column type="gboolean"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Automatic</col> + <col id="1">automatic</col> + <col id="2">True</col> + <col id="3">False</col> + <col id="4">False</col> + </row> + <row> + <col id="0" translatable="yes">DirectSound</col> + <col id="1">directsound</col> + <col id="2">False</col> + <col id="3">True</col> + <col id="4">True</col> + </row> + <row> + <col id="0" translatable="yes">ESD</col> + <col id="1">esd</col> + <col id="2">False</col> + <col id="3">True</col> + <col id="4">False</col> + </row> + <row> + <col id="0" translatable="yes">ALSA</col> + <col id="1">alsa</col> + <col id="2">False</col> + <col id="3">True</col> + <col id="4">False</col> + </row> + <row> + <col id="0" translatable="yes">PlaySound</col> + <col id="1">playsoundw</col> + <col id="2">False</col> + <col id="3">False</col> + <col id="4">True</col> + </row> + <row> + <col id="0" translatable="yes">Console beep</col> + <col id="1">beep</col> + <col id="2">False</col> + <col id="3">False</col> + <col id="4">False</col> + </row> + <row> + <col id="0" translatable="yes">Command</col> + <col id="1">custom</col> + <col id="2">False</col> + <col id="3">False</col> + <col id="4">False</col> + </row> + <row> + <col id="0" translatable="yes">No sounds</col> + <col id="1">none</col> + <col id="2">True</col> + <col id="3">False</col> + <col id="4">False</col> + </row> + </data> + </object> + <object class="GtkTreeModelFilter" id="sound.method.store"> + <property name="child_model">sound.method.store_raw</property> + </object> + <object class="GtkListStore" id="sound.while_status.store"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name value --> + <column type="gint"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Only when available</col> + <col id="1">1</col> + </row> + <row> + <col id="0" translatable="yes">Only when not available</col> + <col id="1">2</col> + </row> + <row> + <col id="0" translatable="yes">Always</col> + <col id="1">3</col> + </row> + </data> + </object> <template class="PidginPrefsWindow" parent="GtkDialog"> <property name="can_focus">False</property> <property name="title" translatable="yes">Preferences</property> @@ -2430,6 +2547,508 @@ </packing> </child> <child> + <object class="GtkBox" id="keyring.page"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="orientation">vertical</property> + <property name="spacing">18</property> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkBox" id="keyring.vbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Keyring:</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="keyring.active.combo"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">keyring.active.store</property> + <child> + <object class="GtkCellRendererText"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">6</property> + <property name="label" translatable="yes">Keyring</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="position">6</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Password Storage</property> + </object> + <packing> + <property name="position">6</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <object class="GtkBox" id="sound.page"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="orientation">vertical</property> + <property name="spacing">18</property> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Method:</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="sound.method.combo"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">sound.method.store</property> + <property name="id_column">1</property> + <child> + <object class="GtkCellRendererText"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="sound.method_vbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkBox" id="sound.command_hbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label17"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Sound c_ommand: +(%s for filename)</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">sound.command</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="sound.command"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <signal name="changed" handler="sound_cmd_yeah" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="sound.mute"> + <property name="label" translatable="yes">M_ute sounds</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="sound.conv_focus"> + <property name="label" translatable="yes">Sounds when conversation has _focus</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Enable sounds:</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="sound.while_status.combo"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">sound.while_status.store</property> + <child> + <object class="GtkCellRendererText"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">6</property> + <property name="label" translatable="yes">Sound Options</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <property name="min_content_height">100</property> + <child> + <object class="GtkTreeView" id="sound.event.view"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="model">sound.event.store</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"> + <signal name="changed" handler="prefs_sound_sel" object="PidginPrefsWindow" swapped="no"/> + </object> + </child> + <child> + <object class="GtkTreeViewColumn"> + <property name="title" translatable="yes">Play</property> + <child> + <object class="GtkCellRendererToggle"> + <signal name="toggled" handler="event_toggled" object="sound.event.store" swapped="no"/> + </object> + <attributes> + <attribute name="active">0</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn"> + <property name="title" translatable="yes">Event</property> + <child> + <object class="GtkCellRendererText"/> + <attributes> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkEntry" id="sound.entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">_Browse...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="select_sound" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">Pre_view</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="test_sound" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">_Reset</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="reset_sound" object="PidginPrefsWindow" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">6</property> + <property name="label" translatable="yes">Sound Events</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">7</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Sounds</property> + </object> + <packing> + <property name="position">7</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> <object class="GtkBox" id="away.page"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -2758,7 +3377,7 @@ </child> </object> <packing> - <property name="position">6</property> + <property name="position">8</property> </packing> </child> <child type="tab"> @@ -2768,7 +3387,302 @@ <property name="label" translatable="yes">Status / Idle</property> </object> <packing> - <property name="position">6</property> + <property name="position">8</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <object class="GtkBox" id="theme.page"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="orientation">vertical</property> + <property name="spacing">18</property> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Select a theme that you would like to use from the lists below. +New themes can be installed by dragging and dropping them onto the theme list.</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label19"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Buddy List Theme:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="theme.blist"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="prefs_set_blist_theme_cb" swapped="no"/> + <child> + <object class="GtkCellRendererPixbuf"> + <property name="width">32</property> + <property name="height">32</property> + </object> + <attributes> + <attribute name="pixbuf">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="markup">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label20"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Status Icon Theme:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="theme.status"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="prefs_set_status_icon_theme_cb" swapped="no"/> + <child> + <object class="GtkCellRendererPixbuf"> + <property name="width">32</property> + <property name="height">32</property> + </object> + <attributes> + <attribute name="pixbuf">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="markup">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label21"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Sound Theme:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="theme.sound"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="prefs_set_sound_theme_cb" object="PidginPrefsWindow" swapped="no"/> + <child> + <object class="GtkCellRendererPixbuf"> + <property name="width">32</property> + <property name="height">32</property> + </object> + <attributes> + <attribute name="pixbuf">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="markup">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label18"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Smiley Theme:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="theme.smiley"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="prefs_set_smiley_theme_cb" swapped="no"/> + <child> + <object class="GtkCellRendererPixbuf"> + <property name="width">32</property> + <property name="height">32</property> + </object> + <attributes> + <attribute name="pixbuf">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="markup">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">6</property> + <property name="label" translatable="yes">Theme Selections</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="position">9</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Themes</property> + </object> + <packing> + <property name="position">9</property> <property name="tab_fill">False</property> </packing> </child> @@ -2815,4 +3729,27 @@ <widget name="label11"/> </widgets> </object> + <object class="GtkSizeGroup" id="sound.sg"> + <widgets> + <widget name="label15"/> + <widget name="label16"/> + <widget name="label17"/> + </widgets> + </object> + <object class="GtkSizeGroup" id="theme.combo_sg"> + <widgets> + <widget name="theme.blist"/> + <widget name="theme.status"/> + <widget name="theme.sound"/> + <widget name="theme.smiley"/> + </widgets> + </object> + <object class="GtkSizeGroup" id="theme.label_sg"> + <widgets> + <widget name="label18"/> + <widget name="label19"/> + <widget name="label20"/> + <widget name="label21"/> + </widgets> + </object> </interface>