comparison src/gtkblist.c @ 5234:890b29f00b68

[gaim-migrate @ 5604] Chats in the buddy list! You can now put chat rooms in your buddy list, and double-click them to join them, instead of having to do all that typing. I'm eventually gonna add auto-join support, so that ugly hack involving pouncing can go away. Someone should make some new artwork so we don't have 2 + icons next to each other in the menus. This also has some fixes to let gaim compile again, after the renaming of the buddy list files. This also fixes the problem with offline buddies not showing up in the list sometimes for accounts that didn't log in at startup. This probably fixes other stuff, but I can't remember any of it off the top of my head. I'm going to stop typing and let people play with this now. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Sat, 26 Apr 2003 20:30:43 +0000
parents 1a53330dfd34
children 757d680f923d
comparison
equal deleted inserted replaced
5233:202105dbed8f 5234:890b29f00b68
48 #include "sound.h" 48 #include "sound.h"
49 #include "gaim.h" 49 #include "gaim.h"
50 #include "gtkblist.h" 50 #include "gtkblist.h"
51 #include "gtkpounce.h" 51 #include "gtkpounce.h"
52 #include "gtkft.h" 52 #include "gtkft.h"
53 #include "gtkdebug.h"
53 54
54 #ifdef _WIN32 55 #ifdef _WIN32
55 #include "win32dep.h" 56 #include "win32dep.h"
56 #endif 57 #endif
57 58
60 /* part of the best damn Docklet code this side of Tahiti */ 61 /* part of the best damn Docklet code this side of Tahiti */
61 static gboolean gaim_gtk_blist_obscured = FALSE; 62 static gboolean gaim_gtk_blist_obscured = FALSE;
62 63
63 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); 64 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data);
64 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); 65 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node);
65 static char *gaim_get_tooltip_text(struct buddy *b); 66 static char *gaim_get_tooltip_text(GaimBlistNode *node);
66 static char *item_factory_translate_func (const char *path, gpointer func_data); 67 static char *item_factory_translate_func (const char *path, gpointer func_data);
67 68
68 /*************************************************** 69 /***************************************************
69 * Callbacks * 70 * Callbacks *
70 ***************************************************/ 71 ***************************************************/
137 serv_get_info(b->account->gc, b->name); 138 serv_get_info(b->account->gc, b->name);
138 } 139 }
139 140
140 static void gtk_blist_menu_im_cb(GtkWidget *w, struct buddy *b) 141 static void gtk_blist_menu_im_cb(GtkWidget *w, struct buddy *b)
141 { 142 {
142 gaim_conversation_new(GAIM_CONV_IM, b->account, b->name); 143 gaim_conversation_new(GAIM_CONV_IM, b->account, b->name);
143 } 144 }
144 145
145 static void gtk_blist_menu_alias_cb(GtkWidget *w, struct buddy *b) 146 static void gtk_blist_menu_join_cb(GtkWidget *w, struct chat *chat)
146 { 147 {
147 alias_dialog_bud(b); 148 serv_join_chat(chat->account->gc, chat->components);
149 }
150
151 static void gtk_blist_menu_alias_cb(GtkWidget *w, GaimBlistNode *node)
152 {
153 if(GAIM_BLIST_NODE_IS_BUDDY(node))
154 alias_dialog_bud((struct buddy*)node);
155 else if(GAIM_BLIST_NODE_IS_CHAT(node))
156 alias_dialog_chat((struct chat*)node);
148 } 157 }
149 158
150 static void gtk_blist_menu_bp_cb(GtkWidget *w, struct buddy *b) 159 static void gtk_blist_menu_bp_cb(GtkWidget *w, struct buddy *b)
151 { 160 {
152 gaim_gtkpounce_dialog_show(b, NULL); 161 gaim_gtkpounce_dialog_show(b, NULL);
153 } 162 }
154 163
155 static void gtk_blist_menu_showlog_cb(GtkWidget *w, struct buddy *b) 164 static void gtk_blist_menu_showlog_cb(GtkWidget *w, struct buddy *b)
156 { 165 {
157 show_log(b->name); 166 show_log(b->name);
158 } 167 }
159 168
160 static void gtk_blist_show_systemlog_cb() 169 static void gtk_blist_show_systemlog_cb()
161 { 170 {
162 show_log(NULL); 171 show_log(NULL);
163 } 172 }
164 173
165 static void gtk_blist_show_onlinehelp_cb() 174 static void gtk_blist_show_onlinehelp_cb()
166 { 175 {
167 open_url(NULL, WEBSITE "documentation.php"); 176 open_url(NULL, WEBSITE "documentation.php");
168 } 177 }
169 178
170 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv) 179 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv)
171 { 180 {
172 GtkTreeIter iter; 181 GtkTreeIter iter;
201 } 210 }
202 } 211 }
203 show_info_dialog(); 212 show_info_dialog();
204 } 213 }
205 214
206 static void gtk_blist_button_chat_cb(GtkWidget *w, gpointer data) 215 static void gtk_blist_button_chat_cb(GtkWidget *w, GtkTreeView *tv)
207 { 216 {
208 /* FIXME: someday, we can check to see if we've selected a chat node */ 217 GtkTreeIter iter;
218 GtkTreeModel *model = gtk_tree_view_get_model(tv);
219 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv);
220
221 if(gtk_tree_selection_get_selected(sel, &model, &iter)){
222 GaimBlistNode *node;
223
224 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
225 if (GAIM_BLIST_NODE_IS_CHAT(node)) {
226 serv_join_chat(((struct chat *)node)->account->gc, ((struct chat*)node)->components);
227 return;
228 }
229 }
209 join_chat(); 230 join_chat();
210 } 231 }
211 232
212 static void gtk_blist_button_away_cb(GtkWidget *w, gpointer data) 233 static void gtk_blist_button_away_cb(GtkWidget *w, gpointer data)
213 { 234 {
259 gaim_window_raise(gaim_conversation_get_window(conv)); 280 gaim_window_raise(gaim_conversation_get_window(conv));
260 gaim_window_switch_conversation( 281 gaim_window_switch_conversation(
261 gaim_conversation_get_window(conv), 282 gaim_conversation_get_window(conv),
262 gaim_conversation_get_index(conv)); 283 gaim_conversation_get_index(conv));
263 } 284 }
285 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
286 serv_join_chat(((struct chat *)node)->account->gc, ((struct chat*)node)->components);
264 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { 287 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
265 if (gtk_tree_view_row_expanded(tv, path)) 288 if (gtk_tree_view_row_expanded(tv, path))
266 gtk_tree_view_collapse_row(tv, path); 289 gtk_tree_view_collapse_row(tv, path);
267 else 290 else
268 gtk_tree_view_expand_row(tv,path,FALSE); 291 gtk_tree_view_expand_row(tv,path,FALSE);
269 } 292 }
270 } 293 }
271 294
272 static void gaim_gtk_blist_add_buddy_cb() 295 static void gaim_gtk_blist_add_chat_cb()
273 { 296 {
274 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); 297 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
275 GtkTreeIter iter; 298 GtkTreeIter iter;
276 GaimBlistNode *node; 299 GaimBlistNode *node;
277 300
278 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ 301 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
279 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); 302 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
280 if (GAIM_BLIST_NODE_IS_BUDDY(node)) 303 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CHAT(node))
304 show_add_chat(NULL, (struct group*)node->parent);
305 else if (GAIM_BLIST_NODE_IS_GROUP(node))
306 show_add_chat(NULL, (struct group*)node);
307 }
308 else {
309 show_add_chat(NULL, NULL);
310 }
311 }
312
313 static void gaim_gtk_blist_add_buddy_cb()
314 {
315 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
316 GtkTreeIter iter;
317 GaimBlistNode *node;
318
319 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
320 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
321 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CHAT(node))
281 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); 322 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL);
282 else if (GAIM_BLIST_NODE_IS_GROUP(node)) 323 else if (GAIM_BLIST_NODE_IS_GROUP(node))
283 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); 324 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL);
284 } 325 }
285 else { 326 else {
291 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) 332 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node)
292 { 333 {
293 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 334 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
294 struct buddy *b = (struct buddy*)node; 335 struct buddy *b = (struct buddy*)node;
295 show_confirm_del(b->account->gc, b->name); 336 show_confirm_del(b->account->gc, b->name);
337 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
338 struct chat *chat = (struct chat*)node;
339 show_confirm_del_chat(chat);
296 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { 340 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
297 struct group *g = (struct group*)node; 341 struct group *g = (struct group*)node;
298 show_confirm_del_group(g); 342 show_confirm_del_group(g);
299 } 343 }
300 } 344 }
329 node = g_value_get_pointer(&val); 373 node = g_value_get_pointer(&val);
330 menu = gtk_menu_new(); 374 menu = gtk_menu_new();
331 375
332 if (GAIM_BLIST_NODE_IS_GROUP(node)) { 376 if (GAIM_BLIST_NODE_IS_GROUP(node)) {
333 gaim_new_item_from_stock(menu, _("_Add a Buddy"), GTK_STOCK_ADD, G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL); 377 gaim_new_item_from_stock(menu, _("_Add a Buddy"), GTK_STOCK_ADD, G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL);
378 gaim_new_item_from_stock(menu, _("_Add a Chat"), GTK_STOCK_ADD, G_CALLBACK(gaim_gtk_blist_add_chat_cb), node, 0, 0, NULL);
334 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); 379 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL);
335 gaim_new_item_from_stock(menu, _("_Rename"), NULL, G_CALLBACK(show_rename_group), node, 0, 0, NULL); 380 gaim_new_item_from_stock(menu, _("_Rename"), NULL, G_CALLBACK(show_rename_group), node, 0, 0, NULL);
381 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
382 gaim_new_item_from_stock(menu, _("_Join"), GAIM_STOCK_CHAT, G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL);
383 gaim_new_item_from_stock(menu, _("_Alias"), GAIM_STOCK_EDIT, G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL);
384 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL);
336 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 385 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
337 /* Protocol specific options */ 386 /* Protocol specific options */
338 prpl = gaim_find_prpl(((struct buddy*)node)->account->protocol); 387 prpl = gaim_find_prpl(((struct buddy*)node)->account->protocol);
339 388
340 if (prpl != NULL) 389 if (prpl != NULL)
458 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); 507 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
459 node = g_value_get_pointer(&val); 508 node = g_value_get_pointer(&val);
460 509
461 if (GAIM_BLIST_NODE_IS_BUDDY(n)) { 510 if (GAIM_BLIST_NODE_IS_BUDDY(n)) {
462 struct buddy *b = (struct buddy*)n; 511 struct buddy *b = (struct buddy*)n;
463 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 512 if (GAIM_BLIST_NODE_IS_BUDDY(node) ||
513 GAIM_BLIST_NODE_IS_CHAT(node)) {
464 switch(position) { 514 switch(position) {
465 case GTK_TREE_VIEW_DROP_AFTER: 515 case GTK_TREE_VIEW_DROP_AFTER:
466 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: 516 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
467 gaim_blist_add_buddy(b, (struct group*)node->parent, node); 517 gaim_blist_add_buddy(b, (struct group*)node->parent, node);
468 break; 518 break;
471 gaim_blist_add_buddy(b, (struct group*)node->parent, node->prev); 521 gaim_blist_add_buddy(b, (struct group*)node->parent, node->prev);
472 break; 522 break;
473 } 523 }
474 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { 524 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
475 gaim_blist_add_buddy(b, (struct group*)node, NULL); 525 gaim_blist_add_buddy(b, (struct group*)node, NULL);
526 }
527 } else if (GAIM_BLIST_NODE_IS_CHAT(n)) {
528 struct chat *chat = (struct chat*)n;
529 if (GAIM_BLIST_NODE_IS_BUDDY(node) ||
530 GAIM_BLIST_NODE_IS_CHAT(node)) {
531 switch(position) {
532 case GTK_TREE_VIEW_DROP_AFTER:
533 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
534 gaim_blist_add_chat(chat, (struct group*)node->parent, node);
535 break;
536 case GTK_TREE_VIEW_DROP_BEFORE:
537 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
538 gaim_blist_add_chat(chat, (struct group*)node->parent, node->prev);
539 break;
540 }
541 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
542 gaim_blist_add_chat(chat, (struct group*)node, NULL);
476 } 543 }
477 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { 544 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) {
478 struct group *g = (struct group*)n; 545 struct group *g = (struct group*)n;
479 if (GAIM_BLIST_NODE_IS_GROUP(node)) { 546 if (GAIM_BLIST_NODE_IS_GROUP(node)) {
480 switch (position) { 547 switch (position) {
486 case GTK_TREE_VIEW_DROP_BEFORE: 553 case GTK_TREE_VIEW_DROP_BEFORE:
487 gaim_blist_add_group(g, node->prev); 554 gaim_blist_add_group(g, node->prev);
488 break; 555 break;
489 } 556 }
490 557
491 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { 558 } else if(GAIM_BLIST_NODE_IS_BUDDY(node) ||
559 GAIM_BLIST_NODE_IS_CHAT(node)) {
492 gaim_blist_add_group(g, node->parent); 560 gaim_blist_add_group(g, node->parent);
493 } 561 }
494 562
495 } 563 }
496 564
498 gaim_blist_save(); 566 gaim_blist_save();
499 } 567 }
500 } 568 }
501 } 569 }
502 570
503 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, struct buddy *b) 571 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, GaimBlistNode *node)
504 { 572 {
505 GtkStyle *style; 573 GtkStyle *style;
506 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(b, GAIM_STATUS_ICON_LARGE); 574 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(node, GAIM_STATUS_ICON_LARGE);
507 PangoLayout *layout; 575 PangoLayout *layout;
508 char *tooltiptext = gaim_get_tooltip_text(b); 576 char *tooltiptext = gaim_get_tooltip_text(node);
509 577
510 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); 578 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL);
511 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); 579 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext));
512 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); 580 pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
513 pango_layout_set_width(layout, 300000); 581 pango_layout_set_width(layout, 300000);
536 { 604 {
537 GtkTreePath *path; 605 GtkTreePath *path;
538 GtkTreeIter iter; 606 GtkTreeIter iter;
539 GaimBlistNode *node; 607 GaimBlistNode *node;
540 GValue val = {0}; 608 GValue val = {0};
609 int scr_w,scr_h, w, h, x, y;
610 PangoLayout *layout;
611 char *tooltiptext = NULL;
541 612
542 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL)) 613 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL))
543 return FALSE; 614 return FALSE;
544 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); 615 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
545 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); 616 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
546 node = g_value_get_pointer(&val); 617 node = g_value_get_pointer(&val);
547 618 if(!GAIM_BLIST_NODE_IS_BUDDY(node) && !GAIM_BLIST_NODE_IS_CHAT(node))
548 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 619 return FALSE;
549 int scr_w,scr_h, w, h, x, y; 620
550 PangoLayout *layout; 621 tooltiptext = gaim_get_tooltip_text(node);
551 struct buddy *buddy = (struct buddy*)node; 622 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP);
552 char *tooltiptext = gaim_get_tooltip_text(buddy); 623 gtkblist->tipwindow->parent = tv;
553 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); 624 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE);
554 gtkblist->tipwindow->parent = tv; 625 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE);
555 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); 626 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips");
556 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); 627 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event",
557 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); 628 G_CALLBACK(gaim_gtk_blist_paint_tip), node);
558 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", 629 gtk_widget_ensure_style (gtkblist->tipwindow);
559 G_CALLBACK(gaim_gtk_blist_paint_tip), buddy); 630
560 gtk_widget_ensure_style (gtkblist->tipwindow); 631 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL);
561 632 pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
562 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); 633 pango_layout_set_width(layout, 300000);
563 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); 634 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext));
564 pango_layout_set_width(layout, 300000); 635 scr_w = gdk_screen_width();
565 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); 636 scr_h = gdk_screen_height();
566 scr_w = gdk_screen_width(); 637 pango_layout_get_size (layout, &w, &h);
567 scr_h = gdk_screen_height(); 638 w = PANGO_PIXELS(w) + 8;
568 pango_layout_get_size (layout, &w, &h); 639 h = PANGO_PIXELS(h) + 8;
569 w = PANGO_PIXELS(w) + 8; 640
570 h = PANGO_PIXELS(h) + 8; 641 /* 38 is the size of a large status icon plus 4 pixels padding on each side.
571 642 * I should #define this or something */
572 /* 38 is the size of a large status icon plus 4 pixels padding on each side. 643 w = w + 38;
573 I should #define this or something */ 644 h = MAX(h, 38);
574 w = w + 38; 645
575 h = MAX(h, 38); 646 gdk_window_get_pointer(NULL, &x, &y, NULL);
576 647 if (GTK_WIDGET_NO_WINDOW(gtkblist->window))
577 gdk_window_get_pointer(NULL, &x, &y, NULL); 648 y+=gtkblist->window->allocation.y;
578 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) 649
579 y+=gtkblist->window->allocation.y; 650 x -= ((w >> 1) + 4);
580 651
581 x -= ((w >> 1) + 4); 652 if ((x + w) > scr_w)
582 653 x -= (x + w) - scr_w;
583 if ((x + w) > scr_w) 654 else if (x < 0)
584 x -= (x + w) - scr_w; 655 x = 0;
585 else if (x < 0) 656
586 x = 0; 657 if ((y + h + 4) > scr_h)
587 658 y = y - h;
588 if ((y + h + 4) > scr_h) 659 else
589 y = y - h; 660 y = y + 6;
590 else 661 g_object_unref (layout);
591 y = y + 6; 662 g_free(tooltiptext);
592 g_object_unref (layout); 663 gtk_widget_set_size_request(gtkblist->tipwindow, w, h);
593 g_free(tooltiptext); 664 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y);
594 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); 665 gtk_widget_show(gtkblist->tipwindow);
595 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y);
596 gtk_widget_show(gtkblist->tipwindow);
597 }
598 666
599 gtk_tree_path_free(path); 667 gtk_tree_path_free(path);
600 return FALSE; 668 return FALSE;
601 } 669 }
602 670
660 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, "<StockItem>", GAIM_STOCK_CHAT }, 728 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, "<StockItem>", GAIM_STOCK_CHAT },
661 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, "<StockItem>", GAIM_STOCK_INFO }, 729 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, "<StockItem>", GAIM_STOCK_INFO },
662 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, 730 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" },
663 { N_("/Buddies/_Show Offline Buddies"), NULL, gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"}, 731 { N_("/Buddies/_Show Offline Buddies"), NULL, gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"},
664 { N_("/Buddies/Show _Empty Groups"), NULL, gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"}, 732 { N_("/Buddies/Show _Empty Groups"), NULL, gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"},
665 { N_("/Buddies/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, 733 { N_("/Buddies/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
734 { N_("/Buddies/_Add a Chat..."), NULL, gaim_gtk_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD },
666 { N_("/Buddies/Add a _Group..."), NULL, show_add_group, 0, NULL}, 735 { N_("/Buddies/Add a _Group..."), NULL, show_add_group, 0, NULL},
667 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, 736 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" },
668 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, "<StockItem>", GAIM_STOCK_SIGN_OFF }, 737 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, "<StockItem>", GAIM_STOCK_SIGN_OFF },
669 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, 738 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
670 739
690 759
691 /********************************************************* 760 /*********************************************************
692 * Private Utility functions * 761 * Private Utility functions *
693 *********************************************************/ 762 *********************************************************/
694 763
695 static char *gaim_get_tooltip_text(struct buddy *b) 764 static char *gaim_get_tooltip_text(GaimBlistNode *node)
696 { 765 {
697 GaimPlugin *prpl;
698 GaimPluginProtocolInfo *prpl_info = NULL;
699 char *text = NULL; 766 char *text = NULL;
700 char *statustext = NULL; 767
701 char *aliastext = NULL, *nicktext = NULL; 768 if(GAIM_BLIST_NODE_IS_CHAT(node)) {
702 char *warning = NULL, *idletime = NULL; 769 struct chat *chat = (struct chat *)node;
703 770 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>",
704 prpl = gaim_find_prpl(b->account->protocol); 771 chat->alias);
705 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); 772 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
706 773 GaimPlugin *prpl;
707 if (prpl_info->tooltip_text) { 774 GaimPluginProtocolInfo *prpl_info = NULL;
708 const char *end; 775 struct buddy *b = (struct buddy *)node;
709 statustext = prpl_info->tooltip_text(b); 776 char *statustext = NULL;
710 777 char *aliastext = NULL, *nicktext = NULL;
711 if(statustext && !g_utf8_validate(statustext, -1, &end)) { 778 char *warning = NULL, *idletime = NULL;
712 char *new = g_strndup(statustext, 779
713 g_utf8_pointer_to_offset(statustext, end)); 780 prpl = gaim_find_prpl(b->account->protocol);
714 g_free(statustext); 781 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
715 statustext = new; 782
716 } 783 if (prpl_info->tooltip_text) {
717 } 784 const char *end;
718 785 statustext = prpl_info->tooltip_text(b);
719 if (!statustext && !GAIM_BUDDY_IS_ONLINE(b)) 786
720 statustext = g_strdup(_("<b>Status:</b> Offline")); 787 if(statustext && !g_utf8_validate(statustext, -1, &end)) {
721 788 char *new = g_strndup(statustext,
722 if (b->idle > 0) { 789 g_utf8_pointer_to_offset(statustext, end));
723 int ihrs, imin; 790 g_free(statustext);
724 time_t t; 791 statustext = new;
725 time(&t); 792 }
726 ihrs = (t - b->idle) / 3600; 793 }
727 imin = ((t - b->idle) / 60) % 60; 794
728 if (ihrs) 795 if (!statustext && !GAIM_BUDDY_IS_ONLINE(b))
729 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin); 796 statustext = g_strdup(_("<b>Status:</b> Offline"));
730 else 797
731 idletime = g_strdup_printf(_("%dm"), imin); 798 if (b->idle > 0) {
732 } 799 int ihrs, imin;
733 800 time_t t;
734 if(b->alias && b->alias[0]) 801 time(&t);
735 aliastext = g_markup_escape_text(b->alias, -1); 802 ihrs = (t - b->idle) / 3600;
736 803 imin = ((t - b->idle) / 60) % 60;
737 if(b->server_alias) 804 if (ihrs)
738 nicktext = g_markup_escape_text(b->server_alias, -1); 805 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin);
739 806 else
740 if (b->evil > 0) 807 idletime = g_strdup_printf(_("%dm"), imin);
741 warning = g_strdup_printf(_("%d%%"), b->evil); 808 }
742 809
743 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" 810 if(b->alias && b->alias[0])
811 aliastext = g_markup_escape_text(b->alias, -1);
812
813 if(b->server_alias)
814 nicktext = g_markup_escape_text(b->server_alias, -1);
815
816 if (b->evil > 0)
817 warning = g_strdup_printf(_("%d%%"), b->evil);
818
819 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>"
744 "%s %s" /* Alias */ 820 "%s %s" /* Alias */
745 "%s %s" /* Nickname */ 821 "%s %s" /* Nickname */
746 "%s %s" /* Idle */ 822 "%s %s" /* Idle */
747 "%s %s" /* Warning */ 823 "%s %s" /* Warning */
748 "%s%s" /* Status */ 824 "%s%s" /* Status */
749 "%s", 825 "%s",
750 b->name, 826 b->name,
752 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "", 828 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "",
753 idletime ? _("\n<b>Idle:</b>") : "", idletime ? idletime : "", 829 idletime ? _("\n<b>Idle:</b>") : "", idletime ? idletime : "",
754 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", 830 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "",
755 statustext ? "\n" : "", statustext ? statustext : "", 831 statustext ? "\n" : "", statustext ? statustext : "",
756 !g_ascii_strcasecmp(b->name, "robflynn") ? _("\n<b>Description:</b> Spooky") : ""); 832 !g_ascii_strcasecmp(b->name, "robflynn") ? _("\n<b>Description:</b> Spooky") : "");
757 833
758 if(warning) 834 if(warning)
759 g_free(warning); 835 g_free(warning);
760 if(idletime) 836 if(idletime)
761 g_free(idletime); 837 g_free(idletime);
762 if(statustext) 838 if(statustext)
763 g_free(statustext); 839 g_free(statustext);
764 if(nicktext) 840 if(nicktext)
765 g_free(nicktext); 841 g_free(nicktext);
766 if(aliastext) 842 if(aliastext)
767 g_free(aliastext); 843 g_free(aliastext);
844 }
768 845
769 return text; 846 return text;
770 847 }
771 } 848
772 849 GdkPixbuf *gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size)
773 GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size)
774 { 850 {
775 GdkPixbuf *status = NULL; 851 GdkPixbuf *status = NULL;
776 GdkPixbuf *scale = NULL; 852 GdkPixbuf *scale = NULL;
777 GdkPixbuf *emblem = NULL; 853 GdkPixbuf *emblem = NULL;
778 gchar *filename = NULL; 854 gchar *filename = NULL;
780 856
781 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; 857 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL;
782 858
783 int scalesize = 30; 859 int scalesize = 30;
784 860
785 GaimPlugin *prpl; 861 GaimPlugin *prpl = NULL;
786 GaimPluginProtocolInfo *prpl_info = NULL; 862 GaimPluginProtocolInfo *prpl_info = NULL;
787 863
788 prpl = gaim_find_prpl(b->account->protocol); 864 if(GAIM_BLIST_NODE_IS_BUDDY(node))
789 865 prpl = gaim_find_prpl(((struct buddy *)node)->account->protocol);
790 if (!prpl) 866 else if(GAIM_BLIST_NODE_IS_CHAT(node))
867 prpl = gaim_find_prpl(((struct chat *)node)->account->protocol);
868
869 if (!prpl)
791 return NULL; 870 return NULL;
792 871
793 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); 872 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
794 873
795 if (prpl_info->list_icon) 874 if (prpl_info->list_icon) {
796 protoname = prpl_info->list_icon(b->account, b); 875 if(GAIM_BLIST_NODE_IS_BUDDY(node))
797 if (b->present != GAIM_BUDDY_SIGNING_OFF && prpl_info->list_emblems) 876 protoname = prpl_info->list_icon(((struct buddy*)node)->account,
798 prpl_info->list_emblems(b, &se, &sw, &nw, &ne); 877 (struct buddy *)node);
878 else if(GAIM_BLIST_NODE_IS_CHAT(node))
879 protoname = prpl_info->list_icon(((struct chat*)node)->account, NULL);
880 }
881
882 if (GAIM_BLIST_NODE_IS_BUDDY(node) &&
883 ((struct buddy *)node)->present != GAIM_BUDDY_SIGNING_OFF &&
884 prpl_info->list_emblems) {
885 prpl_info->list_emblems((struct buddy*)node, &se, &sw, &nw, &ne);
886 }
799 887
800 if (size == GAIM_STATUS_ICON_SMALL) { 888 if (size == GAIM_STATUS_ICON_SMALL) {
801 scalesize = 15; 889 scalesize = 15;
802 sw = nw = ne = NULL; /* So that only the se icon will composite */ 890 sw = nw = ne = NULL; /* So that only the se icon will composite */
803 } 891 }
804 892
805 893
806 if (b->present == GAIM_BUDDY_SIGNING_ON) { 894 if (GAIM_BLIST_NODE_IS_BUDDY(node) &&
895 ((struct buddy*)node)->present == GAIM_BUDDY_SIGNING_ON) {
807 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); 896 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL);
808 status = gdk_pixbuf_new_from_file(filename,NULL); 897 status = gdk_pixbuf_new_from_file(filename,NULL);
809 g_free(filename); 898 g_free(filename);
810 } else if (b->present == GAIM_BUDDY_SIGNING_OFF) { 899 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) &&
900 ((struct buddy *)node)->present == GAIM_BUDDY_SIGNING_OFF) {
811 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); 901 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL);
812 status = gdk_pixbuf_new_from_file(filename,NULL); 902 status = gdk_pixbuf_new_from_file(filename,NULL);
813 g_free(filename); 903 g_free(filename);
814 904
815 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and 905 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and
914 } 1004 }
915 } 1005 }
916 1006
917 1007
918 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ 1008 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */
919 if (b->present == GAIM_BUDDY_OFFLINE) 1009 if (GAIM_BLIST_NODE_IS_BUDDY(node) &&
1010 ((struct buddy *)node)->present == GAIM_BUDDY_OFFLINE)
920 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); 1011 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
921 else if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) 1012 else if (GAIM_BLIST_NODE_IS_BUDDY(node) &&
1013 ((struct buddy *)node)->idle &&
1014 blist_options & OPT_BLIST_GREY_IDLERS)
922 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); 1015 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE);
923 return scale; 1016 return scale;
924 } 1017 }
925 1018
926 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) 1019 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b)
1089 } 1182 }
1090 } 1183 }
1091 1184
1092 static gboolean gaim_gtk_blist_refresh_timer(struct gaim_buddy_list *list) 1185 static gboolean gaim_gtk_blist_refresh_timer(struct gaim_buddy_list *list)
1093 { 1186 {
1094 GaimBlistNode *group = list->root; 1187 GaimBlistNode *group, *buddy;
1095 GaimBlistNode *buddy; 1188
1096 1189 for(group = list->root; group; group = group->next) {
1097 while (group) { 1190 if(!GAIM_BLIST_NODE_IS_GROUP(group))
1098 buddy = group->child; 1191 continue;
1099 while (buddy) { 1192 for(buddy = group->child; buddy; buddy = buddy->next) {
1193 if(!GAIM_BLIST_NODE_IS_BUDDY(buddy))
1194 continue;
1100 if (((struct buddy *)buddy)->idle) 1195 if (((struct buddy *)buddy)->idle)
1101 gaim_gtk_blist_update(list, buddy); 1196 gaim_gtk_blist_update(list, buddy);
1102 buddy = buddy->next; 1197 }
1103 }
1104 group = group->next;
1105 } 1198 }
1106 1199
1107 /* keep on going */ 1200 /* keep on going */
1108 return TRUE; 1201 return TRUE;
1109 } 1202 }
1312 1405
1313 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); 1406 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL);
1314 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); 1407 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0);
1315 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); 1408 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1316 gtk_size_group_add_widget(sg, button); 1409 gtk_size_group_add_widget(sg, button);
1317 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); 1410 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), gtkblist->treeview);
1318 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Join a chat room"), NULL); 1411 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Join a chat room"), NULL);
1319 gtk_widget_show(button); 1412 gtk_widget_show(button);
1320 1413
1321 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_ICON_AWAY, GAIM_BUTTON_VERTICAL); 1414 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_ICON_AWAY, GAIM_BUTTON_VERTICAL);
1322 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); 1415 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0);
1333 gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list); 1426 gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list);
1334 } 1427 }
1335 1428
1336 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) 1429 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list)
1337 { 1430 {
1338 GaimBlistNode *group = list->root; 1431 GaimBlistNode *group, *buddy;
1339 GaimBlistNode *buddy; 1432
1340 1433 for(group = list->root; group; group = group->next) {
1341 while (group) { 1434 if(!GAIM_BLIST_NODE_IS_GROUP(group))
1342 buddy = group->child; 1435 continue;
1343 gaim_gtk_blist_update(list, group); 1436 gaim_gtk_blist_update(list, group);
1344 while (buddy) { 1437 for(buddy = group->child; buddy; buddy = buddy->next) {
1345 gaim_gtk_blist_update(list, buddy); 1438 gaim_gtk_blist_update(list, buddy);
1346 buddy = buddy->next; 1439 }
1347 }
1348 group = group->next;
1349 } 1440 }
1350 } 1441 }
1351 1442
1352 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { 1443 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) {
1353 1444
1431 if(gtkblist->selected_node == node) 1522 if(gtkblist->selected_node == node)
1432 gtkblist->selected_node = NULL; 1523 gtkblist->selected_node = NULL;
1433 1524
1434 if (get_iter_from_node(node, &iter)) { 1525 if (get_iter_from_node(node, &iter)) {
1435 gtk_tree_store_remove(gtkblist->treemodel, &iter); 1526 gtk_tree_store_remove(gtkblist->treemodel, &iter);
1436 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { 1527 if(GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CHAT(node)) {
1437 gaim_gtk_blist_update(list, node->parent); 1528 gaim_gtk_blist_update(list, node->parent);
1438 } 1529 }
1439 } 1530 }
1440 } 1531 }
1441 1532
1539 gtk_window_deiconify(GTK_WINDOW(gtkblist->window)); 1630 gtk_window_deiconify(GTK_WINDOW(gtkblist->window));
1540 gdk_window_raise(gtkblist->window->window); 1631 gdk_window_raise(gtkblist->window->window);
1541 } 1632 }
1542 1633
1543 } 1634 }
1544 } 1635 } else if (GAIM_BLIST_NODE_IS_CHAT(node) &&
1545 else if (GAIM_BLIST_NODE_IS_GROUP(node) && 1636 ((struct chat *)node)->account->gc) {
1637 GtkTreeIter groupiter;
1638 GaimBlistNode *oldersibling;
1639 GtkTreeIter oldersiblingiter;
1640 char *collapsed = gaim_group_get_setting((struct group *)node->parent, "collapsed");
1641
1642 if(node->parent &&
1643 !get_iter_from_node(node->parent, &groupiter)) {
1644 /* This buddy's group has not yet been added.
1645 * We do that here */
1646 make_a_group(node->parent, &groupiter);
1647 }
1648 if(!collapsed)
1649 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter);
1650 else
1651 g_free(collapsed);
1652
1653 oldersibling = node->prev;
1654 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) {
1655 oldersibling = oldersibling->prev;
1656 }
1657
1658 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL);
1659
1660 } else if (GAIM_BLIST_NODE_IS_GROUP(node) &&
1546 ((blist_options & OPT_BLIST_SHOW_OFFLINE) || 1661 ((blist_options & OPT_BLIST_SHOW_OFFLINE) ||
1547 !(blist_options & OPT_BLIST_NO_MT_GRP))) { 1662 !(blist_options & OPT_BLIST_NO_MT_GRP))) {
1548 make_a_group(node, &iter); 1663 make_a_group(node, &iter);
1549 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); 1664 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
1550 } 1665 }
1567 -1); 1682 -1);
1568 g_free(mark); 1683 g_free(mark);
1569 } 1684 }
1570 } 1685 }
1571 1686
1572 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present != GAIM_BUDDY_OFFLINE || ((blist_options & OPT_BLIST_SHOW_OFFLINE) && ((struct buddy*)node)->account->gc))) { 1687 if (GAIM_BLIST_NODE_IS_CHAT(node) && ((struct chat*)node)->account->gc) {
1688 GdkPixbuf *status;
1689 char *mark;
1690
1691 status = gaim_gtk_blist_get_status_icon(node,
1692 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL);
1693 mark = g_markup_escape_text(((struct chat*)node)->alias, -1);
1694
1695 gtk_tree_store_set(gtkblist->treemodel, &iter,
1696 STATUS_ICON_COLUMN, status,
1697 STATUS_ICON_VISIBLE_COLUMN, TRUE,
1698 NAME_COLUMN, mark,
1699 NODE_COLUMN, node,
1700 -1);
1701
1702 g_free(mark);
1703 if (status != NULL)
1704 g_object_unref(status);
1705 } else if(GAIM_BLIST_NODE_IS_CHAT(node) && !((struct chat *)node)->account->gc) {
1706 gaim_gtk_blist_remove(list, node);
1707 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present != GAIM_BUDDY_OFFLINE || ((blist_options & OPT_BLIST_SHOW_OFFLINE) && ((struct buddy*)node)->account->gc))) {
1573 GdkPixbuf *status, *avatar; 1708 GdkPixbuf *status, *avatar;
1574 char *mark; 1709 char *mark;
1575 char *warning = NULL, *idle = NULL; 1710 char *warning = NULL, *idle = NULL;
1576 1711
1577 gboolean selected = (gtkblist->selected_node == node); 1712 gboolean selected = (gtkblist->selected_node == node);
1578 1713
1579 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, 1714 status = gaim_gtk_blist_get_status_icon(node,
1580 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); 1715 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL);
1581 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); 1716 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node);
1582 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node, selected); 1717 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node, selected);
1583 1718
1584 if (((struct buddy*)node)->idle > 0) { 1719 if (((struct buddy*)node)->idle > 0) {
1644 g_object_unref(avatar); 1779 g_object_unref(avatar);
1645 1780
1646 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { 1781 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) {
1647 gaim_gtk_blist_remove(list, node); 1782 gaim_gtk_blist_remove(list, node);
1648 } 1783 }
1784
1649 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); 1785 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
1650 1786
1651 1787
1652 if(expand) { 1788 if(expand) {
1653 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, TRUE); 1789 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, TRUE);
1654 gtk_tree_path_free(expand); 1790 gtk_tree_path_free(expand);
1655 } 1791 }
1656 1792
1657 if(GAIM_BLIST_NODE_IS_BUDDY(node)) 1793 if(GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CHAT(node))
1658 gaim_gtk_blist_update(list, node->parent); 1794 gaim_gtk_blist_update(list, node->parent);
1659 } 1795 }
1660 1796
1661 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) 1797 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
1662 { 1798 {