# HG changeset patch # User Sadrul Habib Chowdhury # Date 1168562878 0 # Node ID b17a907065cc82b43613ff9624c7f0a8e8bb4ee8 # Parent d928cf5ead1b335a458694d3d7f32f45597ff109 [gaim-migrate @ 18109] Patch #1259960 ((HEAD) Additions to the privacy API) and #1236132 (Allow/Block option in buddy-context menu). committer: Tailor Script diff -r d928cf5ead1b -r b17a907065cc ChangeLog.API --- a/ChangeLog.API Thu Jan 11 08:43:34 2007 +0000 +++ b/ChangeLog.API Fri Jan 12 00:47:58 2007 +0000 @@ -355,6 +355,7 @@ gtk_tree_view_set_search_equal_func * gaim_xfer_set_bytes_sent(). Sets the offset in the file to read from or write to. + * gaim_privacy_deny and gaim_privacy_allow Signals - Changed: (See the Doxygen docs for details on all signals.) * Signal propagation now stops after a handler returns a non-NULL value. diff -r d928cf5ead1b -r b17a907065cc gtk/gtkblist.c --- a/gtk/gtkblist.c Thu Jan 11 08:43:34 2007 +0000 +++ b/gtk/gtkblist.c Fri Jan 12 00:47:58 2007 +0000 @@ -954,6 +954,47 @@ } } +static void +toggle_privacy(GtkWidget *widget, GaimBlistNode *node) +{ + GaimBuddy *buddy; + GaimAccount *account; + gboolean permitted; + const char *name; + + if (!GAIM_BLIST_NODE_IS_BUDDY(node)) + return; + + buddy = (GaimBuddy *)node; + account = gaim_buddy_get_account(buddy); + name = gaim_buddy_get_name(buddy); + + permitted = gaim_privacy_check(account, name); + + /* XXX: Perhaps ask whether to restore the previous lists where appropirate? */ + + if (permitted) + gaim_privacy_deny(account, name, FALSE, FALSE); + else + gaim_privacy_allow(account, name, FALSE, FALSE); + + gaim_gtk_blist_update(gaim_get_blist(), node); +} + +void gaim_gtk_append_blist_node_privacy_menu(GtkWidget *menu, GaimBlistNode *node) +{ + GaimBuddy *buddy = (GaimBuddy *)node; + GaimAccount *account; + gboolean permitted; + + account = gaim_buddy_get_account(buddy); + permitted = gaim_privacy_check(account, gaim_buddy_get_name(buddy)); + + gaim_new_item_from_stock(menu, permitted ? _("_Block") : _("Un_block"), + GTK_STOCK_DIALOG_ERROR, G_CALLBACK(toggle_privacy), + node, 0 ,0, NULL); +} + void gaim_gtk_append_blist_node_proto_menu(GtkWidget *menu, GaimConnection *gc, GaimBlistNode *node) @@ -1028,6 +1069,8 @@ G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL); } + gaim_gtk_append_blist_node_privacy_menu(menu, (GaimBlistNode *)buddy); + gaim_gtk_append_blist_node_proto_menu(menu, buddy->account->gc, (GaimBlistNode *)buddy); gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy); @@ -1086,7 +1129,6 @@ return FALSE; } - static GtkWidget * create_group_menu (GaimBlistNode *node, GaimGroup *g) { diff -r d928cf5ead1b -r b17a907065cc gtk/gtkblist.h --- a/gtk/gtkblist.h Thu Jan 11 08:43:34 2007 +0000 +++ b/gtk/gtkblist.h Fri Jan 12 00:47:58 2007 +0000 @@ -302,6 +302,12 @@ void gaim_gtk_blist_joinchat_show(void); /** + * Appends the privacy menu items for a GaimBlistNode + * TODO: Rename these. + */ +void gaim_gtk_append_blist_node_privacy_menu(GtkWidget *menu, GaimBlistNode *node); + +/** * Appends the protocol specific menu items for a GaimBlistNode * TODO: Rename these. */ diff -r d928cf5ead1b -r b17a907065cc libgaim/privacy.c --- a/libgaim/privacy.c Thu Jan 11 08:43:34 2007 +0000 +++ b/libgaim/privacy.c Fri Jan 12 00:47:58 2007 +0000 @@ -78,6 +78,7 @@ GSList *l; const char *name; GaimBuddy *buddy; + char *del; g_return_val_if_fail(account != NULL, FALSE); g_return_val_if_fail(who != NULL, FALSE); @@ -92,7 +93,10 @@ if (l == NULL) return FALSE; - g_free(l->data); + /* We should not free l->data just yet. There can be occasions where + * l->data == who. In such cases, freeing l->data here can cause crashes + * later when who is used. */ + del = l->data; account->permit = g_slist_delete_link(account->permit, l); if (!local_only && gaim_account_is_connected(account)) @@ -108,6 +112,7 @@ gaim_signal_emit(gaim_blist_get_handle(), "buddy-privacy-changed", buddy); } + g_free(del); return TRUE; } @@ -197,6 +202,105 @@ return TRUE; } +/* This makes sure that only all the buddies are in the permit list. */ +static void +add_buddies_in_permit(GaimAccount *account, gboolean local) +{ + GSList *list, *iter; + /* Remove anyone in the permit list who is not in the buddylist */ + for (list = account->permit; list != NULL; ) { + char *person = list->data; + list = list->next; + if (!gaim_find_buddy(account, person)) + gaim_privacy_permit_remove(account, person, local); + } + /* Now make sure everyone in the buddylist is in the permit list */ + for (iter = list = gaim_find_buddies(account, NULL); iter; iter = iter->next) { + GaimBuddy *buddy = iter->data; + if (!g_slist_find_custom(account->permit, buddy->name, (GCompareFunc)g_utf8_collate)) + gaim_privacy_permit_add(account, buddy->name, local); + } + g_slist_free(list); +} + +void +gaim_privacy_allow(GaimAccount *account, const char *who, gboolean local, + gboolean restore) +{ + GSList *list; + + switch (account->perm_deny) { + case GAIM_PRIVACY_ALLOW_ALL: + return; + case GAIM_PRIVACY_ALLOW_USERS: + gaim_privacy_permit_add(account, who, local); + break; + case GAIM_PRIVACY_DENY_USERS: + gaim_privacy_deny_remove(account, who, local); + break; + case GAIM_PRIVACY_DENY_ALL: + if (!restore) { + /* Empty the allow-list. */ + for (list = account->permit; list != NULL;) { + char *who = list->data; + list = list->next; + gaim_privacy_permit_remove(account, who, local); + } + } + gaim_privacy_permit_add(account, who, local); + account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; + break; + case GAIM_PRIVACY_ALLOW_BUDDYLIST: + if (!gaim_find_buddy(account, who)) { + add_buddies_in_permit(account, local); + gaim_privacy_permit_add(account, who, local); + account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; + } + break; + default: + g_return_if_reached(); + } +} + +void +gaim_privacy_deny(GaimAccount *account, const char *who, gboolean local, + gboolean restore) +{ + GSList *list; + + switch (account->perm_deny) { + case GAIM_PRIVACY_ALLOW_ALL: + if (!restore) { + /* Empty the deny-list. */ + for (list = account->deny; list != NULL; ) { + char *person = list->data; + list = list->next; + gaim_privacy_deny_remove(account, person, local); + } + } + gaim_privacy_deny_add(account, who, local); + account->perm_deny = GAIM_PRIVACY_DENY_USERS; + break; + case GAIM_PRIVACY_ALLOW_USERS: + gaim_privacy_permit_remove(account, who, local); + break; + case GAIM_PRIVACY_DENY_USERS: + gaim_privacy_deny_add(account, who, local); + break; + case GAIM_PRIVACY_DENY_ALL: + break; + case GAIM_PRIVACY_ALLOW_BUDDYLIST: + if (gaim_find_buddy(account, who)) { + add_buddies_in_permit(account, local); + gaim_privacy_permit_remove(account, who, local); + account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; + } + break; + default: + g_return_if_reached(); + } +} + gboolean gaim_privacy_check(GaimAccount *account, const char *who) { diff -r d928cf5ead1b -r b17a907065cc libgaim/privacy.h --- a/libgaim/privacy.h Thu Jan 11 08:43:34 2007 +0000 +++ b/libgaim/privacy.h Fri Jan 12 00:47:58 2007 +0000 @@ -107,6 +107,51 @@ gboolean gaim_privacy_deny_remove(GaimAccount *account, const char *name, gboolean local_only); +/** + * Allow a user to send messages. If current privacy setting for the account is: + * GAIM_PRIVACY_ALLOW_USERS: The user is added to the allow-list. + * GAIM_PRIVACY_DENY_USERS : The user is removed from the deny-list. + * GAIM_PRIVACY_ALLOW_ALL : No changes made. + * GAIM_PRIVACY_DENY_ALL : The privacy setting is changed to + * GAIM_PRIVACY_ALLOW_USERS and the user + * is added to the allow-list. + * GAIM_PRIVACY_ALLOW_BUDDYLIST: No changes made if the user is already in + * the buddy-list. Otherwise the setting is + * changed to GAIM_PRIVACY_ALLOW_USERS, all the + * buddies are added to the allow-list, and the + * user is also added to the allow-list. + * + * @param account The account. + * @param who The name of the user. + * @param local Whether the change is local-only. + * @param restore Should the previous allow/deny list be restored if the + * privacy setting is changed. + */ +void gaim_privacy_allow(GaimAccount *account, const char *who, gboolean local, + gboolean restore); + +/** + * Block messages from a user. If current privacy setting for the account is: + * GAIM_PRIVACY_ALLOW_USERS: The user is removed from the allow-list. + * GAIM_PRIVACY_DENY_USERS : The user is added to the deny-list. + * GAIM_PRIVACY_DENY_ALL : No changes made. + * GAIM_PRIVACY_ALLOW_ALL : The privacy setting is changed to + * GAIM_PRIVACY_DENY_USERS and the user is + * added to the deny-list. + * GAIM_PRIVACY_ALLOW_BUDDYLIST: If the user is not in the buddy-list, + * then no changes made. Otherwise, the setting + * is changed to GAIM_PRIVACY_ALLOW_USERS, all + * the buddies are added to the allow-list, and + * this user is removed from the list. + * + * @param account The account. + * @param who The name of the user. + * @param local Whether the change is local-only. + * @param restore Should the previous allow/deny list be restored if the + * privacy setting is changed. + */ +void gaim_privacy_deny(GaimAccount *account, const char *who, gboolean local, + gboolean restore); /** * Check the privacy-setting for a user.