| 98 EMBLEM_VISIBLE_COLUMN, |
98 EMBLEM_VISIBLE_COLUMN, |
| 99 PROTOCOL_ICON_COLUMN, |
99 PROTOCOL_ICON_COLUMN, |
| 100 BLIST_COLUMNS |
100 BLIST_COLUMNS |
| 101 }; |
101 }; |
| 102 |
102 |
| 103 static GdkVisibilityState gtk_blist_visibility = GDK_VISIBILITY_UNOBSCURED; |
|
| 104 static gboolean editing_blist = FALSE; |
103 static gboolean editing_blist = FALSE; |
| 105 |
104 |
| 106 static GList *pidgin_blist_sort_methods = NULL; |
105 static GList *pidgin_blist_sort_methods = NULL; |
| 107 static struct _PidginBlistSortMethod *current_sort_method = NULL; |
106 static struct _PidginBlistSortMethod *current_sort_method = NULL; |
| 108 static void sort_method_none(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
107 static void sort_method_none(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
| 111 static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
110 static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); |
| 112 |
111 |
| 113 static PidginBuddyList *gtkblist = NULL; |
112 static PidginBuddyList *gtkblist = NULL; |
| 114 |
113 |
| 115 static GList *groups_tree(void); |
114 static GList *groups_tree(void); |
| 116 static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list); |
|
| 117 static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *node, gboolean status_change); |
115 static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *node, gboolean status_change); |
| 118 static void pidgin_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
116 static void pidgin_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
| 119 static void pidgin_blist_update(PurpleBuddyList *list, PurpleBlistNode *node); |
117 static void pidgin_blist_update(PurpleBuddyList *list, PurpleBlistNode *node); |
| 120 static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node); |
118 static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node); |
| 121 static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *node); |
119 static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *node); |
| 137 } PidginBlistNode; |
135 } PidginBlistNode; |
| 138 |
136 |
| 139 /*************************************************** |
137 /*************************************************** |
| 140 * Callbacks * |
138 * Callbacks * |
| 141 ***************************************************/ |
139 ***************************************************/ |
| 142 static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) |
|
| 143 { |
|
| 144 GdkVisibilityState old_state = gtk_blist_visibility; |
|
| 145 gtk_blist_visibility = event->state; |
|
| 146 |
|
| 147 if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED && |
|
| 148 old_state != GDK_VISIBILITY_FULLY_OBSCURED) { |
|
| 149 |
|
| 150 /* no longer fully obscured */ |
|
| 151 pidgin_blist_refresh_timer(purple_blist_get_default()); |
|
| 152 } |
|
| 153 |
|
| 154 /* continue to handle event normally */ |
|
| 155 return FALSE; |
|
| 156 } |
|
| 157 |
|
| 158 static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data) |
|
| 159 { |
|
| 160 if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { |
|
| 161 if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) |
|
| 162 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE); |
|
| 163 else { |
|
| 164 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE); |
|
| 165 pidgin_blist_refresh_timer(purple_blist_get_default()); |
|
| 166 } |
|
| 167 } |
|
| 168 |
|
| 169 if(event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) { |
|
| 170 if(event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) |
|
| 171 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", TRUE); |
|
| 172 else |
|
| 173 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", FALSE); |
|
| 174 } |
|
| 175 |
|
| 176 /* Refresh gtkblist if un-iconifying */ |
|
| 177 if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){ |
|
| 178 if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) |
|
| 179 pidgin_blist_refresh_timer(purple_blist_get_default()); |
|
| 180 } |
|
| 181 |
|
| 182 return FALSE; |
|
| 183 } |
|
| 184 |
|
| 185 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) |
|
| 186 { |
|
| 187 purple_core_quit(); |
|
| 188 |
|
| 189 /* we handle everything, event should not propagate further */ |
|
| 190 return TRUE; |
|
| 191 } |
|
| 192 |
|
| 193 static void |
140 static void |
| 194 set_node_custom_icon_cb(GtkWidget *widget, gint response, gpointer data) |
141 set_node_custom_icon_cb(GtkWidget *widget, gint response, gpointer data) |
| 195 { |
142 { |
| 196 if (response == GTK_RESPONSE_ACCEPT) { |
143 if (response == GTK_RESPONSE_ACCEPT) { |
| 197 PurpleBlistNode *node = (PurpleBlistNode*)data; |
144 PurpleBlistNode *node = (PurpleBlistNode*)data; |
| 2824 g_free(contact_alias); |
2771 g_free(contact_alias); |
| 2825 |
2772 |
| 2826 return text; |
2773 return text; |
| 2827 } |
2774 } |
| 2828 |
2775 |
| 2829 static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list) |
|
| 2830 { |
|
| 2831 PurpleBlistNode *gnode, *cnode; |
|
| 2832 |
|
| 2833 if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED |
|
| 2834 || !gtk_widget_get_visible(gtkblist->window)) |
|
| 2835 return TRUE; |
|
| 2836 |
|
| 2837 for (gnode = purple_blist_get_root(list); gnode; gnode = gnode->next) { |
|
| 2838 if(!PURPLE_IS_GROUP(gnode)) |
|
| 2839 continue; |
|
| 2840 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
|
| 2841 if(PURPLE_IS_CONTACT(cnode)) { |
|
| 2842 PurpleBuddy *buddy; |
|
| 2843 |
|
| 2844 buddy = purple_contact_get_priority_buddy((PurpleContact*)cnode); |
|
| 2845 |
|
| 2846 if (buddy && |
|
| 2847 purple_presence_is_idle(purple_buddy_get_presence(buddy))) |
|
| 2848 pidgin_blist_update_contact(list, PURPLE_BLIST_NODE(buddy)); |
|
| 2849 } |
|
| 2850 } |
|
| 2851 } |
|
| 2852 |
|
| 2853 /* keep on going */ |
|
| 2854 return TRUE; |
|
| 2855 } |
|
| 2856 |
|
| 2857 static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node, gboolean update) |
2776 static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node, gboolean update) |
| 2858 { |
2777 { |
| 2859 PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA); |
2778 PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA); |
| 2860 GtkTreeIter iter; |
2779 GtkTreeIter iter; |
| 2861 |
2780 |
| 3194 GtkTreeViewColumn *column; |
3113 GtkTreeViewColumn *column; |
| 3195 GtkWidget *sep; |
3114 GtkWidget *sep; |
| 3196 GtkEventController *key_controller = NULL; |
3115 GtkEventController *key_controller = NULL; |
| 3197 GtkTreeSelection *selection; |
3116 GtkTreeSelection *selection; |
| 3198 |
3117 |
| 3199 if (gtkblist && gtkblist->window) { |
|
| 3200 purple_blist_set_visible(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/list_visible")); |
|
| 3201 return; |
|
| 3202 } |
|
| 3203 |
|
| 3204 gtkblist = PIDGIN_BUDDY_LIST(list); |
3118 gtkblist = PIDGIN_BUDDY_LIST(list); |
| 3205 |
3119 |
| 3206 gtkblist->window = pidgin_contact_list_window_new(); |
3120 gtkblist->window = pidgin_contact_list_window_new(); |
| 3207 g_signal_connect(G_OBJECT(gtkblist->window), "focus-in-event", |
3121 g_signal_connect(G_OBJECT(gtkblist->window), "focus-in-event", |
| 3208 G_CALLBACK(blist_focus_cb), gtkblist); |
3122 G_CALLBACK(blist_focus_cb), gtkblist); |
| 3211 |
3125 |
| 3212 /* the main vbox is already packed and shown via glade, we just need a |
3126 /* the main vbox is already packed and shown via glade, we just need a |
| 3213 * reference to it to pack the rest of our widgets here. |
3127 * reference to it to pack the rest of our widgets here. |
| 3214 */ |
3128 */ |
| 3215 gtkblist->vbox = pidgin_contact_list_window_get_vbox(PIDGIN_CONTACT_LIST_WINDOW(gtkblist->window)); |
3129 gtkblist->vbox = pidgin_contact_list_window_get_vbox(PIDGIN_CONTACT_LIST_WINDOW(gtkblist->window)); |
| 3216 |
|
| 3217 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
|
| 3218 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); |
|
| 3219 g_signal_connect(G_OBJECT(gtkblist->window), "window_state_event", G_CALLBACK(gtk_blist_window_state_cb), NULL); |
|
| 3220 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); |
|
| 3221 |
3130 |
| 3222 /****************************** GtkTreeView **********************************/ |
3131 /****************************** GtkTreeView **********************************/ |
| 3223 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, |
3132 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, |
| 3224 GDK_TYPE_PIXBUF, /* Status icon */ |
3133 GDK_TYPE_PIXBUF, /* Status icon */ |
| 3225 G_TYPE_BOOLEAN, /* Status icon visible */ |
3134 G_TYPE_BOOLEAN, /* Status icon visible */ |
| 3300 /* OK... let's show this bad boy. */ |
3209 /* OK... let's show this bad boy. */ |
| 3301 pidgin_blist_refresh(list); |
3210 pidgin_blist_refresh(list); |
| 3302 gtk_widget_show_all(GTK_WIDGET(gtkblist->vbox)); |
3211 gtk_widget_show_all(GTK_WIDGET(gtkblist->vbox)); |
| 3303 purple_blist_set_visible(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/list_visible")); |
3212 purple_blist_set_visible(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/list_visible")); |
| 3304 |
3213 |
| 3305 /* start the refresh timer */ |
|
| 3306 gtkblist->refresh_timer = g_timeout_add_seconds(30, (GSourceFunc)pidgin_blist_refresh_timer, list); |
|
| 3307 |
|
| 3308 handle = pidgin_blist_get_handle(); |
3214 handle = pidgin_blist_get_handle(); |
| 3309 |
3215 |
| 3310 /* sorting */ |
3216 /* sorting */ |
| 3311 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/sort_type", |
3217 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/sort_type", |
| 3312 _prefs_change_sort_method, NULL); |
3218 _prefs_change_sort_method, NULL); |
| 4209 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"); |
4115 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"); |
| 4210 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"); |
4116 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"); |
| 4211 |
4117 |
| 4212 /* Initialize prefs */ |
4118 /* Initialize prefs */ |
| 4213 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/blist"); |
4119 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/blist"); |
| 4214 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE); |
|
| 4215 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", FALSE); |
|
| 4216 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/sort_type", "alphabetical"); |
4120 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/sort_type", "alphabetical"); |
| 4217 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/theme", ""); |
4121 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/theme", ""); |
| 4218 |
4122 |
| 4219 /* Register our signals */ |
4123 /* Register our signals */ |
| 4220 purple_signal_register(gtk_blist_handle, "gtkblist-created", |
4124 purple_signal_register(gtk_blist_handle, "gtkblist-created", |
| 4263 PidginBuddyList *gtkblist = PIDGIN_BUDDY_LIST(obj); |
4167 PidginBuddyList *gtkblist = PIDGIN_BUDDY_LIST(obj); |
| 4264 |
4168 |
| 4265 purple_signals_disconnect_by_handle(gtkblist); |
4169 purple_signals_disconnect_by_handle(gtkblist); |
| 4266 |
4170 |
| 4267 gtk_widget_destroy(gtkblist->window); |
4171 gtk_widget_destroy(gtkblist->window); |
| 4268 |
|
| 4269 if (gtkblist->refresh_timer) { |
|
| 4270 g_source_remove(gtkblist->refresh_timer); |
|
| 4271 gtkblist->refresh_timer = 0; |
|
| 4272 } |
|
| 4273 |
4172 |
| 4274 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; |
4173 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; |
| 4275 g_clear_object(>kblist->treemodel); |
4174 g_clear_object(>kblist->treemodel); |
| 4276 |
4175 |
| 4277 purple_prefs_disconnect_by_handle(pidgin_blist_get_handle()); |
4176 purple_prefs_disconnect_by_handle(pidgin_blist_get_handle()); |