Mercurial > pidgin.yaz
annotate src/buddy.c @ 4773:75f0c2799664
[gaim-migrate @ 5092]
This fixes the crash from signing on then signing off again in less
than 10 seconds. It also fixes the "you have signed on too many
times, wait 10 minutes then try again" crash.
It's like butter.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 14 Mar 2003 16:01:08 +0000 |
parents | c4c28874ecd3 |
children | 6219ffd18c63 |
rev | line source |
---|---|
1 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
342
diff
changeset
|
22 #ifdef HAVE_CONFIG_H |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2048
diff
changeset
|
23 #include <config.h> |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
342
diff
changeset
|
24 #endif |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
25 #ifdef GAIM_PLUGINS |
3630 | 26 #ifndef _WIN32 |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
27 #include <dlfcn.h> |
3630 | 28 #endif |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
29 #endif /* GAIM_PLUGINS */ |
1 | 30 #include <string.h> |
31 #include <stdio.h> | |
32 #include <stdlib.h> | |
3159 | 33 #include <ctype.h> |
1 | 34 #include <math.h> |
35 #include <time.h> | |
3630 | 36 #include <ctype.h> |
37 | |
38 #ifdef _WIN32 | |
39 #include <gdk/gdkwin32.h> | |
40 #else | |
1233
728a90516211
[gaim-migrate @ 1243]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1230
diff
changeset
|
41 #include <unistd.h> |
3630 | 42 #include <gdk/gdkx.h> |
43 #endif | |
1 | 44 |
1634
d029dc28a61e
[gaim-migrate @ 1644]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1625
diff
changeset
|
45 #include <gdk/gdkkeysyms.h> |
1 | 46 #include <gtk/gtk.h> |
1030
38452403563b
[gaim-migrate @ 1040]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1002
diff
changeset
|
47 #include "prpl.h" |
4561 | 48 #include "sound.h" |
1 | 49 #include "gaim.h" |
4687 | 50 #include "gtklist.h" |
51 #include "gtkft.h" | |
3630 | 52 |
53 #ifdef _WIN32 | |
54 #include "win32dep.h" | |
55 #endif | |
56 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
57 static struct gaim_gtk_buddy_list *gtkblist = NULL; |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
58 |
4698 | 59 /* Docklet nonsense */ |
60 static gboolean gaim_gtk_blist_obscured = FALSE; | |
61 | |
4687 | 62 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); |
4724 | 63 static char *gaim_get_tooltip_text(struct buddy *b); |
64 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size); | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
65 |
4687 | 66 /*************************************************** |
67 * Callbacks * | |
68 ***************************************************/ | |
3869 | 69 |
4698 | 70 static void gaim_gtk_blist_destroy_cb() |
71 { | |
72 if (docklet_count) | |
73 gaim_blist_set_visible(FALSE); | |
74 else | |
75 do_quit(); | |
76 } | |
77 | |
4732 | 78 static void gtk_blist_menu_info_cb(GtkWidget *w, struct buddy *b) |
79 { | |
80 serv_get_info(b->account->gc, b->name); | |
81 } | |
82 | |
4697 | 83 static void gtk_blist_menu_im_cb(GtkWidget *w, struct buddy *b) |
84 { | |
85 gaim_conversation_new(GAIM_CONV_IM, b->account, b->name); | |
86 } | |
87 | |
88 static void gtk_blist_menu_alias_cb(GtkWidget *w, struct buddy *b) | |
89 { | |
90 alias_dialog_bud(b); | |
91 } | |
92 | |
93 static void gtk_blist_menu_bp_cb(GtkWidget *w, struct buddy *b) | |
94 { | |
95 show_new_bp(b->name, b->account->gc, b->idle, | |
96 b->uc & UC_UNAVAILABLE, NULL); | |
97 } | |
98 | |
99 static void gtk_blist_menu_showlog_cb(GtkWidget *w, struct buddy *b) | |
100 { | |
101 show_log(b->name); | |
102 } | |
103 | |
104 static void gtk_blist_show_systemlog_cb() | |
105 { | |
106 show_log(NULL); | |
107 } | |
108 | |
4692 | 109 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv) |
110 { | |
111 GtkTreeIter iter; | |
112 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
113 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
114 | |
115 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ | |
116 GaimBlistNode *node; | |
117 | |
118 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
119 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
120 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
121 } | |
4694 | 122 } |
4692 | 123 |
4694 | 124 static void gtk_blist_button_info_cb(GtkWidget *w, GtkTreeView *tv) |
125 { | |
126 GtkTreeIter iter; | |
127 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
128 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
4692 | 129 |
4694 | 130 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ |
131 GaimBlistNode *node; | |
132 | |
133 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
134 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
135 serv_get_info(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
136 return; | |
137 } | |
138 } | |
139 show_info_dialog(); | |
140 } | |
141 | |
142 static void gtk_blist_button_chat_cb(GtkWidget *w, gpointer data) | |
143 { | |
144 /* FIXME: someday, we can check to see if we've selected a chat node */ | |
145 join_chat(); | |
146 } | |
147 | |
148 static void gtk_blist_button_away_cb(GtkWidget *w, gpointer data) | |
149 { | |
150 gtk_menu_popup(GTK_MENU(awaymenu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME); | |
4692 | 151 } |
152 | |
4687 | 153 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { |
154 GaimBlistNode *node; | |
155 GtkTreeIter iter; | |
156 GValue val = { 0, }; | |
3154 | 157 |
4687 | 158 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); |
159 | |
160 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
161 node = g_value_get_pointer(&val); | |
162 | |
163 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
164 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
4697 | 165 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
166 if (gtk_tree_view_row_expanded(tv, path)) | |
167 gtk_tree_view_collapse_row(tv, path); | |
168 else | |
169 gtk_tree_view_expand_row(tv,path,FALSE); | |
1 | 170 } |
171 } | |
172 | |
4687 | 173 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b) |
1 | 174 { |
4687 | 175 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); |
176 if (pbm->callback) | |
177 pbm->callback(pbm->gc, b->name); | |
1396
df7c3cacac92
[gaim-migrate @ 1406]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1392
diff
changeset
|
178 } |
1 | 179 |
4687 | 180 static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer null) |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
181 { |
4687 | 182 GtkTreePath *path; |
183 GaimBlistNode *node; | |
184 GValue val = { 0, }; | |
185 GtkTreeIter iter; | |
186 GtkWidget *menu, *menuitem; | |
187 GtkWidget *image; | |
4702 | 188 GtkTreeSelection *sel; |
4687 | 189 GList *list; |
190 struct prpl *prpl; | |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
191 |
4687 | 192 if (event->button != 3) |
193 return FALSE; | |
4718 | 194 |
4687 | 195 /* Here we figure out which node was clicked */ |
196 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
197 return FALSE; | |
198 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
199 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
200 node = g_value_get_pointer(&val); | |
4718 | 201 |
4721 | 202 if (!GAIM_BLIST_NODE_IS_BUDDY(node)) { |
203 gtk_tree_path_free(path); | |
4687 | 204 return FALSE; |
4721 | 205 } |
4718 | 206 |
4687 | 207 menu = gtk_menu_new(); |
3251 | 208 |
4687 | 209 /* Protocol specific options */ |
210 prpl = find_prpl(((struct buddy*)node)->account->protocol); | |
4732 | 211 |
212 if(prpl && prpl->get_info) { | |
213 menuitem = gtk_image_menu_item_new_with_mnemonic("_Get Info"); | |
214 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_info_cb), node); | |
215 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
216 } | |
217 | |
218 menuitem = gtk_image_menu_item_new_with_mnemonic("_IM"); | |
219 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_im_cb), node); | |
220 image = gtk_image_new_from_stock(GAIM_STOCK_IM, GTK_ICON_SIZE_MENU); | |
221 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
222 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
223 | |
224 menuitem = gtk_image_menu_item_new_with_mnemonic("_Alias"); | |
225 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_alias_cb), node); | |
226 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
227 | |
228 menuitem = gtk_image_menu_item_new_with_mnemonic("Add Buddy _Pounce"); | |
229 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_bp_cb), node); | |
230 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
231 | |
232 menuitem = gtk_image_menu_item_new_with_mnemonic("View _Log"); | |
233 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_showlog_cb), node); | |
234 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
235 | |
4687 | 236 if (prpl) { |
237 list = prpl->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
238 while (list) { | |
239 struct proto_buddy_menu *pbm = list->data; | |
240 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); | |
241 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); | |
242 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node); | |
243 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
244 list = list->next; | |
3313 | 245 } |
3251 | 246 } |
1 | 247 |
4687 | 248 gtk_widget_show_all(menu); |
249 | |
250 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); | |
1 | 251 |
4702 | 252 #if (1) /* This code only exists because GTK doesn't work. If we return FALSE here, as would be normal |
253 * the event propoagates down and somehow gets interpreted as the start of a drag event. */ | |
254 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
255 gtk_tree_selection_select_path(sel, path); | |
4721 | 256 gtk_tree_path_free(path); |
4702 | 257 return TRUE; |
258 #endif | |
1 | 259 } |
260 | |
4687 | 261 static void gaim_gtk_blist_reordered_cb(GtkTreeModel *model, |
262 GtkTreePath *path, | |
263 GtkTreeIter *iter, | |
264 gint *neworder, | |
265 gpointer null) | |
3111 | 266 { |
4687 | 267 debug_printf("This doesn't work because GTK is broken\n"); |
1 | 268 |
269 } | |
270 | |
4687 | 271 /* This is called 10 seconds after the buddy logs in. It removes the "logged in" icon and replaces it with |
272 * the normal status icon */ | |
1072
81d19577285a
[gaim-migrate @ 1082]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1070
diff
changeset
|
273 |
4687 | 274 static gboolean gaim_reset_present_icon(GaimBlistNode *b) |
275 { | |
276 ((struct buddy*)b)->present = 1; | |
277 gaim_gtk_blist_update(NULL, b); | |
278 return FALSE; | |
577
aa9a8bcddd80
[gaim-migrate @ 587]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
544
diff
changeset
|
279 } |
aa9a8bcddd80
[gaim-migrate @ 587]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
544
diff
changeset
|
280 |
4687 | 281 static void gaim_gtk_blist_add_buddy_cb() |
935
5e6ca3dd4d02
[gaim-migrate @ 945]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
921
diff
changeset
|
282 { |
4690 | 283 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); |
4687 | 284 GtkTreeIter iter; |
285 GaimBlistNode *node; | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
286 |
4692 | 287 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ |
288 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
4691 | 289 if (GAIM_BLIST_NODE_IS_BUDDY(node)) |
290 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); | |
291 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
292 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); | |
293 } | |
4697 | 294 else { |
4692 | 295 show_add_buddy(NULL, NULL, NULL, NULL); |
296 } | |
1 | 297 } |
298 | |
4697 | 299 static void gaim_gtk_blist_update_toolbar_icons (GtkWidget *widget, gpointer data) { |
300 if (GTK_IS_IMAGE(widget)) { | |
301 if (blist_options & OPT_BLIST_SHOW_BUTTON_XPM) | |
302 gtk_widget_show(widget); | |
303 else | |
304 gtk_widget_hide(widget); | |
305 } else if (GTK_IS_CONTAINER(widget)) { | |
306 gtk_container_foreach(GTK_CONTAINER(widget), gaim_gtk_blist_update_toolbar_icons, NULL); | |
307 } | |
308 } | |
1 | 309 |
4702 | 310 static void gaim_gtk_blist_drag_data_get_cb (GtkWidget *widget, |
311 GdkDragContext *dc, | |
312 GtkSelectionData *data, | |
313 guint info, | |
314 guint time, | |
315 gpointer *null) | |
316 { | |
317 if (data->target == gdk_atom_intern("GAIM_BUDDY", FALSE)) { | |
318 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); | |
319 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
320 GtkTreeIter iter; | |
321 GaimBlistNode *node = NULL; | |
322 GValue val = {0}; | |
323 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); | |
324 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
325 node = g_value_get_pointer(&val); | |
326 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
327 gtk_selection_data_set (data, | |
328 gdk_atom_intern ("GAIM_BUDDY", FALSE), | |
329 8, /* bits */ | |
330 (void*)&node, | |
331 sizeof (node)); | |
4721 | 332 |
333 gtk_tree_path_free(sourcerow); | |
4702 | 334 } |
4721 | 335 |
4702 | 336 } |
337 | |
338 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
339 GtkSelectionData *sd, guint info, guint t) | |
340 { | |
341 if (sd->target == gdk_atom_intern("GAIM_BUDDY", FALSE)) { | |
342 struct buddy *b = NULL; | |
343 GtkTreePath *path = NULL; | |
4704 | 344 GtkTreeViewDropPosition position; |
4702 | 345 memcpy(&b, sd->data, sizeof(b)); |
4704 | 346 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { |
347 /* if we're here, I think it means the drop is ok */ | |
4770 | 348 GtkTreeIter iter; |
349 GaimBlistNode *node; | |
350 GValue val = {0}; | |
351 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
352 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
353 node = g_value_get_pointer(&val); | |
354 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
355 if (position == GTK_TREE_VIEW_DROP_AFTER) { | |
356 gaim_blist_add_buddy(b, node->parent, node); | |
357 } else if (position == GTK_TREE_VIEW_DROP_BEFORE) { | |
358 gaim_blist_add_buddy(b, node->parent, node->prev); | |
359 } | |
360 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
361 gaim_blist_add_buddy(b, node, NULL); | |
362 } | |
4721 | 363 gtk_tree_path_free(path); |
4704 | 364 } |
4702 | 365 } |
366 } | |
367 | |
4724 | 368 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, struct buddy *b) |
369 { | |
370 GtkStyle *style; | |
371 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(b, GAIM_STATUS_ICON_LARGE); | |
372 PangoLayout *layout; | |
373 char *tooltiptext = gaim_get_tooltip_text(b); | |
374 | |
375 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
376 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
4732 | 377 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
4733 | 378 pango_layout_set_width(layout, 300000); |
4724 | 379 style = gtkblist->tipwindow->style; |
4732 | 380 |
4724 | 381 gtk_paint_flat_box (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
382 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
4729 | 383 |
384 #if GTK_CHECK_VERSION(2,2,0) | |
4724 | 385 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, pixbuf, |
386 0, 0, 4, 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
4729 | 387 #else |
4758 | 388 gdk_pixbuf_render_to_drawable(pixbuf, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 4, 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
4729 | 389 #endif |
4724 | 390 |
391 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, TRUE, | |
392 NULL, gtkblist->tipwindow, "tooltip", 38, 4, layout); | |
393 | |
394 g_object_unref (pixbuf); | |
395 g_object_unref (layout); | |
396 g_free(tooltiptext); | |
397 return; | |
398 } | |
399 | |
400 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) | |
401 { | |
402 GtkTreePath *path; | |
403 GtkTreeIter iter; | |
404 GaimBlistNode *node; | |
405 GValue val = {0}; | |
406 | |
407 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL)) | |
408 return FALSE; | |
409 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
410 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
411 node = g_value_get_pointer(&val); | |
412 | |
413 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
414 int scr_w,scr_h, w, h, x, y; | |
415 PangoLayout *layout; | |
416 struct buddy *buddy = (struct buddy*)node; | |
417 char *tooltiptext = gaim_get_tooltip_text(buddy); | |
418 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); | |
419 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); | |
4729 | 420 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); |
4724 | 421 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); |
422 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
423 G_CALLBACK(gaim_gtk_blist_paint_tip), buddy); | |
424 gtk_widget_ensure_style (gtkblist->tipwindow); | |
425 | |
426 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
4733 | 427 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
428 pango_layout_set_width(layout, 300000); | |
4724 | 429 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); |
430 scr_w = gdk_screen_width(); | |
431 scr_h = gdk_screen_height(); | |
432 pango_layout_get_size (layout, &w, &h); | |
433 w = PANGO_PIXELS(w) + 8; | |
434 h = PANGO_PIXELS(h) + 8; | |
435 | |
436 /* 38 is the size of a large status icon plus 4 pixels padding on each side. | |
437 I should #define this or something */ | |
438 w = w + 38; | |
439 h = MAX(h, 38); | |
440 | |
441 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
442 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) | |
443 y+=gtkblist->window->allocation.y; | |
444 | |
445 x -= ((w >> 1) + 4); | |
446 | |
447 if ((x + w) > scr_w) | |
448 x -= (x + w) - scr_w; | |
449 else if (x < 0) | |
450 x = 0; | |
451 | |
452 if ((y + h + 4) > scr_h) | |
453 y = y - h; | |
454 else | |
455 y = y + 6; | |
456 g_object_unref (layout); | |
457 g_free(tooltiptext); | |
458 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); | |
4729 | 459 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); |
4724 | 460 gtk_widget_show(gtkblist->tipwindow); |
461 } | |
4729 | 462 |
4724 | 463 gtk_tree_path_free(path); |
464 return FALSE; | |
465 } | |
466 | |
4730 | 467 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
4724 | 468 { |
469 GtkTreePath *path; | |
470 | |
471 if (gtkblist->timeout) { | |
472 if ((event->y > gtkblist->rect.y) && ((event->y - gtkblist->rect.height) < gtkblist->rect.y)) | |
4732 | 473 return FALSE; |
4724 | 474 /* We've left the cell. Remove the timeout and create a new one below */ |
475 if (gtkblist->tipwindow) { | |
476 gtk_widget_destroy(gtkblist->tipwindow); | |
477 gtkblist->tipwindow = NULL; | |
478 } | |
479 | |
480 g_source_remove(gtkblist->timeout); | |
481 } | |
482 | |
483 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); | |
484 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->rect); | |
485 if (path) | |
486 gtk_tree_path_free(path); | |
487 gtkblist->timeout = g_timeout_add(500, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); | |
4730 | 488 return FALSE; |
4724 | 489 } |
490 | |
491 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
492 { | |
493 if (gtkblist->timeout == 0) | |
494 return; | |
495 if (gtkblist->tipwindow) { | |
496 gtk_widget_destroy(gtkblist->tipwindow); | |
497 gtkblist->tipwindow = NULL; | |
498 } | |
499 g_source_remove(gtkblist->timeout); | |
500 gtkblist->timeout = 0; | |
501 } | |
502 | |
4687 | 503 /*************************************************** |
504 * Crap * | |
505 ***************************************************/ | |
506 static GtkItemFactoryEntry blist_menu[] = | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
507 { |
4687 | 508 /* Buddies menu */ |
509 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
510 { N_("/Buddies/_Add A Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, | |
511 "<StockItem>", GTK_STOCK_ADD }, | |
512 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0, | |
513 "<StockItem>", GAIM_STOCK_IM }, | |
514 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, | |
515 "<StockItem>", GAIM_STOCK_CHAT }, | |
516 { N_("/Buddies/sep1"), NULL, NULL, 0, "<Separator>" }, | |
517 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, | |
518 "<StockItem>", GAIM_STOCK_INFO }, | |
519 { N_("/Buddies/sep2"), NULL, NULL, 0, "<Separator>" }, | |
520 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL }, | |
521 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, | |
522 "<StockItem>", GTK_STOCK_QUIT }, | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
523 |
4687 | 524 /* Tools */ |
525 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, | |
526 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
527 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
528 { N_("/Tools/sep1"), NULL, NULL, 0, "<Separator>" }, | |
529 { N_("/Tools/A_ccounts"), "<CTL>A", account_editor, 0, NULL }, | |
4694 | 530 { N_("/Tools/Preferences"), "<CTL>P", show_prefs, 0, |
4687 | 531 "<StockItem>", GTK_STOCK_PREFERENCES }, |
4698 | 532 { N_("/Tools/_File Transfers"), NULL, gaim_show_xfer_dialog, 0, |
4687 | 533 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED }, |
534 { N_("/Tools/sep2"), NULL, NULL, 0, "<Separator>" }, | |
535 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, | |
536 { N_("/Tools/Pr_ivacy"), NULL, show_privacy_options, 0, NULL }, | |
4697 | 537 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
3251 | 538 |
4687 | 539 /* Help */ |
540 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
541 { N_("/Help/Online _Help"), "F1", NULL, 0, | |
542 "<StockItem>", GTK_STOCK_HELP }, | |
4755 | 543 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, NULL }, |
4687 | 544 { N_("/Help/_About"), NULL, show_about, 0, NULL }, |
545 | |
546 }; | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
547 |
4687 | 548 /********************************************************* |
549 * Private Utility functions * | |
550 *********************************************************/ | |
551 | |
4724 | 552 static char *gaim_get_tooltip_text(struct buddy *b) |
553 { | |
554 char *text = NULL; | |
555 struct prpl* prpl = find_prpl(b->account->protocol); | |
556 char *statustext = NULL; | |
557 char *warning = NULL, *idletime = NULL; | |
558 | |
559 if (prpl->tooltip_text) { | |
4732 | 560 statustext = prpl->tooltip_text(b); |
4724 | 561 } |
4732 | 562 |
4724 | 563 if (b->idle) { |
564 int ihrs, imin; | |
565 time_t t; | |
566 time(&t); | |
567 ihrs = (t - b->idle) / 3600; | |
568 imin = ((t - b->idle) / 60) % 60; | |
569 if (ihrs) | |
4744 | 570 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin); |
4724 | 571 else |
4744 | 572 idletime = g_strdup_printf(_("%dm"), imin); |
4724 | 573 } |
4732 | 574 |
4724 | 575 if (b->evil > 0) |
4744 | 576 warning = g_strdup_printf(_("%d%%"), b->evil); |
4732 | 577 |
4724 | 578 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" |
4744 | 579 "%s %s" /* Alias */ |
580 "%s %s" /* Nickname */ | |
581 "%s %s" /* Idle */ | |
582 "%s %s" /* Warning */ | |
4741 | 583 "%s%s", /* Status */ |
4724 | 584 b->name, |
4744 | 585 b->alias && b->alias[0] ? _("\n<b>Alias:</b>") : "", b->alias ? b->alias : "", |
586 b->server_alias ? _("\n<b>Nickname:</b>") : "", b->server_alias ? b->server_alias : "", | |
587 b->idle ? _("\n<b>Idle:</b>") : "", b->idle ? idletime : "", | |
588 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", | |
4724 | 589 statustext ? "\n" : "", statustext ? statustext : ""); |
4737 | 590 if(warning) |
591 g_free(warning); | |
592 if(idletime) | |
593 g_free(idletime); | |
594 if(statustext) | |
595 g_free(statustext); | |
596 | |
4724 | 597 return text; |
598 | |
599 } | |
600 | |
601 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size) | |
4687 | 602 { |
603 GdkPixbuf *status = NULL; | |
604 GdkPixbuf *scale = NULL; | |
605 GdkPixbuf *emblem = NULL; | |
4737 | 606 gchar *filename = NULL; |
4687 | 607 const char *protoname = NULL; |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
608 |
4691 | 609 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; |
4737 | 610 |
4687 | 611 int scalesize = 30; |
612 | |
613 struct prpl* prpl = find_prpl(b->account->protocol); | |
614 if (prpl->list_icon) | |
615 protoname = prpl->list_icon(b->account, b); | |
616 if (prpl->list_emblems) | |
617 prpl->list_emblems(b, &se, &sw, &nw, &ne); | |
4737 | 618 |
4724 | 619 if (size == GAIM_STATUS_ICON_SMALL) { |
4687 | 620 scalesize = 15; |
621 sw = nw = ne = NULL; /* So that only the se icon will composite */ | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
622 } |
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
623 |
4701 | 624 |
4687 | 625 if (b->present == 2) { |
4701 | 626 struct gaim_gtk_blist_node *gtknode; |
4687 | 627 /* If b->present is 2, that means this buddy has just signed on. We use the "login" icon for the |
628 * status, and we set a timeout to change it to a normal icon after 10 seconds. */ | |
629 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); | |
630 status = gdk_pixbuf_new_from_file(filename,NULL); | |
631 g_free(filename); | |
4701 | 632 |
633 gtknode = GAIM_GTK_BLIST_NODE((GaimBlistNode*)b); | |
4773 | 634 if (gtknode->timer > 0) |
635 g_source_remove(gtknode->timer); | |
4701 | 636 gtknode->timer = g_timeout_add(10000, (GSourceFunc)gaim_reset_present_icon, b); |
637 | |
4737 | 638 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and |
4687 | 639 then it will look up protoname from the theme */ |
640 } else { | |
641 char *image = g_strdup_printf("%s.png", protoname); | |
642 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
643 status = gdk_pixbuf_new_from_file(filename,NULL); | |
644 g_free(image); | |
645 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
646 |
4687 | 647 } |
4737 | 648 |
4687 | 649 if (!status) |
650 return NULL; | |
4737 | 651 |
4687 | 652 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); |
4737 | 653 |
654 g_object_unref(G_OBJECT(status)); | |
655 | |
4687 | 656 /* Emblems */ |
4737 | 657 |
4687 | 658 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" |
659 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
4737 | 660 |
4687 | 661 /* XXX Clean this crap up, yo. */ |
662 if (se) { | |
663 char *image = g_strdup_printf("%s.png", se); | |
664 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
665 g_free(image); | |
666 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
667 g_free(filename); | |
668 if (emblem) { | |
4724 | 669 if (size == GAIM_STATUS_ICON_LARGE) |
4687 | 670 gdk_pixbuf_composite (emblem, |
671 scale, 15, 15, | |
672 15, 15, | |
673 15, 15, | |
674 1, 1, | |
675 GDK_INTERP_BILINEAR, | |
676 255); | |
677 else | |
678 gdk_pixbuf_composite (emblem, | |
679 scale, 0, 0, | |
680 15, 15, | |
681 0, 0, | |
682 1, 1, | |
683 GDK_INTERP_BILINEAR, | |
684 255); | |
4737 | 685 g_object_unref(G_OBJECT(emblem)); |
4687 | 686 } |
687 } | |
688 if (sw) { | |
689 char *image = g_strdup_printf("%s.png", sw); | |
690 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
691 g_free(image); | |
692 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
693 g_free(filename); | |
694 if (emblem) { | |
4737 | 695 gdk_pixbuf_composite (emblem, |
696 scale, 0, 15, | |
697 15, 15, | |
698 0, 15, | |
699 1, 1, | |
700 GDK_INTERP_BILINEAR, | |
701 255); | |
702 g_object_unref(G_OBJECT(emblem)); | |
4687 | 703 } |
704 } | |
705 if (nw) { | |
706 char *image = g_strdup_printf("%s.png", nw); | |
707 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
708 g_free(image); | |
709 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
710 g_free(filename); | |
711 if (emblem) { | |
712 gdk_pixbuf_composite (emblem, | |
713 scale, 0, 0, | |
714 15, 15, | |
715 0, 0, | |
716 1, 1, | |
717 GDK_INTERP_BILINEAR, | |
718 255); | |
4737 | 719 g_object_unref(G_OBJECT(emblem)); |
4687 | 720 } |
721 } | |
722 if (ne) { | |
723 char *image = g_strdup_printf("%s.png", ne); | |
724 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
725 g_free(image); | |
726 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
727 g_free(filename); | |
728 if (emblem) { | |
729 gdk_pixbuf_composite (emblem, | |
730 scale, 15, 0, | |
731 15, 15, | |
732 15, 0, | |
733 1, 1, | |
734 GDK_INTERP_BILINEAR, | |
735 255); | |
736 } | |
4737 | 737 } |
4687 | 738 |
4737 | 739 |
4718 | 740 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ |
4699 | 741 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4687 | 742 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); |
743 return scale; | |
1 | 744 } |
745 | |
4737 | 746 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 747 { |
4687 | 748 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
4737 | 749 char *file; |
750 GdkPixbuf *buf, *ret; | |
751 | |
4687 | 752 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) |
753 return NULL; | |
4737 | 754 |
4757 | 755 if ((file = gaim_buddy_get_setting(b, "buddy_icon")) == NULL) |
756 return NULL; | |
757 | |
4737 | 758 buf = gdk_pixbuf_new_from_file(file, NULL); |
759 g_free(file); | |
760 | |
761 | |
4687 | 762 if (buf) { |
4699 | 763 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) { |
4687 | 764 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
765 } |
4737 | 766 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
767 g_object_unref(G_OBJECT(buf)); | |
768 return ret; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
769 } |
4687 | 770 return NULL; |
2986 | 771 } |
772 | |
4687 | 773 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b) |
1 | 774 { |
4687 | 775 char *name = gaim_get_buddy_alias(b); |
776 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
4722 | 777 struct prpl* prpl = find_prpl(b->account->protocol); |
778 | |
4687 | 779 /* XXX Clean up this crap */ |
4699 | 780 |
4687 | 781 int ihrs, imin; |
4724 | 782 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
4732 | 783 time_t t; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
784 |
4687 | 785 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
4699 | 786 if (b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS) { |
4718 | 787 text = g_strdup_printf("<span color='dim grey'>%s</span>", |
4699 | 788 esc); |
4687 | 789 g_free(esc); |
790 return text; | |
791 } else { | |
792 return esc; | |
793 } | |
1 | 794 } |
795 | |
4687 | 796 time(&t); |
797 ihrs = (t - b->idle) / 3600; | |
798 imin = ((t - b->idle) / 60) % 60; | |
4699 | 799 |
4722 | 800 if (prpl->status_text) { |
4732 | 801 char *tmp = prpl->status_text(b); |
802 | |
803 if(tmp) { | |
804 if(strlen(tmp) > 20) | |
4757 | 805 statustext = g_strdup_printf("%.20s... ", tmp); |
4732 | 806 else |
4757 | 807 statustext = g_strdup_printf("%s ", tmp); |
4732 | 808 g_free(tmp); |
809 } | |
4722 | 810 } |
4732 | 811 |
4687 | 812 if (b->idle) { |
813 if (ihrs) | |
4757 | 814 idletime = g_strdup_printf(_("Idle (%dh%02dm) "), ihrs, imin); |
4687 | 815 else |
4757 | 816 idletime = g_strdup_printf(_("Idle (%dm) "), imin); |
4687 | 817 } |
4757 | 818 |
4687 | 819 if (b->evil > 0) |
4757 | 820 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil); |
821 | |
4699 | 822 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4757 | 823 text = g_strdup_printf("<span color='dim grey'>%s</span>\n<span color='dim grey' size='smaller'>%s%s%s</span>", |
4687 | 824 esc, |
4722 | 825 statustext != NULL ? statustext : "", |
826 idletime != NULL ? idletime : "", | |
827 warning != NULL ? warning : ""); | |
4687 | 828 else |
4757 | 829 text = g_strdup_printf("%s\n<span color='dim grey' size='smaller'>%s%s%s</span>", esc, |
4722 | 830 statustext != NULL ? statustext : "", |
831 idletime != NULL ? idletime : "", | |
832 warning != NULL ? warning : ""); | |
833 if (idletime) | |
4687 | 834 g_free(idletime); |
4722 | 835 if (warning) |
4687 | 836 g_free(warning); |
4722 | 837 if (statustext) |
838 g_free(statustext); | |
4737 | 839 if (esc) |
840 g_free(esc); | |
4699 | 841 |
4687 | 842 return text; |
843 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
844 |
4687 | 845 /********************************************************************************** |
846 * Public API Functions * | |
847 **********************************************************************************/ | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
848 static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
849 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
850 blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
851 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
852 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
853 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
854 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
855 node->ui_data = g_new0(struct gaim_gtk_blist_node, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
856 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
857 |
4729 | 858 void gaim_gtk_blist_update_columns() |
859 { | |
860 if (blist_options & OPT_BLIST_SHOW_ICONS) { | |
861 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); | |
862 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
863 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
864 } else { | |
865 gtk_tree_view_column_set_visible(gtkblist->idle_column, blist_options & OPT_BLIST_SHOW_IDLETIME); | |
866 gtk_tree_view_column_set_visible(gtkblist->warning_column, blist_options & OPT_BLIST_SHOW_WARN); | |
867 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); | |
868 } | |
869 } | |
870 | |
4702 | 871 enum {DRAG_BUDDY, DRAG_ROW}; |
872 | |
4687 | 873 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) |
874 { | |
875 GtkItemFactory *ift; | |
876 GtkCellRenderer *rend; | |
877 GtkTreeViewColumn *column; | |
878 GtkWidget *sw; | |
879 GtkWidget *button; | |
4694 | 880 GtkSizeGroup *sg; |
4729 | 881 GtkTargetEntry gte[] = {{"GAIM_BUDDY", GTK_TARGET_SAME_APP, DRAG_ROW}, |
4702 | 882 {"application/x-im-contact", 0, DRAG_BUDDY}}; |
4690 | 883 |
4745 | 884 if (gtkblist && gtkblist->window) { |
4687 | 885 gtk_widget_show(gtkblist->window); |
886 return; | |
887 } | |
4690 | 888 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
889 gtkblist = GAIM_GTK_BLIST(list); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
890 |
4687 | 891 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
892 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); | |
4690 | 893 |
4687 | 894 gtkblist->vbox = gtk_vbox_new(FALSE, 6); |
895 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | |
1 | 896 |
4698 | 897 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gaim_gtk_blist_destroy_cb), NULL); |
898 | |
4687 | 899 /******************************* Menu bar *************************************/ |
900 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | |
901 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), | |
902 blist_menu, NULL); | |
903 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 904 |
4694 | 905 awaymenu = gtk_item_factory_get_widget(ift, "/Tools/Away"); |
906 do_away_menu(); | |
907 | |
4696 | 908 bpmenu = gtk_item_factory_get_widget(ift, "/Tools/Buddy Pounce"); |
909 do_bp_menu(); | |
910 | |
911 protomenu = gtk_item_factory_get_widget(ift, "/Tools/Protocol Actions"); | |
912 do_proto_menu(); | |
913 | |
4687 | 914 /****************************** GtkTreeView **********************************/ |
915 sw = gtk_scrolled_window_new(NULL,NULL); | |
916 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
917 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
4690 | 918 gtk_widget_set_size_request(sw, 200, 200); |
4687 | 919 |
4729 | 920 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, |
4687 | 921 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
4702 | 922 |
4687 | 923 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); |
4704 | 924 |
4702 | 925 /* Set up dnd */ |
926 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte, | |
927 2, GDK_ACTION_COPY); | |
4704 | 928 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, |
4702 | 929 GDK_ACTION_COPY | GDK_ACTION_MOVE); |
4704 | 930 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
931 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); | |
932 | |
4724 | 933 /* Tooltips */ |
934 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
935 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
4687 | 936 |
937 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 938 |
4687 | 939 rend = gtk_cell_renderer_pixbuf_new(); |
940 column = gtk_tree_view_column_new_with_attributes("Status", rend, "pixbuf", STATUS_ICON_COLUMN, NULL); | |
941 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4716 | 942 g_object_set(rend, "ypad", 0.0, NULL); |
4706 | 943 |
4687 | 944 rend = gtk_cell_renderer_text_new(); |
945 column = gtk_tree_view_column_new_with_attributes("Name", rend, "markup", NAME_COLUMN, NULL); | |
946 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4706 | 947 g_object_set(rend, "ypad", 0.0, NULL); |
948 | |
4687 | 949 rend = gtk_cell_renderer_text_new(); |
4725 | 950 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); |
951 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
4716 | 952 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4687 | 953 |
954 rend = gtk_cell_renderer_text_new(); | |
4725 | 955 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
956 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
4716 | 957 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
1 | 958 |
4687 | 959 rend = gtk_cell_renderer_pixbuf_new(); |
4725 | 960 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); |
4706 | 961 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4725 | 962 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); |
4718 | 963 |
4687 | 964 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); |
965 g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL); | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
966 |
4687 | 967 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
968 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
4725 | 969 gaim_gtk_blist_update_columns(); |
4687 | 970 /**************************** Button Box **************************************/ |
4694 | 971 |
972 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | |
4687 | 973 gtkblist->bbox = gtk_hbox_new(TRUE, 0); |
974 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
975 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); | |
976 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
977 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 978 gtk_size_group_add_widget(sg, button); |
4692 | 979 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_im_cb), |
4697 | 980 gtkblist->treeview); |
981 | |
4687 | 982 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); |
983 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
984 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 985 gtk_size_group_add_widget(sg, button); |
986 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_info_cb), | |
4697 | 987 gtkblist->treeview); |
4729 | 988 |
4687 | 989 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); |
990 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
991 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 992 gtk_size_group_add_widget(sg, button); |
993 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); | |
994 | |
4687 | 995 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_AWAY, GAIM_BUTTON_VERTICAL); |
996 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
997 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 998 gtk_size_group_add_widget(sg, button); |
999 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | |
4687 | 1000 |
1001 /* OK... let's show this bad boy. */ | |
1002 gaim_gtk_blist_refresh(list); | |
1003 gtk_widget_show_all(gtkblist->window); | |
4729 | 1004 |
4697 | 1005 gaim_gtk_blist_update_toolbar(); |
1006 | |
4687 | 1007 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1008 |
4687 | 1009 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
1010 { | |
1011 GaimBlistNode *group = list->root; | |
1012 GaimBlistNode *buddy; | |
4690 | 1013 |
4687 | 1014 while (group) { |
1015 gaim_gtk_blist_update(list, group); | |
1016 buddy = group->child; | |
1017 while (buddy) { | |
4699 | 1018 gaim_gtk_blist_update(list, buddy); |
4687 | 1019 buddy = buddy->next; |
1020 } | |
1021 group = group->next; | |
1022 } | |
1023 } | |
1 | 1024 |
4699 | 1025 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { |
1026 do { | |
1027 GaimBlistNode *n; | |
1028 GtkTreeIter child; | |
1029 | |
1030 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1); | |
1031 if(n == node) { | |
1032 *iter = *root; | |
1033 return TRUE; | |
1034 } | |
1035 | |
1036 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) { | |
1037 if(get_iter_from_node_helper(node,iter,&child)) | |
1038 return TRUE; | |
1039 } | |
1040 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root)); | |
1041 | |
1042 return FALSE; | |
1043 } | |
1044 | |
1045 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { | |
1046 GtkTreeIter root; | |
1047 | |
1048 if (!gtkblist) | |
1049 return FALSE; | |
1050 | |
1051 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root)) | |
1052 return FALSE; | |
1053 | |
1054 return get_iter_from_node_helper(node, iter, &root); | |
1055 } | |
1056 | |
4697 | 1057 void gaim_gtk_blist_update_toolbar() { |
1058 if (!gtkblist) | |
1059 return; | |
4699 | 1060 |
4697 | 1061 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); |
4699 | 1062 |
4697 | 1063 if (blist_options & OPT_BLIST_NO_BUTTONS) |
1064 gtk_widget_hide(gtkblist->bbox); | |
1065 else | |
1066 gtk_widget_show_all(gtkblist->bbox); | |
1067 } | |
1068 | |
4701 | 1069 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
1070 { | |
1071 struct gaim_gtk_blist_node *gtknode; | |
1072 GtkTreeIter iter; | |
1073 | |
1074 if (!node->ui_data) | |
1075 return; | |
1076 | |
1077 gtknode = (struct gaim_gtk_blist_node *)node->ui_data; | |
1078 | |
1079 if (gtknode->timer > 0) { | |
1080 g_source_remove(gtknode->timer); | |
1081 gtknode->timer = 0; | |
1082 } | |
1083 | |
1084 if (get_iter_from_node(node, &iter)) { | |
1085 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
1086 if(GAIM_BLIST_NODE_IS_BUDDY(node) && gaim_blist_get_group_online_count((struct group *)node->parent) == 0) { | |
1087 GtkTreeIter groupiter; | |
1088 if(get_iter_from_node(node->parent, &groupiter)) | |
1089 gtk_tree_store_remove(gtkblist->treemodel, &groupiter); | |
1090 } | |
1091 } | |
1092 } | |
1093 | |
1094 | |
4687 | 1095 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
1096 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1097 struct gaim_gtk_blist_node *gtknode; |
4699 | 1098 GtkTreeIter iter; |
4687 | 1099 gboolean expand = FALSE; |
4699 | 1100 gboolean new_entry = FALSE; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1101 |
4687 | 1102 if (!gtkblist) |
1103 return; | |
4699 | 1104 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1105 gtknode = GAIM_GTK_BLIST_NODE(node); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1106 |
4690 | 1107 |
4699 | 1108 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ |
1109 new_entry = TRUE; | |
4687 | 1110 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1111 if (((struct buddy*)node)->present) { | |
4699 | 1112 GtkTreeIter groupiter; |
1113 GaimBlistNode *oldersibling; | |
1114 GtkTreeIter oldersiblingiter; | |
4690 | 1115 |
4699 | 1116 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { |
1117 /* This buddy's group has not yet been added. We do that here */ | |
4757 | 1118 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, |
1119 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); | |
4687 | 1120 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name); |
4699 | 1121 oldersibling = node->parent->prev; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1122 |
4687 | 1123 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ |
4699 | 1124 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) |
1125 oldersibling = oldersibling->prev; | |
4690 | 1126 |
4687 | 1127 /* This is where we create the node and add it. */ |
4699 | 1128 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL); |
1129 gtk_tree_store_set(gtkblist->treemodel, &groupiter, | |
4757 | 1130 STATUS_ICON_COLUMN, groupicon, |
4687 | 1131 NAME_COLUMN, mark, |
1132 NODE_COLUMN, node->parent, | |
1133 -1); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1134 |
4737 | 1135 g_free(mark); |
4757 | 1136 g_object_unref(G_OBJECT(groupicon)); |
4737 | 1137 |
4687 | 1138 expand = TRUE; |
1139 } | |
4767 | 1140 |
4699 | 1141 oldersibling = node->prev; |
1142 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) | |
1143 oldersibling = oldersibling->prev; | |
1144 | |
1145 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); | |
4767 | 1146 |
1147 if (blist_options & OPT_BLIST_POPUP) | |
1148 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4699 | 1149 |
4687 | 1150 if (expand) { /* expand was set to true if this is the first element added to a group. In such case |
1151 * we expand the group node */ | |
4699 | 1152 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter); |
1153 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); | |
4721 | 1154 gtk_tree_path_free(path); |
4687 | 1155 } |
4699 | 1156 } |
1157 } | |
1158 } | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1159 |
4687 | 1160 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { |
1161 GdkPixbuf *status, *avatar; | |
1162 char *mark; | |
4697 | 1163 char *warning = NULL, *idle = NULL; |
1164 | |
4724 | 1165 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, |
1166 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); | |
4687 | 1167 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); |
1168 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node); | |
4697 | 1169 |
4725 | 1170 if (((struct buddy*)node)->idle > 0) { |
4697 | 1171 time_t t; |
1172 int ihrs, imin; | |
1173 time(&t); | |
1174 ihrs = (t - ((struct buddy *)node)->idle) / 3600; | |
1175 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; | |
4718 | 1176 if(ihrs > 0) |
1177 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
1178 else | |
1179 idle = g_strdup_printf("(%d)", imin); | |
4697 | 1180 } |
1181 | |
4725 | 1182 if (((struct buddy*)node)->evil > 0) |
4699 | 1183 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); |
4725 | 1184 |
4697 | 1185 |
4718 | 1186 if((blist_options & OPT_BLIST_GREY_IDLERS) |
1187 && ((struct buddy *)node)->idle) { | |
1188 if(warning) { | |
1189 char *w2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1190 warning); | |
1191 g_free(warning); | |
1192 warning = w2; | |
1193 } | |
1194 | |
1195 if(idle) { | |
1196 char *i2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1197 idle); | |
1198 g_free(idle); | |
1199 idle = i2; | |
1200 } | |
1201 } | |
1202 | |
1203 | |
4699 | 1204 gtk_tree_store_set(gtkblist->treemodel, &iter, |
4687 | 1205 STATUS_ICON_COLUMN, status, |
1206 NAME_COLUMN, mark, | |
4697 | 1207 WARNING_COLUMN, warning, |
1208 IDLE_COLUMN, idle, | |
4699 | 1209 BUDDY_ICON_COLUMN, avatar, |
4687 | 1210 NODE_COLUMN, node, |
1211 -1); | |
4699 | 1212 |
4687 | 1213 g_free(mark); |
4697 | 1214 if (idle) |
1215 g_free(idle); | |
1216 if (warning) | |
1217 g_free(warning); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1218 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1219 if (status != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1220 g_object_unref(status); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1221 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1222 if (avatar != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1223 g_object_unref(avatar); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1224 |
4701 | 1225 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { |
1226 gaim_gtk_blist_remove(list, node); | |
4767 | 1227 if (blist_options & OPT_BLIST_POPUP) |
1228 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4687 | 1229 } |
1230 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1231 |
4687 | 1232 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) |
1233 { | |
4770 | 1234 if (!gtkblist) |
1235 return; | |
4687 | 1236 gtk_widget_destroy(gtkblist->window); |
4745 | 1237 |
1238 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; | |
1239 gtkblist->treemodel = NULL; | |
1240 gtkblist->idle_column = NULL; | |
1241 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
1242 gtkblist->bbox = gtkblist->tipwindow = NULL; | |
1243 protomenu = NULL; | |
1244 awaymenu = NULL; | |
1245 bpmenu = NULL; | |
1246 | |
1247 gtkblist->timeout = 0; | |
4687 | 1248 } |
1 | 1249 |
4687 | 1250 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1251 { | |
4698 | 1252 if (show) { |
4699 | 1253 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
4698 | 1254 } else { |
1255 if (!connections || docklet_count) { | |
1256 #ifdef _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1257 wgaim_systray_minimize(gtkblist->window); |
4698 | 1258 #endif |
1259 gtk_widget_hide(gtkblist->window); | |
1260 } else { | |
1261 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
1262 } | |
1263 } | |
1264 } | |
1265 | |
1266 void gaim_gtk_blist_docklet_toggle() { | |
1267 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
1268 /* This is called when one of those is clicked--it will show/hide the | |
1269 buddy list/login window--depending on which is active */ | |
1270 if (connections && gtkblist) { | |
1271 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
1272 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1273 } else { | |
1274 #if _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1275 wgaim_systray_maximize(gtkblist->window); |
4698 | 1276 #endif |
1277 gaim_blist_set_visible(TRUE); | |
1278 } | |
1279 } else if (connections) { | |
1280 /* we're logging in or something... do nothing */ | |
1281 debug_printf("docklet_toggle called with connections but no blist!\n"); | |
1282 } else { | |
1283 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
1284 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { | |
1285 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1286 } else { | |
1287 #if _WIN32 | |
1288 wgaim_systray_minimize(mainwindow); | |
1289 #endif | |
1290 gtk_widget_hide(mainwindow); | |
1291 } | |
1292 } else { | |
1293 #if _WIN32 | |
1294 wgaim_systray_maximize(mainwindow); | |
1295 #endif | |
1296 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1297 } | |
1298 } | |
1299 } | |
1300 | |
1301 void gaim_gtk_blist_docklet_add() | |
1302 { | |
1303 docklet_count++; | |
1304 } | |
1305 | |
1306 void gaim_gtk_blist_docklet_remove() | |
1307 { | |
1308 docklet_count--; | |
1309 if (!docklet_count) { | |
1310 if (connections) { | |
1311 gaim_blist_set_visible(TRUE); | |
4745 | 1312 } else if(gtkblist && gtkblist->window) { |
4698 | 1313 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
1314 } | |
1315 } | |
4687 | 1316 } |
1 | 1317 |
4687 | 1318 static struct gaim_blist_ui_ops blist_ui_ops = |
1319 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1320 gaim_gtk_blist_new_list, |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1321 gaim_gtk_blist_new_node, |
4687 | 1322 gaim_gtk_blist_show, |
1323 gaim_gtk_blist_update, | |
1324 gaim_gtk_blist_remove, | |
1325 gaim_gtk_blist_destroy, | |
1326 gaim_gtk_blist_set_visible | |
1327 }; | |
1 | 1328 |
1329 | |
4687 | 1330 struct gaim_blist_ui_ops *gaim_get_gtk_blist_ui_ops() |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1331 { |
4687 | 1332 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1333 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1334 |
3131 | 1335 |
1336 | |
4687 | 1337 /********************************************************************* |
1338 * Public utility functions * | |
1339 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
1340 |
4687 | 1341 GdkPixbuf * |
1342 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
1343 { |
4687 | 1344 struct prpl *prpl = find_prpl(account->protocol); |
1345 GdkPixbuf *status = NULL; | |
1346 char *filename = NULL; | |
1347 const char *protoname = prpl->list_icon(account, NULL); | |
1348 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
1349 then it will look up protoname from the theme */ | |
1350 if (!strcmp(protoname, "aim")) { | |
1351 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "aim.png", NULL); | |
1352 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1353 g_free(filename); | |
1354 } else if (!strcmp(protoname, "yahoo")) { | |
1355 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "yahoo.png", NULL); | |
1356 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1357 g_free(filename); | |
1358 } else if (!strcmp(protoname, "msn")) { | |
1359 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "msn.png", NULL); | |
1360 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1361 g_free(filename); | |
1362 } else if (!strcmp(protoname, "jabber")) { | |
1363 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "jabber.png", NULL); | |
1364 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1365 g_free(filename); | |
1366 } else if (!strcmp(protoname, "icq")) { | |
1367 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "icq.png", NULL); | |
1368 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1369 g_free(filename); | |
1370 } else if (!strcmp(protoname, "gadu-gadu")) { | |
1371 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "gadugadu.png", NULL); | |
1372 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1373 g_free(filename); | |
1374 } else if (!strcmp(protoname, "napster")) { | |
1375 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "napster.png", NULL); | |
1376 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1377 g_free(filename); | |
1378 } else if (!strcmp(protoname, "irc")) { | |
1379 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "irc.png", NULL); | |
1380 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1381 g_free(filename); | |
960
fa681641643d
[gaim-migrate @ 970]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
945
diff
changeset
|
1382 } |
4687 | 1383 return status; |
1 | 1384 } |
4699 | 1385 |