comparison src/buddy.c @ 4349:0c68d402f59f

[gaim-migrate @ 4614] XML Blist Gaim stores all the buddy lists in one big happy file now. You can order the buddies however you want, and they'll stay ordered that way. We can also store some per-buddy information now, which will be cool. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Sun, 19 Jan 2003 22:16:52 +0000
parents c5851f0e120e
children 5fb47ec9bfe4
comparison
equal deleted inserted replaced
4348:922b66840a51 4349:0c68d402f59f
116 static void update_idle_time(struct buddy_show *bs); 116 static void update_idle_time(struct buddy_show *bs);
117 117
118 void handle_group_rename(struct group *g, char *prevname) 118 void handle_group_rename(struct group *g, char *prevname)
119 { 119 {
120 struct group_show *gs, *new_gs; 120 struct group_show *gs, *new_gs;
121 struct buddy_show *bs;
122 struct buddy *b;
123 GSList *m;
124 GtkCTreeNode *c; 121 GtkCTreeNode *c;
125 122
126 c = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, g); 123 c = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, g);
127 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, g->name); 124 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, g->name);
128 125
132 } 129 }
133 new_gs = find_group_show(g->name); 130 new_gs = find_group_show(g->name);
134 if (new_gs) { 131 if (new_gs) {
135 /* transfer everything that was in gs and is in the same gaim_conn as g 132 /* transfer everything that was in gs and is in the same gaim_conn as g
136 * over to new_gs. */ 133 * over to new_gs. */
137 m = gs->members; 134 while (gs->members) {
138 while (m) { 135 new_gs->members = g_slist_append(new_gs->members, gs->members->data);
139 bs = (struct buddy_show *)m->data; 136 gs->members = g_slist_remove(gs->members, gs->members->data);
140 if (g_slist_index(bs->connlist, g->gc) >= 0) { 137
141 b = find_buddy(g->gc, bs->name); 138 }
142 m = g_slist_next(m); 139 shows = g_slist_remove(shows, gs);
143 bs->connlist = g_slist_remove(bs->connlist, g->gc); 140 gtk_tree_remove_item(GTK_TREE(buddies), gs->item);
144 if (!bs->connlist) { 141 g_free(gs->name);
145 gs->members = g_slist_remove(gs->members, bs); 142 g_free(gs);
146 if (bs->log_timer > 0)
147 g_source_remove(bs->log_timer);
148 bs->log_timer = 0;
149 remove_buddy_show(gs, bs);
150 g_free(bs->name);
151 g_free(bs);
152 }
153 if ((bs = find_buddy_show(new_gs, b->name)) == NULL) {
154 if (g->gc->prpl->list_icon) {
155 bs = new_buddy_show(new_gs, b,
156 g->gc->prpl->list_icon(b->uc));
157 } else {
158 bs = new_buddy_show(new_gs, b, (char **)no_icon_xpm);
159 }
160 }
161 bs->connlist = g_slist_append(bs->connlist, g->gc);
162 } else {
163 m = g_slist_next(m);
164 }
165 }
166 if (!gs->members) {
167 /* we just transferred all of the members out of this group_show,
168 * so this group_show serves no purpose now. */
169 shows = g_slist_remove(shows, gs);
170 gtk_tree_remove_item(GTK_TREE(buddies), gs->item);
171 g_free(gs->name);
172 g_free(gs);
173 } else {
174 update_num_group(gs);
175 }
176 update_num_group(new_gs); 143 update_num_group(new_gs);
177 } else { 144 } else {
178 /* two possible actions: if gs contains things that are only from g, 145 g_free(gs->name);
179 * just rename gs and fix the label. otherwise, move everything in g 146 gs->name = g_strdup(g->name);
180 * over to another group_show */ 147 update_num_group(gs);
181 for (m = gs->members; m != NULL; m = g_slist_next(m)) {
182 bs = (struct buddy_show *)m->data;
183 if (g_slist_index(bs->connlist, g->gc) < 0 || g_slist_length(bs->connlist) > 1) {
184 break;
185 }
186 }
187 if (m) {
188 /* there's something from a different gaim_connection. */
189 new_gs = new_group_show(g->name);
190 m = gs->members;
191 while (m) {
192 bs = (struct buddy_show *)m->data;
193 if (g_slist_index(bs->connlist, g->gc) >= 0) {
194 b = find_buddy(g->gc, bs->name);
195 m = g_slist_next(m);
196 bs->connlist = g_slist_remove(bs->connlist, g->gc);
197 if (!bs->connlist) {
198 gs->members = g_slist_remove(gs->members, bs);
199 if (bs->log_timer > 0)
200 g_source_remove(bs->log_timer);
201 bs->log_timer = 0;
202 remove_buddy_show(gs, bs);
203 g_free(bs->name);
204 g_free(bs);
205 }
206 if (g->gc->prpl->list_icon) {
207 bs = new_buddy_show(new_gs, b,
208 g->gc->prpl->list_icon(b->uc));
209 } else {
210 bs = new_buddy_show(new_gs, b, (char **)no_icon_xpm);
211 }
212 bs->connlist = g_slist_append(NULL, g->gc);
213 } else {
214 m = g_slist_next(m);
215 }
216 }
217 update_num_group(gs);
218 update_num_group(new_gs);
219 } else {
220 g_free(gs->name);
221 gs->name = g_strdup(g->name);
222 update_num_group(gs);
223 }
224 } 148 }
225 } 149 }
226 150
227 void handle_buddy_rename(struct buddy *b, char *prevname) 151 void handle_buddy_rename(struct buddy *b, char *prevname)
228 { 152 {
241 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, buf); 165 gtk_ctree_node_set_text(GTK_CTREE(edittree), c, 0, buf);
242 166
243 if ((cnv = find_conversation(b->name)) != NULL) 167 if ((cnv = find_conversation(b->name)) != NULL)
244 set_convo_title(cnv); 168 set_convo_title(cnv);
245 169
246 g = find_group_by_buddy(b->gc, b->name); 170 g = find_group_by_buddy(b);
247 if (!g) { 171 if (!g) {
248 /* shouldn't happen */ 172 /* shouldn't happen */
249 return; 173 return;
250 } 174 }
251 gs = find_group_show(g->name); 175 gs = find_group_show(g->name);
257 /* buddy's offline */ 181 /* buddy's offline */
258 return; 182 return;
259 } 183 }
260 184
261 if (g_strcasecmp(b->name, prevname)) { 185 if (g_strcasecmp(b->name, prevname)) {
262 bs->connlist = g_slist_remove(bs->connlist, b->gc); 186 bs->connlist = g_slist_remove(bs->connlist, b->user->gc);
263 if (!bs->connlist) { 187 if (!bs->connlist) {
264 gs->members = g_slist_remove(gs->members, bs); 188 gs->members = g_slist_remove(gs->members, bs);
265 if (bs->log_timer > 0) 189 if (bs->log_timer > 0)
266 g_source_remove(bs->log_timer); 190 g_source_remove(bs->log_timer);
267 bs->log_timer = 0; 191 bs->log_timer = 0;
381 s = g_slist_next(s); 305 s = g_slist_next(s);
382 } 306 }
383 307
384 } else { 308 } else {
385 /* put back all groups */ 309 /* put back all groups */
386 GSList *c = connections; 310 GSList *m = groups;
387 struct gaim_connection *gc; 311
388 GSList *m; 312 while (m) {
389 struct group *g; 313 struct group *g = (struct group *)m->data;
390 314 if (!find_group_show(g->name) && gaim_group_on_account(g, NULL))
391 while (c) { 315 new_group_show(g->name);
392 gc = (struct gaim_connection *)c->data; 316 m = g_slist_next(m);
393 m = gc->groups; 317 }
394 while (m) {
395 g = (struct group *)m->data;
396 m = g_slist_next(m);
397 if (!find_group_show(g->name))
398 new_group_show(g->name);
399 }
400 c = g_slist_next(c);
401 }
402
403 } 318 }
404 } 319 }
405 320
406 void toggle_buddy_pixmaps() 321 void toggle_buddy_pixmaps()
407 { 322 {
426 } 341 }
427 342
428 static void update_num_group(struct group_show *gs) 343 static void update_num_group(struct group_show *gs)
429 { 344 {
430 GSList *c = connections; 345 GSList *c = connections;
431 struct gaim_connection *gc; 346 struct group *g = find_group(gs->name);
432 struct group *g; 347 struct buddy *b;
433 struct buddy_show *b;
434 int total = 0, on = 0; 348 int total = 0, on = 0;
435 char buf[256]; 349 char buf[256];
436 350
437 if (!g_slist_find(shows, gs)) { 351 if (!g_slist_find(shows, gs)) {
438 debug_printf("update_num_group called for unfound group_show %s\n", gs->name); 352 debug_printf("update_num_group called for unfound group_show %s\n", gs->name);
439 return; 353 return;
440 } 354 }
441 355 if (g) {
442 while (c) { 356 for (c = g->members; c; c = c->next) {
443 gc = (struct gaim_connection *)c->data; 357 b = c->data;
444 g = find_group(gc, gs->name); 358 if(b->user->gc) {
445 if (g) { 359 if(b->present)
446 total += g_slist_length(g->members); 360 on++;
447 } 361 total++;
448 c = g_slist_next(c); 362 }
449 } 363 }
450
451 c = gs->members;
452 while (c) {
453 b = (struct buddy_show *)c->data;
454 on += g_slist_length(b->connlist);
455 c = g_slist_next(c);
456 } 364 }
457 365
458 if (blist_options & OPT_BLIST_SHOW_GRPNUM) 366 if (blist_options & OPT_BLIST_SHOW_GRPNUM)
459 g_snprintf(buf, sizeof buf, "%s (%d/%d)", gs->name, on, total); 367 g_snprintf(buf, sizeof buf, "%s (%d/%d)", gs->name, on, total);
460 else 368 else
535 if (c != NULL) { 443 if (c != NULL) {
536 gdk_window_show(c->window->window); 444 gdk_window_show(c->window->window);
537 } else { 445 } else {
538 c = new_conversation(b->name); 446 c = new_conversation(b->name);
539 447
540 set_convo_gc(c, b->gc); 448 set_convo_gc(c, b->user->gc);
541 } 449 }
542 } 450 }
543 451
544 void pressed_im(GtkWidget *widget, struct buddy_show *b) 452 void pressed_im(GtkWidget *widget, struct buddy_show *b)
545 { 453 {
566 show_log(NULL); 474 show_log(NULL);
567 } 475 }
568 476
569 void pressed_alias_bs(GtkWidget *widget, struct buddy_show *bs) 477 void pressed_alias_bs(GtkWidget *widget, struct buddy_show *bs)
570 { 478 {
571 alias_dialog_bud(find_buddy(bs->connlist->data, bs->name)); 479 struct gaim_connection *gc = bs->connlist->data;
480 alias_dialog_bud(find_buddy(gc->user, bs->name));
572 } 481 }
573 482
574 void pressed_alias_bud(GtkWidget *widget, struct buddy *b) 483 void pressed_alias_bud(GtkWidget *widget, struct buddy *b)
575 { 484 {
576 alias_dialog_bud(b); 485 alias_dialog_bud(b);
738 static void un_alias(GtkWidget *a, struct buddy *b) 647 static void un_alias(GtkWidget *a, struct buddy *b)
739 { 648 {
740 b->alias[0] = '\0'; 649 b->alias[0] = '\0';
741 handle_buddy_rename(b, b->name); /* make me a sammich! */ 650 handle_buddy_rename(b, b->name); /* make me a sammich! */
742 serv_alias_buddy(b); 651 serv_alias_buddy(b);
743 do_export(b->gc); 652 gaim_blist_save();
744 } 653 }
745 654
746 static gboolean click_edit_tree(GtkWidget *widget, GdkEventButton *event, gpointer data) 655 static gboolean click_edit_tree(GtkWidget *widget, GdkEventButton *event, gpointer data)
747 { 656 {
748 GtkCTreeNode *node; 657 GtkCTreeNode *node;
829 gtk_widget_show(button); 738 gtk_widget_show(button);
830 739
831 /* 740 /*
832 * Add protocol-specific edit buddy menu items if they exist 741 * Add protocol-specific edit buddy menu items if they exist
833 */ 742 */
834 if (b->gc->prpl->edit_buddy_menu) { 743 if (b->user->gc && b->user->gc->prpl->edit_buddy_menu) {
835 GList *mo = mo_top = b->gc->prpl->edit_buddy_menu(b->gc, b->name); 744 GList *mo = mo_top = b->user->gc->prpl->edit_buddy_menu(b->user->gc, b->name);
836 745
837 while (mo) { 746 while (mo) {
838 struct proto_buddy_menu *pbm = mo->data; 747 struct proto_buddy_menu *pbm = mo->data;
839 GtkWidget *button; 748 GtkWidget *button;
840 749
870 { 779 {
871 gtk_ctree_remove_node(GTK_CTREE(edittree), bnode); 780 gtk_ctree_remove_node(GTK_CTREE(edittree), bnode);
872 } 781 }
873 } 782 }
874 783
875 void ui_remove_buddy(struct gaim_connection *gc, struct group *rem_g, struct buddy *rem_b) 784 void ui_remove_buddy(struct buddy *rem_b)
876 { 785 {
877 struct conversation *c; 786 struct conversation *c;
787 struct group *rem_g = find_group_by_buddy(rem_b);
878 struct group_show *gs; 788 struct group_show *gs;
879 struct buddy_show *bs; 789 struct buddy_show *bs;
880 790
881 gs = find_group_show(rem_g->name); 791 gs = find_group_show(rem_g->name);
882 if (gs) { 792 if (gs) {
883 bs = find_buddy_show(gs, rem_b->name); 793 bs = find_buddy_show(gs, rem_b->name);
884 if (bs) { 794 if (bs) {
885 if (g_slist_find(bs->connlist, gc)) { 795 if (g_slist_find(bs->connlist, rem_b->user->gc)) {
886 bs->connlist = g_slist_remove(bs->connlist, gc); 796 bs->connlist = g_slist_remove(bs->connlist, rem_b->user->gc);
887 if (!g_slist_length(bs->connlist)) { 797 if (!g_slist_length(bs->connlist)) {
888 gs->members = g_slist_remove(gs->members, bs); 798 gs->members = g_slist_remove(gs->members, bs);
889 if (bs->log_timer > 0) 799 if (bs->log_timer > 0)
890 g_source_remove(bs->log_timer); 800 g_source_remove(bs->log_timer);
891 bs->log_timer = 0; 801 bs->log_timer = 0;
892 remove_buddy_show(gs, bs); 802 remove_buddy_show(gs, bs);
893 g_free(bs->name); 803 g_free(bs->name);
894 g_free(bs); 804 g_free(bs);
895 if (!g_slist_length(gs->members) && 805 if ((!g_slist_length(gs->members) &&
896 (blist_options & OPT_BLIST_NO_MT_GRP)) { 806 (blist_options & OPT_BLIST_NO_MT_GRP)) ||
807 gaim_group_on_account(rem_g, NULL)) {
897 shows = g_slist_remove(shows, gs); 808 shows = g_slist_remove(shows, gs);
898 gtk_tree_remove_item(GTK_TREE(buddies), gs->item); 809 gtk_tree_remove_item(GTK_TREE(buddies), gs->item);
899 g_free(gs->name); 810 g_free(gs->name);
900 g_free(gs); 811 g_free(gs);
901 gs = NULL; 812 gs = NULL;
914 /* Remove CTree node for buddy */ 825 /* Remove CTree node for buddy */
915 ui_remove_buddy_node(rem_g, rem_b); 826 ui_remove_buddy_node(rem_g, rem_b);
916 827
917 } 828 }
918 829
919 void ui_remove_group(struct gaim_connection *gc, struct group *rem_g) 830 void ui_remove_group(struct group *rem_g)
920 { 831 {
921 struct group_show *gs; 832 struct group_show *gs;
833 GtkCTreeNode *gnode = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, rem_g);
834 gtk_ctree_remove_node(GTK_CTREE(edittree), gnode);
835
922 836
923 if ((gs = find_group_show(rem_g->name)) != NULL) { 837 if ((gs = find_group_show(rem_g->name)) != NULL) {
924 shows = g_slist_remove(shows, gs); 838 shows = g_slist_remove(shows, gs);
925 gtk_tree_remove_item(GTK_TREE(buddies), gs->item); 839 gtk_tree_remove_item(GTK_TREE(buddies), gs->item);
926 g_free(gs->name); 840 g_free(gs->name);
933 { 847 {
934 int *type; 848 int *type;
935 849
936 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), source_node); 850 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), source_node);
937 851
938 if (*type == EDIT_GC) { 852 if (*type == EDIT_GROUP) {
939 if (!new_parent) 853 if (!new_parent)
940 return TRUE; 854 return TRUE;
941 } else if (*type == EDIT_BUDDY) { 855 } else if (*type == EDIT_BUDDY) {
942 if (new_parent) { 856 if (new_parent) {
943 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), new_parent); 857 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), new_parent);
944 if (*type == EDIT_GROUP) 858 if (*type == EDIT_GROUP)
945 return TRUE; 859 return TRUE;
946 } 860 }
947 } else { /* group */
948
949 if (g_slist_length(connections) > 1 && new_parent) {
950 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), new_parent);
951 if (*type == EDIT_GC)
952 return TRUE;
953 } else if (g_slist_length(connections) == 1 && !new_parent)
954 return TRUE;
955 } 861 }
956 862
957 return FALSE; 863 return FALSE;
958 } 864 }
959 865
974 * people not seeing the login icon for the full 10 seconds. butt fuck them. */ 880 * people not seeing the login icon for the full 10 seconds. butt fuck them. */
975 GSList *s = shows; 881 GSList *s = shows;
976 struct group_show *gs; 882 struct group_show *gs;
977 GSList *m; 883 GSList *m;
978 struct buddy_show *bs; 884 struct buddy_show *bs;
979 GSList *c = connections;
980 struct gaim_connection *gc;
981 GSList *gr; 885 GSList *gr;
982 struct group *g; 886 struct group *g;
983 struct buddy *b; 887 struct buddy *b;
984 888
985 if (!blist) 889 if (!blist)
1000 } 904 }
1001 g_free(gs->name); 905 g_free(gs->name);
1002 g_free(gs); 906 g_free(gs);
1003 } 907 }
1004 shows = NULL; 908 shows = NULL;
1005 while (c) { 909 gr = groups;
1006 gc = (struct gaim_connection *)c->data; 910 while (gr) {
1007 c = c->next; 911 g = (struct group *)gr->data;
1008 gr = gc->groups; 912 gr = gr->next;
1009 while (gr) { 913 gs = find_group_show(g->name);
1010 g = (struct group *)gr->data; 914 if (!gs && !(blist_options & OPT_BLIST_NO_MT_GRP)
1011 gr = gr->next; 915 && gaim_group_on_account(g, NULL))
1012 gs = find_group_show(g->name); 916 gs = new_group_show(g->name);
1013 if (!gs && !(blist_options & OPT_BLIST_NO_MT_GRP)) 917 m = g->members;
1014 gs = new_group_show(g->name); 918 while (m) {
1015 m = g->members; 919 b = (struct buddy *)m->data;
1016 while (m) { 920 m = m->next;
1017 b = (struct buddy *)m->data; 921 if (b->present) {
1018 m = m->next; 922 if (!gs)
1019 if (b->present) { 923 gs = new_group_show(g->name);
1020 if (!gs) 924 bs = find_buddy_show(gs, b->name);
1021 gs = new_group_show(g->name); 925 if (!bs) {
1022 bs = find_buddy_show(gs, b->name); 926 if (b->user->gc->prpl->list_icon)
1023 if (!bs) { 927 bs = new_buddy_show(gs, b,
1024 if (gc->prpl->list_icon) 928 b->user->gc->prpl->list_icon(b->
1025 bs = new_buddy_show(gs, b, 929 uc));
1026 gc->prpl->list_icon(b-> 930 else
1027 uc)); 931 bs = new_buddy_show(gs, b, (char **)no_icon_xpm);
1028 else
1029 bs = new_buddy_show(gs, b, (char **)no_icon_xpm);
1030 }
1031 bs->connlist = g_slist_append(bs->connlist, gc);
1032 update_num_group(gs);
1033 } 932 }
933 bs->connlist = g_slist_append(bs->connlist, b->user->gc);
934 update_num_group(gs);
1034 } 935 }
1035 } 936 }
1036 } 937 }
1037 update_idle_times(); 938 update_idle_times();
1038 } 939 }
1039 940
1040 static void edit_tree_move(GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 941 static void edit_tree_move(GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent,
1041 GtkCTreeNode *sibling, gpointer data) 942 GtkCTreeNode *sibling, gpointer data)
1042 { 943 {
1043 struct gaim_connection *gc, *pc = NULL, *sc = NULL;
1044 int *ctype, *ptype = NULL, *stype = NULL; 944 int *ctype, *ptype = NULL, *stype = NULL;
1045 945
1046 ctype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), child); 946 ctype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), child);
1047 947
1048 if (parent) 948 if (parent)
1049 ptype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), parent); 949 ptype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), parent);
1050 950
1051 if (sibling) 951 if (sibling)
1052 stype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), sibling); 952 stype = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(ctree), sibling);
1053 953
1054 if (*ctype == EDIT_GC) { 954 if (*ctype == EDIT_BUDDY) {
1055 /* not that it particularly matters which order the connections
1056 * are in, but just for debugging sake, i guess.... */
1057 gc = (struct gaim_connection *)ctype;
1058 connections = g_slist_remove(connections, gc);
1059 if (sibling) {
1060 int pos;
1061 sc = (struct gaim_connection *)stype;
1062 pos = g_slist_index(connections, sc);
1063 if (pos)
1064 connections = g_slist_insert(connections, gc, pos);
1065 else
1066 connections = g_slist_prepend(connections, gc);
1067 } else
1068 connections = g_slist_append(connections, gc);
1069 redo_convo_menus(); /* this is evil */
1070 } else if (*ctype == EDIT_BUDDY) {
1071 /* we moved a buddy. hopefully we just changed groups or positions or something. 955 /* we moved a buddy. hopefully we just changed groups or positions or something.
1072 * if we changed connections, we copy the buddy to the new connection. if the new 956 * if we changed connections, we copy the buddy to the new connection. if the new
1073 * connection already had the buddy in its buddy list but in a different group, 957 * connection already had the buddy in its buddy list but in a different group,
1074 * we change the group that the buddy is in */ 958 * we change the group that the buddy is in */
1075 struct group *old_g, *new_g = (struct group *)ptype; 959 struct group *old_g, *new_g = (struct group *)ptype;
1076 struct buddy *s = NULL, *buddy = (struct buddy *)ctype; 960 struct buddy *s = NULL, *buddy = (struct buddy *)ctype;
1077 gboolean add = FALSE;
1078 int pos; 961 int pos;
1079 962
1080 if (buddy->gc != new_g->gc) { 963 old_g = find_group_by_buddy(buddy);
1081 /* we changed connections */ 964
1082 struct buddy *a; 965 old_g->members = g_slist_remove(old_g->members, buddy);
1083
1084 a = find_buddy(new_g->gc, buddy->name);
1085
1086 if (a) {
1087 /* the buddy is in the new connection, so we'll remove it from
1088 * its current group and add it to the proper group below */
1089 struct group *og;
1090 og = find_group_by_buddy(new_g->gc, buddy->name);
1091 og->members = g_slist_remove(og->members, a);
1092 } else {
1093 /* we don't have this buddy yet; let's add him */
1094 add = TRUE;
1095 }
1096 }
1097
1098 old_g = find_group_by_buddy(buddy->gc, buddy->name);
1099
1100 if (buddy->gc == new_g->gc)
1101 /* this is the same connection, so we'll remove it from its old group */
1102 old_g->members = g_slist_remove(old_g->members, buddy);
1103 966
1104 if (sibling) { 967 if (sibling) {
1105 s = (struct buddy *)stype; 968 s = (struct buddy *)stype;
1106 pos = g_slist_index(new_g->members, s); 969 pos = g_slist_index(new_g->members, s);
1107 if (pos) 970 if (pos)
1109 else 972 else
1110 new_g->members = g_slist_prepend(new_g->members, buddy); 973 new_g->members = g_slist_prepend(new_g->members, buddy);
1111 } else 974 } else
1112 new_g->members = g_slist_append(new_g->members, buddy); 975 new_g->members = g_slist_append(new_g->members, buddy);
1113 976
1114 /* 977 serv_move_buddy(buddy, old_g, new_g);
1115 * we do the add after it's added locally so that prpls can find it if necessary 978
1116 * JFIXME: Er, shouldn't the buddy be removed from the old server, as well? 979 gaim_blist_save();
1117 */
1118 if (add) {
1119 serv_add_buddy(new_g->gc, buddy->name);
1120 } else {
1121 serv_move_buddy(buddy, old_g, new_g);
1122 }
1123
1124 do_export(buddy->gc);
1125 if (buddy->gc != new_g->gc) {
1126 do_export(new_g->gc);
1127 build_edit_tree();
1128 }
1129 } else { /* group */ 980 } else { /* group */
1130 981
1131 /* move the group. if moving connections, copy the group, and each buddy in the 982 /* move the group. if moving connections, copy the group, and each buddy in the
1132 * group. if the buddy exists in the new connection, leave it where it is. */ 983 * group. if the buddy exists in the new connection, leave it where it is. */
1133 984
1134 struct group *g, *g2, *group; 985 struct group *g, *g2, *group;
1135 int pos; 986 int pos;
1136 987
1137 pc = (struct gaim_connection *)ptype;
1138 group = (struct group *)ctype; 988 group = (struct group *)ctype;
1139 989
1140 if (g_slist_length(connections) > 1) { 990 g = group;
1141 g = find_group(pc, group->name); 991
1142 if (!g) 992 groups = g_slist_remove(groups, g);
1143 g = add_group(pc, group->name); 993
1144 994 if (sibling) {
1145 pc->groups = g_slist_remove(pc->groups, g); 995 g2 = (struct group *)stype;
1146 996 pos = g_slist_index(groups, g2);
1147 if (sibling) { 997 if (pos)
1148 g2 = (struct group *)stype; 998 groups = g_slist_insert(groups, g, pos);
1149 pos = g_slist_index(pc->groups, g2); 999 else
1150 if (pos) 1000 groups = g_slist_prepend(groups, g);
1151 pc->groups = g_slist_insert(pc->groups, g, pos); 1001 } else
1152 else 1002 groups = g_slist_append(groups, g);
1153 pc->groups = g_slist_prepend(pc->groups, g); 1003
1154 } else 1004 gaim_blist_save();
1155 pc->groups = g_slist_append(pc->groups, g);
1156
1157 if (pc != group->gc) {
1158 GSList *mem;
1159 struct buddy *b;
1160 g2 = group;
1161
1162 mem = g2->members;
1163 while (mem) {
1164 b = (struct buddy *)mem->data;
1165 if (!find_buddy(pc, b->name))
1166 add_buddy(pc, g->name, b->name, b->alias);
1167 mem = mem->next;
1168 }
1169 }
1170 do_export(pc);
1171 } else {
1172 g = group;
1173 gc = g->gc;
1174
1175 gc->groups = g_slist_remove(gc->groups, g);
1176
1177 if (sibling) {
1178 g2 = (struct group *)stype;
1179 pos = g_slist_index(gc->groups, g2);
1180 if (pos)
1181 gc->groups = g_slist_insert(gc->groups, g, pos);
1182 else
1183 gc->groups = g_slist_prepend(gc->groups, g);
1184 } else
1185 gc->groups = g_slist_append(gc->groups, g);
1186 do_export(gc);
1187 }
1188 } 1005 }
1189 1006
1190 redo_buddy_list(); 1007 redo_buddy_list();
1191 update_num_groups(); 1008 update_num_groups();
1192 } 1009 }
1223 *pixmap = gdk_pixmap_create_from_xpm_d(widget->window, mask, &style->bg[GTK_STATE_NORMAL], xpm); 1040 *pixmap = gdk_pixmap_create_from_xpm_d(widget->window, mask, &style->bg[GTK_STATE_NORMAL], xpm);
1224 } 1041 }
1225 1042
1226 void build_edit_tree() 1043 void build_edit_tree()
1227 { 1044 {
1228 GtkCTreeNode *c = NULL, *p = NULL, *n; 1045 GtkCTreeNode *p = NULL, *n;
1229 GSList *con = connections;
1230 GSList *grp; 1046 GSList *grp;
1231 GSList *mem; 1047 GSList *mem;
1232 struct gaim_connection *z;
1233 struct group *g; 1048 struct group *g;
1234 struct buddy *b; 1049 struct buddy *b;
1235 char *text[1]; 1050 char *text[1];
1236 1051
1237 if (!blist) 1052 if (!blist)
1239 1054
1240 gtk_clist_freeze(GTK_CLIST(edittree)); 1055 gtk_clist_freeze(GTK_CLIST(edittree));
1241 gtk_clist_clear(GTK_CLIST(edittree)); 1056 gtk_clist_clear(GTK_CLIST(edittree));
1242 1057
1243 1058
1244 while (con) { 1059 grp = groups;
1245 z = (struct gaim_connection *)con->data; 1060
1246 1061 while (grp) {
1247 if (g_slist_length(connections) > 1) { 1062
1248 GdkPixmap *pixmap; 1063 g = (struct group *)grp->data;
1249 GdkBitmap *mask; 1064
1250 1065 text[0] = g->name;
1251 text[0] = z->username; 1066
1252 1067 p = gtk_ctree_insert_node(GTK_CTREE(edittree), NULL,
1253 create_prpl_icon(blist, z, &pixmap, &mask); 1068 NULL, text, 5, NULL, NULL, NULL, NULL, 0, 1);
1254 1069
1255 c = gtk_ctree_insert_node(GTK_CTREE(edittree), NULL, 1070 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), p, g);
1256 NULL, text, 3, pixmap, mask, pixmap, mask, 0, 1); 1071
1257 1072 n = NULL;
1258 gdk_pixmap_unref (pixmap); 1073
1259 gdk_bitmap_unref (mask); 1074 mem = g->members;
1260 1075
1261 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), c, z); 1076 while (mem) {
1262 } else 1077 char buf[256];
1263 c = NULL; 1078 b = (struct buddy *)mem->data;
1264 1079 if(b->user->gc) {
1265 grp = z->groups;
1266
1267 while (grp) {
1268
1269 g = (struct group *)grp->data;
1270
1271 text[0] = g->name;
1272
1273 p = gtk_ctree_insert_node(GTK_CTREE(edittree), c,
1274 NULL, text, 5, NULL, NULL, NULL, NULL, 0, 1);
1275
1276 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), p, g);
1277
1278 n = NULL;
1279
1280 mem = g->members;
1281
1282 while (mem) {
1283 char buf[256];
1284 b = (struct buddy *)mem->data;
1285 if (get_buddy_alias_only(b)) { 1080 if (get_buddy_alias_only(b)) {
1286 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b)); 1081 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b));
1287 text[0] = buf; 1082 text[0] = buf;
1288 } else 1083 } else
1289 text[0] = b->name; 1084 text[0] = b->name;
1290 1085
1291 n = gtk_ctree_insert_node(GTK_CTREE(edittree), 1086 n = gtk_ctree_insert_node(GTK_CTREE(edittree),
1292 p, NULL, text, 5, 1087 p, NULL, text, 5,
1293 NULL, NULL, NULL, NULL, 1, 1); 1088 NULL, NULL, NULL, NULL, 1, 1);
1294 1089
1295 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), n, b); 1090 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), n, b);
1296
1297 mem = mem->next;
1298
1299 } 1091 }
1300 grp = g_slist_next(grp); 1092
1301 } 1093 mem = mem->next;
1302 con = g_slist_next(con); 1094 }
1095 grp = g_slist_next(grp);
1303 } 1096 }
1304 1097
1305 gtk_clist_thaw(GTK_CLIST(edittree)); 1098 gtk_clist_thaw(GTK_CLIST(edittree));
1306 1099
1307 } 1100 }
1317 1110
1318 if (gs) 1111 if (gs)
1319 update_num_group(gs); 1112 update_num_group(gs);
1320 1113
1321 if (!blist) 1114 if (!blist)
1115 return;
1116
1117 if(!b->user->gc)
1322 return; 1118 return;
1323 1119
1324 p = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, g); 1120 p = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, g);
1325 if (get_buddy_alias_only(b)) { 1121 if (get_buddy_alias_only(b)) {
1326 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b)); 1122 g_snprintf(buf, sizeof(buf), "%s (%s)", b->name, get_buddy_alias(b));
1330 1126
1331 n = gtk_ctree_insert_node(GTK_CTREE(edittree), p, NULL, text, 5, NULL, NULL, NULL, NULL, 1, 1); 1127 n = gtk_ctree_insert_node(GTK_CTREE(edittree), p, NULL, text, 5, NULL, NULL, NULL, NULL, 1, 1);
1332 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), n, b); 1128 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), n, b);
1333 } 1129 }
1334 1130
1335 void ui_add_group(struct gaim_connection *gc, struct group *g) 1131 void ui_add_group(struct group *g)
1336 { 1132 {
1337 GtkCTreeNode *c = NULL, *p; 1133 GtkCTreeNode *p;
1338 char *text[1]; 1134 char *text[1];
1339 1135
1340 g->edittype = EDIT_GROUP; 1136 g->edittype = EDIT_GROUP;
1341 1137
1342 if (!blist) 1138 if (!blist)
1343 return; 1139 return;
1344 1140
1345 c = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, gc);
1346 text[0] = g->name; 1141 text[0] = g->name;
1347 p = gtk_ctree_insert_node(GTK_CTREE(edittree), c, NULL, text, 5, NULL, NULL, NULL, NULL, 0, 1); 1142 p = gtk_ctree_insert_node(GTK_CTREE(edittree), NULL, NULL, text, 5, NULL, NULL, NULL, NULL, 0, 1);
1348 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), p, g); 1143 gtk_ctree_node_set_row_data(GTK_CTREE(edittree), p, g);
1349 1144
1350 if (!(blist_options & OPT_BLIST_NO_MT_GRP) && !find_group_show(g->name)) 1145 if (!(blist_options & OPT_BLIST_NO_MT_GRP) && !find_group_show(g->name)
1146 && gaim_group_on_account(g, NULL))
1351 new_group_show(g->name); 1147 new_group_show(g->name);
1352 } 1148 }
1353 1149
1354 1150
1355 static void do_del_buddy(GtkWidget *w, GtkCTree *ctree) 1151 static void do_del_buddy(GtkWidget *w, GtkCTree *ctree)
1364 if (i) { 1160 if (i) {
1365 node = i->data; 1161 node = i->data;
1366 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node); 1162 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node);
1367 1163
1368 if (*type == EDIT_BUDDY) { 1164 if (*type == EDIT_BUDDY) {
1369 struct gaim_connection *gct;
1370 b = (struct buddy *)type; 1165 b = (struct buddy *)type;
1371 g = find_group_by_buddy(b->gc, b->name); 1166 g = find_group_by_buddy(b);
1372 gct = b->gc; 1167 serv_remove_buddy(b->user->gc, b->name, g->name);
1373 serv_remove_buddy(b->gc, b->name, g->name); 1168 remove_buddy(b);
1374 remove_buddy(b->gc, g, b); 1169 gaim_blist_save();
1375 do_export(gct);
1376 } else if (*type == EDIT_GROUP) { 1170 } else if (*type == EDIT_GROUP) {
1377 struct gaim_connection *gc = ((struct group *)type)->gc; 1171 remove_group((struct group *)type);
1378 remove_group(gc, (struct group *)type); 1172 gaim_blist_save();
1379 gtk_ctree_remove_node(GTK_CTREE(edittree), node);
1380 do_export(gc);
1381 } 1173 }
1382 1174
1383 } else { 1175 } else {
1384 /* Nothing selected. */ 1176 /* Nothing selected. */
1385 } 1177 }
1404 node = i->data; 1196 node = i->data;
1405 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node); 1197 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node);
1406 1198
1407 if (*type == EDIT_BUDDY) { 1199 if (*type == EDIT_BUDDY) {
1408 struct buddy *b = (struct buddy *)type; 1200 struct buddy *b = (struct buddy *)type;
1409 struct group *g = find_group_by_buddy(b->gc, b->name); 1201 struct group *g = find_group_by_buddy(b);
1410 grp = g->name; 1202 grp = g->name;
1411 gc = b->gc; 1203 gc = b->user->gc;
1412 } else if (*type == EDIT_GROUP) { 1204 } else if (*type == EDIT_GROUP) {
1413 struct group *g = (struct group *)type; 1205 struct group *g = (struct group *)type;
1414 grp = g->name; 1206 grp = g->name;
1415 gc = g->gc; 1207 if(g->members)
1208 gc = ((struct buddy *)g->members->data)->user->gc;
1209 else
1210 gc = connections->data;
1416 } else { 1211 } else {
1417 gc = (struct gaim_connection *)type; 1212 gc = (struct gaim_connection *)type;
1418 } 1213 }
1419 } 1214 }
1420 show_add_buddy(gc, NULL, grp, NULL); 1215 show_add_buddy(gc, NULL, grp, NULL);
1431 i = GTK_CLIST(edittree)->selection; 1226 i = GTK_CLIST(edittree)->selection;
1432 if (i) { 1227 if (i) {
1433 node = i->data; 1228 node = i->data;
1434 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node); 1229 type = (int *)gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node);
1435 if (*type == EDIT_BUDDY) 1230 if (*type == EDIT_BUDDY)
1436 gc = ((struct buddy *)type)->gc; 1231 gc = ((struct buddy *)type)->user->gc;
1437 else if (*type == EDIT_GROUP) 1232 else if (*type == EDIT_GROUP)
1438 gc = ((struct group *)type)->gc; 1233 gc = connections->data;
1439 else 1234 else
1440 gc = (struct gaim_connection *)type; 1235 gc = (struct gaim_connection *)type;
1441 } 1236 }
1442 show_add_group(gc); 1237 show_add_group(gc);
1443 } 1238 }
1625 } 1420 }
1626 1421
1627 static void new_bp_callback(GtkWidget *w, struct buddy *b) 1422 static void new_bp_callback(GtkWidget *w, struct buddy *b)
1628 { 1423 {
1629 if (b) 1424 if (b)
1630 show_new_bp(b->name, b->gc, b->idle, b->uc & UC_UNAVAILABLE, NULL); 1425 show_new_bp(b->name, b->user->gc, b->idle, b->uc & UC_UNAVAILABLE, NULL);
1631 else 1426 else
1632 show_new_bp(NULL, NULL, 0, 0, NULL); 1427 show_new_bp(NULL, NULL, 0, 0, NULL);
1633 } 1428 }
1634 1429
1635 static void edit_bp_callback(GtkWidget *w, struct buddy_pounce *b) 1430 static void edit_bp_callback(GtkWidget *w, struct buddy_pounce *b)
1756 return b; 1551 return b;
1757 } 1552 }
1758 1553
1759 static int group_number(char *group) 1554 static int group_number(char *group)
1760 { 1555 {
1761 GSList *c = connections;
1762 struct gaim_connection *g;
1763 GSList *m; 1556 GSList *m;
1764 struct group *p; 1557 struct group *p;
1765 int pos = 0; 1558 int pos = 0;
1766 1559
1767 while (c) { 1560 m = groups;
1768 g = (struct gaim_connection *)c->data; 1561 while (m) {
1769 m = g->groups; 1562 p = (struct group *)m->data;
1770 while (m) { 1563 if (!strcmp(p->name, group))
1771 p = (struct group *)m->data; 1564 return pos;
1772 if (!strcmp(p->name, group)) 1565 if (find_group_show(p->name))
1773 return pos; 1566 pos++;
1774 if (find_group_show(p->name)) 1567 m = m->next;
1775 pos++;
1776 m = m->next;
1777 }
1778 c = c->next;
1779 } 1568 }
1780 /* um..... we'll never get here */ 1569 /* um..... we'll never get here */
1781 return -1; 1570 return -1;
1782 } 1571 }
1783 1572
1784 static int buddy_number(char *group, char *buddy) 1573 static int buddy_number(char *group, char *buddy)
1785 { 1574 {
1786 GSList *c = connections;
1787 struct gaim_connection *g;
1788 struct group *p; 1575 struct group *p;
1789 GSList *z; 1576 GSList *z;
1790 struct buddy *b; 1577 struct buddy *b;
1791 int pos = 0; 1578 int pos = 0;
1792 char *tmp1 = g_strdup(normalize (buddy)); 1579 char *tmp1 = g_strdup(normalize (buddy));
1793 struct group_show *gs = find_group_show(group); 1580 struct group_show *gs = find_group_show(group);
1794 1581 struct buddy_show *bs;
1795 while (c) { 1582 GSList *seen = NULL;
1796 g = (struct gaim_connection *)c->data; 1583
1797 p = find_group(g, group); 1584 p = find_group(group);
1798 if (!p) { 1585 if(p) {
1799 c = c->next;
1800 continue;
1801 }
1802 z = p->members; 1586 z = p->members;
1803 while (z) { 1587 while (z) {
1804 b = (struct buddy *)z->data; 1588 b = (struct buddy *)z->data;
1805 if (!strcmp(tmp1, normalize (b->name))) { 1589 if (!strcmp(tmp1, normalize (b->name))) {
1806 g_free(tmp1); 1590 g_free(tmp1);
1591 g_slist_free(seen);
1807 return pos; 1592 return pos;
1808 } 1593 }
1809 if (find_buddy_show(gs, b->name)) 1594 if ((bs = find_buddy_show(gs, b->name))) {
1810 pos++; 1595 if(!g_slist_find(seen, bs)) {
1596 seen = g_slist_append(seen, bs);
1597 pos++;
1598 }
1599 }
1811 z = z->next; 1600 z = z->next;
1812 } 1601 }
1813 c = c->next;
1814 } 1602 }
1815 /* we shouldn't ever get here */ 1603 /* we shouldn't ever get here */
1816 debug_printf("got to bad place in buddy_number\n"); 1604 debug_printf("got to bad place in buddy_number\n");
1817 g_free(tmp1); 1605 g_free(tmp1);
1606 g_slist_free(seen);
1818 return -1; 1607 return -1;
1819 } 1608 }
1820 1609
1821 1610
1822 1611
2121 } else { 1910 } else {
2122 /* um.... what do we have to do here? just update the pixmap? */ 1911 /* um.... what do we have to do here? just update the pixmap? */
2123 GdkPixmap *pm; 1912 GdkPixmap *pm;
2124 GdkBitmap *bm; 1913 GdkBitmap *bm;
2125 gchar **xpm = NULL; 1914 gchar **xpm = NULL;
2126 struct buddy *light = find_buddy(b->connlist->data, b->name); 1915 struct gaim_connection *gc = b->connlist->data;
2127 if (((struct gaim_connection *)b->connlist->data)->prpl->list_icon) 1916 struct buddy *light = find_buddy(gc->user, b->name);
2128 xpm = 1917 if (gc->prpl->list_icon)
2129 (*((struct gaim_connection *)b->connlist->data)->prpl->list_icon)(light->uc); 1918 xpm = gc->prpl->list_icon(light->uc);
2130 if (xpm == NULL) 1919 if (xpm == NULL)
2131 xpm = (char **)no_icon_xpm; 1920 xpm = (char **)no_icon_xpm;
2132 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm); 1921 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm);
2133 gtk_widget_hide(b->pix); 1922 gtk_widget_hide(b->pix);
2134 gtk_pixmap_set(GTK_PIXMAP(b->pix), pm, bm); 1923 gtk_pixmap_set(GTK_PIXMAP(b->pix), pm, bm);
2231 char caps[256]; 2020 char caps[256];
2232 char alias[512]; 2021 char alias[512];
2233 char serv_alias[512]; 2022 char serv_alias[512];
2234 char *sotime = NULL, *itime; 2023 char *sotime = NULL, *itime;
2235 2024
2025 struct gaim_connection *gc;
2026
2236 int i; 2027 int i;
2237 2028
2238 time(&t); 2029 time(&t);
2239 if (!bs->connlist) 2030 if (!bs->connlist)
2240 return; 2031 return;
2241 b = find_buddy(bs->connlist->data, bs->name); 2032 gc = bs->connlist->data;
2033 b = find_buddy(gc->user, bs->name);
2242 if (!b) 2034 if (!b)
2243 return; 2035 return;
2244 ihrs = (t - b->idle) / 3600; 2036 ihrs = (t - b->idle) / 3600;
2245 imin = ((t - b->idle) / 60) % 60; 2037 imin = ((t - b->idle) / 60) % 60;
2246 2038
2346 } 2138 }
2347 } 2139 }
2348 2140
2349 void set_buddy(struct gaim_connection *gc, struct buddy *b) 2141 void set_buddy(struct gaim_connection *gc, struct buddy *b)
2350 { 2142 {
2351 struct group *g = find_group_by_buddy(gc, b->name); 2143 struct group *g = find_group_by_buddy(b);
2352 struct group_show *gs; 2144 struct group_show *gs;
2353 struct buddy_show *bs; 2145 struct buddy_show *bs;
2354 GdkPixmap *pm; 2146 GdkPixmap *pm;
2355 GdkBitmap *bm; 2147 GdkBitmap *bm;
2356 char **xpm = NULL; 2148 char **xpm = NULL;