comparison src/buddy.c @ 4699:2222cd30008a

[gaim-migrate @ 5010] more buddy list stuff. who woulda guessed? - buddies are in the correct order now - crash fixes - the grey idle option works again - Sean is cool committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Tue, 11 Mar 2003 02:06:11 +0000
parents aa2ceea841b4
children ac7ca2bd6d4f
comparison
equal deleted inserted replaced
4698:aa2ceea841b4 4699:2222cd30008a
461 } 461 }
462 } 462 }
463 463
464 464
465 /* Idle gray buddies affects the whole row. This converts the status icon to greyscale. */ 465 /* Idle gray buddies affects the whole row. This converts the status icon to greyscale. */
466 if (b->idle) 466 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS)
467 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); 467 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE);
468 return scale; 468 return scale;
469 } 469 }
470 470
471 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) 471 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b)
476 476
477 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) 477 if (!(blist_options & OPT_BLIST_SHOW_ICONS))
478 return NULL; 478 return NULL;
479 479
480 if (buf) { 480 if (buf) {
481 if (b->idle) { 481 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) {
482 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); 482 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE);
483 } 483 }
484 return gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); 484 return gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR);
485 } 485 }
486 return NULL; 486 return NULL;
489 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b) 489 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b)
490 { 490 {
491 char *name = gaim_get_buddy_alias(b); 491 char *name = gaim_get_buddy_alias(b);
492 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; 492 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL;
493 /* XXX Clean up this crap */ 493 /* XXX Clean up this crap */
494 494
495 int ihrs, imin; 495 int ihrs, imin;
496 char *idletime = ""; 496 char *idletime = "";
497 char *warning = idletime; 497 char *warning = idletime;
498 time_t t; 498 time_t t;
499 499
500 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { 500 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) {
501 if (b->idle > 0) { 501 if (b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS) {
502 text = g_strdup_printf("<span color='gray'>%s</span>", 502 text = g_strdup_printf("<span color='gray'>%s</span>",
503 esc); 503 esc);
504 g_free(esc); 504 g_free(esc);
505 return text; 505 return text;
506 } else { 506 } else {
507 return esc; 507 return esc;
508 } 508 }
509 } 509 }
510 510
511 time(&t); 511 time(&t);
512 ihrs = (t - b->idle) / 3600; 512 ihrs = (t - b->idle) / 3600;
513 imin = ((t - b->idle) / 60) % 60; 513 imin = ((t - b->idle) / 60) % 60;
514 514
515 if (b->idle) { 515 if (b->idle) {
516 if (ihrs) 516 if (ihrs)
517 idletime = g_strdup_printf(_("Idle (%dh%02dm)"), ihrs, imin); 517 idletime = g_strdup_printf(_("Idle (%dh%02dm)"), ihrs, imin);
518 else 518 else
519 idletime = g_strdup_printf(_("Idle (%dm)"), imin); 519 idletime = g_strdup_printf(_("Idle (%dm)"), imin);
520 } 520 }
521 521
522 if (b->evil > 0) 522 if (b->evil > 0)
523 warning = g_strdup_printf(_("Warned (%d%%)"), b->evil); 523 warning = g_strdup_printf(_("Warned (%d%%)"), b->evil);
524 524
525 if (b->idle) 525 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS)
526 text = g_strdup_printf("<span color='grey'>%s</span>\n<span color='gray' size='smaller'>%s %s</span>", 526 text = g_strdup_printf("<span color='grey'>%s</span>\n<span color='gray' size='smaller'>%s %s</span>",
527 esc, 527 esc,
528 idletime, warning); 528 idletime, warning);
529 else 529 else
530 text = g_strdup_printf("%s\n<span color='gray' size='smaller'>%s</span>", esc, warning); 530 text = g_strdup_printf("%s\n<span color='gray' size='smaller'>%s %s</span>", esc, idletime, warning);
531 531
532 if (idletime[0]) 532 if (idletime[0])
533 g_free(idletime); 533 g_free(idletime);
534 if (warning[0]) 534 if (warning[0])
535 g_free(warning); 535 g_free(warning);
536 536
537 return text; 537 return text;
538 } 538 }
539 539
540 /********************************************************************************** 540 /**********************************************************************************
541 * Public API Functions * 541 * Public API Functions *
677 677
678 while (group) { 678 while (group) {
679 gaim_gtk_blist_update(list, group); 679 gaim_gtk_blist_update(list, group);
680 buddy = group->child; 680 buddy = group->child;
681 while (buddy) { 681 while (buddy) {
682 gaim_gtk_blist_update(list, buddy); 682 gaim_gtk_blist_update(list, buddy);
683 buddy = buddy->next; 683 buddy = buddy->next;
684 } 684 }
685 group = group->next; 685 group = group->next;
686 } 686 }
687 }
688
689 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) {
690 do {
691 GaimBlistNode *n;
692 GtkTreeIter child;
693
694 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1);
695 if(n == node) {
696 *iter = *root;
697 return TRUE;
698 }
699
700 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) {
701 if(get_iter_from_node_helper(node,iter,&child))
702 return TRUE;
703 }
704 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root));
705
706 return FALSE;
707 }
708
709 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) {
710 GtkTreeIter root;
711
712 if (!gtkblist)
713 return FALSE;
714
715 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root))
716 return FALSE;
717
718 return get_iter_from_node_helper(node, iter, &root);
687 } 719 }
688 720
689 void gaim_gtk_blist_update_toolbar() { 721 void gaim_gtk_blist_update_toolbar() {
690 if (!gtkblist) 722 if (!gtkblist)
691 return; 723 return;
692 724
693 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); 725 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL);
694 726
695 if (blist_options & OPT_BLIST_NO_BUTTONS) 727 if (blist_options & OPT_BLIST_NO_BUTTONS)
696 gtk_widget_hide(gtkblist->bbox); 728 gtk_widget_hide(gtkblist->bbox);
697 else 729 else
698 gtk_widget_show_all(gtkblist->bbox); 730 gtk_widget_show_all(gtkblist->bbox);
699 } 731 }
700 732
701 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) 733 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node)
702 { 734 {
703 struct gaim_gtk_blist_node *gtknode; 735 struct gaim_gtk_blist_node *gtknode;
704 GtkTreeIter *iter; 736 GtkTreeIter iter;
705 gboolean expand = FALSE; 737 gboolean expand = FALSE;
738 gboolean new_entry = FALSE;
706 739
707 if (!gtkblist) 740 if (!gtkblist)
708 return; 741 return;
709 742
710 gtknode = GAIM_GTK_BLIST_NODE(node); 743 gtknode = GAIM_GTK_BLIST_NODE(node);
711 iter = gtknode->iter; 744
712 745
713 746 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */
714 if (!iter) { /* This is a newly added node */ 747 new_entry = TRUE;
715 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 748 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
716 if (((struct buddy*)node)->present) { 749 if (((struct buddy*)node)->present) {
717 if(node->parent && node->parent && 750 GtkTreeIter groupiter;
718 !GAIM_GTK_BLIST_NODE(node->parent)->iter) { 751 GaimBlistNode *oldersibling;
719 752 GtkTreeIter oldersiblingiter;
753
754 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) {
720 /* This buddy's group has not yet been added. We do that here */ 755 /* This buddy's group has not yet been added. We do that here */
721
722 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name); 756 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name);
723 GtkTreeIter *iter2 = g_new0(GtkTreeIter, 1); 757 oldersibling = node->parent->prev;
724 GaimBlistNode *insertat = node->parent->prev;
725 GtkTreeIter *insertatiter = NULL;
726 758
727 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ 759 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */
728 while (insertat && !GAIM_GTK_BLIST_NODE(insertat)->iter) 760 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter))
729 insertat = insertat->prev; 761 oldersibling = oldersibling->prev;
730
731 if (insertat)
732 insertatiter = GAIM_GTK_BLIST_NODE(insertat)->iter;
733 762
734 /* This is where we create the node and add it. */ 763 /* This is where we create the node and add it. */
735 gtk_tree_store_insert_after(gtkblist->treemodel, iter2, 764 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL);
736 node->parent->parent ? 765 gtk_tree_store_set(gtkblist->treemodel, &groupiter,
737 GAIM_GTK_BLIST_NODE(node->parent->parent)->iter : NULL, insertatiter);
738 gtk_tree_store_set(gtkblist->treemodel, iter2,
739 STATUS_ICON_COLUMN, gtk_widget_render_icon 766 STATUS_ICON_COLUMN, gtk_widget_render_icon
740 (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_SMALL_TOOLBAR,NULL), 767 (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_SMALL_TOOLBAR,NULL),
741 NAME_COLUMN, mark, 768 NAME_COLUMN, mark,
742 NODE_COLUMN, node->parent, 769 NODE_COLUMN, node->parent,
743 -1); 770 -1);
744 771
745 GAIM_GTK_BLIST_NODE(node->parent)->iter = iter2;
746 expand = TRUE; 772 expand = TRUE;
747 } 773 }
748 iter = g_new0(GtkTreeIter, 1); 774
749 775 oldersibling = node->prev;
750 GAIM_GTK_BLIST_NODE(node)->iter = iter; 776 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter))
751 777 oldersibling = oldersibling->prev;
752 gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent ? GAIM_GTK_BLIST_NODE(node->parent)->iter : NULL, 778
753 node->prev ? GAIM_GTK_BLIST_NODE(node->prev)->iter : NULL); 779 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL);
754 780
755
756 if (expand) { /* expand was set to true if this is the first element added to a group. In such case 781 if (expand) { /* expand was set to true if this is the first element added to a group. In such case
757 * we expand the group node */ 782 * we expand the group node */
758 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node->parent)->iter); 783 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter);
759 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); 784 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE);
760 } 785 }
761
762 GAIM_GTK_BLIST_NODE(node)->iter = iter;
763 } 786 }
764 } 787 }
765 } 788 }
766 789
767 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { 790 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) {
768 GdkPixbuf *status, *avatar; 791 GdkPixbuf *status, *avatar;
769 char *mark; 792 char *mark;
770 char *warning = NULL, *idle = NULL; 793 char *warning = NULL, *idle = NULL;
771 794
772 status = gaim_gtk_blist_get_status_icon((struct buddy*)node); 795 status = gaim_gtk_blist_get_status_icon((struct buddy*)node);
773 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); 796 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node);
774 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node); 797 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node);
775 798
776 if ((((struct buddy*)node)->idle > 0) && 799 if ((((struct buddy*)node)->idle > 0) &&
777 (!(blist_options & OPT_BLIST_SHOW_ICONS) && (blist_options & OPT_BLIST_SHOW_IDLETIME))) { 800 (!(blist_options & OPT_BLIST_SHOW_ICONS) && (blist_options & OPT_BLIST_SHOW_IDLETIME))) {
778 time_t t; 801 time_t t;
779 int ihrs, imin; 802 int ihrs, imin;
780 time(&t); 803 time(&t);
781 ihrs = (t - ((struct buddy *)node)->idle) / 3600; 804 ihrs = (t - ((struct buddy *)node)->idle) / 3600;
782 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; 805 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60;
783 idle = g_strdup_printf("%d:%02d", ihrs, imin); 806 idle = g_strdup_printf("%d:%02d", ihrs, imin);
784 } 807 }
785 808
786 if ((((struct buddy*)node)->evil > 0) && 809 if ((((struct buddy*)node)->evil > 0) &&
787 (!(blist_options & OPT_BLIST_SHOW_ICONS) && (blist_options & OPT_BLIST_SHOW_WARN))) { 810 (!(blist_options & OPT_BLIST_SHOW_ICONS) && (blist_options & OPT_BLIST_SHOW_WARN))) {
788 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); 811 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil);
789 } 812 }
790 813
791 gtk_tree_store_set(gtkblist->treemodel, iter, 814 gtk_tree_store_set(gtkblist->treemodel, &iter,
792 STATUS_ICON_COLUMN, status, 815 STATUS_ICON_COLUMN, status,
793 NAME_COLUMN, mark, 816 NAME_COLUMN, mark,
794 WARNING_COLUMN, warning, 817 WARNING_COLUMN, warning,
795 IDLE_COLUMN, idle, 818 IDLE_COLUMN, idle,
796 BUDDY_ICON_COLUMN, avatar, 819 BUDDY_ICON_COLUMN, avatar,
797 NODE_COLUMN, node, 820 NODE_COLUMN, node,
798 -1); 821 -1);
799 822
800 g_free(mark); 823 g_free(mark);
801 if (idle) 824 if (idle)
802 g_free(idle); 825 g_free(idle);
803 if (warning) 826 if (warning)
804 g_free(warning); 827 g_free(warning);
807 g_object_unref(status); 830 g_object_unref(status);
808 831
809 if (avatar != NULL) 832 if (avatar != NULL)
810 g_object_unref(avatar); 833 g_object_unref(avatar);
811 834
812 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && GAIM_GTK_BLIST_NODE(node)->iter){ 835 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry){
813 gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node)->iter); 836 gtk_tree_store_remove(gtkblist->treemodel, &iter);
814 837 }
815 g_free(GAIM_GTK_BLIST_NODE(node)->iter);
816 GAIM_GTK_BLIST_NODE(node)->iter = NULL;
817 }
818
819 } 838 }
820 839
821 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) 840 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node)
822 { 841 {
823 struct gaim_gtk_blist_node *gtknode; 842 struct gaim_gtk_blist_node *gtknode;
843 GtkTreeIter iter;
824 844
825 if (!node->ui_data) 845 if (!node->ui_data)
826 return; 846 return;
827 847
828 gtknode = (struct gaim_gtk_blist_node *)node->ui_data; 848 gtknode = (struct gaim_gtk_blist_node *)node->ui_data;
829 849
830 if (gtknode->timer > 0) 850 if (gtknode->timer > 0)
831 g_source_remove(gtknode->timer); 851 g_source_remove(gtknode->timer);
832 852
833 if (gtknode->iter != NULL) 853 if (get_iter_from_node(node, &iter))
834 gtk_tree_store_remove(gtkblist->treemodel, gtknode->iter); 854 gtk_tree_store_remove(gtkblist->treemodel, &iter);
835 } 855 }
836 856
837 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) 857 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
838 { 858 {
839 gtk_widget_destroy(gtkblist->window); 859 gtk_widget_destroy(gtkblist->window);
840 } 860 }
841 861
842 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) 862 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show)
843 { 863 {
844 if (show) { 864 if (show) {
845 gtk_window_present(gtkblist->window); 865 gtk_window_present(GTK_WINDOW(gtkblist->window));
846 } else { 866 } else {
847 if (!connections || docklet_count) { 867 if (!connections || docklet_count) {
848 #ifdef _WIN32 868 #ifdef _WIN32
849 wgaim_systray_minimize(blist); 869 wgaim_systray_minimize(blist);
850 #endif 870 #endif
972 status = gdk_pixbuf_new_from_file(filename,NULL); 992 status = gdk_pixbuf_new_from_file(filename,NULL);
973 g_free(filename); 993 g_free(filename);
974 } 994 }
975 return status; 995 return status;
976 } 996 }
997