Mercurial > pidgin
comparison libpurple/protocols/jabber/roster.c @ 27494:93a41017dca9
Various roster cleanups. Refs #7008.
I haven't tested it, but this may resolve the grouping/case problem (strcmp => purple_utf8_strcasecmp)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 07 Jun 2009 00:16:05 +0000 |
parents | 65b5bc543214 |
children | c8390dc125c1 |
comparison
equal
deleted
inserted
replaced
27493:65b5bc543214 | 27494:93a41017dca9 |
---|---|
50 purple_blist_remove_buddy(l->data); | 50 purple_blist_remove_buddy(l->data); |
51 | 51 |
52 g_slist_free(buddies); | 52 g_slist_free(buddies); |
53 } | 53 } |
54 | 54 |
55 static void add_purple_buddies_to_groups(JabberStream *js, const char *jid, | 55 static void add_purple_buddy_to_groups(JabberStream *js, const char *jid, |
56 const char *alias, GSList *groups) | 56 const char *alias, GSList *groups) |
57 { | 57 { |
58 GSList *buddies, *g2, *l; | 58 GSList *buddies, *l; |
59 gchar *my_bare_jid; | 59 gchar *my_bare_jid; |
60 GList *pool = NULL; | 60 GList *pool = NULL; |
61 | 61 |
62 buddies = purple_find_buddies(js->gc->account, jid); | 62 buddies = purple_find_buddies(js->gc->account, jid); |
63 | 63 |
64 g2 = groups; | |
65 | |
66 if(!groups) { | 64 if(!groups) { |
67 if(!buddies) | 65 if(!buddies) |
68 g2 = g_slist_append(g2, g_strdup(_("Buddies"))); | 66 groups = g_slist_append(groups, g_strdup(_("Buddies"))); |
69 else { | 67 else { |
68 /* TODO: What should we do here? Removing the local buddies | |
69 * is wrong, but so is letting the group state get out of sync with | |
70 * the server. | |
71 */ | |
70 g_slist_free(buddies); | 72 g_slist_free(buddies); |
71 return; | 73 return; |
72 } | 74 } |
73 } | 75 } |
74 | 76 |
76 | 78 |
77 while(buddies) { | 79 while(buddies) { |
78 PurpleBuddy *b = buddies->data; | 80 PurpleBuddy *b = buddies->data; |
79 PurpleGroup *g = purple_buddy_get_group(b); | 81 PurpleGroup *g = purple_buddy_get_group(b); |
80 | 82 |
81 buddies = g_slist_remove(buddies, b); | 83 buddies = g_slist_delete_link(buddies, buddies); |
82 | 84 |
83 if((l = g_slist_find_custom(g2, purple_group_get_name(g), (GCompareFunc)strcmp))) { | 85 /* XMPP groups are case-sensitive, but libpurple groups are |
86 * case-insensitive. We treat a buddy in both "Friends" and "friends" | |
87 * as only being in one group, so if we push changes about the buddy | |
88 * to the server, the buddy will be dropped from one of the groups. | |
89 */ | |
90 if((l = g_slist_find_custom(groups, purple_group_get_name(g), (GCompareFunc)purple_utf8_strcasecmp))) { | |
91 /* The buddy is already on the local list. Update info. */ | |
84 const char *servernick, *balias; | 92 const char *servernick, *balias; |
85 | 93 |
86 /* Previously stored serverside / buddy-supplied alias */ | 94 /* Previously stored serverside / buddy-supplied alias */ |
87 if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"))) | 95 if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"))) |
88 serv_got_alias(js->gc, jid, servernick); | 96 serv_got_alias(js->gc, jid, servernick); |
89 | 97 |
90 /* Alias from our roster retrieval */ | 98 /* Alias from our roster retrieval */ |
91 balias = purple_buddy_get_local_buddy_alias(b); | 99 balias = purple_buddy_get_local_buddy_alias(b); |
92 if(alias && (!balias || strcmp(balias, alias))) | 100 if(alias && !purple_strequal(alias, balias)) |
93 purple_serv_got_private_alias(js->gc, jid, alias); | 101 purple_serv_got_private_alias(js->gc, jid, alias); |
94 g_free(l->data); | 102 g_free(l->data); |
95 g2 = g_slist_delete_link(g2, l); | 103 groups = g_slist_delete_link(groups, l); |
96 } else { | 104 } else { |
105 /* This buddy isn't in the group on the server anymore */ | |
97 pool = g_list_prepend(pool, b); | 106 pool = g_list_prepend(pool, b); |
98 } | 107 } |
99 } | 108 } |
100 | 109 |
101 while(g2) { | 110 while(groups) { |
102 PurpleGroup *g = purple_find_group(g2->data); | 111 PurpleGroup *g = purple_find_group(groups->data); |
103 PurpleBuddy *b = NULL; | 112 PurpleBuddy *b = NULL; |
104 | 113 |
114 /* If there are buddies we would otherwise delete, move them to | |
115 * the new group (instead of deleting them below) | |
116 */ | |
105 if (pool) { | 117 if (pool) { |
106 b = pool->data; | 118 b = pool->data; |
107 pool = g_list_delete_link(pool, pool); | 119 pool = g_list_delete_link(pool, pool); |
108 } else { | 120 } else { |
109 b = purple_buddy_new(js->gc->account, jid, alias); | 121 b = purple_buddy_new(js->gc->account, jid, alias); |
110 } | 122 } |
111 | 123 |
112 if(!g) { | 124 if(!g) { |
113 g = purple_group_new(g2->data); | 125 g = purple_group_new(groups->data); |
114 purple_blist_add_group(g, NULL); | 126 purple_blist_add_group(g, NULL); |
115 } | 127 } |
116 | 128 |
117 purple_blist_add_buddy(b, NULL, g, NULL); | 129 purple_blist_add_buddy(b, NULL, g, NULL); |
118 purple_blist_alias_buddy(b, alias); | 130 purple_blist_alias_buddy(b, alias); |
129 gpresence = purple_account_get_presence(account); | 141 gpresence = purple_account_get_presence(account); |
130 status = purple_presence_get_active_status(gpresence); | 142 status = purple_presence_get_active_status(gpresence); |
131 jabber_presence_fake_to_self(js, status); | 143 jabber_presence_fake_to_self(js, status); |
132 } | 144 } |
133 | 145 |
134 g_free(g2->data); | 146 g_free(groups->data); |
135 g2 = g_slist_delete_link(g2, g2); | 147 groups = g_slist_delete_link(groups, groups); |
136 } | 148 } |
137 | 149 |
150 /* Remove this person from all the groups they're no longer in on the | |
151 * server */ | |
138 while (pool) { | 152 while (pool) { |
139 PurpleBuddy *b = pool->data; | 153 PurpleBuddy *b = pool->data; |
140 purple_blist_remove_buddy(b); | 154 purple_blist_remove_buddy(b); |
141 pool = g_list_delete_link(pool, pool); | 155 pool = g_list_delete_link(pool, pool); |
142 } | 156 } |
203 | 217 |
204 if(jb->subscription == JABBER_SUB_REMOVE) { | 218 if(jb->subscription == JABBER_SUB_REMOVE) { |
205 remove_purple_buddies(js, jid); | 219 remove_purple_buddies(js, jid); |
206 } else { | 220 } else { |
207 GSList *groups = NULL; | 221 GSList *groups = NULL; |
222 gboolean seen_empty = FALSE; | |
208 | 223 |
209 if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) | 224 if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) |
210 if (!jabber_google_roster_incoming(js, item)) | 225 if (!jabber_google_roster_incoming(js, item)) |
211 continue; | 226 continue; |
212 | 227 |
213 for(group = xmlnode_get_child(item, "group"); group; group = xmlnode_get_next_twin(group)) { | 228 for(group = xmlnode_get_child(item, "group"); group; group = xmlnode_get_next_twin(group)) { |
214 char *group_name; | 229 char *group_name = xmlnode_get_data(group); |
215 | 230 |
216 if(!(group_name = xmlnode_get_data(group))) | 231 if (!group_name && !seen_empty) { |
217 group_name = g_strdup(""); | 232 group_name = g_strdup(""); |
218 | 233 seen_empty = TRUE; |
219 if (g_slist_find_custom(groups, group_name, (GCompareFunc)purple_utf8_strcasecmp) == NULL) | 234 } |
220 groups = g_slist_append(groups, group_name); | 235 |
221 else | 236 groups = g_slist_prepend(groups, group_name); |
222 g_free(group_name); | |
223 } | 237 } |
224 add_purple_buddies_to_groups(js, jid, name, groups); | 238 |
239 add_purple_buddy_to_groups(js, jid, name, groups); | |
225 } | 240 } |
226 } | 241 } |
227 | 242 |
228 g_free(own_jid); | 243 g_free(own_jid); |
229 js->currently_parsing_roster_push = FALSE; | 244 js->currently_parsing_roster_push = FALSE; |