# HG changeset patch # User Etan Reisner # Date 1198373427 0 # Node ID 2b6e6dd24a37dd8ce3157e1a3d3990b289cebb8c # Parent e9005670e279c5c5bed298cc410667cf3be59dc3 Add tooltips to groups in the buddy list. The tooltips show the current online buddy count, the total buddy count (for online accounts) and the names of all the accounts which have buddies in the group (both online and offline). There was a ticket filed about the buddy note plugin which complained that since groups don't have tooltips (and thus no way to display the notes) the plugin shouldn't let you add them, this should fix that (the ticket was already closed because the patch in it was no good). I don't think the current account bit of the tooltip is particularly pretty so suggestions or fixes are welcome. diff -r e9005670e279 -r 2b6e6dd24a37 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sat Dec 22 23:18:08 2007 +0000 +++ b/pidgin/gtkblist.c Sun Dec 23 01:30:27 2007 +0000 @@ -2575,28 +2575,37 @@ static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean full) { - char *tooltip_text = NULL; struct tooltip_data *td = g_new0(struct tooltip_data, 1); PurpleAccount *account = NULL; - char *tmp, *node_name; - - if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { + char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL; + + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { account = ((PurpleBuddy*)(node))->account; - } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) { + } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { account = ((PurpleChat*)(node))->account; } td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE); td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE); - td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + if (account != NULL) { + td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + } tooltip_text = pidgin_get_tooltip_text(node, full); td->layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); td->name_layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); - if (PURPLE_BLIST_NODE_IS_BUDDY(node)) + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { tmp = g_markup_escape_text(purple_buddy_get_name((PurpleBuddy*)node), -1); - else + } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { tmp = g_markup_escape_text(purple_chat_get_name((PurpleChat*)node), -1); + } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { + tmp = g_markup_escape_text(purple_group_get_name((PurpleGroup*)node), -1); + } else { + /* I don't believe this can happen currently, I think + * everything that calls this function checks for one of the + * above node types first. */ + tmp = g_strdup(_("Unknown node type")); + } node_name = g_strdup_printf("%s", tmp); g_free(tmp); @@ -2687,14 +2696,15 @@ } #if GTK_CHECK_VERSION(2,2,0) - if (dir == GTK_TEXT_DIR_RTL) - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, - 0, 0, max_width - TOOLTIP_BORDER - STATUS_SIZE, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); - else - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, - 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); - if(td->avatar) - { + if (td->status_icon) { + if (dir == GTK_TEXT_DIR_RTL) + gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, + 0, 0, max_width - TOOLTIP_BORDER - STATUS_SIZE, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + else + gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, + 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); + } + if(td->avatar) { if (dir == GTK_TEXT_DIR_RTL) gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->avatar, 0, 0, TOOLTIP_BORDER, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); @@ -2712,7 +2722,9 @@ -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); #else - gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 12, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + if (td->status_icon) { + gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 12, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + } if(td->avatar) gdk_pixbuf_render_to_drawable(td->avatar, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, @@ -2778,7 +2790,9 @@ int width, height; gtkblist->tipwindow = widget; - if(PURPLE_BLIST_NODE_IS_CHAT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node)) { + if(PURPLE_BLIST_NODE_IS_CHAT(node) || + PURPLE_BLIST_NODE_IS_BUDDY(node) || + PURPLE_BLIST_NODE_IS_GROUP(node)) { struct tooltip_data *td = create_tip_for_node(node, TRUE); gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); width = TOOLTIP_BORDER + STATUS_SIZE + SMALL_SPACE + @@ -3271,10 +3285,44 @@ g_free(tmp); purple_notify_user_info_destroy(user_info); - } - - purple_signal_emit(pidgin_blist_get_handle(), - "drawing-tooltip", node, str, full); + } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { + GSList *accounts; + PurpleGroup *group = (PurpleGroup*)node; + PurpleNotifyUserInfo *user_info; + + user_info = purple_notify_user_info_new(); + + /* Total buddies (from online accounts) in group */ + tmp = g_strdup_printf("%d", + purple_blist_get_group_size(group, FALSE)); + purple_notify_user_info_add_pair(user_info, _("Total Buddies"), + tmp); + g_free(tmp); + + /* Online buddies in group */ + tmp = g_strdup_printf("%d", + purple_blist_get_group_online_count(group)); + purple_notify_user_info_add_pair(user_info, _("Online Buddies"), + tmp); + g_free(tmp); + + /* Accounts with buddies in group */ + accounts = purple_group_get_accounts(group); + for (; accounts != NULL; + accounts = g_slist_remove_link(accounts, accounts)) { + PurpleAccount *account = accounts->data; + purple_notify_user_info_add_pair(user_info, _("Account"), purple_account_get_username(account)); + } + + tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n"); + g_string_append(str, tmp); + g_free(tmp); + + purple_notify_user_info_destroy(user_info); + } + + purple_signal_emit(pidgin_blist_get_handle(), "drawing-tooltip", + node, str, full); return g_string_free(str, FALSE); }