pidgin/gtkblist.c

changeset 41506
fff3a446f76d
parent 41502
d00bcebf0f90
child 41507
bdacc88a9562
equal deleted inserted replaced
41505:3f120d577610 41506:fff3a446f76d
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(&gtkblist->treemodel); 4174 g_clear_object(&gtkblist->treemodel);
4276 4175
4277 purple_prefs_disconnect_by_handle(pidgin_blist_get_handle()); 4176 purple_prefs_disconnect_by_handle(pidgin_blist_get_handle());

mercurial