Mercurial > pidgin.yaz
annotate src/buddy.c @ 4770:c4c28874ecd3
[gaim-migrate @ 5088]
I want to go to sleep. This is drag-n-drop moving of buddies in the list.
I think it works, but I didn't actually test it... I really should have though;
I can't imagine it working fine as-is. ;)
I'm holding off on the rest of my Edit Buddy List stuff for tomorrow... I love
last minute things, don't I?
Note: I created gaim_blist_members and gaim_blist_groups to reproduce the
effects of the old groups GSList and the members GSList of the group struct
that I removed. This is really sub-optimal and should be replaced to iterate
the Buddy List directly. If someone wants to do that, please do. Even if you
don't want to do that, just review the changes I made and make sure I didn't
do anything stupid. It is past 6am and I'm a bit tired and prone to mistake
making.
Thanks.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Fri, 14 Mar 2003 11:38:21 +0000 |
parents | f6d83e81d45a |
children | 75f0c2799664 |
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); | |
634 gtknode->timer = g_timeout_add(10000, (GSourceFunc)gaim_reset_present_icon, b); | |
635 | |
4737 | 636 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and |
4687 | 637 then it will look up protoname from the theme */ |
638 } else { | |
639 char *image = g_strdup_printf("%s.png", protoname); | |
640 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
641 status = gdk_pixbuf_new_from_file(filename,NULL); | |
642 g_free(image); | |
643 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
644 |
4687 | 645 } |
4737 | 646 |
4687 | 647 if (!status) |
648 return NULL; | |
4737 | 649 |
4687 | 650 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); |
4737 | 651 |
652 g_object_unref(G_OBJECT(status)); | |
653 | |
4687 | 654 /* Emblems */ |
4737 | 655 |
4687 | 656 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" |
657 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
4737 | 658 |
4687 | 659 /* XXX Clean this crap up, yo. */ |
660 if (se) { | |
661 char *image = g_strdup_printf("%s.png", se); | |
662 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
663 g_free(image); | |
664 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
665 g_free(filename); | |
666 if (emblem) { | |
4724 | 667 if (size == GAIM_STATUS_ICON_LARGE) |
4687 | 668 gdk_pixbuf_composite (emblem, |
669 scale, 15, 15, | |
670 15, 15, | |
671 15, 15, | |
672 1, 1, | |
673 GDK_INTERP_BILINEAR, | |
674 255); | |
675 else | |
676 gdk_pixbuf_composite (emblem, | |
677 scale, 0, 0, | |
678 15, 15, | |
679 0, 0, | |
680 1, 1, | |
681 GDK_INTERP_BILINEAR, | |
682 255); | |
4737 | 683 g_object_unref(G_OBJECT(emblem)); |
4687 | 684 } |
685 } | |
686 if (sw) { | |
687 char *image = g_strdup_printf("%s.png", sw); | |
688 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
689 g_free(image); | |
690 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
691 g_free(filename); | |
692 if (emblem) { | |
4737 | 693 gdk_pixbuf_composite (emblem, |
694 scale, 0, 15, | |
695 15, 15, | |
696 0, 15, | |
697 1, 1, | |
698 GDK_INTERP_BILINEAR, | |
699 255); | |
700 g_object_unref(G_OBJECT(emblem)); | |
4687 | 701 } |
702 } | |
703 if (nw) { | |
704 char *image = g_strdup_printf("%s.png", nw); | |
705 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
706 g_free(image); | |
707 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
708 g_free(filename); | |
709 if (emblem) { | |
710 gdk_pixbuf_composite (emblem, | |
711 scale, 0, 0, | |
712 15, 15, | |
713 0, 0, | |
714 1, 1, | |
715 GDK_INTERP_BILINEAR, | |
716 255); | |
4737 | 717 g_object_unref(G_OBJECT(emblem)); |
4687 | 718 } |
719 } | |
720 if (ne) { | |
721 char *image = g_strdup_printf("%s.png", ne); | |
722 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
723 g_free(image); | |
724 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
725 g_free(filename); | |
726 if (emblem) { | |
727 gdk_pixbuf_composite (emblem, | |
728 scale, 15, 0, | |
729 15, 15, | |
730 15, 0, | |
731 1, 1, | |
732 GDK_INTERP_BILINEAR, | |
733 255); | |
734 } | |
4737 | 735 } |
4687 | 736 |
4737 | 737 |
4718 | 738 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ |
4699 | 739 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4687 | 740 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); |
741 return scale; | |
1 | 742 } |
743 | |
4737 | 744 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 745 { |
4687 | 746 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
4737 | 747 char *file; |
748 GdkPixbuf *buf, *ret; | |
749 | |
4687 | 750 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) |
751 return NULL; | |
4737 | 752 |
4757 | 753 if ((file = gaim_buddy_get_setting(b, "buddy_icon")) == NULL) |
754 return NULL; | |
755 | |
4737 | 756 buf = gdk_pixbuf_new_from_file(file, NULL); |
757 g_free(file); | |
758 | |
759 | |
4687 | 760 if (buf) { |
4699 | 761 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) { |
4687 | 762 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
763 } |
4737 | 764 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
765 g_object_unref(G_OBJECT(buf)); | |
766 return ret; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
767 } |
4687 | 768 return NULL; |
2986 | 769 } |
770 | |
4687 | 771 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b) |
1 | 772 { |
4687 | 773 char *name = gaim_get_buddy_alias(b); |
774 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
4722 | 775 struct prpl* prpl = find_prpl(b->account->protocol); |
776 | |
4687 | 777 /* XXX Clean up this crap */ |
4699 | 778 |
4687 | 779 int ihrs, imin; |
4724 | 780 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
4732 | 781 time_t t; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
782 |
4687 | 783 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
4699 | 784 if (b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS) { |
4718 | 785 text = g_strdup_printf("<span color='dim grey'>%s</span>", |
4699 | 786 esc); |
4687 | 787 g_free(esc); |
788 return text; | |
789 } else { | |
790 return esc; | |
791 } | |
1 | 792 } |
793 | |
4687 | 794 time(&t); |
795 ihrs = (t - b->idle) / 3600; | |
796 imin = ((t - b->idle) / 60) % 60; | |
4699 | 797 |
4722 | 798 if (prpl->status_text) { |
4732 | 799 char *tmp = prpl->status_text(b); |
800 | |
801 if(tmp) { | |
802 if(strlen(tmp) > 20) | |
4757 | 803 statustext = g_strdup_printf("%.20s... ", tmp); |
4732 | 804 else |
4757 | 805 statustext = g_strdup_printf("%s ", tmp); |
4732 | 806 g_free(tmp); |
807 } | |
4722 | 808 } |
4732 | 809 |
4687 | 810 if (b->idle) { |
811 if (ihrs) | |
4757 | 812 idletime = g_strdup_printf(_("Idle (%dh%02dm) "), ihrs, imin); |
4687 | 813 else |
4757 | 814 idletime = g_strdup_printf(_("Idle (%dm) "), imin); |
4687 | 815 } |
4757 | 816 |
4687 | 817 if (b->evil > 0) |
4757 | 818 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil); |
819 | |
4699 | 820 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) |
4757 | 821 text = g_strdup_printf("<span color='dim grey'>%s</span>\n<span color='dim grey' size='smaller'>%s%s%s</span>", |
4687 | 822 esc, |
4722 | 823 statustext != NULL ? statustext : "", |
824 idletime != NULL ? idletime : "", | |
825 warning != NULL ? warning : ""); | |
4687 | 826 else |
4757 | 827 text = g_strdup_printf("%s\n<span color='dim grey' size='smaller'>%s%s%s</span>", esc, |
4722 | 828 statustext != NULL ? statustext : "", |
829 idletime != NULL ? idletime : "", | |
830 warning != NULL ? warning : ""); | |
831 if (idletime) | |
4687 | 832 g_free(idletime); |
4722 | 833 if (warning) |
4687 | 834 g_free(warning); |
4722 | 835 if (statustext) |
836 g_free(statustext); | |
4737 | 837 if (esc) |
838 g_free(esc); | |
4699 | 839 |
4687 | 840 return text; |
841 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
842 |
4687 | 843 /********************************************************************************** |
844 * Public API Functions * | |
845 **********************************************************************************/ | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
846 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
|
847 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
848 blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); |
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 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
851 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
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 node->ui_data = g_new0(struct gaim_gtk_blist_node, 1); |
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 |
4729 | 856 void gaim_gtk_blist_update_columns() |
857 { | |
858 if (blist_options & OPT_BLIST_SHOW_ICONS) { | |
859 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); | |
860 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
861 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
862 } else { | |
863 gtk_tree_view_column_set_visible(gtkblist->idle_column, blist_options & OPT_BLIST_SHOW_IDLETIME); | |
864 gtk_tree_view_column_set_visible(gtkblist->warning_column, blist_options & OPT_BLIST_SHOW_WARN); | |
865 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); | |
866 } | |
867 } | |
868 | |
4702 | 869 enum {DRAG_BUDDY, DRAG_ROW}; |
870 | |
4687 | 871 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) |
872 { | |
873 GtkItemFactory *ift; | |
874 GtkCellRenderer *rend; | |
875 GtkTreeViewColumn *column; | |
876 GtkWidget *sw; | |
877 GtkWidget *button; | |
4694 | 878 GtkSizeGroup *sg; |
4729 | 879 GtkTargetEntry gte[] = {{"GAIM_BUDDY", GTK_TARGET_SAME_APP, DRAG_ROW}, |
4702 | 880 {"application/x-im-contact", 0, DRAG_BUDDY}}; |
4690 | 881 |
4745 | 882 if (gtkblist && gtkblist->window) { |
4687 | 883 gtk_widget_show(gtkblist->window); |
884 return; | |
885 } | |
4690 | 886 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
887 gtkblist = GAIM_GTK_BLIST(list); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
888 |
4687 | 889 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
890 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); | |
4690 | 891 |
4687 | 892 gtkblist->vbox = gtk_vbox_new(FALSE, 6); |
893 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | |
1 | 894 |
4698 | 895 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gaim_gtk_blist_destroy_cb), NULL); |
896 | |
4687 | 897 /******************************* Menu bar *************************************/ |
898 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | |
899 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), | |
900 blist_menu, NULL); | |
901 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 902 |
4694 | 903 awaymenu = gtk_item_factory_get_widget(ift, "/Tools/Away"); |
904 do_away_menu(); | |
905 | |
4696 | 906 bpmenu = gtk_item_factory_get_widget(ift, "/Tools/Buddy Pounce"); |
907 do_bp_menu(); | |
908 | |
909 protomenu = gtk_item_factory_get_widget(ift, "/Tools/Protocol Actions"); | |
910 do_proto_menu(); | |
911 | |
4687 | 912 /****************************** GtkTreeView **********************************/ |
913 sw = gtk_scrolled_window_new(NULL,NULL); | |
914 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
915 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
4690 | 916 gtk_widget_set_size_request(sw, 200, 200); |
4687 | 917 |
4729 | 918 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, |
4687 | 919 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
4702 | 920 |
4687 | 921 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); |
4704 | 922 |
4702 | 923 /* Set up dnd */ |
924 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte, | |
925 2, GDK_ACTION_COPY); | |
4704 | 926 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, |
4702 | 927 GDK_ACTION_COPY | GDK_ACTION_MOVE); |
4704 | 928 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
929 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); | |
930 | |
4724 | 931 /* Tooltips */ |
932 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
933 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
4687 | 934 |
935 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 936 |
4687 | 937 rend = gtk_cell_renderer_pixbuf_new(); |
938 column = gtk_tree_view_column_new_with_attributes("Status", rend, "pixbuf", STATUS_ICON_COLUMN, NULL); | |
939 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4716 | 940 g_object_set(rend, "ypad", 0.0, NULL); |
4706 | 941 |
4687 | 942 rend = gtk_cell_renderer_text_new(); |
943 column = gtk_tree_view_column_new_with_attributes("Name", rend, "markup", NAME_COLUMN, NULL); | |
944 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4706 | 945 g_object_set(rend, "ypad", 0.0, NULL); |
946 | |
4687 | 947 rend = gtk_cell_renderer_text_new(); |
4725 | 948 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); |
949 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
4716 | 950 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4687 | 951 |
952 rend = gtk_cell_renderer_text_new(); | |
4725 | 953 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
954 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
4716 | 955 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
1 | 956 |
4687 | 957 rend = gtk_cell_renderer_pixbuf_new(); |
4725 | 958 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); |
4706 | 959 g_object_set(rend, "xalign", 1.0, "ypad", 0.0, NULL); |
4725 | 960 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); |
4718 | 961 |
4687 | 962 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); |
963 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
|
964 |
4687 | 965 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
966 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
4725 | 967 gaim_gtk_blist_update_columns(); |
4687 | 968 /**************************** Button Box **************************************/ |
4694 | 969 |
970 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | |
4687 | 971 gtkblist->bbox = gtk_hbox_new(TRUE, 0); |
972 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
973 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); | |
974 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
975 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 976 gtk_size_group_add_widget(sg, button); |
4692 | 977 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_im_cb), |
4697 | 978 gtkblist->treeview); |
979 | |
4687 | 980 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); |
981 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
982 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 983 gtk_size_group_add_widget(sg, button); |
984 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_info_cb), | |
4697 | 985 gtkblist->treeview); |
4729 | 986 |
4687 | 987 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); |
988 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
989 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 990 gtk_size_group_add_widget(sg, button); |
991 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); | |
992 | |
4687 | 993 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_AWAY, GAIM_BUTTON_VERTICAL); |
994 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
995 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 996 gtk_size_group_add_widget(sg, button); |
997 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | |
4687 | 998 |
999 /* OK... let's show this bad boy. */ | |
1000 gaim_gtk_blist_refresh(list); | |
1001 gtk_widget_show_all(gtkblist->window); | |
4729 | 1002 |
4697 | 1003 gaim_gtk_blist_update_toolbar(); |
1004 | |
4687 | 1005 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1006 |
4687 | 1007 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
1008 { | |
1009 GaimBlistNode *group = list->root; | |
1010 GaimBlistNode *buddy; | |
4690 | 1011 |
4687 | 1012 while (group) { |
1013 gaim_gtk_blist_update(list, group); | |
1014 buddy = group->child; | |
1015 while (buddy) { | |
4699 | 1016 gaim_gtk_blist_update(list, buddy); |
4687 | 1017 buddy = buddy->next; |
1018 } | |
1019 group = group->next; | |
1020 } | |
1021 } | |
1 | 1022 |
4699 | 1023 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { |
1024 do { | |
1025 GaimBlistNode *n; | |
1026 GtkTreeIter child; | |
1027 | |
1028 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1); | |
1029 if(n == node) { | |
1030 *iter = *root; | |
1031 return TRUE; | |
1032 } | |
1033 | |
1034 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) { | |
1035 if(get_iter_from_node_helper(node,iter,&child)) | |
1036 return TRUE; | |
1037 } | |
1038 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root)); | |
1039 | |
1040 return FALSE; | |
1041 } | |
1042 | |
1043 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { | |
1044 GtkTreeIter root; | |
1045 | |
1046 if (!gtkblist) | |
1047 return FALSE; | |
1048 | |
1049 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root)) | |
1050 return FALSE; | |
1051 | |
1052 return get_iter_from_node_helper(node, iter, &root); | |
1053 } | |
1054 | |
4697 | 1055 void gaim_gtk_blist_update_toolbar() { |
1056 if (!gtkblist) | |
1057 return; | |
4699 | 1058 |
4697 | 1059 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); |
4699 | 1060 |
4697 | 1061 if (blist_options & OPT_BLIST_NO_BUTTONS) |
1062 gtk_widget_hide(gtkblist->bbox); | |
1063 else | |
1064 gtk_widget_show_all(gtkblist->bbox); | |
1065 } | |
1066 | |
4701 | 1067 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
1068 { | |
1069 struct gaim_gtk_blist_node *gtknode; | |
1070 GtkTreeIter iter; | |
1071 | |
1072 if (!node->ui_data) | |
1073 return; | |
1074 | |
1075 gtknode = (struct gaim_gtk_blist_node *)node->ui_data; | |
1076 | |
1077 if (gtknode->timer > 0) { | |
1078 g_source_remove(gtknode->timer); | |
1079 gtknode->timer = 0; | |
1080 } | |
1081 | |
1082 if (get_iter_from_node(node, &iter)) { | |
1083 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
1084 if(GAIM_BLIST_NODE_IS_BUDDY(node) && gaim_blist_get_group_online_count((struct group *)node->parent) == 0) { | |
1085 GtkTreeIter groupiter; | |
1086 if(get_iter_from_node(node->parent, &groupiter)) | |
1087 gtk_tree_store_remove(gtkblist->treemodel, &groupiter); | |
1088 } | |
1089 } | |
1090 } | |
1091 | |
1092 | |
4687 | 1093 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
1094 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1095 struct gaim_gtk_blist_node *gtknode; |
4699 | 1096 GtkTreeIter iter; |
4687 | 1097 gboolean expand = FALSE; |
4699 | 1098 gboolean new_entry = FALSE; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1099 |
4687 | 1100 if (!gtkblist) |
1101 return; | |
4699 | 1102 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1103 gtknode = GAIM_GTK_BLIST_NODE(node); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1104 |
4690 | 1105 |
4699 | 1106 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ |
1107 new_entry = TRUE; | |
4687 | 1108 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1109 if (((struct buddy*)node)->present) { | |
4699 | 1110 GtkTreeIter groupiter; |
1111 GaimBlistNode *oldersibling; | |
1112 GtkTreeIter oldersiblingiter; | |
4690 | 1113 |
4699 | 1114 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { |
1115 /* This buddy's group has not yet been added. We do that here */ | |
4757 | 1116 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, |
1117 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); | |
4687 | 1118 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name); |
4699 | 1119 oldersibling = node->parent->prev; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1120 |
4687 | 1121 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ |
4699 | 1122 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) |
1123 oldersibling = oldersibling->prev; | |
4690 | 1124 |
4687 | 1125 /* This is where we create the node and add it. */ |
4699 | 1126 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL); |
1127 gtk_tree_store_set(gtkblist->treemodel, &groupiter, | |
4757 | 1128 STATUS_ICON_COLUMN, groupicon, |
4687 | 1129 NAME_COLUMN, mark, |
1130 NODE_COLUMN, node->parent, | |
1131 -1); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1132 |
4737 | 1133 g_free(mark); |
4757 | 1134 g_object_unref(G_OBJECT(groupicon)); |
4737 | 1135 |
4687 | 1136 expand = TRUE; |
1137 } | |
4767 | 1138 |
4699 | 1139 oldersibling = node->prev; |
1140 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) | |
1141 oldersibling = oldersibling->prev; | |
1142 | |
1143 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); | |
4767 | 1144 |
1145 if (blist_options & OPT_BLIST_POPUP) | |
1146 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4699 | 1147 |
4687 | 1148 if (expand) { /* expand was set to true if this is the first element added to a group. In such case |
1149 * we expand the group node */ | |
4699 | 1150 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter); |
1151 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); | |
4721 | 1152 gtk_tree_path_free(path); |
4687 | 1153 } |
4699 | 1154 } |
1155 } | |
1156 } | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1157 |
4687 | 1158 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { |
1159 GdkPixbuf *status, *avatar; | |
1160 char *mark; | |
4697 | 1161 char *warning = NULL, *idle = NULL; |
1162 | |
4724 | 1163 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, |
1164 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); | |
4687 | 1165 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); |
1166 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node); | |
4697 | 1167 |
4725 | 1168 if (((struct buddy*)node)->idle > 0) { |
4697 | 1169 time_t t; |
1170 int ihrs, imin; | |
1171 time(&t); | |
1172 ihrs = (t - ((struct buddy *)node)->idle) / 3600; | |
1173 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; | |
4718 | 1174 if(ihrs > 0) |
1175 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
1176 else | |
1177 idle = g_strdup_printf("(%d)", imin); | |
4697 | 1178 } |
1179 | |
4725 | 1180 if (((struct buddy*)node)->evil > 0) |
4699 | 1181 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); |
4725 | 1182 |
4697 | 1183 |
4718 | 1184 if((blist_options & OPT_BLIST_GREY_IDLERS) |
1185 && ((struct buddy *)node)->idle) { | |
1186 if(warning) { | |
1187 char *w2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1188 warning); | |
1189 g_free(warning); | |
1190 warning = w2; | |
1191 } | |
1192 | |
1193 if(idle) { | |
1194 char *i2 = g_strdup_printf("<span color='dim grey'>%s</span>", | |
1195 idle); | |
1196 g_free(idle); | |
1197 idle = i2; | |
1198 } | |
1199 } | |
1200 | |
1201 | |
4699 | 1202 gtk_tree_store_set(gtkblist->treemodel, &iter, |
4687 | 1203 STATUS_ICON_COLUMN, status, |
1204 NAME_COLUMN, mark, | |
4697 | 1205 WARNING_COLUMN, warning, |
1206 IDLE_COLUMN, idle, | |
4699 | 1207 BUDDY_ICON_COLUMN, avatar, |
4687 | 1208 NODE_COLUMN, node, |
1209 -1); | |
4699 | 1210 |
4687 | 1211 g_free(mark); |
4697 | 1212 if (idle) |
1213 g_free(idle); | |
1214 if (warning) | |
1215 g_free(warning); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1216 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1217 if (status != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1218 g_object_unref(status); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1219 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1220 if (avatar != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1221 g_object_unref(avatar); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1222 |
4701 | 1223 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { |
1224 gaim_gtk_blist_remove(list, node); | |
4767 | 1225 if (blist_options & OPT_BLIST_POPUP) |
1226 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4687 | 1227 } |
1228 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1229 |
4687 | 1230 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) |
1231 { | |
4770 | 1232 if (!gtkblist) |
1233 return; | |
4687 | 1234 gtk_widget_destroy(gtkblist->window); |
4745 | 1235 |
1236 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; | |
1237 gtkblist->treemodel = NULL; | |
1238 gtkblist->idle_column = NULL; | |
1239 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
1240 gtkblist->bbox = gtkblist->tipwindow = NULL; | |
1241 protomenu = NULL; | |
1242 awaymenu = NULL; | |
1243 bpmenu = NULL; | |
1244 | |
1245 gtkblist->timeout = 0; | |
4687 | 1246 } |
1 | 1247 |
4687 | 1248 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1249 { | |
4698 | 1250 if (show) { |
4699 | 1251 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
4698 | 1252 } else { |
1253 if (!connections || docklet_count) { | |
1254 #ifdef _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1255 wgaim_systray_minimize(gtkblist->window); |
4698 | 1256 #endif |
1257 gtk_widget_hide(gtkblist->window); | |
1258 } else { | |
1259 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
1260 } | |
1261 } | |
1262 } | |
1263 | |
1264 void gaim_gtk_blist_docklet_toggle() { | |
1265 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
1266 /* This is called when one of those is clicked--it will show/hide the | |
1267 buddy list/login window--depending on which is active */ | |
1268 if (connections && gtkblist) { | |
1269 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
1270 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1271 } else { | |
1272 #if _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1273 wgaim_systray_maximize(gtkblist->window); |
4698 | 1274 #endif |
1275 gaim_blist_set_visible(TRUE); | |
1276 } | |
1277 } else if (connections) { | |
1278 /* we're logging in or something... do nothing */ | |
1279 debug_printf("docklet_toggle called with connections but no blist!\n"); | |
1280 } else { | |
1281 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
1282 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { | |
1283 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1284 } else { | |
1285 #if _WIN32 | |
1286 wgaim_systray_minimize(mainwindow); | |
1287 #endif | |
1288 gtk_widget_hide(mainwindow); | |
1289 } | |
1290 } else { | |
1291 #if _WIN32 | |
1292 wgaim_systray_maximize(mainwindow); | |
1293 #endif | |
1294 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1295 } | |
1296 } | |
1297 } | |
1298 | |
1299 void gaim_gtk_blist_docklet_add() | |
1300 { | |
1301 docklet_count++; | |
1302 } | |
1303 | |
1304 void gaim_gtk_blist_docklet_remove() | |
1305 { | |
1306 docklet_count--; | |
1307 if (!docklet_count) { | |
1308 if (connections) { | |
1309 gaim_blist_set_visible(TRUE); | |
4745 | 1310 } else if(gtkblist && gtkblist->window) { |
4698 | 1311 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
1312 } | |
1313 } | |
4687 | 1314 } |
1 | 1315 |
4687 | 1316 static struct gaim_blist_ui_ops blist_ui_ops = |
1317 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1318 gaim_gtk_blist_new_list, |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1319 gaim_gtk_blist_new_node, |
4687 | 1320 gaim_gtk_blist_show, |
1321 gaim_gtk_blist_update, | |
1322 gaim_gtk_blist_remove, | |
1323 gaim_gtk_blist_destroy, | |
1324 gaim_gtk_blist_set_visible | |
1325 }; | |
1 | 1326 |
1327 | |
4687 | 1328 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
|
1329 { |
4687 | 1330 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1331 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1332 |
3131 | 1333 |
1334 | |
4687 | 1335 /********************************************************************* |
1336 * Public utility functions * | |
1337 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
1338 |
4687 | 1339 GdkPixbuf * |
1340 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
1341 { |
4687 | 1342 struct prpl *prpl = find_prpl(account->protocol); |
1343 GdkPixbuf *status = NULL; | |
1344 char *filename = NULL; | |
1345 const char *protoname = prpl->list_icon(account, NULL); | |
1346 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
1347 then it will look up protoname from the theme */ | |
1348 if (!strcmp(protoname, "aim")) { | |
1349 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "aim.png", NULL); | |
1350 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1351 g_free(filename); | |
1352 } else if (!strcmp(protoname, "yahoo")) { | |
1353 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "yahoo.png", NULL); | |
1354 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1355 g_free(filename); | |
1356 } else if (!strcmp(protoname, "msn")) { | |
1357 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "msn.png", NULL); | |
1358 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1359 g_free(filename); | |
1360 } else if (!strcmp(protoname, "jabber")) { | |
1361 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "jabber.png", NULL); | |
1362 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1363 g_free(filename); | |
1364 } else if (!strcmp(protoname, "icq")) { | |
1365 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "icq.png", NULL); | |
1366 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1367 g_free(filename); | |
1368 } else if (!strcmp(protoname, "gadu-gadu")) { | |
1369 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "gadugadu.png", NULL); | |
1370 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1371 g_free(filename); | |
1372 } else if (!strcmp(protoname, "napster")) { | |
1373 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "napster.png", NULL); | |
1374 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1375 g_free(filename); | |
1376 } else if (!strcmp(protoname, "irc")) { | |
1377 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "irc.png", NULL); | |
1378 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1379 g_free(filename); | |
960
fa681641643d
[gaim-migrate @ 970]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
945
diff
changeset
|
1380 } |
4687 | 1381 return status; |
1 | 1382 } |
4699 | 1383 |