* Pidgin is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA #include "pidginaccountchooser.h" GtkWidget *remove_button; GtkWidget *removeall_button; GtkListStore *allow_store; GtkListStore *block_store; } PidginPrivacyRequestData; PurpleAccountPrivacyType type; { N_("Allow all users to contact me"), PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL }, { N_("Allow only the users on my buddy list"), PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST }, { N_("Allow only the users below"), PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS }, { N_("Block all users"), PURPLE_ACCOUNT_PRIVACY_DENY_ALL }, { N_("Block only the users below"), PURPLE_ACCOUNT_PRIVACY_DENY_USERS } static const size_t menu_entry_count = sizeof(menu_entries) / sizeof(*menu_entries); static PidginPrivacyDialog *privacy_dialog = NULL; rebuild_allow_list(PidginPrivacyDialog *dialog) gtk_list_store_clear(dialog->allow_store); for (l = purple_account_privacy_get_permitted(dialog->account); 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); rebuild_block_list(PidginPrivacyDialog *dialog) gtk_list_store_clear(dialog->block_store); for (l = purple_account_privacy_get_denied(dialog->account); 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); user_selected_cb(GtkTreeSelection *sel, PidginPrivacyDialog *dialog) gtk_widget_set_sensitive(dialog->remove_button, TRUE); build_list(PidginPrivacyDialog *dialog, GtkListStore *model, GtkWidget **ret_treeview) GtkTreeViewColumn *column; 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, 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); sw = pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 200); 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); build_allow_list(PidginPrivacyDialog *dialog) dialog->allow_store = gtk_list_store_new(1, G_TYPE_STRING); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->allow_store), 0, GTK_SORT_ASCENDING); widget = build_list(dialog, dialog->allow_store, &list); dialog->allow_list = list; rebuild_allow_list(dialog); build_block_list(PidginPrivacyDialog *dialog) dialog->block_store = gtk_list_store_new(1, G_TYPE_STRING); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->block_store), 0, GTK_SORT_ASCENDING); widget = build_list(dialog, dialog->block_store, &list); dialog->block_list = list; rebuild_block_list(dialog); destroy_cb(GtkWidget *w, GdkEvent *event, PidginPrivacyDialog *dialog) pidgin_privacy_dialog_hide(); select_account_cb(GtkWidget *chooser, PidginPrivacyDialog *dialog) PurpleAccount *account = pidgin_account_chooser_get_selected(chooser); dialog->account = account; for (i = 0; i < menu_entry_count; i++) { if (menu_entries[i].type == purple_account_get_privacy_type(account)) { gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->type_menu), i); rebuild_allow_list(dialog); rebuild_block_list(dialog); * TODO: Setting the permit/deny setting needs to go through privacy.c * Even better: the privacy API needs to not suck. type_changed_cb(GtkComboBox *combo, PidginPrivacyDialog *dialog) PurpleAccountPrivacyType new_type = menu_entries[gtk_combo_box_get_active(combo)].type; purple_account_set_privacy_type(dialog->account, new_type); purple_serv_set_permit_deny(purple_account_get_connection(dialog->account)); gtk_widget_hide(dialog->allow_widget); gtk_widget_hide(dialog->block_widget); gtk_widget_hide(dialog->button_box); if (new_type == PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS) { gtk_widget_show(dialog->allow_widget); gtk_widget_show_all(dialog->button_box); dialog->in_allow_list = TRUE; else if (new_type == PURPLE_ACCOUNT_PRIVACY_DENY_USERS) { gtk_widget_show(dialog->block_widget); gtk_widget_show_all(dialog->button_box); dialog->in_allow_list = FALSE; gtk_widget_show_all(dialog->close_button); gtk_widget_show(dialog->button_box); purple_blist_schedule_save(); pidgin_blist_refresh(purple_blist_get_default()); add_cb(GtkWidget *button, PidginPrivacyDialog *dialog) if (dialog->in_allow_list) pidgin_request_add_permit(dialog->account, NULL); pidgin_request_add_block(dialog->account, NULL); remove_cb(GtkWidget *button, PidginPrivacyDialog *dialog) if (dialog->in_allow_list && dialog->allow_store == NULL) if (!dialog->in_allow_list && dialog->block_store == NULL) if (dialog->in_allow_list) { model = GTK_TREE_MODEL(dialog->allow_store); sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->allow_list)); 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); if (dialog->in_allow_list) purple_account_privacy_permit_remove(dialog->account, name, FALSE); purple_account_privacy_deny_remove(dialog->account, name, FALSE); removeall_cb(GtkWidget *button, PidginPrivacyDialog *dialog) if (dialog->in_allow_list) l = purple_account_privacy_get_permitted(dialog->account); l = purple_account_privacy_get_denied(dialog->account); if (dialog->in_allow_list) purple_account_privacy_permit_remove(dialog->account, user, FALSE); purple_account_privacy_deny_remove(dialog->account, user, FALSE); close_cb(GtkWidget *button, PidginPrivacyDialog *dialog) gtk_widget_destroy(dialog->win); pidgin_privacy_dialog_hide(); static PidginPrivacyDialog * PidginPrivacyDialog *dialog; dialog = g_new0(PidginPrivacyDialog, 1); dialog->win = pidgin_create_dialog(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", TRUE); g_signal_connect(G_OBJECT(dialog->win), "delete_event", G_CALLBACK(destroy_cb), dialog); vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog->win), FALSE, PIDGIN_HIG_BORDER); _("Changes to privacy settings take effect immediately.")); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_label_set_xalign(GTK_LABEL(label), 0); dropdown = pidgin_account_chooser_new(NULL, FALSE); pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Set privacy for:"), NULL, dropdown, TRUE, NULL); g_signal_connect(dropdown, "changed", G_CALLBACK(select_account_cb), dialog->account = pidgin_account_chooser_get_selected(dropdown); /* Add the drop-down list with the allow/block types. */ dialog->type_menu = gtk_combo_box_text_new(); gtk_box_pack_start(GTK_BOX(vbox), dialog->type_menu, FALSE, FALSE, 0); gtk_widget_show(dialog->type_menu); for (i = 0; i < menu_entry_count; i++) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(dialog->type_menu), _(menu_entries[i].text)); if (menu_entries[i].type == purple_account_get_privacy_type(dialog->account)) gtk_combo_box_set_active(GTK_COMBO_BOX(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, Remove All */ dialog->button_box = pidgin_dialog_get_action_area(GTK_DIALOG(dialog->win)); button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_ADD, G_CALLBACK(add_cb), dialog); dialog->add_button = button; button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_REMOVE, G_CALLBACK(remove_cb), dialog); dialog->remove_button = button; /* TODO: This button should be sensitive/invisitive more cleverly */ gtk_widget_set_sensitive(button, FALSE); button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), _("Remove Al_l"), G_CALLBACK(removeall_cb), dialog); dialog->removeall_button = button; button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_CLOSE, G_CALLBACK(close_cb), dialog); dialog->close_button = button; type_changed_cb(GTK_COMBO_BOX(dialog->type_menu), dialog); if (purple_account_get_privacy_type(dialog->account) == PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS) { gtk_widget_show(dialog->allow_widget); gtk_widget_show(dialog->button_box); dialog->in_allow_list = TRUE; else if (purple_account_get_privacy_type(dialog->account) == PURPLE_ACCOUNT_PRIVACY_DENY_USERS) { gtk_widget_show(dialog->block_widget); gtk_widget_show(dialog->button_box); dialog->in_allow_list = FALSE; pidgin_privacy_dialog_show(void) g_return_if_fail(purple_connections_get_all() != NULL); if (privacy_dialog == NULL) privacy_dialog = privacy_dialog_new(); gtk_widget_show(privacy_dialog->win); gdk_window_raise(gtk_widget_get_window(privacy_dialog->win)); pidgin_privacy_dialog_hide(void) if (privacy_dialog == NULL) g_object_unref(G_OBJECT(privacy_dialog->allow_store)); g_object_unref(G_OBJECT(privacy_dialog->block_store)); destroy_request_data(PidginPrivacyRequestData *data) confirm_permit_block_cb(PidginPrivacyRequestData *data, int option) purple_account_privacy_deny(data->account, data->name); purple_account_privacy_allow(data->account, data->name); destroy_request_data(data); add_permit_block_cb(PidginPrivacyRequestData *data, const char *name) data->name = g_strdup(name); confirm_permit_block_cb(data, 0); pidgin_request_add_permit(PurpleAccount *account, const char *name) PidginPrivacyRequestData *data; g_return_if_fail(account != NULL); data = g_new0(PidginPrivacyRequestData, 1); data->name = g_strdup(name); purple_request_input(account, _("Permit User"), _("Type a user you permit to contact you."), _("Please enter the name of the user you wish to be " NULL, FALSE, FALSE, NULL, _("_Permit"), G_CALLBACK(add_permit_block_cb), _("Cancel"), G_CALLBACK(destroy_request_data), purple_request_cpar_from_account(account), char *primary = g_strdup_printf(_("Allow %s to contact you?"), name); g_strdup_printf(_("Are you sure you wish to allow " "%s to contact you?"), name); purple_request_action(account, _("Permit User"), primary, secondary, 0, purple_request_cpar_from_account(account), _("_Permit"), G_CALLBACK(confirm_permit_block_cb), _("Cancel"), G_CALLBACK(destroy_request_data)); pidgin_request_add_block(PurpleAccount *account, const char *name) PidginPrivacyRequestData *data; g_return_if_fail(account != NULL); data = g_new0(PidginPrivacyRequestData, 1); data->name = g_strdup(name); purple_request_input(account, _("Block User"), _("Type a user to block."), _("Please enter the name of the user you wish to block."), NULL, FALSE, FALSE, NULL, _("_Block"), G_CALLBACK(add_permit_block_cb), _("Cancel"), G_CALLBACK(destroy_request_data), purple_request_cpar_from_account(account), char *primary = g_strdup_printf(_("Block %s?"), name); g_strdup_printf(_("Are you sure you want to block %s?"), name); purple_request_action(account, _("Block User"), primary, secondary, 0, purple_request_cpar_from_account(account), _("_Block"), G_CALLBACK(confirm_permit_block_cb), _("Cancel"), G_CALLBACK(destroy_request_data)); pidgin_permit_added_removed(PurpleAccount *account, const char *name) if (privacy_dialog != NULL) rebuild_allow_list(privacy_dialog); pidgin_deny_added_removed(PurpleAccount *account, const char *name) if (privacy_dialog != NULL) rebuild_block_list(privacy_dialog); pidgin_privacy_init(void) PurpleAccountUiOps *ops = pidgin_accounts_get_ui_ops(); ops->permit_added = ops->permit_removed = pidgin_permit_added_removed; ops->deny_added = ops->deny_removed = pidgin_deny_added_removed;