# HG changeset patch # User Richard Laager # Date 1179560979 0 # Node ID 3034129a10b64eeb92ac385fe8b354c6ce9875ba # Parent 9fae99335d355d19face337c6ba803fd680a0f7f# Parent b079dad9d5698eee61426875e3c1ff8627273d32 explicit merge of 'bb7e144daba6e060c1f8ed699733a119ea3e107f' and '37064abba4819599b4b7ad9b9301856633236f2f' to branch 'im.pidgin.pidgin' diff -r 9fae99335d35 -r 3034129a10b6 ChangeLog --- a/ChangeLog Sat May 19 07:47:16 2007 +0000 +++ b/ChangeLog Sat May 19 07:49:39 2007 +0000 @@ -28,6 +28,9 @@ * Turning off "Show formatting on incoming messages" now ignores formatting in tags too * File transfer progress for transfers on MSN is now correctly displayed + * You can set/change alias of buddies/chats by double-clicking on the + conversation tabs. (Ma Xuan) + * Fix IRC connection bug with dircproxy (xjoe) Finch: * Userlist in chat windows, which can be turned on or off using diff -r 9fae99335d35 -r 3034129a10b6 libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Sat May 19 07:47:16 2007 +0000 +++ b/libpurple/protocols/irc/msgs.c Sat May 19 07:49:39 2007 +0000 @@ -35,6 +35,7 @@ static char *irc_mask_userhost(const char *mask); static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2]); static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc); +static void irc_connected(struct irc_conn *irc, const char *nick); static void irc_msg_handle_privmsg(struct irc_conn *irc, const char *name, const char *from, const char *to, @@ -70,6 +71,52 @@ g_free(message); } +static void irc_connected(struct irc_conn *irc, const char *nick) +{ + PurpleConnection *gc; + PurpleStatus *status; + PurpleBlistNode *gnode, *cnode, *bnode; + + if ((gc = purple_account_get_connection(irc->account)) == NULL + || PURPLE_CONNECTION_IS_CONNECTED(gc)) + return; + + purple_connection_set_display_name(gc, nick); + purple_connection_set_state(gc, PURPLE_CONNECTED); + + /* If we're away then set our away message */ + status = purple_account_get_active_status(irc->account); + if (!purple_status_get_type(status) != PURPLE_STATUS_AVAILABLE) { + PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + prpl_info->set_status(irc->account, status); + } + + /* this used to be in the core, but it's not now */ + for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + continue; + for(cnode = gnode->child; cnode; cnode = cnode->next) { + if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) + continue; + for(bnode = cnode->child; bnode; bnode = bnode->next) { + PurpleBuddy *b; + if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) + continue; + b = (PurpleBuddy *)bnode; + if(b->account == gc->account) { + struct irc_buddy *ib = g_new0(struct irc_buddy, 1); + ib->name = g_strdup(b->name); + g_hash_table_insert(irc->buddies, ib->name, ib); + } + } + } + } + + irc_blist_timeout(irc); + if (!irc->timer) + irc->timer = purple_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc); +} + void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args) { purple_debug(PURPLE_DEBUG_INFO, "irc", "Unrecognized message: %s\n", args[0]); @@ -95,56 +142,16 @@ void irc_msg_luser(struct irc_conn *irc, const char *name, const char *from, char **args) { - PurpleConnection *gc; - PurpleStatus *status; - PurpleBlistNode *gnode, *cnode, *bnode; - - if (!args || !args[0] || !args[1]) - return; - - gc = purple_account_get_connection(irc->account); - if (!gc) + if (!args || !args[0]) return; if (!strcmp(name, "251")) { - /* 251 is required, so we pluck our nick from here */ - purple_connection_set_display_name(gc, args[0]); + /* 251 is required, so we pluck our nick from here and + * finalize connection */ + irc_connected(irc, args[0]); /* Some IRC servers seem to not send a 255 numeric, so * I guess we can't require it; 251 will do. */ /* } else if (!strcmp(name, "255")) { */ - purple_connection_set_state(gc, PURPLE_CONNECTED); - - /* If we're away then set our away message */ - status = purple_account_get_active_status(irc->account); - if (!purple_status_get_type(status) != PURPLE_STATUS_AVAILABLE) { - PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); - prpl_info->set_status(irc->account, status); - } - - /* this used to be in the core, but it's not now */ - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { - if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) - continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) - continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { - PurpleBuddy *b; - if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - b = (PurpleBuddy *)bnode; - if(b->account == gc->account) { - struct irc_buddy *ib = g_new0(struct irc_buddy, 1); - ib->name = g_strdup(b->name); - g_hash_table_insert(irc->buddies, ib->name, ib); - } - } - } - } - - irc_blist_timeout(irc); - if (!irc->timer) - irc->timer = purple_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc); } } @@ -523,6 +530,9 @@ { char *escaped; + if (!args || !args[0]) + return; + if (!irc->motd) irc->motd = g_string_new(""); @@ -532,7 +542,9 @@ irc->motd = g_string_new(""); return; } else if (!strcmp(name, "376")) { - /* We no longer have to do anything for ENDMOTD */ + /* dircproxy 1.0.5 does not send 251 on reconnection, so + * finalize the connection here if it is not already done. */ + irc_connected(irc, args[0]); return; } @@ -541,6 +553,9 @@ return; } + if (!args[1]) + return; + escaped = g_markup_escape_text(args[1], -1); g_string_append_printf(irc->motd, "%s
", escaped); g_free(escaped); diff -r 9fae99335d35 -r 3034129a10b6 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat May 19 07:47:16 2007 +0000 +++ b/pidgin/gtkconv.c Sat May 19 07:49:39 2007 +0000 @@ -3977,6 +3977,12 @@ } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) update_chat_alias((PurpleBuddy *)node, conv, gc, prpl_info); + else if (PURPLE_BLIST_NODE_IS_CHAT(node) && + purple_conversation_get_account(conv) == ((PurpleChat*)node)->account) + { + if (old_alias == NULL || g_utf8_collate(old_alias, purple_conversation_get_title(conv)) == 0) + pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE); + } } static void @@ -4591,6 +4597,18 @@ } } +static gboolean +ignore_middle_click(GtkWidget *widget, GdkEventButton *e, gpointer null) +{ + /* A click on the pane is propagated to the notebook containing the pane. + * So if Stu accidentally aims high and middle clicks on the pane-handle, + * it causes a conversation tab to close. Let's stop that from happening. + */ + if (e->button == 2 && e->type == GDK_BUTTON_PRESS) + return TRUE; + return FALSE; +} + /************************************************************************** * Conversation UI operations **************************************************************************/ @@ -4664,6 +4682,8 @@ te, sizeof(te) / sizeof(GtkTargetEntry), GDK_ACTION_COPY); + g_signal_connect(G_OBJECT(pane), "button_press_event", + G_CALLBACK(ignore_middle_click), NULL); g_signal_connect(G_OBJECT(pane), "drag_data_received", G_CALLBACK(conv_dnd_recv), gtkconv); g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received", @@ -7815,6 +7835,105 @@ } static void +remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry) +{ + g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gtkconv); + gtk_widget_show(gtkconv->tab_label); + gtk_widget_grab_focus(gtkconv->entry); + gtk_widget_destroy(entry); +} + +static gboolean +alias_focus_cb(GtkWidget *widget, GdkEventFocus *event, gpointer user_data) +{ + remove_edit_entry(user_data, widget); + return FALSE; +} + +static gboolean +alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) +{ + if (event->keyval == GDK_Escape) { + remove_edit_entry(user_data, widget); + return TRUE; + } + return FALSE; +} + +static void +alias_cb(GtkEntry *entry, gpointer user_data) +{ + PidginConversation *gtkconv; + PurpleConversation *conv; + PurpleAccount *account; + const char *name; + + gtkconv = (PidginConversation *)user_data; + if (gtkconv == NULL) { + return; + } + conv = gtkconv->active_conv; + account = purple_conversation_get_account(conv); + name = purple_conversation_get_name(conv); + + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + PurpleBuddy *buddy; + buddy = purple_find_buddy(account, name); + if (buddy != NULL) { + purple_blist_alias_buddy(buddy, + gtk_entry_get_text(entry)); + } + serv_alias_buddy(buddy); + } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + PurpleChat *chat; + + chat = purple_blist_find_chat(account, name); + if (chat != NULL) { + purple_blist_alias_chat(chat, + gtk_entry_get_text(entry)); + } + } + remove_edit_entry(user_data, GTK_WIDGET(entry)); +} + +static gboolean +alias_double_click_cb(GtkNotebook *notebook, GdkEventButton *event, PidginConversation *gtkconv) +{ + GtkWidget *entry = NULL; + + if (event->button != 1 || event->type != GDK_2BUTTON_PRESS) { + return FALSE; + } + + if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { + /* There's already an entry for alias. Let's not create another one. */ + return FALSE; + } + + /* alias label */ + entry = gtk_entry_new(); + gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 10); + gtk_entry_set_alignment(GTK_ENTRY(entry), 0.5); + + gtk_box_pack_start(GTK_BOX(gtkconv->tabby), entry, TRUE, TRUE, 0); + /* after the tab label */ + gtk_box_reorder_child(GTK_BOX(gtkconv->tabby), entry, 2); + + g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(alias_cb), gtkconv); + g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(alias_focus_cb), gtkconv); + g_signal_connect(G_OBJECT(entry), "key-press-event", G_CALLBACK(alias_key_press_cb), gtkconv); + gtk_entry_set_text(GTK_ENTRY(entry), + gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); + gtk_widget_show(entry); + gtk_widget_hide(gtkconv->tab_label); + gtk_widget_grab_focus(entry); + + return FALSE; +} + +static void switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, gpointer user_data) { @@ -8157,7 +8276,7 @@ { gboolean tabs_side = FALSE; gint angle = 0; - GtkWidget *first, *third; + GtkWidget *first, *third, *ebox; if (purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/tab_side") == GTK_POS_LEFT || purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/tab_side") == GTK_POS_RIGHT) @@ -8202,6 +8321,11 @@ third = gtkconv->close; } + ebox = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby); + g_signal_connect(G_OBJECT(ebox), "button-press-event", + G_CALLBACK(alias_double_click_cb), gtkconv); + if (gtkconv->tab_label->parent == NULL) { /* Pack if it's a new widget */ gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0); @@ -8209,7 +8333,7 @@ gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0); /* Add this pane to the conversation's notebook. */ - gtk_notebook_append_page(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, gtkconv->tabby); + gtk_notebook_append_page(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); } else { /* reparent old widgets on preference changes */ gtk_widget_reparent(first, gtkconv->tabby); @@ -8220,7 +8344,7 @@ gtk_box_set_child_packing(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0, GTK_PACK_START); /* Reset the tabs label to the new version */ - gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, gtkconv->tabby); + gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); } gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, !tabs_side && !angle, TRUE, GTK_PACK_START); @@ -8231,6 +8355,7 @@ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs")) gtk_widget_show(gtkconv->close); gtk_widget_show(gtkconv->tabby); + gtk_widget_show(ebox); } void