comparison src/blist.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
196 g_free(buddy->name); 196 g_free(buddy->name);
197 buddy->name = g_strdup(name); 197 buddy->name = g_strdup(name);
198 if (ops) 198 if (ops)
199 ops->update(gaimbuddylist, (GaimBlistNode*)buddy); 199 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
200 } 200 }
201
202 void gaim_blist_alias_chat(struct chat *chat, const char *alias)
203 {
204 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
205
206 if(!alias || !strlen(alias))
207 return;
208
209 g_free(chat->alias);
210 chat->alias = g_strdup(alias);
211 if(ops)
212 ops->update(gaimbuddylist, (GaimBlistNode*)chat);
213 }
214
201 void gaim_blist_alias_buddy (struct buddy *buddy, const char *alias) 215 void gaim_blist_alias_buddy (struct buddy *buddy, const char *alias)
202 { 216 {
203 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; 217 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
204 struct gaim_conversation *conv; 218 struct gaim_conversation *conv;
205 219
225 g_free(group->name); 239 g_free(group->name);
226 group->name = g_strdup(name); 240 group->name = g_strdup(name);
227 if (ops) 241 if (ops)
228 ops->update(gaimbuddylist, (GaimBlistNode*)group); 242 ops->update(gaimbuddylist, (GaimBlistNode*)group);
229 } 243 }
244
245 struct chat *gaim_chat_new(struct gaim_account *account, const char *alias, GHashTable *components)
246 {
247 struct chat *chat;
248 struct gaim_blist_ui_ops *ops;
249
250 if(!alias || !strlen(alias) || !components)
251 return NULL;
252
253 chat = g_new0(struct chat, 1);
254 chat->account = account;
255 chat->alias = g_strdup(alias);
256 chat->components = components;
257
258 ((GaimBlistNode*)chat)->type = GAIM_BLIST_CHAT_NODE;
259
260 ops = gaim_get_blist_ui_ops();
261
262 if (ops != NULL && ops->new_node != NULL)
263 ops->new_node((GaimBlistNode *)chat);
264
265 return chat;
266 }
267
230 struct buddy *gaim_buddy_new(struct gaim_account *account, const char *screenname, const char *alias) 268 struct buddy *gaim_buddy_new(struct gaim_account *account, const char *screenname, const char *alias)
231 { 269 {
232 struct buddy *b; 270 struct buddy *b;
233 struct gaim_blist_ui_ops *ops; 271 struct gaim_blist_ui_ops *ops;
234 272
244 if (ops != NULL && ops->new_node != NULL) 282 if (ops != NULL && ops->new_node != NULL)
245 ops->new_node((GaimBlistNode *)b); 283 ops->new_node((GaimBlistNode *)b);
246 284
247 return b; 285 return b;
248 } 286 }
287 void gaim_blist_add_chat(struct chat *chat, struct group *group, GaimBlistNode *node)
288 {
289 GaimBlistNode *n = node, *cnode = (GaimBlistNode*)chat;
290 struct group *g = group;
291 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
292 gboolean save = FALSE;
293
294 if (!n) {
295 if (!g) {
296 g = gaim_group_new(_("Chats"));
297 gaim_blist_add_group(g, NULL);
298 }
299 n = gaim_blist_get_last_child((GaimBlistNode*)g);
300 } else {
301 g = (struct group*)n->parent;
302 }
303
304 /* if we're moving to overtop of ourselves, do nothing */
305 if(cnode == n)
306 return;
307
308 if (cnode->parent) {
309 /* This chat was already in the list and is
310 * being moved.
311 */
312 if(cnode->next)
313 cnode->next->prev = cnode->prev;
314 if(cnode->prev)
315 cnode->prev->next = cnode->next;
316 if(cnode->parent->child == cnode)
317 cnode->parent->child = cnode->next;
318
319 ops->remove(gaimbuddylist, cnode);
320
321 save = TRUE;
322 }
323
324 if (n) {
325 if(n->next)
326 n->next->prev = cnode;
327 cnode->next = n->next;
328 cnode->prev = n;
329 cnode->parent = n->parent;
330 n->next = cnode;
331 } else {
332 ((GaimBlistNode*)g)->child = cnode;
333 cnode->next = cnode->prev = NULL;
334 cnode->parent = (GaimBlistNode*)g;
335 }
336
337 if (ops)
338 ops->update(gaimbuddylist, (GaimBlistNode*)cnode);
339 if (save)
340 gaim_blist_save();
341 }
342
249 void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node) 343 void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node)
250 { 344 {
251 GaimBlistNode *n = node, *bnode = (GaimBlistNode*)buddy; 345 GaimBlistNode *n = node, *bnode = (GaimBlistNode*)buddy;
252 struct group *g = group; 346 struct group *g = group;
253 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; 347 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
400 g_free(buddy->name); 494 g_free(buddy->name);
401 g_free(buddy->alias); 495 g_free(buddy->alias);
402 g_free(buddy); 496 g_free(buddy);
403 } 497 }
404 498
499 void gaim_blist_remove_chat (struct chat *chat)
500 {
501 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
502
503 GaimBlistNode *gnode, *node = (GaimBlistNode*)chat;
504 struct group *group;
505
506 gnode = node->parent;
507 group = (struct group *)gnode;
508
509 if(gnode->child == node)
510 gnode->child = node->next;
511 if (node->prev)
512 node->prev->next = node->next;
513 if (node->next)
514 node->next->prev = node->prev;
515
516 ops->remove(gaimbuddylist, node);
517 g_hash_table_destroy(chat->components);
518 g_free(chat->alias);
519 g_free(chat);
520 }
521
405 void gaim_blist_remove_group (struct group *group) 522 void gaim_blist_remove_group (struct group *group)
406 { 523 {
407 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; 524 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
408 GaimBlistNode *node = (GaimBlistNode*)group; 525 GaimBlistNode *node = (GaimBlistNode*)group;
409 526
468 585
469 group = gaimbuddylist->root; 586 group = gaimbuddylist->root;
470 while (group) { 587 while (group) {
471 buddy = group->child; 588 buddy = group->child;
472 while (buddy) { 589 while (buddy) {
473 if (!gaim_utf8_strcasecmp(normalize(((struct buddy*)buddy)->name), norm_name) && account == ((struct buddy*)buddy)->account) { 590 if(GAIM_BLIST_NODE_IS_BUDDY(buddy)) {
474 g_free(norm_name); 591 if (!gaim_utf8_strcasecmp(normalize(((struct buddy*)buddy)->name), norm_name) && account == ((struct buddy*)buddy)->account) {
475 return (struct buddy*)buddy; 592 g_free(norm_name);
593 return (struct buddy*)buddy;
594 }
476 } 595 }
477 buddy = buddy->next; 596 buddy = buddy->next;
478 } 597 }
479 group = group->next; 598 group = group->next;
480 } 599 }
513 child = child->next; 632 child = child->next;
514 } 633 }
515 return l; 634 return l;
516 } 635 }
517 636
637 void gaim_blist_add_account(struct gaim_account *account)
638 {
639 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
640 GaimBlistNode *group, *buddy;
641
642 if(!gaimbuddylist)
643 return;
644
645 for(group = gaimbuddylist->root; group; group = group->next) {
646 if(!GAIM_BLIST_NODE_IS_GROUP(group))
647 continue;
648 for(buddy = group->child; buddy; buddy = buddy->next) {
649 if(GAIM_BLIST_NODE_IS_BUDDY(buddy)) {
650 if (account == ((struct buddy*)buddy)->account) {
651 if(ops)
652 ops->update(gaimbuddylist, buddy);
653 }
654 } else if(GAIM_BLIST_NODE_IS_CHAT(buddy)) {
655 if (account == ((struct chat*)buddy)->account) {
656 if(ops)
657 ops->update(gaimbuddylist, buddy);
658 }
659 }
660 }
661 }
662 }
663
518 void gaim_blist_remove_account(struct gaim_account *account) 664 void gaim_blist_remove_account(struct gaim_account *account)
519 { 665 {
520 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; 666 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
521 GaimBlistNode *group = gaimbuddylist->root; 667 GaimBlistNode *group, *buddy;
522 GaimBlistNode *buddy; 668
523 if (!gaimbuddylist) 669 if (!gaimbuddylist)
524 return; 670 return;
525 while (group) { 671
526 buddy = group->child; 672 for(group = gaimbuddylist->root; group; group = group->next) {
527 while (buddy) { 673 if(!GAIM_BLIST_NODE_IS_GROUP(group))
528 if (account == ((struct buddy*)buddy)->account) { 674 continue;
529 ((struct buddy*)buddy)->present = GAIM_BUDDY_OFFLINE; 675 for(buddy = group->child; buddy; buddy = buddy->next) {
530 if(ops) 676 if(GAIM_BLIST_NODE_IS_BUDDY(buddy)) {
531 ops->remove(gaimbuddylist, buddy); 677 if (account == ((struct buddy*)buddy)->account) {
532 } 678 ((struct buddy*)buddy)->present = GAIM_BUDDY_OFFLINE;
533 buddy = buddy->next; 679 if(ops)
534 } 680 ops->remove(gaimbuddylist, buddy);
535 group = group->next; 681 }
682 } else if(GAIM_BLIST_NODE_IS_CHAT(buddy)) {
683 if (account == ((struct chat*)buddy)->account) {
684 if(ops)
685 ops->remove(gaimbuddylist, buddy);
686 }
687 }
688 }
536 } 689 }
537 } 690 }
538 691
539 void parse_toc_buddy_list(struct gaim_account *account, char *config) 692 void parse_toc_buddy_list(struct gaim_account *account, char *config)
540 { 693 {
916 1069
917 static char *blist_parser_group_name = NULL; 1070 static char *blist_parser_group_name = NULL;
918 static char *blist_parser_person_name = NULL; 1071 static char *blist_parser_person_name = NULL;
919 static char *blist_parser_account_name = NULL; 1072 static char *blist_parser_account_name = NULL;
920 static int blist_parser_account_protocol = 0; 1073 static int blist_parser_account_protocol = 0;
1074 static char *blist_parser_chat_alias = NULL;
1075 static char *blist_parser_component_name = NULL;
1076 static char *blist_parser_component_value = NULL;
921 static char *blist_parser_buddy_name = NULL; 1077 static char *blist_parser_buddy_name = NULL;
922 static char *blist_parser_buddy_alias = NULL; 1078 static char *blist_parser_buddy_alias = NULL;
923 static char *blist_parser_setting_name = NULL; 1079 static char *blist_parser_setting_name = NULL;
924 static char *blist_parser_setting_value = NULL; 1080 static char *blist_parser_setting_value = NULL;
925 static GHashTable *blist_parser_buddy_settings = NULL; 1081 static GHashTable *blist_parser_buddy_settings = NULL;
926 static GHashTable *blist_parser_group_settings = NULL; 1082 static GHashTable *blist_parser_group_settings = NULL;
1083 static GHashTable *blist_parser_chat_components = NULL;
927 static int blist_parser_privacy_mode = 0; 1084 static int blist_parser_privacy_mode = 0;
928 static GList *tag_stack = NULL; 1085 static GList *tag_stack = NULL;
929 enum { 1086 enum {
930 BLIST_TAG_GAIM, 1087 BLIST_TAG_GAIM,
931 BLIST_TAG_BLIST, 1088 BLIST_TAG_BLIST,
932 BLIST_TAG_GROUP, 1089 BLIST_TAG_GROUP,
1090 BLIST_TAG_CHAT,
1091 BLIST_TAG_COMPONENT,
933 BLIST_TAG_PERSON, 1092 BLIST_TAG_PERSON,
934 BLIST_TAG_BUDDY, 1093 BLIST_TAG_BUDDY,
935 BLIST_TAG_NAME, 1094 BLIST_TAG_NAME,
936 BLIST_TAG_ALIAS, 1095 BLIST_TAG_ALIAS,
937 BLIST_TAG_SETTING, 1096 BLIST_TAG_SETTING,
965 } 1124 }
966 if(blist_parser_group_name) { 1125 if(blist_parser_group_name) {
967 struct group *g = gaim_group_new(blist_parser_group_name); 1126 struct group *g = gaim_group_new(blist_parser_group_name);
968 gaim_blist_add_group(g,NULL); 1127 gaim_blist_add_group(g,NULL);
969 } 1128 }
1129 } else if(!strcmp(element_name, "chat")) {
1130 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_CHAT));
1131 for(i=0; attribute_names[i]; i++) {
1132 if(!strcmp(attribute_names[i], "account")) {
1133 g_free(blist_parser_account_name);
1134 blist_parser_account_name = g_strdup(attribute_values[i]);
1135 } else if(!strcmp(attribute_names[i], "protocol")) {
1136 blist_parser_account_protocol = atoi(attribute_values[i]);
1137 }
1138 }
970 } else if(!strcmp(element_name, "person")) { 1139 } else if(!strcmp(element_name, "person")) {
971 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PERSON)); 1140 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PERSON));
972 for(i=0; attribute_names[i]; i++) { 1141 for(i=0; attribute_names[i]; i++) {
973 if(!strcmp(attribute_names[i], "name")) { 1142 if(!strcmp(attribute_names[i], "name")) {
974 g_free(blist_parser_person_name); 1143 g_free(blist_parser_person_name);
995 if(!strcmp(attribute_names[i], "name")) { 1164 if(!strcmp(attribute_names[i], "name")) {
996 g_free(blist_parser_setting_name); 1165 g_free(blist_parser_setting_name);
997 blist_parser_setting_name = g_strdup(attribute_values[i]); 1166 blist_parser_setting_name = g_strdup(attribute_values[i]);
998 } 1167 }
999 } 1168 }
1169 } else if(!strcmp(element_name, "component")) {
1170 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_COMPONENT));
1171 for(i=0; attribute_names[i]; i++) {
1172 if(!strcmp(attribute_names[i], "name")) {
1173 g_free(blist_parser_component_name);
1174 blist_parser_component_name = g_strdup(attribute_values[i]);
1175 }
1176 }
1177
1000 } else if(!strcmp(element_name, "privacy")) { 1178 } else if(!strcmp(element_name, "privacy")) {
1001 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PRIVACY)); 1179 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_PRIVACY));
1002 } else if(!strcmp(element_name, "account")) { 1180 } else if(!strcmp(element_name, "account")) {
1003 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_ACCOUNT)); 1181 tag_stack = g_list_prepend(tag_stack, GINT_TO_POINTER(BLIST_TAG_ACCOUNT));
1004 for(i=0; attribute_names[i]; i++) { 1182 for(i=0; attribute_names[i]; i++) {
1032 g_hash_table_destroy(g->settings); 1210 g_hash_table_destroy(g->settings);
1033 g->settings = blist_parser_group_settings; 1211 g->settings = blist_parser_group_settings;
1034 } 1212 }
1035 tag_stack = g_list_delete_link(tag_stack, tag_stack); 1213 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1036 blist_parser_group_settings = NULL; 1214 blist_parser_group_settings = NULL;
1215 } else if(!strcmp(element_name, "chat")) {
1216 struct gaim_account *account = gaim_account_find(blist_parser_account_name,
1217 blist_parser_account_protocol);
1218 if(account && blist_parser_chat_alias) {
1219 struct chat *chat = gaim_chat_new(account, blist_parser_chat_alias, blist_parser_chat_components);
1220 struct group *g = gaim_find_group(blist_parser_group_name);
1221 gaim_blist_add_chat(chat,g,NULL);
1222 }
1223 g_free(blist_parser_chat_alias);
1224 blist_parser_chat_alias = NULL;
1225 g_free(blist_parser_account_name);
1226 blist_parser_account_name = NULL;
1227 blist_parser_chat_components = NULL;
1228 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1037 } else if(!strcmp(element_name, "person")) { 1229 } else if(!strcmp(element_name, "person")) {
1038 g_free(blist_parser_person_name); 1230 g_free(blist_parser_person_name);
1039 blist_parser_person_name = NULL; 1231 blist_parser_person_name = NULL;
1040 tag_stack = g_list_delete_link(tag_stack, tag_stack); 1232 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1041 } else if(!strcmp(element_name, "buddy")) { 1233 } else if(!strcmp(element_name, "buddy")) {
1060 tag_stack = g_list_delete_link(tag_stack, tag_stack); 1252 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1061 } else if(!strcmp(element_name, "name")) { 1253 } else if(!strcmp(element_name, "name")) {
1062 tag_stack = g_list_delete_link(tag_stack, tag_stack); 1254 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1063 } else if(!strcmp(element_name, "alias")) { 1255 } else if(!strcmp(element_name, "alias")) {
1064 tag_stack = g_list_delete_link(tag_stack, tag_stack); 1256 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1257 } else if(!strcmp(element_name, "component")) {
1258 if(!blist_parser_chat_components)
1259 blist_parser_chat_components = g_hash_table_new_full(g_str_hash,
1260 g_str_equal, g_free, g_free);
1261 if(blist_parser_component_name && blist_parser_component_value) {
1262 g_hash_table_replace(blist_parser_chat_components,
1263 g_strdup(blist_parser_component_name),
1264 g_strdup(blist_parser_component_value));
1265 }
1266 g_free(blist_parser_component_name);
1267 g_free(blist_parser_component_value);
1268 blist_parser_component_name = NULL;
1269 blist_parser_component_value = NULL;
1270 tag_stack = g_list_delete_link(tag_stack, tag_stack);
1065 } else if(!strcmp(element_name, "setting")) { 1271 } else if(!strcmp(element_name, "setting")) {
1066 if(GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_BUDDY) { 1272 if(GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_BUDDY) {
1067 if(!blist_parser_buddy_settings) 1273 if(!blist_parser_buddy_settings)
1068 blist_parser_buddy_settings = g_hash_table_new_full(g_str_hash, 1274 blist_parser_buddy_settings = g_hash_table_new_full(g_str_hash,
1069 g_str_equal, g_free, g_free); 1275 g_str_equal, g_free, g_free);
1127 switch(GPOINTER_TO_INT(tag_stack->data)) { 1333 switch(GPOINTER_TO_INT(tag_stack->data)) {
1128 case BLIST_TAG_NAME: 1334 case BLIST_TAG_NAME:
1129 blist_parser_buddy_name = g_strndup(text, text_len); 1335 blist_parser_buddy_name = g_strndup(text, text_len);
1130 break; 1336 break;
1131 case BLIST_TAG_ALIAS: 1337 case BLIST_TAG_ALIAS:
1132 blist_parser_buddy_alias = g_strndup(text, text_len); 1338 if(tag_stack->next &&
1339 GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_BUDDY)
1340 blist_parser_buddy_alias = g_strndup(text, text_len);
1341 else if(tag_stack->next &&
1342 GPOINTER_TO_INT(tag_stack->next->data) == BLIST_TAG_CHAT)
1343 blist_parser_chat_alias = g_strndup(text, text_len);
1133 break; 1344 break;
1134 case BLIST_TAG_PERMIT: 1345 case BLIST_TAG_PERMIT:
1135 case BLIST_TAG_BLOCK: 1346 case BLIST_TAG_BLOCK:
1136 case BLIST_TAG_IGNORE: 1347 case BLIST_TAG_IGNORE:
1137 blist_parser_buddy_name = g_strndup(text, text_len); 1348 blist_parser_buddy_name = g_strndup(text, text_len);
1349 break;
1350 case BLIST_TAG_COMPONENT:
1351 blist_parser_component_value = g_strndup(text, text_len);
1138 break; 1352 break;
1139 case BLIST_TAG_SETTING: 1353 case BLIST_TAG_SETTING:
1140 blist_parser_setting_value = g_strndup(text, text_len); 1354 blist_parser_setting_value = g_strndup(text, text_len);
1141 break; 1355 break;
1142 default: 1356 default:
1274 1488
1275 key_val = g_markup_escape_text(key, -1); 1489 key_val = g_markup_escape_text(key, -1);
1276 data_val = g_markup_escape_text(data, -1); 1490 data_val = g_markup_escape_text(data, -1);
1277 1491
1278 fprintf(file, "\t\t\t\t\t<setting name=\"%s\">%s</setting>\n", key_val, 1492 fprintf(file, "\t\t\t\t\t<setting name=\"%s\">%s</setting>\n", key_val,
1493 data_val);
1494 g_free(key_val);
1495 g_free(data_val);
1496 }
1497
1498 static void blist_print_chat_components(gpointer key, gpointer data,
1499 gpointer user_data) {
1500 char *key_val;
1501 char *data_val;
1502 FILE *file = user_data;
1503
1504 if(!key || !data)
1505 return;
1506
1507 key_val = g_markup_escape_text(key, -1);
1508 data_val = g_markup_escape_text(data, -1);
1509
1510 fprintf(file, "\t\t\t\t<component name=\"%s\">%s</component>\n", key_val,
1279 data_val); 1511 data_val);
1280 g_free(key_val); 1512 g_free(key_val);
1281 g_free(data_val); 1513 g_free(data_val);
1282 } 1514 }
1283 1515
1297 if(!exp_acct || gaim_group_on_account(group, exp_acct)) { 1529 if(!exp_acct || gaim_group_on_account(group, exp_acct)) {
1298 char *group_name = g_markup_escape_text(group->name, -1); 1530 char *group_name = g_markup_escape_text(group->name, -1);
1299 fprintf(file, "\t\t<group name=\"%s\">\n", group_name); 1531 fprintf(file, "\t\t<group name=\"%s\">\n", group_name);
1300 g_hash_table_foreach(group->settings, blist_print_group_settings, file); 1532 g_hash_table_foreach(group->settings, blist_print_group_settings, file);
1301 for(bnode = gnode->child; bnode; bnode = bnode->next) { 1533 for(bnode = gnode->child; bnode; bnode = bnode->next) {
1302 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) 1534 if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) {
1303 continue; 1535 bud = (struct buddy *)bnode;
1304 bud = (struct buddy *)bnode; 1536 if(!exp_acct || bud->account == exp_acct) {
1305 if(!exp_acct || bud->account == exp_acct) { 1537 char *bud_name = g_markup_escape_text(bud->name, -1);
1306 char *bud_name = g_markup_escape_text(bud->name, -1); 1538 char *bud_alias = NULL;
1307 char *bud_alias = NULL; 1539 char *acct_name = g_markup_escape_text(bud->account->username, -1);
1308 char *acct_name = g_markup_escape_text(bud->account->username, -1); 1540 if(bud->alias)
1309 if(bud->alias) 1541 bud_alias= g_markup_escape_text(bud->alias, -1);
1310 bud_alias= g_markup_escape_text(bud->alias, -1); 1542 fprintf(file, "\t\t\t<person name=\"%s\">\n",
1311 fprintf(file, "\t\t\t<person name=\"%s\">\n", 1543 bud_alias ? bud_alias : bud_name);
1312 bud_alias ? bud_alias : bud_name); 1544 fprintf(file, "\t\t\t\t<buddy protocol=\"%d\" "
1313 fprintf(file, "\t\t\t\t<buddy protocol=\"%d\" " 1545 "account=\"%s\">\n", bud->account->protocol,
1314 "account=\"%s\">\n", bud->account->protocol, 1546 acct_name);
1315 acct_name); 1547 fprintf(file, "\t\t\t\t\t<name>%s</name>\n", bud_name);
1316 fprintf(file, "\t\t\t\t\t<name>%s</name>\n", bud_name); 1548 if(bud_alias) {
1317 if(bud_alias) { 1549 fprintf(file, "\t\t\t\t\t<alias>%s</alias>\n",
1318 fprintf(file, "\t\t\t\t\t<alias>%s</alias>\n", 1550 bud_alias);
1319 bud_alias); 1551 }
1552 g_hash_table_foreach(bud->settings,
1553 blist_print_buddy_settings, file);
1554 fprintf(file, "\t\t\t\t</buddy>\n");
1555 fprintf(file, "\t\t\t</person>\n");
1556 g_free(bud_name);
1557 g_free(bud_alias);
1558 g_free(acct_name);
1320 } 1559 }
1321 g_hash_table_foreach(bud->settings, 1560 } else if(GAIM_BLIST_NODE_IS_CHAT(bnode)) {
1322 blist_print_buddy_settings, file); 1561 struct chat *chat = (struct chat *)bnode;
1323 fprintf(file, "\t\t\t\t</buddy>\n"); 1562 if(!exp_acct || chat->account == exp_acct) {
1324 fprintf(file, "\t\t\t</person>\n"); 1563 char *chat_alias = g_markup_escape_text(chat->alias, -1);
1325 g_free(bud_name); 1564 char *acct_name = g_markup_escape_text(chat->account->username, -1);
1326 g_free(bud_alias); 1565 fprintf(file, "\t\t\t<chat protocol=\"%d\" account=\"%s\">\n", chat->account->protocol, acct_name);
1327 g_free(acct_name); 1566 fprintf(file, "\t\t\t\t<alias>%s</alias>\n", chat_alias);
1567 g_hash_table_foreach(chat->components,
1568 blist_print_chat_components, file);
1569 fprintf(file, "\t\t\t</chat>\n");
1570 }
1328 } 1571 }
1329 } 1572 }
1330 fprintf(file, "\t\t</group>\n"); 1573 fprintf(file, "\t\t</group>\n");
1331 g_free(group_name); 1574 g_free(group_name);
1332 } 1575 }
1517 for(node = group->node.child; node; node = node->next) { 1760 for(node = group->node.child; node; node = node->next) {
1518 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { 1761 if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
1519 struct buddy *b = (struct buddy *)node; 1762 struct buddy *b = (struct buddy *)node;
1520 if(b->account->gc || offline) 1763 if(b->account->gc || offline)
1521 count++; 1764 count++;
1765 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
1766 struct chat *chat = (struct chat *)node;
1767 if(chat->account->gc || offline)
1768 count++;
1522 } 1769 }
1523 } 1770 }
1524 1771
1525 return count; 1772 return count;
1526 } 1773 }
1535 for(node = group->node.child; node; node = node->next) { 1782 for(node = group->node.child; node; node = node->next) {
1536 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { 1783 if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
1537 struct buddy *b = (struct buddy *)node; 1784 struct buddy *b = (struct buddy *)node;
1538 if(GAIM_BUDDY_IS_ONLINE(b)) 1785 if(GAIM_BUDDY_IS_ONLINE(b))
1539 count++; 1786 count++;
1787 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) {
1788 count++;
1540 } 1789 }
1541 } 1790 }
1542 1791
1543 return count; 1792 return count;
1544 } 1793 }