src/gtkblist.c

changeset 11910
4f8184cdcfff
parent 11906
7a6ee2d896dd
child 11915
2803eadda83e
equal deleted inserted replaced
11909:a0a7331365e1 11910:4f8184cdcfff
125 static void gaim_gtk_blist_tooltip_destroy(); 125 static void gaim_gtk_blist_tooltip_destroy();
126 126
127 struct _gaim_gtk_blist_node { 127 struct _gaim_gtk_blist_node {
128 GtkTreeRowReference *row; 128 GtkTreeRowReference *row;
129 gboolean contact_expanded; 129 gboolean contact_expanded;
130 gboolean recent_signonoff;
131 gint recent_signonoff_timer;
130 }; 132 };
131 133
132 134
133 static char dim_grey_string[8] = ""; 135 static char dim_grey_string[8] = "";
134 static char *dim_grey() 136 static char *dim_grey()
2120 return FALSE; 2122 return FALSE;
2121 } 2123 }
2122 2124
2123 static gboolean buddy_is_displayable(GaimBuddy *buddy) 2125 static gboolean buddy_is_displayable(GaimBuddy *buddy)
2124 { 2126 {
2125 return (buddy && gaim_account_is_connected(buddy->account) && 2127 struct _gaim_gtk_blist_node *gtknode;
2128
2129 if(!buddy)
2130 return FALSE;
2131
2132 gtknode = ((GaimBlistNode*)buddy)->ui_data;
2133
2134 return (gaim_account_is_connected(buddy->account) &&
2126 (gaim_presence_is_online(buddy->presence) || 2135 (gaim_presence_is_online(buddy->presence) ||
2127 buddy->present == GAIM_BUDDY_SIGNING_OFF || 2136 (gtknode && gtknode->recent_signonoff) ||
2128 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies") || 2137 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies") ||
2129 gaim_blist_node_get_bool((GaimBlistNode*)buddy, "show_offline"))); 2138 gaim_blist_node_get_bool((GaimBlistNode*)buddy, "show_offline")));
2130 } 2139 }
2131 2140
2132 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) 2141 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv)
2133 { 2142 {
2134 GtkTreePath *path; 2143 GtkTreePath *path;
2542 g_free(tmp); 2551 g_free(tmp);
2543 } 2552 }
2544 } 2553 }
2545 2554
2546 /* Last Seen */ 2555 /* Last Seen */
2547 if ((!GAIM_BUDDY_IS_ONLINE(b) && b->present != GAIM_BUDDY_SIGNING_OFF) || 2556 if (!GAIM_BUDDY_IS_ONLINE(b))
2548 b->present == GAIM_BUDDY_SIGNING_ON)
2549 { 2557 {
2550 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode *)c)->ui_data; 2558 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode *)c)->ui_data;
2551 GaimBlistNode *bnode; 2559 GaimBlistNode *bnode;
2552 int lastseen = 0; 2560 int lastseen = 0;
2553 2561
2630 GdkPixbuf *scale, *status = NULL; 2638 GdkPixbuf *scale, *status = NULL;
2631 int i, scalesize = 30; 2639 int i, scalesize = 30;
2632 char *filename; 2640 char *filename;
2633 const char *protoname = NULL; 2641 const char *protoname = NULL;
2634 struct _gaim_gtk_blist_node *gtknode = node->ui_data; 2642 struct _gaim_gtk_blist_node *gtknode = node->ui_data;
2643 struct _gaim_gtk_blist_node *gtkbuddynode = NULL;
2635 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, 2644 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15},
2636 {NULL, 0, 0}, {NULL, 15, 0}}; 2645 {NULL, 0, 0}, {NULL, 15, 0}};
2637 GaimPresence *presence = NULL; 2646 GaimPresence *presence = NULL;
2638 GaimBuddy *buddy = NULL; 2647 GaimBuddy *buddy = NULL;
2639 GaimChat *chat = NULL; 2648 GaimChat *chat = NULL;
2640 2649
2641 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { 2650 if(GAIM_BLIST_NODE_IS_CONTACT(node)) {
2642 if(!gtknode->contact_expanded) 2651 if(!gtknode->contact_expanded) {
2643 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); 2652 buddy = gaim_contact_get_priority_buddy((GaimContact*)node);
2653 gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data;
2654 }
2644 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { 2655 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
2645 buddy = (GaimBuddy*)node; 2656 buddy = (GaimBuddy*)node;
2657 gtkbuddynode = node->ui_data;
2646 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { 2658 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
2647 chat = (GaimChat*)node; 2659 chat = (GaimChat*)node;
2648 } else { 2660 } else {
2649 return NULL; 2661 return NULL;
2650 } 2662 }
2667 2679
2668 if(prpl_info && prpl_info->list_icon) { 2680 if(prpl_info && prpl_info->list_icon) {
2669 protoname = prpl_info->list_icon(account, buddy); 2681 protoname = prpl_info->list_icon(account, buddy);
2670 } 2682 }
2671 if(prpl_info && prpl_info->list_emblems && buddy) { 2683 if(prpl_info && prpl_info->list_emblems && buddy) {
2672 if(buddy->present != GAIM_BUDDY_SIGNING_OFF) 2684 if(!gtknode->recent_signonoff)
2673 prpl_info->list_emblems(buddy, &emblems[0].filename, 2685 prpl_info->list_emblems(buddy, &emblems[0].filename,
2674 &emblems[1].filename, &emblems[2].filename, 2686 &emblems[1].filename, &emblems[2].filename,
2675 &emblems[3].filename); 2687 &emblems[3].filename);
2676 } 2688 }
2677 } 2689 }
2680 scalesize = 15; 2692 scalesize = 15;
2681 /* So that only the se icon will composite */ 2693 /* So that only the se icon will composite */
2682 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; 2694 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL;
2683 } 2695 }
2684 2696
2685 if(buddy && buddy->present == GAIM_BUDDY_SIGNING_ON) { 2697 if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode->recent_signonoff) {
2686 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); 2698 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL);
2687 } else if(buddy && buddy->present == GAIM_BUDDY_SIGNING_OFF) { 2699 } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode->recent_signonoff) {
2688 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); 2700 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL);
2689 } else if(buddy || chat) { 2701 } else if(buddy || chat) {
2690 char *image = g_strdup_printf("%s.png", protoname); 2702 char *image = g_strdup_printf("%s.png", protoname);
2691 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); 2703 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL);
2692 g_free(image); 2704 g_free(image);
3492 return TRUE; 3504 return TRUE;
3493 } 3505 }
3494 3506
3495 static void gaim_gtk_blist_remove(GaimBuddyList *list, GaimBlistNode *node) 3507 static void gaim_gtk_blist_remove(GaimBuddyList *list, GaimBlistNode *node)
3496 { 3508 {
3509 struct _gaim_gtk_blist_node *gtknode = node->ui_data;
3510
3497 gaim_request_close_with_handle(node); 3511 gaim_request_close_with_handle(node);
3498 3512
3499 gaim_gtk_blist_hide_node(list, node); 3513 gaim_gtk_blist_hide_node(list, node);
3500 3514
3501 if(node->parent) 3515 if(node->parent)
3507 * valgrind found several reasons why it's good. If this causes problems 3521 * valgrind found several reasons why it's good. If this causes problems
3508 * comment it out again. Stu */ 3522 * comment it out again. Stu */
3509 /* Of course it still causes problems - this breaks dragging buddies into 3523 /* Of course it still causes problems - this breaks dragging buddies into
3510 * contacts, the dragged buddy mysteriously 'disappears'. Stu. */ 3524 * contacts, the dragged buddy mysteriously 'disappears'. Stu. */
3511 /* I think it's fixed now. Stu. */ 3525 /* I think it's fixed now. Stu. */
3526
3527 if(gtknode->recent_signonoff_timer > 0)
3528 gaim_timeout_remove(gtknode->recent_signonoff_timer);
3529
3512 g_free(node->ui_data); 3530 g_free(node->ui_data);
3513 node->ui_data = NULL; 3531 node->ui_data = NULL;
3514 } 3532 }
3515 3533
3516 static gboolean do_selection_changed(GaimBlistNode *new_selection) 3534 static gboolean do_selection_changed(GaimBlistNode *new_selection)
3776 3794
3777 gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data; 3795 gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data;
3778 3796
3779 if (gtkparentnode->contact_expanded && 3797 if (gtkparentnode->contact_expanded &&
3780 (gaim_presence_is_online(buddy->presence) || 3798 (gaim_presence_is_online(buddy->presence) ||
3781 buddy->present == GAIM_BUDDY_SIGNING_OFF || 3799 (0 /* XXX: if we just signed off, need to show logout.png */) ||
3782 (gaim_account_is_connected(buddy->account) && 3800 (gaim_account_is_connected(buddy->account) &&
3783 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || 3801 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) ||
3784 gaim_blist_node_get_bool(node->parent, "show_offline"))) 3802 gaim_blist_node_get_bool(node->parent, "show_offline")))
3785 { 3803 {
3786 GtkTreeIter iter; 3804 GtkTreeIter iter;
4583 static int handle; 4601 static int handle;
4584 4602
4585 return &handle; 4603 return &handle;
4586 } 4604 }
4587 4605
4606 static gboolean buddy_signonoff_timeout_cb(GaimBuddy *buddy)
4607 {
4608 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode*)buddy)->ui_data;
4609 GaimConversation *conv;
4610
4611 gtknode->recent_signonoff = FALSE;
4612 gtknode->recent_signonoff_timer = 0;
4613
4614 gaim_gtk_blist_update(NULL, (GaimBlistNode*)buddy);
4615
4616 if((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account))) {
4617 if(GAIM_BUDDY_IS_ONLINE(buddy)) {
4618 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE);
4619 } else {
4620 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_OFFLINE);
4621 }
4622 }
4623
4624 return FALSE;
4625 }
4626
4627 static void buddy_signonoff_cb(GaimBuddy *buddy)
4628 {
4629 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode*)buddy)->ui_data;
4630
4631 gtknode->recent_signonoff = TRUE;
4632
4633 if(gtknode->recent_signonoff_timer > 0)
4634 gaim_timeout_remove(gtknode->recent_signonoff_timer);
4635 gtknode->recent_signonoff_timer = gaim_timeout_add(10000,
4636 (GSourceFunc)buddy_signonoff_timeout_cb, buddy);
4637 }
4638
4588 void gaim_gtk_blist_init(void) 4639 void gaim_gtk_blist_init(void)
4589 { 4640 {
4590 void *gtk_blist_handle = gaim_gtk_blist_get_handle(); 4641 void *gtk_blist_handle = gaim_gtk_blist_get_handle();
4591 4642
4592 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", 4643 gaim_signal_connect(gaim_connections_get_handle(), "signed-on",
4614 4665
4615 gaim_signal_register(gtk_blist_handle, "drawing-tooltip", 4666 gaim_signal_register(gtk_blist_handle, "drawing-tooltip",
4616 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, 4667 gaim_marshal_VOID__POINTER_POINTER, NULL, 2,
4617 gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_BLIST_NODE), 4668 gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_BLIST_NODE),
4618 gaim_value_new_outgoing(GAIM_TYPE_BOXED, "GString *")); 4669 gaim_value_new_outgoing(GAIM_TYPE_BOXED, "GString *"));
4670
4671
4672 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL);
4673 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL);
4619 } 4674 }
4620 4675
4621 void 4676 void
4622 gaim_gtk_blist_uninit(void) { 4677 gaim_gtk_blist_uninit(void) {
4623 gaim_signals_unregister_by_instance(gaim_gtk_blist_get_handle()); 4678 gaim_signals_unregister_by_instance(gaim_gtk_blist_get_handle());

mercurial