# HG changeset patch # User Sadrul Habib Chowdhury # Date 1239432048 0 # Node ID 15ae2dea92b3853f657480cfe615294f68d2ed92 # Parent 384eaba9974ee1141b35ac78133f074107eb4451 Open a chat-invite dialog when a buddy is dragged onto a chat. A somewhat warmenhoved patch from Zzzoom. Closes #504. Refs #8871. diff -r 384eaba9974e -r 15ae2dea92b3 ChangeLog --- a/ChangeLog Sat Apr 11 06:01:36 2009 +0000 +++ b/ChangeLog Sat Apr 11 06:40:48 2009 +0000 @@ -8,6 +8,7 @@ in a group on the buddy list. * Removed the unmaintained and unneeded toc protocol plugin. * Fixed NTLM authentication on big-endian systems. + * Dragging a buddy onto a chat pops up a chat-invitation dialog. libpurple: * Various memory cleanups when unloading libpurple. (Nick Hebner) diff -r 384eaba9974e -r 15ae2dea92b3 ChangeLog.API --- a/ChangeLog.API Sat Apr 11 06:01:36 2009 +0000 +++ b/ChangeLog.API Sat Apr 11 06:40:48 2009 +0000 @@ -22,6 +22,7 @@ * purple_connection_get_protocol_data * purple_connection_set_protocol_data * purple_contact_destroy + * purple_conv_chat_invite_user * purple_global_proxy_set_info * purple_group_destroy * purple_log_get_activity_score diff -r 384eaba9974e -r 15ae2dea92b3 finch/gntconv.c --- a/finch/gntconv.c Sat Apr 11 06:01:36 2009 +0000 +++ b/finch/gntconv.c Sat Apr 11 06:40:48 2009 +0000 @@ -559,44 +559,11 @@ } static void -invite_select_cb(FinchConv *fc, PurpleRequestFields *fields) -{ - PurpleConversation *conv = fc->active_conv; - const char *buddy = purple_request_fields_get_string(fields, "screenname"); - const char *message = purple_request_fields_get_string(fields, "message"); - serv_chat_invite(purple_conversation_get_gc(conv), - purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), - message, buddy); - -} - -static void invite_cb(GntMenuItem *item, gpointer ggconv) { - PurpleRequestFields *fields; - PurpleRequestFieldGroup *group; - PurpleRequestField *field; - - fields = purple_request_fields_new(); - - group = purple_request_field_group_new(NULL); - purple_request_fields_add_group(fields, group); - - field = purple_request_field_string_new("screenname", _("Name"), NULL, FALSE); - purple_request_field_set_type_hint(field, "screenname"); - purple_request_field_set_required(field, TRUE); - purple_request_field_group_add_field(group, field); - field = purple_request_field_string_new("message", _("Invite message"), NULL, FALSE); - purple_request_field_group_add_field(group, field); - purple_request_fields(finch_conv_get_handle(), _("Invite"), - NULL, - _("Please enter the name of the user " - "you wish to invite,\nalong with an optional invite message."), - fields, - _("OK"), G_CALLBACK(invite_select_cb), - _("Cancel"), NULL, - NULL, NULL, NULL, - ggconv); + FinchConv *fc = ggconv; + PurpleConversation *conv = fc->active_conv; + purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), NULL, NULL, TRUE); } static void diff -r 384eaba9974e -r 15ae2dea92b3 libpurple/conversation.c --- a/libpurple/conversation.c Sat Apr 11 06:01:36 2009 +0000 +++ b/libpurple/conversation.c Sat Apr 11 06:40:48 2009 +0000 @@ -2005,6 +2005,66 @@ purple_conversation_update(chat->conv, PURPLE_CONV_UPDATE_CHATLEFT); } +static void +invite_user_to_chat(gpointer data, PurpleRequestFields *fields) +{ + PurpleConversation *conv; + PurpleConvChat *chat; + const char *user, *message; + + conv = data; + chat = PURPLE_CONV_CHAT(conv); + user = purple_request_fields_get_string(fields, "screenname"); + message = purple_request_fields_get_string(fields, "message"); + + serv_chat_invite(purple_conversation_get_gc(conv), chat->id, message, user); +} + +void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user, + const char *message, gboolean confirm) +{ + PurpleAccount *account; + PurpleConversation *conv; + PurpleRequestFields *fields; + PurpleRequestFieldGroup *group; + PurpleRequestField *field; + + g_return_if_fail(chat); + + if (!user || !*user || !message || !*message) + confirm = TRUE; + + conv = chat->conv; + account = conv->account; + + if (!confirm) { + serv_chat_invite(purple_account_get_connection(account), + purple_conv_chat_get_id(chat), message, user); + return; + } + + fields = purple_request_fields_new(); + group = purple_request_field_group_new(_("Invite to chat")); + purple_request_fields_add_group(fields, group); + + field = purple_request_field_string_new("screenname", _("Buddy"), user, FALSE); + purple_request_field_group_add_field(group, field); + purple_request_field_set_required(field, TRUE); + purple_request_field_set_type_hint(field, "screenname"); + + field = purple_request_field_string_new("message", _("Message"), message, FALSE); + purple_request_field_group_add_field(group, field); + + purple_request_fields(conv, _("Invite to chat"), NULL, + _("Please enter the name of the user you wish to invite, " + "along with an optional invite message."), + fields, + _("Invite"), G_CALLBACK(invite_user_to_chat), + _("Cancel"), NULL, + account, user, conv, + conv); +} + gboolean purple_conv_chat_has_left(PurpleConvChat *chat) { diff -r 384eaba9974e -r 15ae2dea92b3 libpurple/conversation.h --- a/libpurple/conversation.h Sat Apr 11 06:01:36 2009 +0000 +++ b/libpurple/conversation.h Sat Apr 11 06:40:48 2009 +0000 @@ -1300,6 +1300,22 @@ void purple_conv_chat_left(PurpleConvChat *chat); /** + * Invite a user to a chat. + * The user will be prompted to enter the user's name or a message if one is + * not given. + * + * @param chat The chat. + * @param user The user to invite to the chat. + * @param message The message to send with the invitation. + * @param confirm Prompt before sending the invitation. The user is always + * prompted if either #user or #message is @c NULL. + * + * @since 2.6.0 + */ +void purple_conv_chat_invite_user(PurpleConvChat *chat, const char *user, + const char *message, gboolean confirm); + +/** * Returns true if we're no longer in this chat, * and just left the window open. * diff -r 384eaba9974e -r 15ae2dea92b3 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat Apr 11 06:01:36 2009 +0000 +++ b/pidgin/gtkconv.c Sat Apr 11 06:40:48 2009 +0000 @@ -4981,11 +4981,17 @@ PurpleConversation *conv = gtkconv->active_conv; PidginWindow *win = gtkconv->win; PurpleConversation *c; + PurpleAccount *convaccount = purple_conversation_get_account(conv); + PurpleConnection *gc = purple_account_get_connection(convaccount); + PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL; + if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) { PurpleBlistNode *n = NULL; PurpleBuddy *b; PidginConversation *gtkconv = NULL; + PurpleAccount *buddyaccount; + const char *buddyname; n = *(PurpleBlistNode **)sd->data; @@ -4996,32 +5002,44 @@ else return; + buddyaccount = purple_buddy_get_account(b); + buddyname = purple_buddy_get_name(b); /* - * If we already have an open conversation with this buddy, then - * just move the conv to this window. Otherwise, create a new - * conv and add it to this window. + * If a buddy is dragged to a chat window of the same protocol, + * invite him to the chat. */ - c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account); - if (c != NULL) { - PidginWindow *oldwin; - gtkconv = PIDGIN_CONVERSATION(c); - oldwin = gtkconv->win; - if (oldwin != win) { - pidgin_conv_window_remove_gtkconv(oldwin, gtkconv); - pidgin_conv_window_add_gtkconv(win, gtkconv); - } + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && + prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) && + strcmp(purple_account_get_protocol_id(convaccount), + purple_account_get_protocol_id(buddyaccount)) == 0) { + purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), buddyname, NULL, TRUE); } else { - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, b->account, b->name); - gtkconv = PIDGIN_CONVERSATION(c); - if (gtkconv->win != win) - { - pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); - pidgin_conv_window_add_gtkconv(win, gtkconv); + /* + * If we already have an open conversation with this buddy, then + * just move the conv to this window. Otherwise, create a new + * conv and add it to this window. + */ + c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddyname, buddyaccount); + if (c != NULL) { + PidginWindow *oldwin; + gtkconv = PIDGIN_CONVERSATION(c); + oldwin = gtkconv->win; + if (oldwin != win) { + pidgin_conv_window_remove_gtkconv(oldwin, gtkconv); + pidgin_conv_window_add_gtkconv(win, gtkconv); + } + } else { + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, buddyaccount, buddyname); + gtkconv = PIDGIN_CONVERSATION(c); + if (gtkconv->win != win) { + pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); + pidgin_conv_window_add_gtkconv(win, gtkconv); + } } - } - - /* Make this conversation the active conversation */ - pidgin_conv_window_switch_gtkconv(win, gtkconv); + + /* Make this conversation the active conversation */ + pidgin_conv_window_switch_gtkconv(win, gtkconv); + } gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); } @@ -5040,15 +5058,22 @@ purple_notify_error(win, NULL, _("You are not currently signed on with an account that " "can add that buddy."), NULL); - } - else - { - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username); - gtkconv = PIDGIN_CONVERSATION(c); - if (gtkconv->win != win) - { - pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); - pidgin_conv_window_add_gtkconv(win, gtkconv); + } else { + /* + * If a buddy is dragged to a chat window of the same protocol, + * invite him to the chat. + */ + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && + prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) && + strcmp(purple_account_get_protocol_id(convaccount), protocol) == 0) { + purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), username, NULL, TRUE); + } else { + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username); + gtkconv = PIDGIN_CONVERSATION(c); + if (gtkconv->win != win) { + pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); + pidgin_conv_window_add_gtkconv(win, gtkconv); + } } } } @@ -5060,7 +5085,7 @@ } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) { if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) - pidgin_dnd_file_manage(sd, purple_conversation_get_account(conv), purple_conversation_get_name(conv)); + pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv)); gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); } else @@ -6801,7 +6826,8 @@ wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message, PurpleConversation *conv, PurpleMessageFlags flags, gpointer null) { - if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv)) + PidginConversation *gtkconv = conv ? PIDGIN_CONVERSATION(conv) : NULL; + if (conv == NULL || (gtkconv && gtkconv->win != hidden_convwin)) return; if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) { PidginUnseenState unseen = PIDGIN_UNSEEN_NONE;