Mercurial > pidgin.yaz
annotate src/buddy.c @ 4755:54fbd9769677
[gaim-migrate @ 5072]
This fixes the debug window. It's probably not an ideal fix, but it
works. Some kind of core/ui splittage here would be nice.
I also made the gtk convo destroy function remove the timer to redraw
animated buddy icons, if it exists. This doesn't really affect anything,
since the redraw function checks to make sure the convo exists, but
it's probably more better this way.
Also, I meant to misspell "definitely." Really. I did. You don't
believe me? It's ok, I wouldn't believe me either.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 13 Mar 2003 22:57:58 +0000 |
parents | 01cae9259e2f |
children | c4ebe1a8484b |
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 */ | |
4721 | 348 gtk_tree_path_free(path); |
4704 | 349 } |
4702 | 350 } |
351 } | |
352 | |
4724 | 353 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, struct buddy *b) |
354 { | |
355 GtkStyle *style; | |
356 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(b, GAIM_STATUS_ICON_LARGE); | |
357 PangoLayout *layout; | |
358 char *tooltiptext = gaim_get_tooltip_text(b); | |
359 | |
360 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
361 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
4732 | 362 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
4733 | 363 pango_layout_set_width(layout, 300000); |
4724 | 364 style = gtkblist->tipwindow->style; |
4732 | 365 |
4724 | 366 gtk_paint_flat_box (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
367 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
4729 | 368 |
369 #if GTK_CHECK_VERSION(2,2,0) | |
4724 | 370 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, pixbuf, |
371 0, 0, 4, 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
4729 | 372 #else |
373 gdk_pixbuf_render_to_drawable(pixbuf, NULL, GDK_DRAWABLE(gtkblist->tipwindow->window), 0, 0, 4, 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); | |
374 #endif | |
4724 | 375 |
376 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, TRUE, | |
377 NULL, gtkblist->tipwindow, "tooltip", 38, 4, layout); | |
378 | |
379 g_object_unref (pixbuf); | |
380 g_object_unref (layout); | |
381 g_free(tooltiptext); | |
382 return; | |
383 } | |
384 | |
385 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) | |
386 { | |
387 GtkTreePath *path; | |
388 GtkTreeIter iter; | |
389 GaimBlistNode *node; | |
390 GValue val = {0}; | |
391 | |
392 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL)) | |
393 return FALSE; | |
394 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
395 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
396 node = g_value_get_pointer(&val); | |
397 | |
398 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
399 int scr_w,scr_h, w, h, x, y; | |
400 PangoLayout *layout; | |
401 struct buddy *buddy = (struct buddy*)node; | |
402 char *tooltiptext = gaim_get_tooltip_text(buddy); | |
403 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); | |
404 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); | |
4729 | 405 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); |
4724 | 406 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); |
407 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
408 G_CALLBACK(gaim_gtk_blist_paint_tip), buddy); | |
409 gtk_widget_ensure_style (gtkblist->tipwindow); | |
410 | |
411 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
4733 | 412 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
413 pango_layout_set_width(layout, 300000); | |
4724 | 414 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); |
415 scr_w = gdk_screen_width(); | |
416 scr_h = gdk_screen_height(); | |
417 pango_layout_get_size (layout, &w, &h); | |
418 w = PANGO_PIXELS(w) + 8; | |
419 h = PANGO_PIXELS(h) + 8; | |
420 | |
421 /* 38 is the size of a large status icon plus 4 pixels padding on each side. | |
422 I should #define this or something */ | |
423 w = w + 38; | |
424 h = MAX(h, 38); | |
425 | |
426 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
427 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) | |
428 y+=gtkblist->window->allocation.y; | |
429 | |
430 x -= ((w >> 1) + 4); | |
431 | |
432 if ((x + w) > scr_w) | |
433 x -= (x + w) - scr_w; | |
434 else if (x < 0) | |
435 x = 0; | |
436 | |
437 if ((y + h + 4) > scr_h) | |
438 y = y - h; | |
439 else | |
440 y = y + 6; | |
441 g_object_unref (layout); | |
442 g_free(tooltiptext); | |
443 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); | |
4729 | 444 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); |
4724 | 445 gtk_widget_show(gtkblist->tipwindow); |
446 } | |
4729 | 447 |
4724 | 448 gtk_tree_path_free(path); |
449 return FALSE; | |
450 } | |
451 | |
4730 | 452 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
4724 | 453 { |
454 GtkTreePath *path; | |
455 | |
456 if (gtkblist->timeout) { | |
457 if ((event->y > gtkblist->rect.y) && ((event->y - gtkblist->rect.height) < gtkblist->rect.y)) | |
4732 | 458 return FALSE; |
4724 | 459 /* We've left the cell. Remove the timeout and create a new one below */ |
460 if (gtkblist->tipwindow) { | |
461 gtk_widget_destroy(gtkblist->tipwindow); | |
462 gtkblist->tipwindow = NULL; | |
463 } | |
464 | |
465 g_source_remove(gtkblist->timeout); | |
466 } | |
467 | |
468 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); | |
469 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->rect); | |
470 if (path) | |
471 gtk_tree_path_free(path); | |
472 gtkblist->timeout = g_timeout_add(500, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); | |
4730 | 473 return FALSE; |
4724 | 474 } |
475 | |
476 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
477 { | |
478 if (gtkblist->timeout == 0) | |
479 return; | |
480 if (gtkblist->tipwindow) { | |
481 gtk_widget_destroy(gtkblist->tipwindow); | |
482 gtkblist->tipwindow = NULL; | |
483 } | |
484 g_source_remove(gtkblist->timeout); | |
485 gtkblist->timeout = 0; | |
486 } | |
487 | |
4687 | 488 /*************************************************** |
489 * Crap * | |
490 ***************************************************/ | |
491 static GtkItemFactoryEntry blist_menu[] = | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
492 { |
4687 | 493 /* Buddies menu */ |
494 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
495 { N_("/Buddies/_Add A Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, | |
496 "<StockItem>", GTK_STOCK_ADD }, | |
497 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0, | |
498 "<StockItem>", GAIM_STOCK_IM }, | |
499 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, | |
500 "<StockItem>", GAIM_STOCK_CHAT }, | |
501 { N_("/Buddies/sep1"), NULL, NULL, 0, "<Separator>" }, | |
502 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, | |
503 "<StockItem>", GAIM_STOCK_INFO }, | |
504 { N_("/Buddies/sep2"), NULL, NULL, 0, "<Separator>" }, | |
505 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL }, | |
506 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, | |
507 "<StockItem>", GTK_STOCK_QUIT }, | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
508 |
4687 | 509 /* Tools */ |
510 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, | |
511 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
512 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
513 { N_("/Tools/sep1"), NULL, NULL, 0, "<Separator>" }, | |
514 { N_("/Tools/A_ccounts"), "<CTL>A", account_editor, 0, NULL }, | |
4694 | 515 { N_("/Tools/Preferences"), "<CTL>P", show_prefs, 0, |
4687 | 516 "<StockItem>", GTK_STOCK_PREFERENCES }, |
4698 | 517 { N_("/Tools/_File Transfers"), NULL, gaim_show_xfer_dialog, 0, |
4687 | 518 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED }, |
519 { N_("/Tools/sep2"), NULL, NULL, 0, "<Separator>" }, | |
520 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, | |
521 { N_("/Tools/Pr_ivacy"), NULL, show_privacy_options, 0, NULL }, | |
4697 | 522 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
3251 | 523 |
4687 | 524 /* Help */ |
525 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
526 { N_("/Help/Online _Help"), "F1", NULL, 0, | |
527 "<StockItem>", GTK_STOCK_HELP }, | |
4755 | 528 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, NULL }, |
4687 | 529 { N_("/Help/_About"), NULL, show_about, 0, NULL }, |
530 | |
531 }; | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
532 |
4687 | 533 /********************************************************* |
534 * Private Utility functions * | |
535 *********************************************************/ | |
536 | |
4724 | 537 static char *gaim_get_tooltip_text(struct buddy *b) |
538 { | |
539 char *text = NULL; | |
540 struct prpl* prpl = find_prpl(b->account->protocol); | |
541 char *statustext = NULL; | |
542 char *warning = NULL, *idletime = NULL; | |
543 | |
544 if (prpl->tooltip_text) { | |
4732 | 545 statustext = prpl->tooltip_text(b); |
4724 | 546 } |
4732 | 547 |
4724 | 548 if (b->idle) { |
549 int ihrs, imin; | |
550 time_t t; | |
551 time(&t); | |
552 ihrs = (t - b->idle) / 3600; | |
553 imin = ((t - b->idle) / 60) % 60; | |
554 if (ihrs) | |
4744 | 555 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin); |
4724 | 556 else |
4744 | 557 idletime = g_strdup_printf(_("%dm"), imin); |
4724 | 558 } |
4732 | 559 |
4724 | 560 if (b->evil > 0) |
4744 | 561 warning = g_strdup_printf(_("%d%%"), b->evil); |
4732 | 562 |
4724 | 563 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" |
4744 | 564 "%s %s" /* Alias */ |
565 "%s %s" /* Nickname */ | |
566 "%s %s" /* Idle */ | |
567 "%s %s" /* Warning */ | |
4741 | 568 "%s%s", /* Status */ |
4724 | 569 b->name, |
4744 | 570 b->alias && b->alias[0] ? _("\n<b>Alias:</b>") : "", b->alias ? b->alias : "", |
571 b->server_alias ? _("\n<b>Nickname:</b>") : "", b->server_alias ? b->server_alias : "", | |
572 b->idle ? _("\n<b>Idle:</b>") : "", b->idle ? idletime : "", | |
573 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", | |
4724 | 574 statustext ? "\n" : "", statustext ? statustext : ""); |
4737 | 575 if(warning) |
576 g_free(warning); | |
577 if(idletime) | |
578 g_free(idletime); | |
579 if(statustext) | |
580 g_free(statustext); | |
581 | |
4724 | 582 return text; |
583 | |
584 } | |
585 | |
586 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size) | |
4687 | 587 { |
588 GdkPixbuf *status = NULL; | |
589 GdkPixbuf *scale = NULL; | |
590 GdkPixbuf *emblem = NULL; | |
4737 | 591 gchar *filename = NULL; |
4687 | 592 const char *protoname = NULL; |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
593 |
4691 | 594 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; |
4737 | 595 |
4687 | 596 int scalesize = 30; |
597 | |
598 struct prpl* prpl = find_prpl(b->account->protocol); | |
599 if (prpl->list_icon) | |
600 protoname = prpl->list_icon(b->account, b); | |
601 if (prpl->list_emblems) | |
602 prpl->list_emblems(b, &se, &sw, &nw, &ne); | |
4737 | 603 |
4724 | 604 if (size == GAIM_STATUS_ICON_SMALL) { |
4687 | 605 scalesize = 15; |
606 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
|
607 } |
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
608 |
4701 | 609 |
4687 | 610 if (b->present == 2) { |
4701 | 611 struct gaim_gtk_blist_node *gtknode; |
4687 | 612 /* If b->present is 2, that means this buddy has just signed on. We use the "login" icon for the |
613 * status, and we set a timeout to change it to a normal icon after 10 seconds. */ | |
614 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); | |
615 status = gdk_pixbuf_new_from_file(filename,NULL); | |
616 g_free(filename); | |
4701 | 617 |
618 gtknode = GAIM_GTK_BLIST_NODE((GaimBlistNode*)b); | |
619 gtknode->timer = g_timeout_add(10000, (GSourceFunc)gaim_reset_present_icon, b); | |
620 | |
4737 | 621 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and |
4687 | 622 then it will look up protoname from the theme */ |
623 } else { | |
624 char *image = g_strdup_printf("%s.png", protoname); | |
625 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
626 status = gdk_pixbuf_new_from_file(filename,NULL); | |
627 g_free(image); | |
628 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
629 |
4687 | 630 } |
4737 | 631 |
4687 | 632 if (!status) |
633 return NULL; | |
4737 | 634 |
4687 | 635 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); |
4737 | 636 |
637 g_object_unref(G_OBJECT(status)); | |
638 | |
4687 | 639 /* Emblems */ |
4737 | 640 |
4687 | 641 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" |
642 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
4737 | 643 |
4687 | 644 /* XXX Clean this crap up, yo. */ |
645 if (se) { | |
646 char *image = g_strdup_printf("%s.png", se); | |
647 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
648 g_free(image); | |
649 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
650 g_free(filename); | |
651 if (emblem) { | |
4724 | 652 if (size == GAIM_STATUS_ICON_LARGE) |
4687 | 653 gdk_pixbuf_composite (emblem, |
654 scale, 15, 15, | |
655 15, 15, | |
656 15, 15, | |
657 1, 1, | |
658 GDK_INTERP_BILINEAR, | |
659 255); | |
660 else | |
661 gdk_pixbuf_composite (emblem, | |
662 scale, 0, 0, | |
663 15, 15, | |
664 0, 0, | |
665 1, 1, | |
666 GDK_INTERP_BILINEAR, | |
667 255); | |
4737 | 668 g_object_unref(G_OBJECT(emblem)); |
4687 | 669 } |
670 } | |
671 if (sw) { | |
672 char *image = g_strdup_printf("%s.png", sw); | |
673 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
674 g_free(image); | |
675 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
676 g_free(filename); | |
677 if (emblem) { | |
4737 | 678 gdk_pixbuf_composite (emblem, |
679 scale, 0, 15, | |
680 15, 15, | |
681 0, 15, | |
682 1, 1, | |
683 GDK_INTERP_BILINEAR, | |
684 255); | |
685 g_object_unref(G_OBJECT(emblem)); | |
4687 | 686 } |
687 } | |
688 if (nw) { | |
689 char *image = g_strdup_printf("%s.png", nw); | |
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) { | |
695 gdk_pixbuf_composite (emblem, | |
696 scale, 0, 0, | |
697 15, 15, | |
698 0, 0, | |
699 1, 1, | |
700 GDK_INTERP_BILINEAR, | |
701 255); | |
4737 | 702 g_object_unref(G_OBJECT(emblem)); |
4687 | 703 } |
704 } | |
705 if (ne) { | |
706 char *image = g_strdup_printf("%s.png", ne); | |
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, 15, 0, | |
714 15, 15, | |
715 15, 0, | |
716 1, 1, | |
717 GDK_INTERP_BILINEAR, | |
718 255); | |
719 } | |
4737 | 720 } |
4687 | 721 |
4737 | 722 |
4718 | 723 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ |
4699 | 724 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4687 | 725 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); |
726 return scale; | |
1 | 727 } |
728 | |
4737 | 729 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 730 { |
4687 | 731 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
4737 | 732 char *file; |
733 GdkPixbuf *buf, *ret; | |
734 | |
4687 | 735 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) |
736 return NULL; | |
4737 | 737 |
738 file = g_build_filename(gaim_user_dir(), "icons", normalize(b->name), NULL); | |
739 buf = gdk_pixbuf_new_from_file(file, NULL); | |
740 g_free(file); | |
741 | |
742 | |
4687 | 743 if (buf) { |
4699 | 744 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) { |
4687 | 745 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
746 } |
4737 | 747 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
748 g_object_unref(G_OBJECT(buf)); | |
749 return ret; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
750 } |
4687 | 751 return NULL; |
2986 | 752 } |
753 | |
4687 | 754 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b) |
1 | 755 { |
4687 | 756 char *name = gaim_get_buddy_alias(b); |
757 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
4722 | 758 struct prpl* prpl = find_prpl(b->account->protocol); |
759 | |
4687 | 760 /* XXX Clean up this crap */ |
4699 | 761 |
4687 | 762 int ihrs, imin; |
4724 | 763 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
4732 | 764 time_t t; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
765 |
4687 | 766 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
4699 | 767 if (b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS) { |
4718 | 768 text = g_strdup_printf("<span color='dim grey'>%s</span>", |
4699 | 769 esc); |
4687 | 770 g_free(esc); |
771 return text; | |
772 } else { | |
773 return esc; | |
774 } | |
1 | 775 } |
776 | |
4687 | 777 time(&t); |
778 ihrs = (t - b->idle) / 3600; | |
779 imin = ((t - b->idle) / 60) % 60; | |
4699 | 780 |
4722 | 781 if (prpl->status_text) { |
4732 | 782 char *tmp = prpl->status_text(b); |
783 | |
784 if(tmp) { | |
785 if(strlen(tmp) > 20) | |
786 statustext = g_strdup_printf("%.16s...", tmp); | |
787 else | |
788 statustext = g_strdup(tmp); | |
789 g_free(tmp); | |
790 } | |
4722 | 791 } |
4732 | 792 |
4687 | 793 if (b->idle) { |
794 if (ihrs) | |
795 idletime = g_strdup_printf(_("Idle (%dh%02dm)"), ihrs, imin); | |
796 else | |
797 idletime = g_strdup_printf(_("Idle (%dm)"), imin); | |
798 } | |
4722 | 799 |
4687 | 800 if (b->evil > 0) |
801 warning = g_strdup_printf(_("Warned (%d%%)"), b->evil); | |
4722 | 802 |
4699 | 803 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4722 | 804 text = g_strdup_printf("<span color='dim grey'>%s</span>\n<span color='dim grey' size='smaller'>%s %s %s</span>", |
4687 | 805 esc, |
4722 | 806 statustext != NULL ? statustext : "", |
807 idletime != NULL ? idletime : "", | |
808 warning != NULL ? warning : ""); | |
4687 | 809 else |
4722 | 810 text = g_strdup_printf("%s\n<span color='dim grey' size='smaller'>%s %s %s</span>", esc, |
811 statustext != NULL ? statustext : "", | |
812 idletime != NULL ? idletime : "", | |
813 warning != NULL ? warning : ""); | |
814 if (idletime) | |
4687 | 815 g_free(idletime); |
4722 | 816 if (warning) |
4687 | 817 g_free(warning); |
4722 | 818 if (statustext) |
819 g_free(statustext); | |
4737 | 820 if (esc) |
821 g_free(esc); | |
4699 | 822 |
4687 | 823 return text; |
824 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
825 |
4687 | 826 /********************************************************************************** |
827 * Public API Functions * | |
828 **********************************************************************************/ | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
829 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
|
830 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
831 blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
832 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
833 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
834 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
835 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
836 node->ui_data = g_new0(struct gaim_gtk_blist_node, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
837 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
838 |
4729 | 839 void gaim_gtk_blist_update_columns() |
840 { | |
841 if (blist_options & OPT_BLIST_SHOW_ICONS) { | |
842 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); | |
843 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
844 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
845 } else { | |
846 gtk_tree_view_column_set_visible(gtkblist->idle_column, blist_options & OPT_BLIST_SHOW_IDLETIME); | |
847 gtk_tree_view_column_set_visible(gtkblist->warning_column, blist_options & OPT_BLIST_SHOW_WARN); | |
848 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); | |
849 } | |
850 } | |
851 | |
4702 | 852 enum {DRAG_BUDDY, DRAG_ROW}; |
853 | |
4687 | 854 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) |
855 { | |
856 GtkItemFactory *ift; | |
857 GtkCellRenderer *rend; | |
858 GtkTreeViewColumn *column; | |
859 GtkWidget *sw; | |
860 GtkWidget *button; | |
4694 | 861 GtkSizeGroup *sg; |
4729 | 862 GtkTargetEntry gte[] = {{"GAIM_BUDDY", GTK_TARGET_SAME_APP, DRAG_ROW}, |
4702 | 863 {"application/x-im-contact", 0, DRAG_BUDDY}}; |
4690 | 864 |
4745 | 865 if (gtkblist && gtkblist->window) { |
4687 | 866 gtk_widget_show(gtkblist->window); |
867 return; | |
868 } | |
4690 | 869 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
870 gtkblist = GAIM_GTK_BLIST(list); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
871 |
4687 | 872 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
873 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); | |
4690 | 874 |
4687 | 875 gtkblist->vbox = gtk_vbox_new(FALSE, 6); |
876 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | |
1 | 877 |
4698 | 878 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gaim_gtk_blist_destroy_cb), NULL); |
879 | |
4687 | 880 /******************************* Menu bar *************************************/ |
881 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | |
882 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), | |
883 blist_menu, NULL); | |
884 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 885 |
4694 | 886 awaymenu = gtk_item_factory_get_widget(ift, "/Tools/Away"); |
887 do_away_menu(); | |
888 | |
4696 | 889 bpmenu = gtk_item_factory_get_widget(ift, "/Tools/Buddy Pounce"); |
890 do_bp_menu(); | |
891 | |
892 protomenu = gtk_item_factory_get_widget(ift, "/Tools/Protocol Actions"); | |
893 do_proto_menu(); | |
894 | |
4687 | 895 /****************************** GtkTreeView **********************************/ |
896 sw = gtk_scrolled_window_new(NULL,NULL); | |
897 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
898 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
4690 | 899 gtk_widget_set_size_request(sw, 200, 200); |
4687 | 900 |
4729 | 901 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, |
4687 | 902 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
4702 | 903 |
4687 | 904 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); |
4704 | 905 |
4702 | 906 /* Set up dnd */ |
907 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte, | |
908 2, GDK_ACTION_COPY); | |
4704 | 909 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, |
4702 | 910 GDK_ACTION_COPY | GDK_ACTION_MOVE); |
4704 | 911 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
912 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); | |
913 | |
4724 | 914 /* Tooltips */ |
915 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
916 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
4687 | 917 |
918 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 919 |
4687 | 920 rend = gtk_cell_renderer_pixbuf_new(); |
921 column = gtk_tree_view_column_new_with_attributes("Status", rend, "pixbuf", STATUS_ICON_COLUMN, NULL); | |
922 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4716 | 923 g_object_set(rend, "ypad", 0.0, NULL); |
4706 | 924 |
4687 | 925 rend = gtk_cell_renderer_text_new(); |
926 column = gtk_tree_view_column_new_with_attributes("Name", rend, "markup", NAME_COLUMN, NULL); | |
927 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4706 | 928 g_object_set(rend, "ypad", 0.0, NULL); |
929 | |
4687 | 930 rend = gtk_cell_renderer_text_new(); |
4725 | 931 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); |
932 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
4716 | 933 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4687 | 934 |
935 rend = gtk_cell_renderer_text_new(); | |
4725 | 936 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
937 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
4716 | 938 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
1 | 939 |
4687 | 940 rend = gtk_cell_renderer_pixbuf_new(); |
4725 | 941 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); |
4706 | 942 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4725 | 943 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); |
4718 | 944 |
4687 | 945 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); |
946 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
|
947 |
4687 | 948 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
949 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
4725 | 950 gaim_gtk_blist_update_columns(); |
4687 | 951 /**************************** Button Box **************************************/ |
4694 | 952 |
953 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | |
4687 | 954 gtkblist->bbox = gtk_hbox_new(TRUE, 0); |
955 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
956 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); | |
957 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
958 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 959 gtk_size_group_add_widget(sg, button); |
4692 | 960 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_im_cb), |
4697 | 961 gtkblist->treeview); |
962 | |
4687 | 963 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); |
964 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
965 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 966 gtk_size_group_add_widget(sg, button); |
967 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_info_cb), | |
4697 | 968 gtkblist->treeview); |
4729 | 969 |
4687 | 970 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); |
971 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
972 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 973 gtk_size_group_add_widget(sg, button); |
974 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); | |
975 | |
4687 | 976 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_AWAY, GAIM_BUTTON_VERTICAL); |
977 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
978 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 979 gtk_size_group_add_widget(sg, button); |
980 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | |
4687 | 981 |
982 /* OK... let's show this bad boy. */ | |
983 gaim_gtk_blist_refresh(list); | |
984 gtk_widget_show_all(gtkblist->window); | |
4729 | 985 |
4697 | 986 gaim_gtk_blist_update_toolbar(); |
987 | |
4687 | 988 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
989 |
4687 | 990 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
991 { | |
992 GaimBlistNode *group = list->root; | |
993 GaimBlistNode *buddy; | |
4690 | 994 |
4687 | 995 while (group) { |
996 gaim_gtk_blist_update(list, group); | |
997 buddy = group->child; | |
998 while (buddy) { | |
4699 | 999 gaim_gtk_blist_update(list, buddy); |
4687 | 1000 buddy = buddy->next; |
1001 } | |
1002 group = group->next; | |
1003 } | |
1004 } | |
1 | 1005 |
4699 | 1006 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { |
1007 do { | |
1008 GaimBlistNode *n; | |
1009 GtkTreeIter child; | |
1010 | |
1011 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1); | |
1012 if(n == node) { | |
1013 *iter = *root; | |
1014 return TRUE; | |
1015 } | |
1016 | |
1017 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) { | |
1018 if(get_iter_from_node_helper(node,iter,&child)) | |
1019 return TRUE; | |
1020 } | |
1021 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root)); | |
1022 | |
1023 return FALSE; | |
1024 } | |
1025 | |
1026 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { | |
1027 GtkTreeIter root; | |
1028 | |
1029 if (!gtkblist) | |
1030 return FALSE; | |
1031 | |
1032 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root)) | |
1033 return FALSE; | |
1034 | |
1035 return get_iter_from_node_helper(node, iter, &root); | |
1036 } | |
1037 | |
4697 | 1038 void gaim_gtk_blist_update_toolbar() { |
1039 if (!gtkblist) | |
1040 return; | |
4699 | 1041 |
4697 | 1042 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); |
4699 | 1043 |
4697 | 1044 if (blist_options & OPT_BLIST_NO_BUTTONS) |
1045 gtk_widget_hide(gtkblist->bbox); | |
1046 else | |
1047 gtk_widget_show_all(gtkblist->bbox); | |
1048 } | |
1049 | |
4701 | 1050 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
1051 { | |
1052 struct gaim_gtk_blist_node *gtknode; | |
1053 GtkTreeIter iter; | |
1054 | |
1055 if (!node->ui_data) | |
1056 return; | |
1057 | |
1058 gtknode = (struct gaim_gtk_blist_node *)node->ui_data; | |
1059 | |
1060 if (gtknode->timer > 0) { | |
1061 g_source_remove(gtknode->timer); | |
1062 gtknode->timer = 0; | |
1063 } | |
1064 | |
1065 if (get_iter_from_node(node, &iter)) { | |
1066 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
1067 if(GAIM_BLIST_NODE_IS_BUDDY(node) && gaim_blist_get_group_online_count((struct group *)node->parent) == 0) { | |
1068 GtkTreeIter groupiter; | |
1069 if(get_iter_from_node(node->parent, &groupiter)) | |
1070 gtk_tree_store_remove(gtkblist->treemodel, &groupiter); | |
1071 } | |
1072 } | |
1073 } | |
1074 | |
1075 | |
4687 | 1076 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
1077 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1078 struct gaim_gtk_blist_node *gtknode; |
4699 | 1079 GtkTreeIter iter; |
4687 | 1080 gboolean expand = FALSE; |
4699 | 1081 gboolean new_entry = FALSE; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1082 |
4687 | 1083 if (!gtkblist) |
1084 return; | |
4699 | 1085 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1086 gtknode = GAIM_GTK_BLIST_NODE(node); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1087 |
4690 | 1088 |
4699 | 1089 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ |
1090 new_entry = TRUE; | |
4687 | 1091 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1092 if (((struct buddy*)node)->present) { | |
4699 | 1093 GtkTreeIter groupiter; |
1094 GaimBlistNode *oldersibling; | |
1095 GtkTreeIter oldersiblingiter; | |
4690 | 1096 |
4699 | 1097 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { |
1098 /* This buddy's group has not yet been added. We do that here */ | |
4687 | 1099 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name); |
4699 | 1100 oldersibling = node->parent->prev; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1101 |
4687 | 1102 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ |
4699 | 1103 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) |
1104 oldersibling = oldersibling->prev; | |
4690 | 1105 |
4687 | 1106 /* This is where we create the node and add it. */ |
4699 | 1107 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL); |
1108 gtk_tree_store_set(gtkblist->treemodel, &groupiter, | |
4687 | 1109 STATUS_ICON_COLUMN, gtk_widget_render_icon |
4691 | 1110 (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_SMALL_TOOLBAR,NULL), |
4687 | 1111 NAME_COLUMN, mark, |
1112 NODE_COLUMN, node->parent, | |
1113 -1); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1114 |
4737 | 1115 g_free(mark); |
1116 | |
4687 | 1117 expand = TRUE; |
1118 } | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1119 |
4699 | 1120 oldersibling = node->prev; |
1121 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) | |
1122 oldersibling = oldersibling->prev; | |
1123 | |
1124 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); | |
1125 | |
4687 | 1126 if (expand) { /* expand was set to true if this is the first element added to a group. In such case |
1127 * we expand the group node */ | |
4699 | 1128 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter); |
1129 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); | |
4721 | 1130 gtk_tree_path_free(path); |
4687 | 1131 } |
4699 | 1132 } |
1133 } | |
1134 } | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1135 |
4687 | 1136 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { |
1137 GdkPixbuf *status, *avatar; | |
1138 char *mark; | |
4697 | 1139 char *warning = NULL, *idle = NULL; |
1140 | |
4724 | 1141 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, |
1142 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); | |
4687 | 1143 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); |
1144 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node); | |
4697 | 1145 |
4725 | 1146 if (((struct buddy*)node)->idle > 0) { |
4697 | 1147 time_t t; |
1148 int ihrs, imin; | |
1149 time(&t); | |
1150 ihrs = (t - ((struct buddy *)node)->idle) / 3600; | |
1151 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; | |
4718 | 1152 if(ihrs > 0) |
1153 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
1154 else | |
1155 idle = g_strdup_printf("(%d)", imin); | |
4697 | 1156 } |
1157 | |
4725 | 1158 if (((struct buddy*)node)->evil > 0) |
4699 | 1159 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); |
4725 | 1160 |
4697 | 1161 |
4718 | 1162 if((blist_options & OPT_BLIST_GREY_IDLERS) |
1163 && ((struct buddy *)node)->idle) { | |
1164 if(warning) { | |
1165 char *w2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1166 warning); | |
1167 g_free(warning); | |
1168 warning = w2; | |
1169 } | |
1170 | |
1171 if(idle) { | |
1172 char *i2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1173 idle); | |
1174 g_free(idle); | |
1175 idle = i2; | |
1176 } | |
1177 } | |
1178 | |
1179 | |
4699 | 1180 gtk_tree_store_set(gtkblist->treemodel, &iter, |
4687 | 1181 STATUS_ICON_COLUMN, status, |
1182 NAME_COLUMN, mark, | |
4697 | 1183 WARNING_COLUMN, warning, |
1184 IDLE_COLUMN, idle, | |
4699 | 1185 BUDDY_ICON_COLUMN, avatar, |
4687 | 1186 NODE_COLUMN, node, |
1187 -1); | |
4699 | 1188 |
4687 | 1189 g_free(mark); |
4697 | 1190 if (idle) |
1191 g_free(idle); | |
1192 if (warning) | |
1193 g_free(warning); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1194 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1195 if (status != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1196 g_object_unref(status); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1197 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1198 if (avatar != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1199 g_object_unref(avatar); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1200 |
4701 | 1201 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { |
1202 gaim_gtk_blist_remove(list, node); | |
4687 | 1203 } |
1204 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1205 |
4687 | 1206 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) |
1207 { | |
1208 gtk_widget_destroy(gtkblist->window); | |
4745 | 1209 |
1210 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; | |
1211 gtkblist->treemodel = NULL; | |
1212 gtkblist->idle_column = NULL; | |
1213 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
1214 gtkblist->bbox = gtkblist->tipwindow = NULL; | |
1215 protomenu = NULL; | |
1216 awaymenu = NULL; | |
1217 bpmenu = NULL; | |
1218 | |
1219 gtkblist->timeout = 0; | |
4687 | 1220 } |
1 | 1221 |
4687 | 1222 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1223 { | |
4698 | 1224 if (show) { |
4699 | 1225 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
4698 | 1226 } else { |
1227 if (!connections || docklet_count) { | |
1228 #ifdef _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1229 wgaim_systray_minimize(gtkblist->window); |
4698 | 1230 #endif |
1231 gtk_widget_hide(gtkblist->window); | |
1232 } else { | |
1233 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
1234 } | |
1235 } | |
1236 } | |
1237 | |
1238 void gaim_gtk_blist_docklet_toggle() { | |
1239 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
1240 /* This is called when one of those is clicked--it will show/hide the | |
1241 buddy list/login window--depending on which is active */ | |
1242 if (connections && gtkblist) { | |
1243 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
1244 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1245 } else { | |
1246 #if _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1247 wgaim_systray_maximize(gtkblist->window); |
4698 | 1248 #endif |
1249 gaim_blist_set_visible(TRUE); | |
1250 } | |
1251 } else if (connections) { | |
1252 /* we're logging in or something... do nothing */ | |
1253 debug_printf("docklet_toggle called with connections but no blist!\n"); | |
1254 } else { | |
1255 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
1256 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { | |
1257 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1258 } else { | |
1259 #if _WIN32 | |
1260 wgaim_systray_minimize(mainwindow); | |
1261 #endif | |
1262 gtk_widget_hide(mainwindow); | |
1263 } | |
1264 } else { | |
1265 #if _WIN32 | |
1266 wgaim_systray_maximize(mainwindow); | |
1267 #endif | |
1268 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1269 } | |
1270 } | |
1271 } | |
1272 | |
1273 void gaim_gtk_blist_docklet_add() | |
1274 { | |
1275 docklet_count++; | |
1276 } | |
1277 | |
1278 void gaim_gtk_blist_docklet_remove() | |
1279 { | |
1280 docklet_count--; | |
1281 if (!docklet_count) { | |
1282 if (connections) { | |
1283 gaim_blist_set_visible(TRUE); | |
4745 | 1284 } else if(gtkblist && gtkblist->window) { |
4698 | 1285 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
1286 } | |
1287 } | |
4687 | 1288 } |
1 | 1289 |
4687 | 1290 static struct gaim_blist_ui_ops blist_ui_ops = |
1291 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1292 gaim_gtk_blist_new_list, |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1293 gaim_gtk_blist_new_node, |
4687 | 1294 gaim_gtk_blist_show, |
1295 gaim_gtk_blist_update, | |
1296 gaim_gtk_blist_remove, | |
1297 gaim_gtk_blist_destroy, | |
1298 gaim_gtk_blist_set_visible | |
1299 }; | |
1 | 1300 |
1301 | |
4687 | 1302 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
|
1303 { |
4687 | 1304 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1305 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1306 |
3131 | 1307 |
1308 | |
4687 | 1309 /********************************************************************* |
1310 * Public utility functions * | |
1311 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
1312 |
4687 | 1313 GdkPixbuf * |
1314 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
1315 { |
4687 | 1316 struct prpl *prpl = find_prpl(account->protocol); |
1317 GdkPixbuf *status = NULL; | |
1318 char *filename = NULL; | |
1319 const char *protoname = prpl->list_icon(account, NULL); | |
1320 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
1321 then it will look up protoname from the theme */ | |
1322 if (!strcmp(protoname, "aim")) { | |
1323 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "aim.png", NULL); | |
1324 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1325 g_free(filename); | |
1326 } else if (!strcmp(protoname, "yahoo")) { | |
1327 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "yahoo.png", NULL); | |
1328 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1329 g_free(filename); | |
1330 } else if (!strcmp(protoname, "msn")) { | |
1331 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "msn.png", NULL); | |
1332 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1333 g_free(filename); | |
1334 } else if (!strcmp(protoname, "jabber")) { | |
1335 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "jabber.png", NULL); | |
1336 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1337 g_free(filename); | |
1338 } else if (!strcmp(protoname, "icq")) { | |
1339 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "icq.png", NULL); | |
1340 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1341 g_free(filename); | |
1342 } else if (!strcmp(protoname, "gadu-gadu")) { | |
1343 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "gadugadu.png", NULL); | |
1344 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1345 g_free(filename); | |
1346 } else if (!strcmp(protoname, "napster")) { | |
1347 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "napster.png", NULL); | |
1348 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1349 g_free(filename); | |
1350 } else if (!strcmp(protoname, "irc")) { | |
1351 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "irc.png", NULL); | |
1352 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1353 g_free(filename); | |
960
fa681641643d
[gaim-migrate @ 970]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
945
diff
changeset
|
1354 } |
4687 | 1355 return status; |
1 | 1356 } |
4699 | 1357 |