Mercurial > pidgin.yaz
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 { |