changeset 15318:b17a907065cc

[gaim-migrate @ 18109] Patch #1259960 ((HEAD) Additions to the privacy API) and #1236132 (Allow/Block option in buddy-context menu). committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 12 Jan 2007 00:47:58 +0000
parents d928cf5ead1b
children f0f79c50b9da
files ChangeLog.API gtk/gtkblist.c gtk/gtkblist.h libgaim/privacy.c libgaim/privacy.h
diffstat 5 files changed, 200 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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)
 {
--- 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.
  */
--- 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)
 {
--- 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.