# HG changeset patch # User Gabriel Schulhof # Date 1242500813 0 # Node ID 88c87a40a738cde2853b27caecb6b9a7429711fa # Parent 7c58f6f50f160e05ebfab72651839cdeac29441c A patch from Gabriel Schulhof, updated to apply by Paul 'darkrain42' Aurich, which eliminates code duplication in gtkblist.c. Fixes #3553 committer: Richard Laager diff -r 7c58f6f50f16 -r 88c87a40a738 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sat May 16 17:11:50 2009 +0000 +++ b/pidgin/gtkblist.c Sat May 16 19:06:53 2009 +0000 @@ -75,47 +75,40 @@ typedef struct { PurpleAccount *account; - GtkWidget *window; + GtkBox *vbox; + GtkWidget *account_menu; + GtkSizeGroup *sg; +} PidginBlistRequestData; + +typedef struct +{ + PidginBlistRequestData rq_data; GtkWidget *combo; GtkWidget *entry; GtkWidget *entry_for_alias; - GtkWidget *account_box; } PidginAddBuddyData; typedef struct { - PurpleAccount *account; + PidginBlistRequestData rq_data; gchar *default_chat_name; - - GtkWidget *window; - GtkWidget *account_menu; + GList *entries; +} PidginChatData; + +typedef struct +{ + PidginChatData chat_data; + GtkWidget *alias_entry; GtkWidget *group_combo; - GtkWidget *entries_box; - GtkSizeGroup *sg; GtkWidget *autojoin; GtkWidget *persistent; - - GList *entries; - } PidginAddChatData; typedef struct { - PurpleAccount *account; - - GtkWidget *window; - GtkWidget *account_menu; - GtkWidget *entries_box; - GtkSizeGroup *sg; - - GList *entries; -} PidginJoinChatData; - -typedef struct -{ /** Used to hold error minidialogs. Gets packed * inside PidginBuddyList.error_buttons */ @@ -868,7 +861,7 @@ } static void -do_join_chat(PidginJoinChatData *data) +do_join_chat(PidginChatData *data) { if (data) { @@ -894,14 +887,14 @@ } } - chat = purple_chat_new(data->account, NULL, components); + chat = purple_chat_new(data->rq_data.account, NULL, components); gtk_blist_join_chat(chat); purple_blist_remove_chat(chat); } } static void -do_joinchat(GtkWidget *dialog, int id, PidginJoinChatData *info) +do_joinchat(GtkWidget *dialog, int id, PidginChatData *info) { switch(id) { @@ -910,7 +903,7 @@ break; case 1: - pidgin_roomlist_dialog_show_with_account(info->account); + pidgin_roomlist_dialog_show_with_account(info->rq_data.account); return; break; @@ -926,11 +919,11 @@ * strings are empty then don't allow the user to click on "OK." */ static void -joinchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) +set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) { PurplePluginProtocolInfo *prpl_info; PurpleConnection *gc; - PidginJoinChatData *data; + PidginChatData *data; GList *tmp; const char *text; gboolean required; @@ -949,13 +942,13 @@ } } - gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); - - gc = purple_account_get_connection(data->account); + gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), GTK_RESPONSE_OK, sensitive); + + gc = purple_account_get_connection(data->rq_data.account); prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL; sensitive = (prpl_info != NULL && prpl_info->roomlist_get_list != NULL); - gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), 1, sensitive); + gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), 1, sensitive); } static void @@ -967,97 +960,6 @@ pidgin_blist_update_buddy(purple_get_blist(), PURPLE_BLIST_NODE(buddy), TRUE); } -static void -rebuild_joinchat_entries(PidginJoinChatData *data) -{ - PurpleConnection *gc; - GList *list = NULL, *tmp; - GHashTable *defaults = NULL; - struct proto_chat_entry *pce; - gboolean focus = TRUE; - - g_return_if_fail(data->account != NULL); - - gc = purple_account_get_connection(data->account); - - gtk_container_foreach(GTK_CONTAINER(data->entries_box), (GtkCallback)gtk_widget_destroy, NULL); - - g_list_free(data->entries); - data->entries = NULL; - - if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) - list = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); - - if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) - defaults = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, NULL); - - for (tmp = list; tmp; tmp = tmp->next) - { - GtkWidget *input; - - pce = tmp->data; - - if (pce->is_int) - { - GtkObject *adjust; - adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, - 1, 10, 10); - input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); - gtk_widget_set_size_request(input, 50, -1); - pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, FALSE, NULL); - } - else - { - char *value; - input = gtk_entry_new(); - gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); - value = g_hash_table_lookup(defaults, pce->identifier); - if (value != NULL) - gtk_entry_set_text(GTK_ENTRY(input), value); - if (pce->secret) - { - gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ - } - pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, TRUE, NULL); - g_signal_connect(G_OBJECT(input), "changed", - G_CALLBACK(joinchat_set_sensitive_if_input_cb), data); - } - - /* Do the following for any type of input widget */ - if (focus) - { - gtk_widget_grab_focus(input); - focus = FALSE; - } - g_object_set_data(G_OBJECT(input), "identifier", (gpointer)pce->identifier); - g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); - g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); - data->entries = g_list_append(data->entries, input); - - g_free(pce); - } - - g_list_free(list); - g_hash_table_destroy(defaults); - - /* Set whether the "OK" button should be clickable initially */ - joinchat_set_sensitive_if_input_cb(NULL, data); - - gtk_widget_show_all(data->entries_box); -} - -static void -joinchat_select_account_cb(GObject *w, PurpleAccount *account, - PidginJoinChatData *data) -{ - data->account = account; - rebuild_joinchat_entries(data); -} - static gboolean chat_account_filter_func(PurpleAccount *account) { @@ -1085,32 +987,38 @@ return FALSE; } -void -pidgin_blist_joinchat_show(void) -{ - GtkWidget *hbox, *vbox; +static GtkWidget * +make_blist_request_dialog(PidginBlistRequestData *data, PurpleAccount *account, + const char *title, const char *window_role, const char *label_text, + GCallback callback_func, PurpleFilterAccountFunc filter_func, + GCallback response_cb) +{ GtkWidget *label; + GtkWidget *img; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWindow *blist_window; PidginBuddyList *gtkblist; - GtkWidget *img = NULL; - PidginJoinChatData *data = NULL; - - gtkblist = purple_blist_get_ui_data(); + + data->account = account; + img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION, - gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); - data = g_new0(PidginJoinChatData, 1); - - data->window = gtk_dialog_new_with_buttons(_("Join a Chat"), - NULL, GTK_DIALOG_NO_SEPARATOR, - _("Room _List"), 1, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - PIDGIN_STOCK_CHAT, GTK_RESPONSE_OK, NULL); + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); + + gtkblist = PIDGIN_BLIST(purple_get_blist()); + blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL; + + data->window = gtk_dialog_new_with_buttons(title, + blist_window, GTK_DIALOG_NO_SEPARATOR, + NULL); + + gtk_window_set_transient_for(GTK_WINDOW(data->window), blist_window); gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE); gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER); - gtk_container_set_border_width( - GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE); - gtk_window_set_role(GTK_WINDOW(data->window), "join_chat"); + gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE); + gtk_window_set_role(GTK_WINDOW(data->window), window_role); hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); @@ -1118,37 +1026,154 @@ gtk_misc_set_alignment(GTK_MISC(img), 0, 0); vbox = gtk_vbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); gtk_container_add(GTK_CONTAINER(hbox), vbox); - label = gtk_label_new(_("Please enter the appropriate information " - "about the chat you would like to join.\n")); + label = gtk_label_new(label_text); + + gtk_widget_set_size_request(label, 400, -1); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - data->account_menu = pidgin_account_option_menu_new(NULL, FALSE, - G_CALLBACK(joinchat_select_account_cb), - chat_account_filter_func, data); - - pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Account:"), data->sg, data->account_menu, TRUE, NULL); - - data->entries_box = gtk_vbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(vbox), data->entries_box); - gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); - - data->account = pidgin_account_option_menu_get_selected(data->account_menu); - - rebuild_joinchat_entries(data); - - g_signal_connect(G_OBJECT(data->window), "response", - G_CALLBACK(do_joinchat), data); + data->account_menu = pidgin_account_option_menu_new(account, FALSE, + callback_func, filter_func, data); + pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_ccount"), data->sg, data->account_menu, TRUE, NULL); + + data->vbox = GTK_BOX(gtk_vbox_new(FALSE, 5)); + gtk_container_set_border_width(GTK_CONTAINER(data->vbox), 0); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(data->vbox), FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(data->window), "response", response_cb, data); g_object_unref(data->sg); - gtk_widget_show_all(data->window); + return vbox; +} + +static void +rebuild_chat_entries(PidginChatData *data, const char *default_chat_name) +{ + PurpleConnection *gc; + GList *list = NULL, *tmp; + GHashTable *defaults = NULL; + struct proto_chat_entry *pce; + gboolean focus = TRUE; + + g_return_if_fail(data->rq_data.account != NULL); + + gc = purple_account_get_connection(data->rq_data.account); + + gtk_container_foreach(GTK_CONTAINER(data->rq_data.vbox), (GtkCallback)gtk_widget_destroy, NULL); + + g_list_free(data->entries); + data->entries = NULL; + + if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) + list = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); + + if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) + defaults = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, default_chat_name); + + for (tmp = list; tmp; tmp = tmp->next) + { + GtkWidget *input; + + pce = tmp->data; + + if (pce->is_int) + { + GtkObject *adjust; + adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, + 1, 10, 10); + input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); + gtk_widget_set_size_request(input, 50, -1); + pidgin_add_widget_to_vbox(GTK_BOX(data->rq_data.vbox), pce->label, data->rq_data.sg, input, FALSE, NULL); + } + else + { + char *value; + input = gtk_entry_new(); + gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); + value = g_hash_table_lookup(defaults, pce->identifier); + if (value != NULL) + gtk_entry_set_text(GTK_ENTRY(input), value); + if (pce->secret) + { + gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); +#if !GTK_CHECK_VERSION(2,16,0) + if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*') + gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR); +#endif /* Less than GTK+ 2.16 */ + } + pidgin_add_widget_to_vbox(data->rq_data.vbox, pce->label, data->rq_data.sg, input, TRUE, NULL); + g_signal_connect(G_OBJECT(input), "changed", + G_CALLBACK(set_sensitive_if_input_cb), data); + } + + /* Do the following for any type of input widget */ + if (focus) + { + gtk_widget_grab_focus(input); + focus = FALSE; + } + g_object_set_data(G_OBJECT(input), "identifier", (gpointer)pce->identifier); + g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); + g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); + data->entries = g_list_append(data->entries, input); + + g_free(pce); + } + + g_list_free(list); + g_hash_table_destroy(defaults); + + /* Set whether the "OK" button should be clickable initially */ + set_sensitive_if_input_cb(NULL, data); + + gtk_widget_show_all(GTK_WIDGET(data->rq_data.vbox)); +} + +static void +chat_select_account_cb(GObject *w, PurpleAccount *account, + PidginChatData *data) +{ + if (strcmp(purple_account_get_protocol_id(data->rq_data.account), + purple_account_get_protocol_id(account)) == 0) + { + data->rq_data.account = account; + } + else + { + data->rq_data.account = account; + rebuild_chat_entries(data, data->default_chat_name); + } +} + +void +pidgin_blist_joinchat_show(void) +{ + PidginChatData *data = NULL; + + data = g_new0(PidginChatData, 1); + + make_blist_request_dialog((PidginBlistRequestData *)data, NULL, + _("Join a Chat"), "join_chat", + _("Please enter the appropriate information about the chat " + "you would like to join.\n"), + G_CALLBACK(chat_select_account_cb), + chat_account_filter_func, (GCallback)do_joinchat); + gtk_dialog_add_buttons(GTK_DIALOG(data->rq_data.window), + _("Room _List"), 1, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + PIDGIN_STOCK_CHAT, GTK_RESPONSE_OK, NULL); + data->default_chat_name = NULL; + data->rq_data.account = pidgin_account_option_menu_get_selected(data->rq_data.account_menu); + + rebuild_chat_entries(data, NULL); + + gtk_widget_show_all(data->rq_data.window); } static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) @@ -6734,7 +6759,7 @@ PidginAddBuddyData *data) { /* Save our account */ - data->account = account; + data->rq_data.account = account; } static void @@ -6747,6 +6772,7 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data) { const char *grp, *who, *whoalias; + PurpleAccount *account; PurpleGroup *g; PurpleBuddy *b; PurpleConversation *c; @@ -6760,6 +6786,8 @@ if (*whoalias == '\0') whoalias = NULL; + account = data->rq_data.account; + g = NULL; if ((grp != NULL) && (*grp != '\0')) { @@ -6769,20 +6797,20 @@ purple_blist_add_group(g, NULL); } - b = purple_find_buddy_in_group(data->account, who, g); + b = purple_find_buddy_in_group(account, who, g); } - else if ((b = purple_find_buddy(data->account, who)) != NULL) + else if ((b = purple_find_buddy(account, who)) != NULL) { g = purple_buddy_get_group(b); } if (b == NULL) { - b = purple_buddy_new(data->account, who, whoalias); + b = purple_buddy_new(account, who, whoalias); purple_blist_add_buddy(b, NULL, g, NULL); } - purple_account_add_buddy(data->account, b); + purple_account_add_buddy(account, b); /* Offer to merge people with the same alias. */ if (whoalias != NULL && g != NULL) @@ -6803,7 +6831,7 @@ * Or something. --Mark */ - c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, data->account); + c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, data->rq_data.account); if (c != NULL) { icon = purple_conv_im_get_icon(PURPLE_CONV_IM(c)); if (icon != NULL) @@ -6811,103 +6839,52 @@ } } - gtk_widget_destroy(data->window); + gtk_widget_destroy(data->rq_data.window); } static void pidgin_blist_request_add_buddy(PurpleAccount *account, const char *username, const char *group, const char *alias) { - GtkWidget *table; - GtkWidget *label; - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *img; - PidginBuddyList *gtkblist; PidginAddBuddyData *data = g_new0(PidginAddBuddyData, 1); - data->account = + make_blist_request_dialog((PidginBlistRequestData *)data, (account != NULL - ? account - : purple_connection_get_account(purple_connections_get_all()->data)); - - img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION, - gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); - - gtkblist = PIDGIN_BLIST(purple_get_blist()); - - data->window = gtk_dialog_new_with_buttons(_("Add Buddy"), - gtkblist ? GTK_WINDOW(gtkblist->window) : NULL, GTK_DIALOG_NO_SEPARATOR, + ? account : purple_connection_get_account(purple_connections_get_all()->data)), + _("Add Buddy"), "add_buddy", + _("Add a buddy.\n"), + G_CALLBACK(add_buddy_select_account_cb), NULL, + G_CALLBACK(add_buddy_cb)); + gtk_dialog_add_buttons(GTK_DIALOG(data->rq_data.window), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_ADD, GTK_RESPONSE_OK, NULL); - if (gtkblist) - gtk_window_set_transient_for(GTK_WINDOW(data->window), GTK_WINDOW(gtkblist->window)); - gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); - gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE); - gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER); - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE); - gtk_window_set_role(GTK_WINDOW(data->window), "add_buddy"); - gtk_window_set_type_hint(GTK_WINDOW(data->window), - GDK_WINDOW_TYPE_HINT_DIALOG); - - hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); - gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); - gtk_misc_set_alignment(GTK_MISC(img), 0, 0); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(hbox), vbox); - - g_signal_connect(G_OBJECT(data->window), "destroy", + g_signal_connect(G_OBJECT(data->rq_data.window), "destroy", G_CALLBACK(destroy_add_buddy_dialog_cb), data); - label = gtk_label_new(_("Add a buddy.\n")); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); - - table = gtk_table_new(4, 2, FALSE); - gtk_table_set_row_spacings(GTK_TABLE(table), 5); - gtk_table_set_col_spacings(GTK_TABLE(table), 5); - gtk_container_set_border_width(GTK_CONTAINER(table), 0); - gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); - - data->account_box = pidgin_account_option_menu_new(account, FALSE, - G_CALLBACK(add_buddy_select_account_cb), NULL, data); - - gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 0, 2, 0, 1); - - label = gtk_label_new_with_mnemonic(_("Buddy's _username:")); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); - data->entry = gtk_entry_new(); - gtk_table_attach_defaults(GTK_TABLE(table), data->entry, 1, 2, 1, 2); + + pidgin_add_widget_to_vbox(data->rq_data.vbox, _("Buddy's _username:"), + data->rq_data.sg, data->entry, TRUE, NULL); gtk_widget_grab_focus(data->entry); if (username != NULL) gtk_entry_set_text(GTK_ENTRY(data->entry), username); else - gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), + gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), GTK_RESPONSE_OK, FALSE); gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE); - gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->entry); - pidgin_set_accessible_label (data->entry, label); g_signal_connect(G_OBJECT(data->entry), "changed", G_CALLBACK(pidgin_set_sensitive_if_input), - data->window); - - label = gtk_label_new_with_mnemonic(_("(Optional) A_lias:")); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); + data->rq_data.window); data->entry_for_alias = gtk_entry_new(); - gtk_table_attach_defaults(GTK_TABLE(table), - data->entry_for_alias, 1, 2, 2, 3); + pidgin_add_widget_to_vbox(data->rq_data.vbox, _("(Optional) A_lias:"), + data->rq_data.sg, data->entry_for_alias, TRUE, + NULL); if (alias != NULL) gtk_entry_set_text(GTK_ENTRY(data->entry_for_alias), alias); @@ -6915,23 +6892,11 @@ if (username != NULL) gtk_widget_grab_focus(GTK_WIDGET(data->entry_for_alias)); - gtk_entry_set_activates_default (GTK_ENTRY(data->entry_for_alias), TRUE); - gtk_label_set_mnemonic_widget(GTK_LABEL(label), data->entry_for_alias); - pidgin_set_accessible_label (data->entry_for_alias, label); - - label = gtk_label_new_with_mnemonic(_("Add buddy to _group:")); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); - data->combo = pidgin_text_combo_box_entry_new(group, groups_tree()); - gtk_table_attach_defaults(GTK_TABLE(table), data->combo, 1, 2, 3, 4); - gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_BIN(data->combo)->child); - pidgin_set_accessible_label (data->combo, label); - - g_signal_connect(G_OBJECT(data->window), "response", - G_CALLBACK(add_buddy_cb), data); - - gtk_widget_show_all(data->window); + pidgin_add_widget_to_vbox(data->rq_data.vbox, _("Add buddy to _group:"), + data->rq_data.sg, data->combo, TRUE, NULL); + + gtk_widget_show_all(data->rq_data.window); } static void @@ -6947,7 +6912,7 @@ components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - for (tmp = data->entries; tmp; tmp = tmp->next) + for (tmp = data->chat_data.entries; tmp; tmp = tmp->next) { if (g_object_get_data(tmp->data, "is_spin")) { @@ -6966,7 +6931,7 @@ } } - chat = purple_chat_new(data->account, + chat = purple_chat_new(data->chat_data.rq_data.account, gtk_entry_get_text(GTK_ENTRY(data->alias_entry)), components); @@ -6990,9 +6955,9 @@ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->persistent))) purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent", TRUE); - gtk_widget_destroy(data->window); - g_free(data->default_chat_name); - g_list_free(data->entries); + gtk_widget_destroy(data->chat_data.rq_data.window); + g_free(data->chat_data.default_chat_name); + g_list_free(data->chat_data.entries); g_free(data); } @@ -7005,166 +6970,25 @@ } else if (resp == 1) { - pidgin_roomlist_dialog_show_with_account(data->account); + pidgin_roomlist_dialog_show_with_account(data->chat_data.rq_data.account); } else { - gtk_widget_destroy(data->window); - g_free(data->default_chat_name); - g_list_free(data->entries); + gtk_widget_destroy(data->chat_data.rq_data.window); + g_free(data->chat_data.default_chat_name); + g_list_free(data->chat_data.entries); g_free(data); } } -/* - * Check the values of all the text entry boxes. If any required input - * strings are empty then don't allow the user to click on "OK." - */ -static void -addchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) -{ - PurplePluginProtocolInfo *prpl_info; - PurpleConnection *gc; - PidginAddChatData *data; - GList *tmp; - const char *text; - gboolean required; - gboolean sensitive = TRUE; - - data = user_data; - - for (tmp = data->entries; tmp != NULL; tmp = tmp->next) - { - if (!g_object_get_data(tmp->data, "is_spin")) - { - required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required")); - text = gtk_entry_get_text(tmp->data); - if (required && (*text == '\0')) - sensitive = FALSE; - } - } - - gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); - - gc = purple_account_get_connection(data->account); - prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL; - sensitive = (prpl_info != NULL && prpl_info->roomlist_get_list != NULL); - - gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), 1, sensitive); -} - -static void -rebuild_addchat_entries(PidginAddChatData *data) -{ - PurpleConnection *gc; - GList *list = NULL, *tmp; - GHashTable *defaults = NULL; - struct proto_chat_entry *pce; - gboolean focus = TRUE; - - g_return_if_fail(data->account != NULL); - - gc = purple_account_get_connection(data->account); - - gtk_container_foreach(GTK_CONTAINER(data->entries_box), (GtkCallback)gtk_widget_destroy, NULL); - - g_list_free(data->entries); - - data->entries = NULL; - - if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) - list = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); - - if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) - defaults = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, data->default_chat_name); - - for (tmp = list; tmp; tmp = tmp->next) - { - GtkWidget *input; - - pce = tmp->data; - - if (pce->is_int) - { - GtkObject *adjust; - adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, - 1, 10, 10); - input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); - gtk_widget_set_size_request(input, 50, -1); - pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, FALSE, NULL); - } - else - { - char *value; - input = gtk_entry_new(); - gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); - value = g_hash_table_lookup(defaults, pce->identifier); - if (value != NULL) - gtk_entry_set_text(GTK_ENTRY(input), value); - if (pce->secret) - { - gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ - } - pidgin_add_widget_to_vbox(GTK_BOX(data->entries_box), pce->label, data->sg, input, TRUE, NULL); - g_signal_connect(G_OBJECT(input), "changed", - G_CALLBACK(addchat_set_sensitive_if_input_cb), data); - } - - /* Do the following for any type of input widget */ - if (focus) - { - gtk_widget_grab_focus(input); - focus = FALSE; - } - g_object_set_data(G_OBJECT(input), "identifier", (gpointer)pce->identifier); - g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); - g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); - data->entries = g_list_append(data->entries, input); - - g_free(pce); - } - - g_list_free(list); - g_hash_table_destroy(defaults); - - /* Set whether the "OK" button should be clickable initially */ - addchat_set_sensitive_if_input_cb(NULL, data); - - gtk_widget_show_all(data->entries_box); -} - -static void -addchat_select_account_cb(GObject *w, PurpleAccount *account, - PidginAddChatData *data) -{ - if (strcmp(purple_account_get_protocol_id(data->account), - purple_account_get_protocol_id(account)) == 0) - { - data->account = account; - } - else - { - data->account = account; - rebuild_addchat_entries(data); - } -} - static void pidgin_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group, const char *alias, const char *name) { PidginAddChatData *data; - PidginBuddyList *gtkblist; GList *l; PurpleConnection *gc; - GtkWidget *label; - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *img; + GtkBox *vbox; if (account != NULL) { gc = purple_account_get_connection(account); @@ -7193,82 +7017,44 @@ } data = g_new0(PidginAddChatData, 1); - data->account = account; - data->default_chat_name = g_strdup(name); - - img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION, - gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); - - gtkblist = PIDGIN_BLIST(purple_get_blist()); - - data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - data->window = gtk_dialog_new_with_buttons(_("Add Chat"), - gtkblist ? GTK_WINDOW(gtkblist->window) : NULL, GTK_DIALOG_NO_SEPARATOR, - _("Room _List"), 1, + vbox = GTK_BOX(make_blist_request_dialog((PidginBlistRequestData *)data, account, + _("Add Chat"), "add_chat", + _("Please enter an alias, and the appropriate information " + "about the chat you would like to add to your buddy list.\n"), + G_CALLBACK(chat_select_account_cb), chat_account_filter_func, + G_CALLBACK(add_chat_resp_cb))); + gtk_dialog_add_buttons(GTK_DIALOG(data->chat_data.rq_data.window), + _("Room List"), 1, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_ADD, GTK_RESPONSE_OK, NULL); - if (gtkblist) - gtk_window_set_transient_for(GTK_WINDOW(data->window), GTK_WINDOW(gtkblist->window)); - gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); - gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE); - gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER); - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE); - gtk_window_set_role(GTK_WINDOW(data->window), "add_chat"); - gtk_window_set_type_hint(GTK_WINDOW(data->window), - GDK_WINDOW_TYPE_HINT_DIALOG); - - hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); - gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); - gtk_misc_set_alignment(GTK_MISC(img), 0, 0); - - vbox = gtk_vbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(hbox), vbox); - - label = gtk_label_new( - _("Please enter an alias, and the appropriate information " - "about the chat you would like to add to your buddy list.\n")); - gtk_widget_set_size_request(label, 400, -1); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); - - data->account_menu = pidgin_account_option_menu_new(account, FALSE, - G_CALLBACK(addchat_select_account_cb), - chat_account_filter_func, data); - pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Account:"), data->sg, data->account_menu, TRUE, NULL); - - data->entries_box = gtk_vbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); - gtk_box_pack_start(GTK_BOX(vbox), data->entries_box, TRUE, TRUE, 0); - - rebuild_addchat_entries(data); + data->chat_data.default_chat_name = g_strdup(name); + + rebuild_chat_entries((PidginChatData *)data, name); data->alias_entry = gtk_entry_new(); if (alias != NULL) gtk_entry_set_text(GTK_ENTRY(data->alias_entry), alias); gtk_entry_set_activates_default(GTK_ENTRY(data->alias_entry), TRUE); - pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_lias:"), data->sg, data->alias_entry, TRUE, NULL); + pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_lias:"), + data->chat_data.rq_data.sg, data->alias_entry, + TRUE, NULL); if (name != NULL) gtk_widget_grab_focus(data->alias_entry); data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree()); - pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"), data->sg, data->group_combo, TRUE, NULL); + pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"), + data->chat_data.rq_data.sg, data->group_combo, + TRUE, NULL); data->autojoin = gtk_check_button_new_with_mnemonic(_("Auto_join when account becomes online.")); data->persistent = gtk_check_button_new_with_mnemonic(_("_Remain in chat after window is closed.")); gtk_box_pack_start(GTK_BOX(vbox), data->autojoin, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), data->persistent, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(data->window), "response", - G_CALLBACK(add_chat_resp_cb), data); - - gtk_widget_show_all(data->window); + gtk_widget_show_all(data->chat_data.rq_data.window); } static void @@ -8195,4 +7981,3 @@ if (activeitem) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE); } -