| 117 static void sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
118 static void sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
| 118 #endif |
119 #endif |
| 119 static GaimGtkBuddyList *gtkblist = NULL; |
120 static GaimGtkBuddyList *gtkblist = NULL; |
| 120 |
121 |
| 121 static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list); |
122 static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list); |
| 122 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node); |
123 static void gaim_gtk_blist_update_buddy_status_icon_key(GaimBlistNode *node, GaimStatusIconSize size); |
| |
124 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node, gboolean statusChange); |
| 123 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
125 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
| 124 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); |
126 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); |
| 125 static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node); |
127 static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node); |
| 126 static char *gaim_get_tooltip_text(GaimBlistNode *node, gboolean full); |
128 static char *gaim_get_tooltip_text(GaimBlistNode *node, gboolean full); |
| 127 static const char *item_factory_translate_func (const char *path, gpointer func_data); |
129 static const char *item_factory_translate_func (const char *path, gpointer func_data); |
| 128 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); |
130 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); |
| 129 static void redo_buddy_list(GaimBuddyList *list, gboolean remove); |
131 static void redo_buddy_list(GaimBuddyList *list, gboolean remove, gboolean rerender); |
| 130 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); |
132 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); |
| 131 |
133 |
| 132 static void gaim_gtk_blist_tooltip_destroy(void); |
134 static void gaim_gtk_blist_tooltip_destroy(void); |
| 133 |
135 |
| 134 struct _gaim_gtk_blist_node { |
136 struct _gaim_gtk_blist_node { |
| 135 GtkTreeRowReference *row; |
137 GtkTreeRowReference *row; |
| 136 gboolean contact_expanded; |
138 gboolean contact_expanded; |
| 137 gboolean recent_signonoff; |
139 gboolean recent_signonoff; |
| 138 gint recent_signonoff_timer; |
140 gint recent_signonoff_timer; |
| |
141 GString *status_icon_key; |
| 139 }; |
142 }; |
| 140 |
143 |
| 141 |
144 |
| 142 static char dim_grey_string[8] = ""; |
145 static char dim_grey_string[8] = ""; |
| 143 static char *dim_grey() |
146 static char *dim_grey() |
| 2690 const char *filename; |
2699 const char *filename; |
| 2691 int x; |
2700 int x; |
| 2692 int y; |
2701 int y; |
| 2693 }; |
2702 }; |
| 2694 |
2703 |
| 2695 GdkPixbuf * |
2704 static void g_string_destroy(GString *destroyable) |
| 2696 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size) |
2705 { |
| 2697 { |
2706 g_string_free(destroyable, TRUE); |
| 2698 GdkPixbuf *scale, *status = NULL; |
2707 return; |
| 2699 int i, scalesize = 30; |
2708 } |
| 2700 char *filename; |
2709 |
| |
2710 static void |
| |
2711 gaim_gtk_blist_update_buddy_status_icon_key(GaimBlistNode *node, GaimStatusIconSize size) |
| |
2712 { |
| |
2713 int i; |
| |
2714 GaimAccount *account; |
| |
2715 GaimPlugin *prpl; |
| |
2716 GaimPluginProtocolInfo *prpl_info; |
| |
2717 GString *key = g_string_sized_new(16); |
| |
2718 GaimBuddy *buddy; |
| 2701 const char *protoname = NULL; |
2719 const char *protoname = NULL; |
| 2702 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
2720 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
| 2703 struct _gaim_gtk_blist_node *gtkbuddynode = NULL; |
2721 struct _gaim_gtk_blist_node *gtkbuddynode = NULL; |
| 2704 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, |
2722 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, |
| 2705 {NULL, 0, 0}, {NULL, 15, 0}}; |
2723 {NULL, 0, 0}, {NULL, 15, 0}}; |
| 2706 GaimPresence *presence = NULL; |
2724 |
| 2707 GaimBuddy *buddy = NULL; |
2725 buddy = (GaimBuddy*)node; |
| 2708 GaimChat *chat = NULL; |
2726 gtkbuddynode = node->ui_data; |
| 2709 |
2727 |
| 2710 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
2728 if (gtkbuddynode && gtkbuddynode->recent_signonoff) { |
| 2711 if(!gtknode->contact_expanded) { |
2729 if (GAIM_BUDDY_IS_ONLINE(buddy)) |
| 2712 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); |
2730 g_string_printf(key, "login"); |
| 2713 gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data; |
2731 else |
| 2714 } |
2732 g_string_printf(key, "logout"); |
| 2715 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
|
| 2716 buddy = (GaimBuddy*)node; |
|
| 2717 gtkbuddynode = node->ui_data; |
|
| 2718 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
|
| 2719 chat = (GaimChat*)node; |
|
| 2720 } else { |
2733 } else { |
| 2721 return NULL; |
2734 GaimConversation *conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| 2722 } |
2735 gaim_buddy_get_name(buddy), |
| 2723 |
2736 gaim_buddy_get_account(buddy)); |
| 2724 if(buddy || chat) { |
2737 |
| 2725 GaimAccount *account; |
2738 account = buddy->account; |
| 2726 GaimPlugin *prpl; |
|
| 2727 GaimPluginProtocolInfo *prpl_info; |
|
| 2728 |
|
| 2729 if(buddy) |
|
| 2730 account = buddy->account; |
|
| 2731 else |
|
| 2732 account = chat->account; |
|
| 2733 |
|
| 2734 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
2739 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| |
2740 |
| 2735 if(!prpl) |
2741 if(!prpl) |
| 2736 return NULL; |
2742 return; |
| 2737 |
2743 |
| 2738 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
2744 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| 2739 |
2745 |
| 2740 if(prpl_info && prpl_info->list_icon) { |
2746 if(prpl_info && prpl_info->list_icon) { |
| 2741 protoname = prpl_info->list_icon(account, buddy); |
2747 protoname = prpl_info->list_icon(account, buddy); |
| 2742 } |
2748 } |
| 2743 if(prpl_info && prpl_info->list_emblems && buddy) { |
2749 if(prpl_info && prpl_info->list_emblems) { |
| 2744 if(gtknode && !gtknode->recent_signonoff) |
2750 if(gtknode) |
| 2745 prpl_info->list_emblems(buddy, &emblems[0].filename, |
2751 prpl_info->list_emblems(buddy, &emblems[0].filename, |
| 2746 &emblems[1].filename, &emblems[2].filename, |
2752 &emblems[1].filename, &emblems[2].filename, |
| 2747 &emblems[3].filename); |
2753 &emblems[3].filename); |
| 2748 } |
2754 } |
| 2749 } |
2755 |
| 2750 |
2756 g_string_assign(key, protoname); |
| 2751 if(buddy) { |
2757 |
| 2752 GaimConversation *conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
|
| 2753 gaim_buddy_get_name(buddy), |
|
| 2754 gaim_buddy_get_account(buddy)); |
|
| 2755 if(conv != NULL) { |
2758 if(conv != NULL) { |
| 2756 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); |
2759 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); |
| 2757 if(gtkconv != NULL && gaim_gtkconv_is_hidden(gtkconv)) { |
2760 if(gtkconv != NULL && gaim_gtkconv_is_hidden(gtkconv)) { |
| 2758 /* add pending emblem */ |
2761 /* add pending emblem */ |
| 2759 if(size == GAIM_STATUS_ICON_SMALL) { |
2762 if(size == GAIM_STATUS_ICON_SMALL) { |
| 2763 emblems[3].filename=emblems[2].filename; |
2766 emblems[3].filename=emblems[2].filename; |
| 2764 emblems[2].filename="pending"; |
2767 emblems[2].filename="pending"; |
| 2765 } |
2768 } |
| 2766 } |
2769 } |
| 2767 } |
2770 } |
| 2768 } |
2771 |
| |
2772 if(size == GAIM_STATUS_ICON_SMALL) { |
| |
2773 /* So that only the se icon will composite */ |
| |
2774 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; |
| |
2775 } |
| |
2776 |
| |
2777 for(i=0; i<4; i++) { |
| |
2778 if(emblems[i].filename) { |
| |
2779 g_string_append_printf(key, "/%s", emblems[i].filename); |
| |
2780 } |
| |
2781 } |
| |
2782 } |
| |
2783 |
| |
2784 if (!GAIM_BUDDY_IS_ONLINE(buddy)) { |
| |
2785 key = g_string_append(key, "/off"); |
| |
2786 } else if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) { |
| |
2787 key = g_string_append(key, "/idle"); |
| |
2788 } |
| |
2789 if (!gaim_privacy_check(buddy->account, gaim_buddy_get_name(buddy))) { |
| |
2790 key = g_string_append(key, "/priv"); |
| |
2791 } |
| |
2792 |
| |
2793 if (gtkbuddynode) { |
| |
2794 if (gtkbuddynode->status_icon_key) |
| |
2795 g_string_free(gtkbuddynode->status_icon_key, TRUE); |
| |
2796 gtkbuddynode->status_icon_key = g_string_new(key->str); |
| |
2797 } |
| |
2798 |
| |
2799 g_string_free(key, TRUE); |
| |
2800 return; |
| |
2801 } |
| |
2802 |
| |
2803 GdkPixbuf * |
| |
2804 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size) |
| |
2805 { |
| |
2806 GdkPixbuf *scale, *status = NULL; |
| |
2807 int i, scalesize = 30; |
| |
2808 char *filename; |
| |
2809 GString *key = g_string_sized_new(16); |
| |
2810 const char *protoname = NULL; |
| |
2811 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
| |
2812 struct _gaim_gtk_blist_node *gtkbuddynode = NULL; |
| |
2813 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, |
| |
2814 {NULL, 0, 0}, {NULL, 15, 0}}; |
| |
2815 GaimPresence *presence = NULL; |
| |
2816 GaimBuddy *buddy = NULL; |
| |
2817 GaimChat *chat = NULL; |
| |
2818 |
| |
2819 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
| |
2820 if(!gtknode->contact_expanded) { |
| |
2821 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); |
| |
2822 gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data; |
| |
2823 } |
| |
2824 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
| |
2825 buddy = (GaimBuddy*)node; |
| |
2826 gtkbuddynode = node->ui_data; |
| |
2827 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
| |
2828 chat = (GaimChat*)node; |
| |
2829 } else { |
| |
2830 return NULL; |
| |
2831 } |
| |
2832 |
| |
2833 if (!status_icon_hash_table) { |
| |
2834 status_icon_hash_table = g_hash_table_new_full((GHashFunc)g_string_hash, |
| |
2835 (GEqualFunc)g_string_equal, |
| |
2836 (GDestroyNotify)g_string_destroy, |
| |
2837 (GDestroyNotify)gdk_pixbuf_unref); |
| |
2838 |
| |
2839 } else if (buddy && gtkbuddynode->status_icon_key && gtkbuddynode->status_icon_key->str) { |
| |
2840 key = g_string_new(gtkbuddynode->status_icon_key->str); |
| |
2841 |
| |
2842 /* Respect the size request given */ |
| |
2843 if (size == GAIM_STATUS_ICON_SMALL) { |
| |
2844 key = g_string_append(key, "/tiny"); |
| |
2845 } |
| |
2846 |
| |
2847 scale = g_hash_table_lookup(status_icon_hash_table, key); |
| |
2848 if (scale) { |
| |
2849 gdk_pixbuf_ref(scale); |
| |
2850 g_string_free(key, TRUE); |
| |
2851 return scale; |
| |
2852 } |
| |
2853 } |
| |
2854 |
| |
2855 if(buddy || chat) { |
| |
2856 GaimAccount *account; |
| |
2857 GaimPlugin *prpl; |
| |
2858 GaimPluginProtocolInfo *prpl_info; |
| |
2859 |
| |
2860 if(buddy) |
| |
2861 account = buddy->account; |
| |
2862 else |
| |
2863 account = chat->account; |
| |
2864 |
| |
2865 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| |
2866 if(!prpl) |
| |
2867 return NULL; |
| |
2868 |
| |
2869 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| |
2870 |
| |
2871 if(prpl_info && prpl_info->list_icon) { |
| |
2872 protoname = prpl_info->list_icon(account, buddy); |
| |
2873 } |
| |
2874 if(prpl_info && prpl_info->list_emblems && buddy) { |
| |
2875 if(gtknode && !gtknode->recent_signonoff) |
| |
2876 prpl_info->list_emblems(buddy, &emblems[0].filename, |
| |
2877 &emblems[1].filename, &emblems[2].filename, |
| |
2878 &emblems[3].filename); |
| |
2879 } |
| |
2880 } |
| |
2881 |
| |
2882 /* Begin Generating Lookup Key */ |
| |
2883 if (buddy) { |
| |
2884 gaim_gtk_blist_update_buddy_status_icon_key(node, size); |
| |
2885 g_string_printf(key, "%s", strdup(gtkbuddynode->status_icon_key->str)); |
| |
2886 } |
| |
2887 /* There are only two options for chat or gaimdude - big or small */ |
| |
2888 else if (chat) { |
| |
2889 GaimAccount *account; |
| |
2890 GaimPlugin *prpl; |
| |
2891 GaimPluginProtocolInfo *prpl_info; |
| |
2892 |
| |
2893 account = chat->account; |
| |
2894 |
| |
2895 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| |
2896 if(!prpl) |
| |
2897 return NULL; |
| |
2898 |
| |
2899 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| |
2900 |
| |
2901 if(prpl_info && prpl_info->list_icon) { |
| |
2902 protoname = prpl_info->list_icon(account, NULL); |
| |
2903 } |
| |
2904 g_string_append_printf(key, "%s-chat", protoname); |
| |
2905 } |
| |
2906 else |
| |
2907 key = g_string_append(key, "gaimdude"); |
| |
2908 |
| |
2909 /* If the icon is small, we do not store this into the status_icon_key |
| |
2910 * in the gtkbuddynode. This way we can respect the size value on cache |
| |
2911 * lookup. Otherwise, different sized icons could not be stored easily. |
| |
2912 */ |
| |
2913 if (size == GAIM_STATUS_ICON_SMALL) { |
| |
2914 key = g_string_append(key, "/tiny"); |
| |
2915 } |
| |
2916 |
| |
2917 /* End Generating Lookup Key */ |
| |
2918 |
| |
2919 /* If we already know this icon, just return it */ |
| |
2920 scale = g_hash_table_lookup(status_icon_hash_table, key); |
| |
2921 if (scale) { |
| |
2922 gdk_pixbuf_ref(scale); |
| |
2923 g_string_free(key, TRUE); |
| |
2924 return scale; |
| |
2925 } |
| |
2926 |
| |
2927 /* Create a new composite icon */ |
| |
2928 |
| |
2929 if(buddy) { |
| |
2930 GaimAccount *account; |
| |
2931 GaimPlugin *prpl; |
| |
2932 GaimPluginProtocolInfo *prpl_info; |
| |
2933 GaimConversation *conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| |
2934 gaim_buddy_get_name(buddy), |
| |
2935 gaim_buddy_get_account(buddy)); |
| |
2936 |
| |
2937 account = buddy->account; |
| |
2938 |
| |
2939 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
| |
2940 if(!prpl) |
| |
2941 return NULL; |
| |
2942 |
| |
2943 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
| |
2944 |
| |
2945 if(prpl_info && prpl_info->list_icon) { |
| |
2946 protoname = prpl_info->list_icon(account, buddy); |
| |
2947 } |
| |
2948 if(prpl_info && prpl_info->list_emblems) { |
| |
2949 if(gtknode && !gtknode->recent_signonoff) |
| |
2950 prpl_info->list_emblems(buddy, &emblems[0].filename, |
| |
2951 &emblems[1].filename, &emblems[2].filename, |
| |
2952 &emblems[3].filename); |
| |
2953 } |
| |
2954 |
| |
2955 if(conv != NULL) { |
| |
2956 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); |
| |
2957 if(gtkconv != NULL && gaim_gtkconv_is_hidden(gtkconv)) { |
| |
2958 /* add pending emblem */ |
| |
2959 if(size == GAIM_STATUS_ICON_SMALL) { |
| |
2960 emblems[0].filename="pending"; |
| |
2961 } |
| |
2962 else { |
| |
2963 emblems[3].filename=emblems[2].filename; |
| |
2964 emblems[2].filename="pending"; |
| |
2965 } |
| |
2966 } |
| |
2967 } |
| |
2968 } |
| 2769 |
2969 |
| 2770 if(size == GAIM_STATUS_ICON_SMALL) { |
2970 if(size == GAIM_STATUS_ICON_SMALL) { |
| 2771 scalesize = 15; |
2971 scalesize = 15; |
| 2772 /* So that only the se icon will composite */ |
2972 /* So that only the se icon will composite */ |
| 2773 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; |
2973 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; |
| 2774 } |
2974 } |
| |
2975 |
| |
2976 |
| 2775 |
2977 |
| 2776 if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
2978 if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
| 2777 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); |
2979 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); |
| 2778 } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
2980 } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
| 2779 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); |
2981 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); |
| 3912 |
4116 |
| 3913 /* emit our created signal */ |
4117 /* emit our created signal */ |
| 3914 gaim_signal_emit(handle, "gtkblist-created", list); |
4118 gaim_signal_emit(handle, "gtkblist-created", list); |
| 3915 } |
4119 } |
| 3916 |
4120 |
| 3917 static void redo_buddy_list(GaimBuddyList *list, gboolean remove) |
4121 static void redo_buddy_list(GaimBuddyList *list, gboolean remove, gboolean rerender) |
| 3918 { |
4122 { |
| 3919 GaimBlistNode *node = list->root; |
4123 GaimBlistNode *node = list->root; |
| 3920 |
4124 |
| 3921 while (node) |
4125 while (node) |
| 3922 { |
4126 { |
| |
4127 /* This is only needed when we're reverting to a non-GTK+ sorted |
| |
4128 * status. We shouldn't need to remove otherwise. |
| |
4129 */ |
| 3923 if (remove && !GAIM_BLIST_NODE_IS_GROUP(node)) |
4130 if (remove && !GAIM_BLIST_NODE_IS_GROUP(node)) |
| 3924 gaim_gtk_blist_hide_node(list, node); |
4131 gaim_gtk_blist_hide_node(list, node, FALSE); |
| 3925 |
4132 |
| 3926 gaim_gtk_blist_update(list, node); |
4133 if (GAIM_BLIST_NODE_IS_BUDDY(node)) |
| |
4134 gaim_gtk_blist_update_buddy(list, node, rerender); |
| |
4135 else if (GAIM_BLIST_NODE_IS_CHAT(node)) |
| |
4136 gaim_gtk_blist_update(list, node); |
| 3927 node = gaim_blist_node_next(node, FALSE); |
4137 node = gaim_blist_node_next(node, FALSE); |
| 3928 } |
4138 } |
| |
4139 |
| |
4140 /* There is no hash table if there is nothing in the buddy list to update */ |
| |
4141 if (status_icon_hash_table) { |
| |
4142 g_hash_table_destroy(status_icon_hash_table); |
| |
4143 status_icon_hash_table = NULL; |
| |
4144 } |
| |
4145 |
| 3929 } |
4146 } |
| 3930 |
4147 |
| 3931 void gaim_gtk_blist_refresh(GaimBuddyList *list) |
4148 void gaim_gtk_blist_refresh(GaimBuddyList *list) |
| 3932 { |
4149 { |
| 3933 redo_buddy_list(list, FALSE); |
4150 redo_buddy_list(list, FALSE, TRUE); |
| 3934 } |
4151 } |
| 3935 |
4152 |
| 3936 void |
4153 void |
| 3937 gaim_gtk_blist_update_refresh_timeout() |
4154 gaim_gtk_blist_update_refresh_timeout() |
| 3938 { |
4155 { |