comparison src/buddy.c @ 4936:cfeab08d4be9

[gaim-migrate @ 5270] This should fix up the group deletion segfaults, makes the offline groups not start out collapsed, and probably something else i've forgotten. Oh, yeah, makes the show offline buddies preference actually work right. Also kills some code duplication. I should make buddy icons 100x100, so they can use some of that new blank space in the buddy list. That'd be cool. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Tue, 01 Apr 2003 03:19:51 +0000
parents b89f7c450d6c
children f0c7d092948d
comparison
equal deleted inserted replaced
4935:b89f7c450d6c 4936:cfeab08d4be9
214 214
215 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { 215 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) {
216 GaimBlistNode *node; 216 GaimBlistNode *node;
217 GtkTreeIter iter; 217 GtkTreeIter iter;
218 GValue val = { 0, }; 218 GValue val = { 0, };
219 219
220 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); 220 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
221 221
222 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); 222 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
223 node = g_value_get_pointer(&val); 223 node = g_value_get_pointer(&val);
224 224
225 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 225 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
226 struct gaim_conversation *conv = 226 struct gaim_conversation *conv =
227 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); 227 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name);
228 if(conv) { 228 if(conv) {
229 gaim_window_raise(gaim_conversation_get_window(conv)); 229 gaim_window_raise(gaim_conversation_get_window(conv));
384 { 384 {
385 ((struct buddy*)b)->present = 1; 385 ((struct buddy*)b)->present = 1;
386 gaim_gtk_blist_update(NULL, b); 386 gaim_gtk_blist_update(NULL, b);
387 return FALSE; 387 return FALSE;
388 } 388 }
389 static void edit_mode_cb() { 389
390 static void edit_mode_cb(gpointer callback_data, guint callback_action,
391 GtkWidget *checkitem) {
390 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); 392 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
391 gdk_window_set_cursor(gtkblist->window->window, cursor); 393 gdk_window_set_cursor(gtkblist->window->window, cursor);
392 while (gtk_events_pending()) 394 while (gtk_events_pending())
393 gtk_main_iteration(); 395 gtk_main_iteration();
394 blist_options ^= OPT_BLIST_SHOW_OFFLINE; 396 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem)))
397 blist_options |= OPT_BLIST_SHOW_OFFLINE;
398 else
399 blist_options &= ~OPT_BLIST_SHOW_OFFLINE;
395 save_prefs(); 400 save_prefs();
396 gdk_cursor_unref(cursor); 401 gdk_cursor_unref(cursor);
397 cursor = gdk_cursor_new(GDK_LEFT_PTR); 402 cursor = gdk_cursor_new(GDK_LEFT_PTR);
398 gdk_window_set_cursor(gtkblist->window->window, cursor); 403 gdk_window_set_cursor(gtkblist->window->window, cursor);
399 gdk_cursor_unref(cursor); 404 gdk_cursor_unref(cursor);
650 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, 655 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0,
651 "<StockItem>", GTK_STOCK_QUIT }, 656 "<StockItem>", GTK_STOCK_QUIT },
652 657
653 /* Edit menu */ 658 /* Edit menu */
654 { N_("/_Edit"), NULL, NULL, 0, "<Branch>" }, 659 { N_("/_Edit"), NULL, NULL, 0, "<Branch>" },
655 { N_("/Edit/_Show Offline Buddies"), NULL, edit_mode_cb, 0, "<CheckItem>"}, 660 { N_("/Edit/_Show Offline Buddies"), NULL, edit_mode_cb, 1, "<CheckItem>"},
656 { N_("/Edit/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, 661 { N_("/Edit/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
657 { N_("/Edit/Add a _Group..."), NULL, show_add_group, 0, NULL}, 662 { N_("/Edit/Add a _Group..."), NULL, show_add_group, 0, NULL},
658 { "/Edit/sep", NULL, NULL, 0, "<Separator>" }, 663 { "/Edit/sep", NULL, NULL, 0, "<Separator>" },
659 { N_("/Edit/A_ccounts"), "<CTL>A", account_editor, 0, NULL }, 664 { N_("/Edit/A_ccounts"), "<CTL>A", account_editor, 0, NULL },
660 { N_("/Edit/Preferences"), "<CTL>P", show_prefs, 0, 665 { N_("/Edit/Preferences"), "<CTL>P", show_prefs, 0,
1121 } 1126 }
1122 1127
1123 gtkblist = GAIM_GTK_BLIST(list); 1128 gtkblist = GAIM_GTK_BLIST(list);
1124 1129
1125 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 1130 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1126 gtk_window_set_gravity(GTK_WINDOW(gtkblist->window), GDK_GRAVITY_NORTH_WEST);
1127 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); 1131 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list");
1128 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); 1132 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List"));
1129 gtk_widget_realize(gtkblist->window); 1133 gtk_widget_realize(gtkblist->window);
1130 1134
1131 gtkblist->vbox = gtk_vbox_new(FALSE, 0); 1135 gtkblist->vbox = gtk_vbox_new(FALSE, 0);
1255 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); 1259 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0);
1256 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); 1260 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1257 gtk_size_group_add_widget(sg, button); 1261 gtk_size_group_add_widget(sg, button);
1258 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); 1262 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL);
1259 1263
1264 /* set the Show Offline Buddies option */
1265 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (ift, N_("/Edit/Show Offline Buddies"))),
1266 blist_options & OPT_BLIST_SHOW_OFFLINE);
1267
1268 /* OK... let's show this bad boy. */
1269 gaim_gtk_blist_refresh(list);
1270 gaim_gtk_blist_restore_position();
1271 gtk_widget_show_all(gtkblist->window);
1272
1260 gaim_gtk_blist_update_toolbar(); 1273 gaim_gtk_blist_update_toolbar();
1261 } 1274 }
1262 1275
1263 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) 1276 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list)
1264 { 1277 {
1381 } 1394 }
1382 /* we set this up as a timeout, otherwise the blist flickers */ 1395 /* we set this up as a timeout, otherwise the blist flickers */
1383 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); 1396 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection);
1384 } 1397 }
1385 1398
1399 static void make_a_group(GaimBlistNode *node, GtkTreeIter *iter) {
1400 GaimBlistNode *sibling;
1401 GtkTreeIter siblingiter;
1402 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview,
1403 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
1404 char *esc = g_markup_escape_text(((struct group*)node)->name, -1);
1405 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc);
1406 g_free(esc);
1407 sibling = node->prev;
1408 while (sibling && !get_iter_from_node(sibling, &siblingiter)) {
1409 sibling = sibling->prev;
1410 }
1411
1412 gtk_tree_store_insert_after(gtkblist->treemodel, iter, NULL,
1413 sibling ? &siblingiter : NULL);
1414 gtk_tree_store_set(gtkblist->treemodel, iter,
1415 STATUS_ICON_COLUMN, groupicon,
1416 NAME_COLUMN, mark,
1417 NODE_COLUMN, node,
1418 -1);
1419 g_free(mark);
1420 g_object_unref(groupicon);
1421 }
1422
1386 1423
1387 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) 1424 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node)
1388 { 1425 {
1389 struct gaim_gtk_blist_node *gtknode; 1426 struct gaim_gtk_blist_node *gtknode;
1390 GtkTreeIter iter; 1427 GtkTreeIter iter;
1391 gboolean expand = FALSE; 1428 GtkTreePath *expand = NULL;
1392 gboolean new_entry = FALSE; 1429 gboolean new_entry = FALSE;
1393 1430
1394 if (!gtkblist) 1431 if (!gtkblist)
1395 return; 1432 return;
1396 1433
1403 if (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc)) { 1440 if (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc)) {
1404 GtkTreeIter groupiter; 1441 GtkTreeIter groupiter;
1405 GaimBlistNode *oldersibling; 1442 GaimBlistNode *oldersibling;
1406 GtkTreeIter oldersiblingiter; 1443 GtkTreeIter oldersiblingiter;
1407 1444
1408 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { 1445 if(node->parent &&
1409 /* This buddy's group has not yet been added. We do that here */ 1446 !get_iter_from_node(node->parent, &groupiter)) {
1410 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, 1447 /* This buddy's group has not yet been added.
1411 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); 1448 * We do that here */
1412 char *esc = g_markup_escape_text(((struct group*)node->parent)->name, -1); 1449 make_a_group(node->parent, &groupiter);
1413 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); 1450 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter);
1414 g_free(esc);
1415 oldersibling = node->parent->prev;
1416
1417 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */
1418 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter))
1419 oldersibling = oldersibling->prev;
1420
1421 /* This is where we create the node and add it. */
1422 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL);
1423 gtk_tree_store_set(gtkblist->treemodel, &groupiter,
1424 STATUS_ICON_COLUMN, groupicon,
1425 NAME_COLUMN, mark,
1426 NODE_COLUMN, node->parent,
1427 -1);
1428
1429 g_free(mark);
1430 g_object_unref(G_OBJECT(groupicon));
1431
1432 expand = TRUE;
1433 } 1451 }
1434 1452
1435 oldersibling = node->prev; 1453 oldersibling = node->prev;
1436 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) { 1454 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) {
1437 oldersibling = oldersibling->prev; 1455 oldersibling = oldersibling->prev;
1440 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); 1458 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL);
1441 1459
1442 if (blist_options & OPT_BLIST_POPUP) 1460 if (blist_options & OPT_BLIST_POPUP)
1443 gtk_window_present(GTK_WINDOW(gtkblist->window)); 1461 gtk_window_present(GTK_WINDOW(gtkblist->window));
1444 1462
1445 if (expand) { /* expand was set to true if this is the first element added to a group. In such case
1446 * we expand the group node */
1447 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter);
1448 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE);
1449 gtk_tree_path_free(path);
1450 }
1451 } 1463 }
1452 } 1464 }
1453 else if (GAIM_BLIST_NODE_IS_GROUP(node) && blist_options & OPT_BLIST_SHOW_OFFLINE) { 1465 else if (GAIM_BLIST_NODE_IS_GROUP(node) && (blist_options & OPT_BLIST_SHOW_OFFLINE)) {
1454 GaimBlistNode *oldersibling; 1466 make_a_group(node, &iter);
1455 GtkTreeIter oldersiblingiter; 1467 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
1456 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, 1468 }
1457 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
1458 char *esc = g_markup_escape_text(((struct group*)node)->name, -1);
1459 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc);
1460 g_free(esc);
1461 oldersibling = node->prev;
1462 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) {
1463 oldersibling = oldersibling->prev;
1464 }
1465
1466 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, NULL, oldersibling ? &oldersiblingiter : NULL);
1467 gtk_tree_store_set(gtkblist->treemodel, &iter,
1468 STATUS_ICON_COLUMN, groupicon,
1469 NAME_COLUMN, mark,
1470 NODE_COLUMN, node,
1471 -1);
1472 g_free(mark);
1473 g_object_unref(groupicon);
1474 }
1475
1476 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { 1469 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
1477 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter) == FALSE && blist_options & OPT_BLIST_SHOW_OFFLINE == FALSE) 1470 if ((gaim_blist_get_group_online_count((struct group *)node) == 0) ||
1471 (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter) && !(blist_options & OPT_BLIST_SHOW_OFFLINE))) {
1478 gtk_tree_store_remove(gtkblist->treemodel, &iter); 1472 gtk_tree_store_remove(gtkblist->treemodel, &iter);
1479 else { 1473 } else {
1480 char *esc = g_markup_escape_text(((struct group*)node)->name, -1); 1474 char *esc = g_markup_escape_text(((struct group*)node)->name, -1);
1481 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); 1475 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc);
1482 g_free(esc); 1476 g_free(esc);
1483 gtk_tree_store_set(gtkblist->treemodel, &iter, 1477 gtk_tree_store_set(gtkblist->treemodel, &iter,
1484 NAME_COLUMN, mark, 1478 NAME_COLUMN, mark,
1485 -1); 1479 -1);
1486 g_free(mark); 1480 g_free(mark);
1487 } 1481 }
1488 } 1482 }
1489 1483
1490 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc))) { 1484 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc))) {
1562 GaimBlistNode *afsad = node->child; 1556 GaimBlistNode *afsad = node->child;
1563 while (afsad) { 1557 while (afsad) {
1564 gaim_gtk_blist_update(list, afsad); 1558 gaim_gtk_blist_update(list, afsad);
1565 afsad = afsad->next; 1559 afsad = afsad->next;
1566 } 1560 }
1567 1561
1568 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); 1562 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
1563 }
1564
1565 if(expand) {
1566 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, TRUE);
1567 gtk_tree_path_free(expand);
1569 } 1568 }
1570 } 1569 }
1571 1570
1572 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) 1571 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
1573 { 1572 {