# HG changeset patch # User Aaron Sheldon # Date 1151523740 0 # Node ID 085b15c33ca49b5f8aebc03f43ba60fc67d9c2fa # Parent 9d66969a2e32a4fdafa122b4223f6cc1f9e6a221 [gaim-migrate @ 16370] Merging r16220 through 16367 from blist-efficiency branch into trunk. committer: Tailor Script diff -r 9d66969a2e32 -r 085b15c33ca4 src/blist.c --- a/src/blist.c Wed Jun 28 19:12:38 2006 +0000 +++ b/src/blist.c Wed Jun 28 19:42:20 2006 +0000 @@ -732,13 +732,15 @@ GaimBlistNode *gaim_blist_node_next(GaimBlistNode *node, gboolean offline) { GaimBlistNode *ret = node; - + + if (offline) + return get_next_node(ret, TRUE); do { ret = get_next_node(ret, TRUE); - } while (ret && !offline && GAIM_BLIST_NODE_IS_BUDDY(ret) && + } while (ret && GAIM_BLIST_NODE_IS_BUDDY(ret) && !gaim_account_is_connected(gaim_buddy_get_account((GaimBuddy *)ret))); - + return ret; } diff -r 9d66969a2e32 -r 085b15c33ca4 src/gtkblist.c --- a/src/gtkblist.c Wed Jun 28 19:12:38 2006 +0000 +++ b/src/gtkblist.c Wed Jun 28 19:42:20 2006 +0000 @@ -118,9 +118,11 @@ #endif static GaimGtkBuddyList *gtkblist = NULL; +static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list); static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node); static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); +static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node); static char *gaim_get_tooltip_text(GaimBlistNode *node, gboolean full); static const char *item_factory_translate_func (const char *path, gpointer func_data); static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); @@ -159,8 +161,10 @@ { if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) gtk_blist_obscured = TRUE; - else - gtk_blist_obscured = FALSE; + else if (gtk_blist_obscured) { + gtk_blist_obscured = FALSE; + gaim_gtk_blist_refresh_timer(gaim_get_blist()); + } /* continue to handle event normally */ return FALSE; @@ -171,8 +175,10 @@ if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", FALSE); - else + else { gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", TRUE); + gaim_gtk_blist_refresh_timer(gaim_get_blist()); + } } if(event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) { @@ -181,7 +187,13 @@ else gaim_prefs_set_bool("/gaim/gtk/blist/list_maximized", FALSE); } - + + /* Refresh gtkblist if un-iconifying */ + if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){ + if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) + gaim_gtk_blist_refresh_timer(gaim_get_blist()); + } + return FALSE; } @@ -877,8 +889,7 @@ gtk_main_iteration(); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(gtkblist->treeview), path, NULL, FALSE, 0, 0); - - gaim_gtk_blist_update(NULL, node); + gaim_gtk_blist_update_contact(NULL, node->child); gtk_tree_path_free(path); } @@ -2869,7 +2880,7 @@ struct _gaim_gtk_blist_node *gtkcontactnode = NULL; char *idletime = NULL, *statustext = NULL; time_t t; - /* XXX Clean up this crap */ + /* XXX Good luck cleaning up this crap */ contact = (GaimContact*)((GaimBlistNode*)b)->parent; if(contact) @@ -2881,11 +2892,6 @@ name = gaim_buddy_get_alias(b); esc = g_markup_escape_text(name, strlen(name)); - prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); - - if (prpl != NULL) - prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); - presence = gaim_buddy_get_presence(b); if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) @@ -2901,6 +2907,11 @@ return esc; } + prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); + + if (prpl != NULL) + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info && prpl_info->status_text && b->account->gc) { char *tmp = prpl_info->status_text(b); const char *end; @@ -2951,66 +2962,68 @@ #endif } - if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time") && - gaim_presence_is_idle(presence)) - { - time_t idle_secs = gaim_presence_get_idle_time(presence); - - if (idle_secs > 0) { - int ihrs, imin; - - time(&t); - ihrs = (t - idle_secs) / 3600; - imin = ((t - idle_secs) / 60) % 60; - - if (ihrs) - idletime = g_strdup_printf(_("Idle %dh %02dm"), ihrs, imin); - else - idletime = g_strdup_printf(_("Idle %dm"), imin); - } - else - idletime = g_strdup(_("Idle")); - } - if(!gaim_presence_is_online(presence) && !statustext) statustext = g_strdup(_("Offline")); - - if (statustext == NULL && idletime == NULL) - { - if (!selected && gaim_presence_is_idle(presence)) - text = g_strdup_printf("%s", dim_grey(), esc); - else - text = g_strdup(esc); - } - else if (!selected) - { - if (gaim_presence_is_idle(presence)) - { - text = g_strdup_printf("%s\n" - "%s%s%s", - dim_grey(), esc, dim_grey(), - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", - statustext != NULL ? statustext : ""); + else if (!statustext) + text = g_strdup(esc); + + if (gaim_presence_is_idle(presence)) { + if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time")) { + time_t idle_secs = gaim_presence_get_idle_time(presence); + + if (idle_secs > 0) { + int ihrs, imin; + + time(&t); + ihrs = (t - idle_secs) / 3600; + imin = ((t - idle_secs) / 60) % 60; + + if (ihrs) + idletime = g_strdup_printf(_("Idle %dh %02dm"), ihrs, imin); + else + idletime = g_strdup_printf(_("Idle %dm"), imin); + } + else + idletime = g_strdup(_("Idle")); + + if (!selected) + text = g_strdup_printf("%s\n" + "%s%s%s", + dim_grey(), esc, dim_grey(), + idletime != NULL ? idletime : "", + (idletime != NULL && statustext != NULL) ? " - " : "", + statustext != NULL ? statustext : ""); } - else - { - text = g_strdup_printf("%s\n" - "%s%s%s", - esc, dim_grey(), - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", - statustext != NULL ? statustext : ""); - } + else if (!selected && !statustext) /* We handle selected text later */ + text = g_strdup_printf("%s", dim_grey(), esc); + else if (!selected && !text) + text = g_strdup_printf("%s\n" + "%s%s%s", + dim_grey(), esc, dim_grey(), + idletime != NULL ? idletime : "", + (idletime != NULL && statustext != NULL) ? " - " : "", + statustext != NULL ? statustext : ""); } - else + + /* Not idle and not selected */ + else if (!selected && !text) + { text = g_strdup_printf("%s\n" - "%s%s%s", - esc, - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", - statustext != NULL ? statustext : ""); - + "%s%s%s", + esc, dim_grey(), + idletime != NULL ? idletime : "", + (idletime != NULL && statustext != NULL) ? " - " : "", + statustext != NULL ? statustext : ""); + } + + /* It is selected. */ + if ((selected && !text) || (selected && idletime)) + text = g_strdup_printf("%s\n" + "%s%s%s", + esc, + idletime != NULL ? idletime : "", + (idletime != NULL && statustext != NULL) ? " - " : "", + statustext != NULL ? statustext : ""); g_free(idletime); g_free(statustext); @@ -3057,6 +3070,9 @@ { GaimBlistNode *gnode, *cnode; + if (gtk_blist_obscured || !GTK_WIDGET_VISIBLE(gtkblist->window)) + return TRUE; + for(gnode = list->root; gnode; gnode = gnode->next) { if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; @@ -3068,7 +3084,7 @@ if (buddy && gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) - gaim_gtk_blist_update(list, cnode); + gaim_gtk_blist_update_contact(list, (GaimBlistNode*)buddy); } } } @@ -3908,7 +3924,7 @@ while (node) { - if (!GAIM_BLIST_NODE_IS_GROUP(node) && remove) + if (remove && !GAIM_BLIST_NODE_IS_GROUP(node)) gaim_gtk_blist_hide_node(list, node); gaim_gtk_blist_update(list, node); @@ -4081,15 +4097,25 @@ return TRUE; } +/*This version of gaim_gtk_blist_update_group can take the original buddy +or a group, but has much better algorithmic performance with a pre-known buddy*/ static void gaim_gtk_blist_update_group(GaimBuddyList *list, GaimBlistNode *node) { GaimGroup *group; int count; gboolean show = FALSE; - - g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP(node)); - - group = (GaimGroup*)node; + GaimBlistNode* gnode; + + + if (GAIM_BLIST_NODE_IS_GROUP(node)) + gnode = node; + else if (GAIM_BLIST_NODE_IS_BUDDY(node)) /* maybe OR'ed with IS_CHAT? */ + gnode = node->parent->parent; + else if (GAIM_BLIST_NODE_IS_CONTACT(node)) + gnode = node->parent; + g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP(gnode)); + + group = (GaimGroup*)gnode; if(gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) count = gaim_blist_get_group_size(group, FALSE); @@ -4098,25 +4124,15 @@ if (count > 0 || gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups")) show = TRUE; - else { - GaimBlistNode *n; - n = node->child; - while (n && !GAIM_BLIST_NODE_IS_GROUP(n)) { - if (GAIM_BLIST_NODE_IS_BUDDY(n)) { - if (buddy_is_displayable((GaimBuddy*)n)) { - show = TRUE; - break; - } - } - n = gaim_blist_node_next(n, FALSE); - } - } + else if (GAIM_BLIST_NODE_IS_BUDDY(node)){ /* Or chat? */ + if (buddy_is_displayable((GaimBuddy*)node)) + show = TRUE;} if (show) { char *mark, *esc; GtkTreeIter iter; - if(!insert_node(list, node, &iter)) + if(!insert_node(list, gnode, &iter)) return; esc = g_markup_escape_text(group->name, -1); @@ -4129,11 +4145,11 @@ STATUS_ICON_COLUMN, NULL, STATUS_ICON_VISIBLE_COLUMN, FALSE, NAME_COLUMN, mark, - NODE_COLUMN, node, + NODE_COLUMN, gnode, -1); g_free(mark); } else { - gaim_gtk_blist_hide_node(list, node); + gaim_gtk_blist_hide_node(list, gnode); } } @@ -4155,7 +4171,8 @@ mark = gaim_gtk_blist_get_name_markup(buddy, selected); if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time") && - gaim_presence_is_idle(presence)) + gaim_presence_is_idle(presence) && + !gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { time_t idle_secs = gaim_presence_get_idle_time(presence); @@ -4166,7 +4183,6 @@ time(&t); ihrs = (t - idle_secs) / 3600; imin = ((t - idle_secs) / 60) % 60; - idle = g_strdup_printf("%d:%02d", ihrs, imin); } } @@ -4197,35 +4213,45 @@ g_object_unref(avatar); } - +/* This is a variation on the original gtk_blist_update_contact. Here we + can know in advance which buddy has changed so we can just update that */ static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node) { + GaimBlistNode *cnode; GaimContact *contact; GaimBuddy *buddy; struct _gaim_gtk_blist_node *gtknode; - g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node)); + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + cnode = node->parent; + else + cnode = node; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(cnode)); /* First things first, update the group */ - gaim_gtk_blist_update_group(list, node->parent); - - contact = (GaimContact*)node; + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + gaim_gtk_blist_update_group(list, node); + else + gaim_gtk_blist_update_group(list, cnode->parent); + + contact = (GaimContact*)cnode; buddy = gaim_contact_get_priority_buddy(contact); - + if (buddy_is_displayable(buddy)) { GtkTreeIter iter; - if(!insert_node(list, node, &iter)) + if(!insert_node(list, cnode, &iter)) return; - gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; + gtknode = (struct _gaim_gtk_blist_node *)cnode->ui_data; if(gtknode->contact_expanded) { GdkPixbuf *status; char *mark; - status = gaim_gtk_blist_get_status_icon(node, + status = gaim_gtk_blist_get_status_icon(cnode, (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); @@ -4242,29 +4268,29 @@ if(status) g_object_unref(status); } else { - buddy_node(buddy, &iter, node); + buddy_node(buddy, &iter, cnode); } } else { - gaim_gtk_blist_hide_node(list, node); + gaim_gtk_blist_hide_node(list, cnode); } } + + static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node) { - GaimContact *contact; GaimBuddy *buddy; struct _gaim_gtk_blist_node *gtkparentnode; g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + if (node->parent == NULL) + return; + buddy = (GaimBuddy*)node; - contact = (GaimContact*)node->parent; - - if (contact == NULL) - return; - + /* First things first, update the contact */ - gaim_gtk_blist_update_contact(list, node->parent); + gaim_gtk_blist_update_contact(list, node); gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data;