# HG changeset patch # User Sadrul Habib Chowdhury # Date 1209554903 0 # Node ID 3fee7e01e51c9b1c05716546ca5883fc107feaf3 # Parent 01e375e9b6812b9973776f577efe12b940066a30# Parent 133798922e2d5301effac8da39d737b9c2e2c299 merge of '0df1437fe05dad8b69aac22bcd7cb8851ca4ebeb' and '6a973c8f7b76929a8de62bbfd78b7aa36551c809' diff -r 01e375e9b681 -r 3fee7e01e51c ChangeLog --- a/ChangeLog Wed Apr 30 11:27:17 2008 +0000 +++ b/ChangeLog Wed Apr 30 11:28:23 2008 +0000 @@ -16,6 +16,8 @@ hard time with the lack of the button. * Clicking on the buddyicon in the conversation window toggles the size of the icon between small and large. + * The settings of a chat (e.g. Handle in an XMPP chat, or Exchange in an + AIM chat) can be edited from its context menu in the buddy list. General: * The configure script now dies on more absent dependencies. The diff -r 01e375e9b681 -r 3fee7e01e51c doc/conversation-signals.dox --- a/doc/conversation-signals.dox Wed Apr 30 11:27:17 2008 +0000 +++ b/doc/conversation-signals.dox Wed Apr 30 11:28:23 2008 +0000 @@ -27,6 +27,7 @@ @signal chat-invited-user @signal chat-invited @signal chat-joined + @signal chat-join-failed @signal chat-left @signal chat-topic-changed @signal conversation-extended-menu @@ -302,6 +303,18 @@ @param new_arrival If the buddy is a new arrival. @endsignaldef + @signaldef chat-join-failed + @signalproto +void (*chat_join_failed)(PurpleConnection *gc, GHashTable *components); + @endsignalproto + @signaldesc + Emitted when an account fails to join a chat room + @param gc The PurpleConnection of the account which failed to join the chat. + @param data The components passed to serv_join_chat() originally. + The hash function should be g_str_hash() and the equal + function should be g_str_equal(). + @endsignaldef + @signaldef chat-buddy-flags @signalproto void (*chat_buddy_flags)(PurpleConversation *conv, const char *name, diff -r 01e375e9b681 -r 3fee7e01e51c finch/gntblist.c --- a/finch/gntblist.c Wed Apr 30 11:27:17 2008 +0000 +++ b/finch/gntblist.c Wed Apr 30 11:28:23 2008 +0000 @@ -380,6 +380,27 @@ fnode = FINCH_GET_DATA(node); if (fnode && fnode->signed_timer) flag |= GNT_TEXT_FLAG_BLINK; + } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { + /* If the node is collapsed, then check to see if any of the priority buddies of + * any of the contacts within this group recently signed on/off, and set the blink + * flag appropriately. */ + /* XXX: Refs #5444 */ + /* XXX: there's no way I can ask if the node is expanded or not? *sigh* + * API addition would be necessary */ +#if 0 + if (!gnt_tree_get_expanded(GNT_TREE(ggblist->tree), node)) { + for (node = purple_blist_node_get_first_child(node); node; + node = purple_blist_node_get_sibling_next(node)) { + PurpleBlistNode *pnode; + pnode = purple_contact_get_priority_buddy((PurpleContact*)node); + fnode = FINCH_GET_DATA(node); + if (fnode && fnode->signed_timer) { + flag |= GNT_TEXT_FLAG_BLINK; + break; + } + } + } +#endif } return flag; @@ -1034,7 +1055,11 @@ else val = g_strdup(purple_request_field_string_get_value(field)); - g_hash_table_replace(purple_chat_get_components(chat), g_strdup(id), val); /* val should not be free'd */ + if (!val) { + g_hash_table_remove(purple_chat_get_components(chat), id); + } else { + g_hash_table_replace(purple_chat_get_components(chat), g_strdup(id), val); /* val should not be free'd */ + } } } } @@ -1065,8 +1090,13 @@ } else { field = purple_request_field_string_new(pce->identifier, pce->label, g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier), FALSE); + if (pce->secret) + purple_request_field_string_set_masked(field, TRUE); } + if (pce->required) + purple_request_field_set_required(field, TRUE); + purple_request_field_group_add_field(group, field); g_free(pce); } diff -r 01e375e9b681 -r 3fee7e01e51c finch/gntlog.c --- a/finch/gntlog.c Wed Apr 30 11:27:17 2008 +0000 +++ b/finch/gntlog.c Wed Apr 30 11:28:23 2008 +0000 @@ -139,7 +139,8 @@ } -static void destroy_cb(GntWidget *w, struct log_viewer_hash_t *ht) { +static void destroy_cb(GntWidget *w, struct log_viewer_hash_t *ht) +{ FinchLogViewer *lv = syslog_viewer; if (ht != NULL) { @@ -162,12 +163,12 @@ gnt_widget_destroy(w); } -static void log_select_cb(GntWidget *w, gpointer old, gpointer new, FinchLogViewer *viewer) { +static void log_select_cb(GntWidget *w, gpointer old, gpointer new, FinchLogViewer *viewer) +{ GntTree *tree = GNT_TREE(w); PurpleLog *log = NULL; PurpleLogReadFlags flags; char *read = NULL, *strip, *newline; - int h; if (!viewer->search && !gnt_tree_get_parent_key(tree, new)) return; @@ -204,8 +205,6 @@ gnt_text_view_clear(GNT_TEXT_VIEW(viewer->text)); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(viewer->text), strip, GNT_TEXT_FLAG_NORMAL); - gnt_widget_get_size(viewer->text, NULL, &h); - gnt_text_view_scroll(GNT_TEXT_VIEW(viewer->text), h - 2); g_free(read); g_free(strip); } @@ -321,6 +320,7 @@ /* Viewer ************/ lv->text = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(hbox), lv->text); + gnt_text_view_set_flag(GNT_TEXT_VIEW(lv->text), GNT_TEXT_VIEW_TOP_ALIGN); hbox = gnt_hbox_new(FALSE); gnt_box_add_widget(GNT_BOX(vbox), hbox); diff -r 01e375e9b681 -r 3fee7e01e51c finch/gntrequest.c --- a/finch/gntrequest.c Wed Apr 30 11:27:17 2008 +0000 +++ b/finch/gntrequest.c Wed Apr 30 11:28:23 2008 +0000 @@ -295,8 +295,7 @@ * updating the fields at the end like here, it updates the appropriate field * instantly whenever a change is made. That allows it to make sure the * 'required' fields are entered before the user can hit OK. It's not the case - * here, althought it can be done. I am not honouring the 'required' fields - * for the moment. */ + * here, althought it can be done. */ for (list = purple_request_fields_get_groups(fields); list; list = list->next) { PurpleRequestFieldGroup *group = list->data; @@ -368,6 +367,15 @@ } } + purple_notify_close_with_handle(button); + + if (!purple_request_fields_all_required_filled(fields)) { + purple_notify_error(button, _("Error"), + _("You must fill all the required fields."), + _("The required fields are underlined.")); + return; + } + if (callback) callback(data, fields); @@ -587,7 +595,11 @@ if (type != PURPLE_REQUEST_FIELD_BOOLEAN && label) { - GntWidget *l = gnt_label_new(label); + GntWidget *l; + if (purple_request_field_is_required(field)) + l = gnt_label_new_with_format(label, GNT_TEXT_FLAG_UNDERLINE); + else + l = gnt_label_new(label); gnt_widget_set_size(l, 0, 1); gnt_box_add_widget(GNT_BOX(hbox), l); } diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/conversation.c --- a/libpurple/conversation.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/conversation.c Wed Apr 30 11:28:23 2008 +0000 @@ -2372,7 +2372,7 @@ purple_marshal_VOID__POINTER_POINTER, NULL, 2, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION), - purple_value_new(PURPLE_TYPE_STRING)); + purple_value_new(PURPLE_TYPE_POINTER)); purple_signal_register(handle, "chat-left", purple_marshal_VOID__POINTER, NULL, 1, diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/protocols/jabber/buddy.c Wed Apr 30 11:28:23 2008 +0000 @@ -155,12 +155,8 @@ } jbr->priority = priority; jbr->state = state; - if(jbr->status) - g_free(jbr->status); - if (status) - jbr->status = g_markup_escape_text(status, -1); - else - jbr->status = NULL; + g_free(jbr->status); + jbr->status = status != NULL ? g_markup_escape_text(status, -1) : NULL; return jbr; } diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/jabber/chat.c --- a/libpurple/protocols/jabber/chat.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/protocols/jabber/chat.c Wed Apr 30 11:28:23 2008 +0000 @@ -222,39 +222,36 @@ if(!handle) handle = js->user->node; - tmp = g_strdup_printf("%s@%s", room, server); - room_jid = g_strdup(jabber_normalize(NULL, tmp)); - g_free(tmp); - if(!jabber_nodeprep_validate(room)) { char *buf = g_strdup_printf(_("%s is not a valid room name"), room); purple_notify_error(gc, _("Invalid Room Name"), _("Invalid Room Name"), buf); - purple_serv_got_join_chat_failed(gc, room_jid); - g_free(room_jid); + purple_serv_got_join_chat_failed(gc, data); g_free(buf); return; } else if(!jabber_nameprep_validate(server)) { char *buf = g_strdup_printf(_("%s is not a valid server name"), server); purple_notify_error(gc, _("Invalid Server Name"), _("Invalid Server Name"), buf); - purple_serv_got_join_chat_failed(gc, room_jid); - g_free(room_jid); + purple_serv_got_join_chat_failed(gc, data); g_free(buf); return; } else if(!jabber_resourceprep_validate(handle)) { char *buf = g_strdup_printf(_("%s is not a valid room handle"), handle); purple_notify_error(gc, _("Invalid Room Handle"), _("Invalid Room Handle"), buf); - purple_serv_got_join_chat_failed(gc, room_jid); + purple_serv_got_join_chat_failed(gc, data); g_free(buf); - g_free(room_jid); return; } if(jabber_chat_find(js, room, server)) return; + tmp = g_strdup_printf("%s@%s", room, server); + room_jid = g_strdup(jabber_normalize(NULL, tmp)); + g_free(tmp); + chat = g_new0(JabberChat, 1); chat->js = gc->proto_data; @@ -262,6 +259,8 @@ chat->server = g_strdup(server); chat->handle = g_strdup(handle); + chat->components = g_hash_table_ref(data); + chat->members = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)jabber_chat_member_free); @@ -322,6 +321,7 @@ g_free(chat->server); g_free(chat->handle); g_hash_table_destroy(chat->members); + g_hash_table_unref(chat->components); g_free(chat); } diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/jabber/chat.h --- a/libpurple/protocols/jabber/chat.h Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/protocols/jabber/chat.h Wed Apr 30 11:28:23 2008 +0000 @@ -41,6 +41,7 @@ char *room; char *server; char *handle; + GHashTable *components; int id; PurpleConversation *conv; gboolean muc; diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/jabber/presence.c --- a/libpurple/protocols/jabber/presence.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/protocols/jabber/presence.c Wed Apr 30 11:28:23 2008 +0000 @@ -369,17 +369,29 @@ typedef struct _JabberPresenceCapabilities { JabberStream *js; - JabberBuddyResource *jbr; + JabberBuddy *jb; char *from; } JabberPresenceCapabilities; static void jabber_presence_set_capabilities(JabberCapsClientInfo *info, gpointer user_data) { JabberPresenceCapabilities *userdata = user_data; + JabberID *jid; + JabberBuddyResource *jbr; GList *iter; - if(userdata->jbr->caps) - jabber_caps_free_clientinfo(userdata->jbr->caps); - userdata->jbr->caps = info; + jid = jabber_id_new(userdata->from); + jbr = jabber_buddy_find_resource(userdata->jb, jid->resource); + jabber_id_free(jid); + + if(!jbr) { + g_free(userdata->from); + g_free(userdata); + return; + } + + if(jbr->caps) + jabber_caps_free_clientinfo(jbr->caps); + jbr->caps = info; if (info) { for(iter = info->features; iter; iter = g_list_next(iter)) { @@ -575,7 +587,7 @@ serv_got_chat_left(js->gc, chat->id); } else { title = g_strdup_printf(_("Error joining chat %s"), from); - purple_serv_got_join_chat_failed(js->gc, room_jid); + purple_serv_got_join_chat_failed(js->gc, chat->components); } purple_notify_error(js->gc, title, title, msg); g_free(title); @@ -742,7 +754,7 @@ if(node && ver) { JabberPresenceCapabilities *userdata = g_new0(JabberPresenceCapabilities, 1); userdata->js = js; - userdata->jbr = jbr; + userdata->jb = jb; userdata->from = g_strdup(from); jabber_caps_get_info(js, from, node, ver, ext, jabber_presence_set_capabilities, userdata); } diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/msn/msn.c diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/msnp9/msn.c diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/myspace/myspace.c diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/protocols/oscar/misc.c --- a/libpurple/protocols/oscar/misc.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/protocols/oscar/misc.c Wed Apr 30 11:28:23 2008 +0000 @@ -39,7 +39,6 @@ void aim_genericreq_n(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype) { - FlapFrame *frame; aim_snacid_t snacid = 0x00000000; flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL); @@ -48,7 +47,6 @@ void aim_genericreq_n_snacid(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype) { - FlapFrame *frame; aim_snacid_t snacid; snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0); diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/prpl.h diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/server.c --- a/libpurple/server.c Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/server.c Wed Apr 30 11:28:23 2008 +0000 @@ -967,10 +967,10 @@ purple_signal_emit(purple_conversations_get_handle(), "chat-left", conv); } -void purple_serv_got_join_chat_failed(PurpleConnection *gc, const char *name) +void purple_serv_got_join_chat_failed(PurpleConnection *gc, GHashTable *data) { purple_signal_emit(purple_conversations_get_handle(), "chat-join-failed", - gc, name); + gc, data); } void serv_got_chat_in(PurpleConnection *g, int id, const char *who, diff -r 01e375e9b681 -r 3fee7e01e51c libpurple/server.h --- a/libpurple/server.h Wed Apr 30 11:27:17 2008 +0000 +++ b/libpurple/server.h Wed Apr 30 11:28:23 2008 +0000 @@ -171,9 +171,11 @@ * fails. * * @param gc The connection on which chat joining failed - * @param name The name of the chat which we did not join + * @param data The components passed to serv_join_chat() originally. + * The hash function should be g_str_hash() and the equal + * function should be g_str_equal(). */ -void purple_serv_got_join_chat_failed(PurpleConnection *gc, const char *name); +void purple_serv_got_join_chat_failed(PurpleConnection *gc, GHashTable *data); void serv_got_chat_left(PurpleConnection *g, int id); void serv_got_chat_in(PurpleConnection *g, int id, const char *who, diff -r 01e375e9b681 -r 3fee7e01e51c pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Wed Apr 30 11:27:17 2008 +0000 +++ b/pidgin/gtkaccount.c Wed Apr 30 11:28:23 2008 +0000 @@ -496,10 +496,6 @@ dialog->password_box = add_pref_box(dialog, vbox, _("_Password:"), dialog->password_entry); - /* Alias */ - dialog->alias_entry = gtk_entry_new(); - add_pref_box(dialog, vbox, _("_Local alias:"), dialog->alias_entry); - /* Remember Password */ dialog->remember_pass_check = gtk_check_button_new_with_mnemonic(_("Remember pass_word")); @@ -571,6 +567,10 @@ gtk_container_add(GTK_CONTAINER(frame), vbox); gtk_widget_show(vbox); + /* Alias */ + dialog->alias_entry = gtk_entry_new(); + add_pref_box(dialog, vbox, _("_Local alias:"), dialog->alias_entry); + /* New mail notifications */ dialog->new_mail_check = gtk_check_button_new_with_mnemonic(_("New _mail notifications")); @@ -654,6 +654,7 @@ set_dialog_icon(dialog, NULL, 0, NULL); } +#if 0 if (!dialog->prpl_info || (!(dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK) && (dialog->prpl_info->icon_spec.format == NULL))) { @@ -661,6 +662,7 @@ /* Nothing to see :( aww. */ gtk_widget_hide(dialog->user_frame); } +#endif } static void diff -r 01e375e9b681 -r 3fee7e01e51c pidgin/gtkblist.c --- a/pidgin/gtkblist.c Wed Apr 30 11:27:17 2008 +0000 +++ b/pidgin/gtkblist.c Wed Apr 30 11:28:23 2008 +0000 @@ -614,6 +614,78 @@ pidgin_blist_refresh(list); } +static void +chat_components_edit_ok(PurpleChat *chat, PurpleRequestFields *allfields) +{ + GList *groups, *fields; + + for (groups = purple_request_fields_get_groups(allfields); groups; groups = groups->next) { + fields = purple_request_field_group_get_fields(groups->data); + for (; fields; fields = fields->next) { + PurpleRequestField *field = fields->data; + const char *id; + char *val; + + id = purple_request_field_get_id(field); + if (purple_request_field_get_type(field) == PURPLE_REQUEST_FIELD_INTEGER) + val = g_strdup_printf("%d", purple_request_field_int_get_value(field)); + else + val = g_strdup(purple_request_field_string_get_value(field)); + + if (!val) { + g_hash_table_remove(purple_chat_get_components(chat), id); + } else { + g_hash_table_replace(purple_chat_get_components(chat), g_strdup(id), val); /* val should not be free'd */ + } + } + } +} + +static void chat_components_edit(GtkWidget *w, PurpleBlistNode *node) +{ + PurpleRequestFields *fields = purple_request_fields_new(); + PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL); + PurpleRequestField *field; + GList *parts, *iter; + struct proto_chat_entry *pce; + PurpleConnection *gc; + PurpleChat *chat = (PurpleChat*)node; + + purple_request_fields_add_group(fields, group); + + gc = purple_account_get_connection(purple_chat_get_account(chat)); + parts = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->chat_info(gc); + + for (iter = parts; iter; iter = iter->next) { + pce = iter->data; + if (pce->is_int) { + int val; + const char *str = g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier); + if (!str || sscanf(str, "%d", &val) != 1) + val = pce->min; + field = purple_request_field_int_new(pce->identifier, pce->label, val); + } else { + field = purple_request_field_string_new(pce->identifier, pce->label, + g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier), FALSE); + if (pce->secret) + purple_request_field_string_set_masked(field, TRUE); + } + + if (pce->required) + purple_request_field_set_required(field, TRUE); + + purple_request_field_group_add_field(group, field); + g_free(pce); + } + + g_list_free(parts); + + purple_request_fields(NULL, _("Edit Chat"), NULL, _("Please Update the necessary fields."), + fields, _("Edit"), G_CALLBACK(chat_components_edit_ok), _("Cancel"), NULL, + NULL, NULL, NULL, + chat); +} + static void gtk_blist_menu_alias_cb(GtkWidget *w, PurpleBlistNode *node) { GtkTreeIter iter; @@ -1510,6 +1582,8 @@ pidgin_separator(menu); + pidgin_new_item_from_stock(menu, _("_Edit Settings..."), NULL, + G_CALLBACK(chat_components_edit), node, 0, 0, NULL); pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS, G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, @@ -3665,13 +3739,13 @@ } return text; } - else - if (hidden_conv) { - char *tmp = esc; - esc = g_strdup_printf("%s", esc); - g_free(tmp); - } - return esc; + else if (hidden_conv) + { + char *tmp = esc; + esc = g_strdup_printf("%s", esc); + g_free(tmp); + } + return esc; } prpl = purple_find_prpl(purple_account_get_protocol_id(b->account)); diff -r 01e375e9b681 -r 3fee7e01e51c pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Wed Apr 30 11:27:17 2008 +0000 +++ b/pidgin/gtkrequest.c Wed Apr 30 11:28:23 2008 +0000 @@ -1120,6 +1120,16 @@ gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); gtk_widget_show(img); + /* Cancel button */ + button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + + /* OK button */ + button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data); + data->ok_button = button; + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_window_set_default(GTK_WINDOW(win), button); + /* Setup the vbox */ vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); @@ -1393,18 +1403,8 @@ g_object_unref(sg); - /* Cancel button */ - button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - - /* OK button */ - button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data); - data->ok_button = button; - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_window_set_default(GTK_WINDOW(win), button); - if (!purple_request_fields_all_required_filled(fields)) - gtk_widget_set_sensitive(button, FALSE); + gtk_widget_set_sensitive(data->ok_button, FALSE); pidgin_auto_parent_window(win);