diff src/gtkprivacy.c @ 6371:8f94cce8faa5

[gaim-migrate @ 6876] I think I touched almost every file. Here's what happened. I started off fixing up the Makefile.am and configure.ac files to help with the core/UI split some. Then I got annoyed with the build_{allow,deny}_list() functions that everything used, and decided to core/UI split privacy. While doing that, I decided to redesign the dialog. So now, a lot has changed, but not really so much. Just that most files got affected. Oh yeah, and the UI stuff was taken out of internal.h and moved to gtkinternal.h. If you use this, please be aware of this change. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Tue, 05 Aug 2003 10:55:04 +0000
parents
children ca73fdf3eb38
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gtkprivacy.c	Tue Aug 05 10:55:04 2003 +0000
@@ -0,0 +1,654 @@
+/**
+ * @file gtkprivacy.c GTK+ Privacy UI
+ * @ingroup gtkui
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org>
+ * Copyright (C) 2002-2003 Rob Flynn <rob@marko.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "gtkinternal.h"
+
+#include "connection.h"
+#include "debug.h"
+#include "privacy.h"
+#include "request.h"
+#include "util.h"
+
+#include "gtkprivacy.h"
+#include "gtkutils.h"
+
+typedef enum
+{
+	GAIM_GTK_PRIVACY_ALLOW_ALL = 0,
+	GAIM_GTK_PRIVACY_ALLOW_BUDDYLIST,
+	GAIM_GTK_PRIVACY_ALLOW_USERS,
+	GAIM_GTK_PRIVACY_DENY_ALL,
+	GAIM_GTK_PRIVACY_DENY_USERS
+
+} GaimGtkPrivacyType;
+
+typedef struct
+{
+	GtkWidget *win;
+
+	GtkWidget *type_menu;
+
+	GtkWidget *add_button;
+	GtkWidget *remove_button;
+	GtkWidget *clear_button;
+
+	GtkWidget *button_box;
+	GtkWidget *allow_widget;
+	GtkWidget *block_widget;
+
+	GtkListStore *allow_store;
+	GtkListStore *block_store;
+
+	GtkWidget *allow_list;
+	GtkWidget *block_list;
+
+	gboolean in_allow_list;
+
+	GaimAccount *account;
+
+} GaimGtkPrivacyDialog;
+
+typedef struct
+{
+	GaimAccount *account;
+	char *name;
+	gboolean block;
+
+} GaimGtkPrivacyRequestData;
+
+static struct
+{
+	const char *text;
+	int num;
+
+} menu_entries[] =
+{
+	{ N_("Allow all users to contact me"),         1 },
+	{ N_("Allow only the users on my buddy list"), 5 },
+	{ N_("Allow only the users below"),            3 },
+	{ N_("Block all users"),                       2 },
+	{ N_("Block the users below"),                 4 }
+};
+
+static size_t menu_entry_count = sizeof(menu_entries) / sizeof(*menu_entries);
+
+static GaimGtkPrivacyDialog *privacy_dialog = NULL;
+
+static void
+rebuild_allow_list(GaimGtkPrivacyDialog *dialog)
+{
+	GSList *l;
+	GtkTreeIter iter;
+
+	gtk_list_store_clear(dialog->allow_store);
+
+	for (l = dialog->account->permit; l != NULL; l = l->next) {
+		gtk_list_store_append(dialog->allow_store, &iter);
+		gtk_list_store_set(dialog->allow_store, &iter, 0, l->data, -1);
+	}
+}
+
+static void
+rebuild_block_list(GaimGtkPrivacyDialog *dialog)
+{
+	GSList *l;
+	GtkTreeIter iter;
+
+	gtk_list_store_clear(dialog->block_store);
+
+	for (l = dialog->account->deny; l != NULL; l = l->next) {
+		gtk_list_store_append(dialog->block_store, &iter);
+		gtk_list_store_set(dialog->block_store, &iter, 0, l->data, -1);
+	}
+}
+
+static const char *
+find_permit_block_by_name(GSList *list, const char *name)
+{
+	const char *temp_name;
+	GSList *l;
+
+	for (l = list; l != NULL; l = l->next) {
+		temp_name = (const char *)l->data;
+
+		if (!gaim_utf8_strcasecmp(name, temp_name))
+			return temp_name;
+	}
+
+	return NULL;
+}
+
+static void
+user_selected_cb(GtkTreeSelection *sel, GaimGtkPrivacyDialog *dialog)
+{
+	gtk_widget_set_sensitive(dialog->remove_button, TRUE);
+}
+
+static GtkWidget *
+build_list(GaimGtkPrivacyDialog *dialog, GtkListStore *model,
+		   GtkWidget **ret_treeview)
+{
+	GtkWidget *sw;
+	GtkWidget *treeview;
+	GtkCellRenderer *rend;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *sel;
+
+	sw = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+								   GTK_POLICY_NEVER,
+								   GTK_POLICY_AUTOMATIC);
+
+	treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
+	*ret_treeview = treeview;
+
+	rend = gtk_cell_renderer_text_new();
+
+	column = gtk_tree_view_column_new_with_attributes(NULL, rend,
+													  "text", 0,
+													  NULL);
+	gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), treeview);
+	gtk_widget_show(treeview);
+
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+
+	g_signal_connect(G_OBJECT(sel), "changed",
+					 G_CALLBACK(user_selected_cb), dialog);
+
+	return sw;
+}
+
+static GtkWidget *
+build_allow_list(GaimGtkPrivacyDialog *dialog)
+{
+	GtkWidget *widget;
+	GtkWidget *list;
+
+	dialog->allow_store = gtk_list_store_new(1, G_TYPE_STRING);
+
+	widget = build_list(dialog, dialog->allow_store, &list);
+
+	dialog->allow_list = list;
+
+	rebuild_allow_list(dialog);
+
+	return widget;
+}
+
+static GtkWidget *
+build_block_list(GaimGtkPrivacyDialog *dialog)
+{
+	GtkWidget *widget;
+	GtkWidget *list;
+
+	dialog->block_store = gtk_list_store_new(1, G_TYPE_STRING);
+
+	widget = build_list(dialog, dialog->block_store, &list);
+
+	dialog->block_list = list;
+
+	rebuild_block_list(dialog);
+
+	return widget;
+}
+
+static gint
+destroy_cb(GtkWidget *w, GdkEvent *event, GaimGtkPrivacyDialog *dialog)
+{
+	g_free(dialog);
+
+	privacy_dialog = NULL;
+
+	return 0;
+}
+
+static void
+select_account_cb(GtkWidget *dropdown, GaimAccount *account,
+				  GaimGtkPrivacyDialog *dialog)
+{
+	int i;
+
+	dialog->account = account;
+
+	gaim_debug(GAIM_DEBUG_MISC, "select_account_cb",
+			   "dialog = %p\n", dialog);
+	gaim_debug(GAIM_DEBUG_MISC, "select_account_cb",
+			   "menu_entry_count = %d\n", menu_entry_count);
+
+	for (i = 0; i < menu_entry_count; i++) {
+		if (menu_entries[i].num == account->perm_deny) {
+			gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->type_menu), i);
+			break;
+		}
+	}
+
+	rebuild_allow_list(dialog);
+	rebuild_block_list(dialog);
+}
+
+static void
+type_changed_cb(GtkOptionMenu *optmenu, GaimGtkPrivacyDialog *dialog)
+{
+	int new_type = gtk_option_menu_get_history(optmenu);
+
+	dialog->account->perm_deny = menu_entries[new_type].num;
+	serv_set_permit_deny(gaim_account_get_connection(dialog->account));
+	gaim_blist_save();
+
+	gtk_widget_hide(dialog->allow_widget);
+	gtk_widget_hide(dialog->block_widget);
+	gtk_widget_hide(dialog->button_box);
+
+	if (new_type == 2) {
+		gtk_widget_show(dialog->allow_widget);
+		gtk_widget_show(dialog->button_box);
+		dialog->in_allow_list = TRUE;
+	}
+	else if (new_type == 4) {
+		gtk_widget_show(dialog->block_widget);
+		gtk_widget_show(dialog->button_box);
+		dialog->in_allow_list = FALSE;
+	}
+}
+
+static void
+add_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
+{
+	if (dialog->in_allow_list)
+		gaim_gtk_request_add_permit(dialog->account, NULL);
+	else
+		gaim_gtk_request_add_block(dialog->account, NULL);
+}
+
+static void
+remove_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	GtkTreeSelection *sel;
+	char *name;
+
+	if (dialog->in_allow_list && dialog->allow_store == NULL)
+		return;
+
+	if (!dialog->in_allow_list && dialog->block_store == NULL)
+		return;
+
+	if (dialog->in_allow_list) {
+		model = GTK_TREE_MODEL(dialog->allow_store);
+		sel   = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->allow_list));
+	}
+	else {
+		model = GTK_TREE_MODEL(dialog->block_store);
+		sel   = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->block_list));
+	}
+
+	if (gtk_tree_selection_get_selected(sel, NULL, &iter))
+		gtk_tree_model_get(model, &iter, 0, &name, -1);
+	else
+		return;
+
+	if (dialog->in_allow_list) {
+		const char *new_name;
+
+		new_name = find_permit_block_by_name(dialog->account->permit, name);
+
+		if (new_name != NULL)
+			gaim_privacy_permit_remove(dialog->account, new_name);
+	}
+	else {
+		const char *new_name;
+
+		new_name = find_permit_block_by_name(dialog->account->deny, name);
+
+		if (new_name != NULL)
+			gaim_privacy_deny_remove(dialog->account, new_name);
+	}
+}
+
+static void
+clear_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
+{
+}
+
+static void
+close_cb(GtkWidget *button, void *user_data)
+{
+	gaim_gtk_privacy_dialog_hide();
+}
+
+static GaimGtkPrivacyDialog *
+privacy_dialog_new(void)
+{
+	GaimGtkPrivacyDialog *dialog;
+	GaimConnection *gc;
+	GtkWidget *bbox;
+	GtkWidget *hbox;
+	GtkWidget *vbox;
+	GtkWidget *button;
+	GtkWidget *dropdown;
+	GtkWidget *label;
+	GtkWidget *menu;
+	GtkWidget *sep;
+	int selected = 0;
+	int i;
+
+	dialog = g_new0(GaimGtkPrivacyDialog, 1);
+
+	gc = (GaimConnection *)gaim_connections_get_all()->data;
+	dialog->account = gaim_connection_get_account(gc);
+
+	dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_resizable(GTK_WINDOW(dialog->win), FALSE);
+	gtk_window_set_role(GTK_WINDOW(dialog->win), "privacy");
+	gtk_window_set_title(GTK_WINDOW(dialog->win), _("Privacy"));
+	gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
+
+	g_signal_connect(G_OBJECT(dialog->win), "delete_event",
+					 G_CALLBACK(destroy_cb), dialog);
+
+	gtk_widget_realize(dialog->win);
+
+	/* Main vbox */
+	vbox = gtk_vbox_new(FALSE, 12);
+	gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
+	gtk_widget_show(vbox);
+
+	/* Description label */
+	label = gtk_label_new(
+		_("Changes to privacy settings take effect immediately."));
+
+	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+	gtk_widget_show(label);
+
+	/* Hbox for the accounts drop-down and label. */
+	hbox = gtk_hbox_new(FALSE, 12);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+	gtk_widget_show(hbox);
+
+	/* "Set privacy for:" label */
+	label = gtk_label_new(_("Set privacy for:"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+
+	/* Accounts drop-down */
+	dropdown = gaim_gtk_account_option_menu_new(dialog->account, FALSE,
+												G_CALLBACK(select_account_cb),
+												dialog);
+	gtk_box_pack_start(GTK_BOX(hbox), dropdown, FALSE, FALSE, 0);
+	gtk_widget_show(dropdown);
+
+	/* Add the drop-down list with the allow/block types. */
+	dialog->type_menu = gtk_option_menu_new();
+	gtk_box_pack_start(GTK_BOX(vbox), dialog->type_menu, FALSE, FALSE, 0);
+	gtk_widget_show(dialog->type_menu);
+
+	/* Build the menu for that. */
+	menu = gtk_menu_new();
+
+	for (i = 0; i < menu_entry_count; i++) {
+		gaim_new_item(menu, _(menu_entries[i].text));
+
+		if (menu_entries[i].num == dialog->account->perm_deny)
+			selected = i;
+	}
+
+	gtk_option_menu_set_menu(GTK_OPTION_MENU(dialog->type_menu), menu);
+	gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->type_menu), selected);
+
+	g_signal_connect(G_OBJECT(dialog->type_menu), "changed",
+					 G_CALLBACK(type_changed_cb), dialog);
+
+	/* Build the treeview for the allow list. */
+	dialog->allow_widget = build_allow_list(dialog);
+	gtk_box_pack_start(GTK_BOX(vbox), dialog->allow_widget, TRUE, TRUE, 0);
+
+	/* Build the treeview for the block list. */
+	dialog->block_widget = build_block_list(dialog);
+	gtk_box_pack_start(GTK_BOX(vbox), dialog->block_widget, TRUE, TRUE, 0);
+
+	/* Add the button box for Add, Remove, Clear */
+	dialog->button_box = bbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
+	gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+	/* Add button */
+	button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+	dialog->add_button = button;
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(add_cb), dialog);
+
+	/* Remove button */
+	button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+	dialog->remove_button = button;
+	gtk_widget_set_sensitive(button, FALSE);
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(remove_cb), dialog);
+
+	/* Clear button */
+	button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
+	dialog->clear_button = button;
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(clear_cb), dialog);
+
+	/* Separator */
+	sep = gtk_hseparator_new();
+	gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
+	gtk_widget_show(sep);
+
+	/* Another button box. */
+	bbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+	gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+	gtk_widget_show(bbox);
+
+	/* Close button */
+	button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(close_cb), dialog);
+
+	if (dialog->account->perm_deny == 2) {
+		gtk_widget_show(dialog->allow_widget);
+		gtk_widget_show(dialog->button_box);
+		dialog->in_allow_list = TRUE;
+	}
+	else if (dialog->account->perm_deny == 4) {
+		gtk_widget_show(dialog->block_widget);
+		gtk_widget_show(dialog->button_box);
+		dialog->in_allow_list = FALSE;
+	}
+
+	return dialog;
+}
+
+void
+gaim_gtk_privacy_dialog_show(void)
+{
+	if (privacy_dialog == NULL)
+		privacy_dialog = privacy_dialog_new();
+
+	gtk_widget_show(privacy_dialog->win);
+	gdk_window_raise(privacy_dialog->win->window);
+}
+
+void
+gaim_gtk_privacy_dialog_hide(void)
+{
+	if (privacy_dialog == NULL)
+		return;
+
+	gtk_widget_destroy(privacy_dialog->win);
+	privacy_dialog = NULL;
+}
+
+static void
+destroy_request_data(GaimGtkPrivacyRequestData *data)
+{
+	if (data->name != NULL)
+		g_free(data->name);
+
+	g_free(data);
+}
+
+static void
+confirm_permit_block_cb(GaimGtkPrivacyRequestData *data, int option)
+{
+	if (data->block)
+		gaim_privacy_deny_add(data->account, data->name);
+	else
+		gaim_privacy_permit_add(data->account, data->name);
+
+	destroy_request_data(data);
+}
+
+static void
+add_permit_block_cb(GaimGtkPrivacyRequestData *data, const char *name)
+{
+	data->name = g_strdup(name);
+
+	confirm_permit_block_cb(data, 0);
+}
+
+void
+gaim_gtk_request_add_permit(GaimAccount *account, const char *name)
+{
+	GaimGtkPrivacyRequestData *data;
+
+	g_return_if_fail(account != NULL);
+
+	data = g_new0(GaimGtkPrivacyRequestData, 1);
+	data->account = account;
+	data->name    = g_strdup(name);
+	data->block   = FALSE;
+
+	if (name == NULL) {
+		gaim_request_input(account, _("Permit User"),
+			_("Type a user you permit to contact you."),
+			_("Please enter the name of the user you wish to be "
+			  "able to contact you."),
+			NULL, FALSE, FALSE,
+			_("Permit"), G_CALLBACK(add_permit_block_cb),
+			_("Cancel"), G_CALLBACK(destroy_request_data),
+			data);
+	}
+	else {
+		char *primary = g_strdup_printf(_("Allow %s to contact you?"), name);
+		char *secondary =
+			g_strdup_printf(_("Are you sure you wish to allow "
+							  "%s to contact you?"), name);
+
+
+		gaim_request_action(account, _("Permit User"), primary, secondary,
+							0, data, 2,
+							_("Permit"), G_CALLBACK(confirm_permit_block_cb),
+							_("Cancel"), G_CALLBACK(destroy_request_data));
+
+		g_free(primary);
+		g_free(secondary);
+	}
+}
+
+void
+gaim_gtk_request_add_block(GaimAccount *account, const char *name)
+{
+	GaimGtkPrivacyRequestData *data;
+
+	g_return_if_fail(account != NULL);
+
+	data = g_new0(GaimGtkPrivacyRequestData, 1);
+	data->account = account;
+	data->name    = g_strdup(name);
+	data->block   = TRUE;
+
+	if (name == NULL) {
+		gaim_request_input(account, _("Block User"),
+			_("Type a user to block."),
+			_("Please enter the name of the user you wish to block."),
+			NULL, FALSE, FALSE,
+			_("Block"), G_CALLBACK(add_permit_block_cb),
+			_("Cancel"), G_CALLBACK(destroy_request_data),
+			data);
+	}
+	else {
+		char *primary = g_strdup_printf(_("Block %s?"), name);
+		char *secondary =
+			g_strdup_printf(_("Are you sure you want to block %s?"), name);
+
+		gaim_request_action(account, _("Block User"), primary, secondary,
+							0, data, 2,
+							_("Block"), G_CALLBACK(confirm_permit_block_cb),
+							_("Cancel"), G_CALLBACK(destroy_request_data));
+
+		g_free(primary);
+		g_free(secondary);
+	}
+}
+
+static void
+gaim_gtk_permit_added_removed(GaimAccount *account, const char *name)
+{
+	if (privacy_dialog != NULL)
+		rebuild_allow_list(privacy_dialog);
+}
+
+static void
+gaim_gtk_deny_added_removed(GaimAccount *account, const char *name)
+{
+	if (privacy_dialog != NULL)
+		rebuild_block_list(privacy_dialog);
+}
+
+static GaimPrivacyUiOps privacy_ops =
+{
+	gaim_gtk_permit_added_removed,
+	gaim_gtk_permit_added_removed,
+	gaim_gtk_deny_added_removed,
+	gaim_gtk_deny_added_removed
+};
+
+GaimPrivacyUiOps *
+gaim_gtk_privacy_get_ui_ops(void)
+{
+	return &privacy_ops;
+}
+
+void
+gaim_gtk_privacy_init(void)
+{
+}