Mercurial > pidgin
comparison src/blist.c @ 9787:904b757835ca
[gaim-migrate @ 10655]
after an utter failure to get comments on this since it was updated, and
thinking that the functionality is worth having, i present to you:
" This is a patch to blist.c and blist.h to modify the
GaimBuddy structure to add a field for flags. It also
adds a single flag GAIM_BUDDY_NO_SAVE, which can be
used to indicate that a particular buddy should not be
saved to file. This will be particularly useful for
prpls with dynamic group support (which I am working on
adding to Meanwhile), such as Oscar's recent buddies group.
I used a negative flag (NO_SAVE rather than SAVE)
because the default should be for saving to happen, and
I didn't want to have to initiate the buddy with a save
flag set. To counteract this, there is a macro called
GAIM_BUDDY_SHOULD_SAVE which checks for the absense of
the flag. Woo-hoo double negative!!
The beefy part of this patch also factors out the
deeply nested loops of the saving code into separate
functions.
This code also fixes a minor possible bug wherein when
saving only a particular account, a group could be
written containing empty contacts (due to checking for
the specific account only at the group and buddy levels)
Here's a version that places the flags field in the
BlistNode, and checks for it at each stage (group, chat,
contact, buddy). It didn't erase my buddy list when I tried
it, so that's nice at least." --Christopher (siege) O'Brien
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Fri, 20 Aug 2004 03:40:33 +0000 |
parents | 4a8bf81b82ae |
children | b23e70bd1215 |
comparison
equal
deleted
inserted
replaced
9786:3e7e294f56f3 | 9787:904b757835ca |
---|---|
916 return contact->alias; | 916 return contact->alias; |
917 | 917 |
918 return gaim_buddy_get_alias(contact->priority); | 918 return gaim_buddy_get_alias(contact->priority); |
919 } | 919 } |
920 | 920 |
921 gboolean gaim_contact_on_account(GaimContact *c, GaimAccount *account) | |
922 { | |
923 GaimBlistNode *bnode, *cnode = (GaimBlistNode *) c; | |
924 | |
925 g_return_val_if_fail(c != NULL, FALSE); | |
926 g_return_val_if_fail(account != NULL, FALSE); | |
927 | |
928 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
929 GaimBuddy *buddy; | |
930 | |
931 if (! GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
932 continue; | |
933 | |
934 buddy = (GaimBuddy *)bnode; | |
935 if (buddy->account == account) | |
936 return TRUE; | |
937 } | |
938 return FALSE; | |
939 } | |
940 | |
921 GaimGroup *gaim_group_new(const char *name) | 941 GaimGroup *gaim_group_new(const char *name) |
922 { | 942 { |
923 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | 943 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); |
924 GaimGroup *group = gaim_find_group(name); | 944 GaimGroup *group = gaim_find_group(name); |
925 | 945 |
1727 } | 1747 } |
1728 } | 1748 } |
1729 | 1749 |
1730 gboolean gaim_group_on_account(GaimGroup *g, GaimAccount *account) | 1750 gboolean gaim_group_on_account(GaimGroup *g, GaimAccount *account) |
1731 { | 1751 { |
1732 GaimBlistNode *cnode, *bnode; | 1752 GaimBlistNode *cnode; |
1733 for (cnode = ((GaimBlistNode *)g)->child; cnode; cnode = cnode->next) { | 1753 for (cnode = ((GaimBlistNode *)g)->child; cnode; cnode = cnode->next) { |
1734 if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | 1754 if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { |
1735 for (bnode = cnode->child; bnode; bnode = bnode->next) { | 1755 if(gaim_contact_on_account((GaimContact *) cnode, account)) |
1736 if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { | 1756 return TRUE; |
1737 GaimBuddy *buddy = (GaimBuddy *)bnode; | |
1738 if ((!account && gaim_account_is_connected(buddy->account)) | |
1739 || buddy->account == account) | |
1740 return TRUE; | |
1741 } | |
1742 } | |
1743 } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { | 1757 } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { |
1744 GaimChat *chat = (GaimChat *)cnode; | 1758 GaimChat *chat = (GaimChat *)cnode; |
1745 if ((!account && gaim_account_is_connected(chat->account)) | 1759 if ((!account && gaim_account_is_connected(chat->account)) |
1746 || chat->account == account) | 1760 || chat->account == account) |
1747 return TRUE; | 1761 return TRUE; |
2169 g_free(bud_name); | 2183 g_free(bud_name); |
2170 g_free(bud_alias); | 2184 g_free(bud_alias); |
2171 g_free(acct_name); | 2185 g_free(acct_name); |
2172 } | 2186 } |
2173 | 2187 |
2188 | |
2189 /* check for flagging and account exclusion on buddy */ | |
2190 static gboolean blist_buddy_should_save(GaimAccount *exp_acct, GaimBuddy *buddy) | |
2191 { | |
2192 if (! GAIM_BLIST_NODE_SHOULD_SAVE((GaimBlistNode *) buddy)) | |
2193 return FALSE; | |
2194 | |
2195 if (exp_acct && buddy->account != exp_acct) | |
2196 return FALSE; | |
2197 | |
2198 return TRUE; | |
2199 } | |
2200 | |
2201 | |
2202 static void blist_write_buddy(FILE *file, GaimAccount *exp_acct, GaimBuddy *buddy) | |
2203 { | |
2204 if (blist_buddy_should_save(exp_acct, buddy)) | |
2205 print_buddy(file, buddy); | |
2206 } | |
2207 | |
2208 | |
2209 /* check for flagging and account exclusion on contact and all members */ | |
2210 static gboolean blist_contact_should_save(GaimAccount *exp_acct, GaimContact *contact) | |
2211 { | |
2212 GaimBlistNode *bnode, *cnode = (GaimBlistNode *) contact; | |
2213 | |
2214 if (! GAIM_BLIST_NODE_SHOULD_SAVE(cnode)) | |
2215 return FALSE; | |
2216 | |
2217 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
2218 if (! GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
2219 continue; | |
2220 | |
2221 if (blist_buddy_should_save(exp_acct, (GaimBuddy *) bnode)) | |
2222 return TRUE; | |
2223 } | |
2224 | |
2225 return FALSE; | |
2226 } | |
2227 | |
2228 | |
2229 static void blist_write_contact(FILE *file, GaimAccount *exp_acct, GaimContact *contact) | |
2230 { | |
2231 GaimBlistNode *bnode, *cnode = (GaimBlistNode *) contact; | |
2232 | |
2233 if (! blist_contact_should_save(exp_acct, contact)) | |
2234 return; | |
2235 | |
2236 fprintf(file, "\t\t\t<contact"); | |
2237 if (contact->alias) { | |
2238 char *alias = g_markup_escape_text(contact->alias, -1); | |
2239 fprintf(file, " alias=\"%s\"", alias); | |
2240 g_free(alias); | |
2241 } | |
2242 fprintf(file, ">\n"); | |
2243 | |
2244 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
2245 if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { | |
2246 blist_write_buddy(file, exp_acct, (GaimBuddy *) bnode); | |
2247 } | |
2248 } | |
2249 | |
2250 g_hash_table_foreach(cnode->settings, blist_print_cnode_settings, file); | |
2251 fprintf(file, "\t\t\t</contact>\n"); | |
2252 } | |
2253 | |
2254 | |
2255 static void blist_write_chat(FILE *file, GaimAccount *exp_acct, GaimChat *chat) | |
2256 { | |
2257 char *acct_name; | |
2258 | |
2259 if (! GAIM_BLIST_NODE_SHOULD_SAVE((GaimBlistNode *) chat)) | |
2260 return; | |
2261 | |
2262 if (exp_acct && chat->account != exp_acct) | |
2263 return; | |
2264 | |
2265 acct_name = g_markup_escape_text(chat->account->username, -1); | |
2266 fprintf(file, "\t\t\t<chat proto=\"%s\" account=\"%s\">\n", | |
2267 gaim_account_get_protocol_id(chat->account), acct_name); | |
2268 g_free(acct_name); | |
2269 | |
2270 if (chat->alias) { | |
2271 char *chat_alias = g_markup_escape_text(chat->alias, -1); | |
2272 fprintf(file, "\t\t\t\t<alias>%s</alias>\n", chat_alias); | |
2273 g_free(chat_alias); | |
2274 } | |
2275 | |
2276 g_hash_table_foreach(chat->components, blist_print_chat_components, file); | |
2277 g_hash_table_foreach(chat->node.settings, blist_print_cnode_settings, file); | |
2278 | |
2279 fprintf(file, "\t\t\t</chat>\n"); | |
2280 } | |
2281 | |
2282 | |
2283 static void blist_write_group(FILE *file, GaimAccount *exp_acct, GaimGroup *group) | |
2284 { | |
2285 GaimBlistNode *cnode, *gnode = (GaimBlistNode *) group; | |
2286 char *group_name; | |
2287 | |
2288 if (! GAIM_BLIST_NODE_SHOULD_SAVE(gnode)) | |
2289 return; | |
2290 | |
2291 if (exp_acct && ! gaim_group_on_account(group, exp_acct)) | |
2292 return; | |
2293 | |
2294 group_name = g_markup_escape_text(group->name, -1); | |
2295 fprintf(file, "\t\t<group name=\"%s\">\n", group_name); | |
2296 g_free(group_name); | |
2297 | |
2298 g_hash_table_foreach(group->node.settings, | |
2299 blist_print_group_settings, file); | |
2300 | |
2301 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
2302 if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
2303 blist_write_contact(file, exp_acct, (GaimContact *) cnode); | |
2304 } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { | |
2305 blist_write_chat(file, exp_acct, (GaimChat *) cnode); | |
2306 } | |
2307 } | |
2308 | |
2309 fprintf(file, "\t\t</group>\n"); | |
2310 } | |
2311 | |
2312 | |
2313 static void blist_write_privacy_account(FILE *file, GaimAccount *exp_acct, GaimAccount *account) | |
2314 { | |
2315 char *acct_name; | |
2316 GSList *buds; | |
2317 | |
2318 if(exp_acct && exp_acct != account) | |
2319 return; | |
2320 | |
2321 acct_name = g_markup_escape_text(account->username, -1); | |
2322 fprintf(file, "\t\t<account proto=\"%s\" name=\"%s\" mode=\"%d\">\n", | |
2323 gaim_account_get_protocol_id(account), | |
2324 acct_name, account->perm_deny); | |
2325 g_free(acct_name); | |
2326 | |
2327 for (buds = account->permit; buds; buds = buds->next) { | |
2328 char *bud_name = g_markup_escape_text(buds->data, -1); | |
2329 fprintf(file, "\t\t\t<permit>%s</permit>\n", bud_name); | |
2330 g_free(bud_name); | |
2331 } | |
2332 | |
2333 for (buds = account->deny; buds; buds = buds->next) { | |
2334 char *bud_name = g_markup_escape_text(buds->data, -1); | |
2335 fprintf(file, "\t\t\t<block>%s</block>\n", bud_name); | |
2336 g_free(bud_name); | |
2337 } | |
2338 | |
2339 fprintf(file, "\t\t</account>\n"); | |
2340 } | |
2341 | |
2342 | |
2174 static void gaim_blist_write(FILE *file, GaimAccount *exp_acct) | 2343 static void gaim_blist_write(FILE *file, GaimAccount *exp_acct) |
2175 { | 2344 { |
2176 GList *accounts; | 2345 GList *accounts; |
2177 GSList *buds; | 2346 GaimBlistNode *gnode; |
2178 GaimBlistNode *gnode, *cnode, *bnode; | 2347 |
2179 fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n"); | 2348 fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n"); |
2180 fprintf(file, "<gaim version=\"1\">\n"); | 2349 fprintf(file, "<gaim version=\"1\">\n"); |
2181 fprintf(file, "\t<blist>\n"); | 2350 fprintf(file, "\t<blist>\n"); |
2182 | 2351 |
2183 for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { | 2352 for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { |
2184 GaimGroup *group; | 2353 if (GAIM_BLIST_NODE_IS_GROUP(gnode)) |
2185 | 2354 blist_write_group(file, exp_acct, (GaimGroup *) gnode); |
2186 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
2187 continue; | |
2188 | |
2189 group = (GaimGroup *)gnode; | |
2190 if (!exp_acct || gaim_group_on_account(group, exp_acct)) { | |
2191 char *group_name = g_markup_escape_text(group->name, -1); | |
2192 fprintf(file, "\t\t<group name=\"%s\">\n", group_name); | |
2193 g_hash_table_foreach(group->node.settings, | |
2194 blist_print_group_settings, file); | |
2195 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
2196 if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
2197 GaimContact *contact = (GaimContact*)cnode; | |
2198 fprintf(file, "\t\t\t<contact"); | |
2199 if (contact->alias) { | |
2200 char *alias = g_markup_escape_text(contact->alias, -1); | |
2201 fprintf(file, " alias=\"%s\"", alias); | |
2202 g_free(alias); | |
2203 } | |
2204 fprintf(file, ">\n"); | |
2205 | |
2206 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
2207 if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { | |
2208 GaimBuddy *buddy = (GaimBuddy *)bnode; | |
2209 if (!exp_acct || buddy->account == exp_acct) { | |
2210 print_buddy(file, buddy); | |
2211 } | |
2212 } | |
2213 } | |
2214 | |
2215 g_hash_table_foreach(cnode->settings, | |
2216 blist_print_cnode_settings, file); | |
2217 | |
2218 fprintf(file, "\t\t\t</contact>\n"); | |
2219 } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { | |
2220 GaimChat *chat = (GaimChat *)cnode; | |
2221 if (!exp_acct || chat->account == exp_acct) { | |
2222 char *acct_name = g_markup_escape_text(chat->account->username, -1); | |
2223 fprintf(file, "\t\t\t<chat proto=\"%s\" account=\"%s\">\n", | |
2224 gaim_account_get_protocol_id(chat->account), | |
2225 acct_name); | |
2226 | |
2227 if (chat->alias) { | |
2228 char *chat_alias = g_markup_escape_text(chat->alias, -1); | |
2229 fprintf(file, "\t\t\t\t<alias>%s</alias>\n", chat_alias); | |
2230 g_free(chat_alias); | |
2231 } | |
2232 g_hash_table_foreach(chat->components, | |
2233 blist_print_chat_components, file); | |
2234 g_hash_table_foreach(chat->node.settings, | |
2235 blist_print_cnode_settings, file); | |
2236 fprintf(file, "\t\t\t</chat>\n"); | |
2237 g_free(acct_name); | |
2238 } | |
2239 } | |
2240 } | |
2241 fprintf(file, "\t\t</group>\n"); | |
2242 g_free(group_name); | |
2243 } | |
2244 } | 2355 } |
2245 | 2356 |
2246 fprintf(file, "\t</blist>\n"); | 2357 fprintf(file, "\t</blist>\n"); |
2247 fprintf(file, "\t<privacy>\n"); | 2358 fprintf(file, "\t<privacy>\n"); |
2248 | 2359 |
2249 for (accounts = gaim_accounts_get_all(); | 2360 for (accounts = gaim_accounts_get_all(); accounts; accounts = accounts->next) { |
2250 accounts != NULL; | 2361 blist_write_privacy_account(file, exp_acct, (GaimAccount *) accounts->data); |
2251 accounts = accounts->next) { | |
2252 | |
2253 GaimAccount *account = accounts->data; | |
2254 char *acct_name = g_markup_escape_text(account->username, -1); | |
2255 if (!exp_acct || account == exp_acct) { | |
2256 fprintf(file, "\t\t<account proto=\"%s\" name=\"%s\" " | |
2257 "mode=\"%d\">\n", gaim_account_get_protocol_id(account), | |
2258 acct_name, account->perm_deny); | |
2259 | |
2260 for (buds = account->permit; buds; buds = buds->next) { | |
2261 char *bud_name = g_markup_escape_text(buds->data, -1); | |
2262 fprintf(file, "\t\t\t<permit>%s</permit>\n", bud_name); | |
2263 g_free(bud_name); | |
2264 } | |
2265 for (buds = account->deny; buds; buds = buds->next) { | |
2266 char *bud_name = g_markup_escape_text(buds->data, -1); | |
2267 fprintf(file, "\t\t\t<block>%s</block>\n", bud_name); | |
2268 g_free(bud_name); | |
2269 } | |
2270 fprintf(file, "\t\t</account>\n"); | |
2271 } | |
2272 g_free(acct_name); | |
2273 } | 2362 } |
2274 | 2363 |
2275 fprintf(file, "\t</privacy>\n"); | 2364 fprintf(file, "\t</privacy>\n"); |
2276 fprintf(file, "</gaim>\n"); | 2365 fprintf(file, "</gaim>\n"); |
2277 } | 2366 } |
2367 | |
2278 | 2368 |
2279 void gaim_blist_sync() | 2369 void gaim_blist_sync() |
2280 { | 2370 { |
2281 FILE *file; | 2371 FILE *file; |
2282 char *user_dir = gaim_user_dir(); | 2372 char *user_dir = gaim_user_dir(); |