diff options
10 files changed, 2239 insertions, 0 deletions
diff --git a/plugins/exchange-operations/ChangeLog b/plugins/exchange-operations/ChangeLog index dea096e0eb..1108d035a7 100644 --- a/plugins/exchange-operations/ChangeLog +++ b/plugins/exchange-operations/ChangeLog @@ -1,3 +1,21 @@ +2005-07-08 Shakti Sen <shprasad@novell.com> + + * exchange-folder-permission.c: Added new file for Folder Permissions. + * exchange-permissions-dialog.c: Added new file for Folder Permissions. + * exchange-permissions-dialog.h: Added new file for Folder Permissions. + * exchange-permissions-dialog.glade: Added newly for Folder Permissions + support. + * org-gnome-folder-permissions.xml: Added new file for Folder + Permissions support. + * exchange-folder-subscription.c: Added new file for Folder + Subscribe/Unsubcribe support. + * exchange-folder-subscription.h: Added new file for Folder + Subscribe/Unsubcribe support. + * exchange-folder.c: Added new file for Folder Subscribe/Unsubcribe + support. + * org-gnome-folder-subscription.xml: Added new file for Folder + Subscribe/Unsubcribe support. + 2005-07-07 Sarfraaz Ahmed <asarfraaz@novell.com> * exchange-account-setup.c : Include exchange-folder-size-display.h diff --git a/plugins/exchange-operations/exchange-folder-permission.c b/plugins/exchange-operations/exchange-folder-permission.c new file mode 100644 index 0000000000..271da02b63 --- /dev/null +++ b/plugins/exchange-operations/exchange-folder-permission.c @@ -0,0 +1,130 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Shakti Sen <shprasad@novell.com> + * Copyright (C) 2005 Novell, Inc. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n.h> +#include <glade/glade.h> +#include <gtk/gtk.h> +#include <gtk/gtkdialog.h> +#include <gconf/gconf-client.h> +#include <libedataserver/e-xml-hash-utils.h> +#include <exchange/exchange-account.h> +#include <e-util/e-dialog-utils.h> +#include "exchange-config-listener.h" +#include "exchange-operations.h" +#include <mail/em-popup.h> +#include <mail/em-menu.h> + +static void org_folder_permissions_cb (EPopup *ep, EPopupItem *p, void *data); +void org_gnome_folder_permissions (EPlugin *ep, EMPopupTargetFolder *t); +void org_gnome_menu_folder_permissions (EPlugin *ep, EMMenuTargetSelect *target); + +gchar *selected_exchange_folder_uri = NULL; + +static EPopupItem popup_items[] = { + { E_POPUP_ITEM, "40.emc.30", N_("Permissions..."), org_folder_permissions_cb, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS } +}; + +static void +popup_free (EPopup *ep, GSList *items, void *data) +{ + g_slist_free (items); +} + +void +org_gnome_folder_permissions (EPlugin *ep, EMPopupTargetFolder *t) +{ + GSList *menus = NULL; + int i = 0; + static int first =1; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + EFolder *folder = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + folder = exchange_account_get_folder (account, t->uri); + + + if (!folder) + return; + + if (! g_strrstr (t->uri, "exchange://") && !folder) + return ; + + selected_exchange_folder_uri = t->uri; + /* for translation*/ + if (first) { + popup_items[0].label = _(popup_items[0].label); + + } + + first++; + + for (i = 0; i < sizeof (popup_items) / sizeof (popup_items[0]); i++) + menus = g_slist_prepend (menus, &popup_items[i]); + + e_popup_add_items (t->target.popup, menus, NULL, popup_free, NULL); + +} + +static void +org_folder_permissions_cb (EPopup *ep, EPopupItem *p, void *data) +{ + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + EFolder *folder = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + folder = exchange_account_get_folder (account, selected_exchange_folder_uri); + if (folder) + exchange_permissions_dialog_new (account, folder, NULL); + +} + +void +org_gnome_menu_folder_permissions (EPlugin *ep, EMMenuTargetSelect *target) +{ + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + EFolder *folder = NULL; + + if (target == NULL) + return; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + folder = exchange_account_get_folder (account, target->uri); + if (folder) + exchange_permissions_dialog_new (account, folder, NULL); +} diff --git a/plugins/exchange-operations/exchange-folder-subscription.c b/plugins/exchange-operations/exchange-folder-subscription.c new file mode 100644 index 0000000000..c54e292ccc --- /dev/null +++ b/plugins/exchange-operations/exchange-folder-subscription.c @@ -0,0 +1,229 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Shakti Sen <shprasad@novell.com> + * Copyright (C) 2005 Novell, Inc. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <glade/glade-xml.h> +#include <gtk/gtk.h> +#include <exchange/e-folder.h> +#include <exchange-account.h> +#include <exchange-hierarchy.h> +#include "exchange-hierarchy-foreign.h" +#include <exchange/e2k-types.h> +#include <exchange/exchange-types.h> +#include <e2k-propnames.h> +#include <libedataserver/e-xml-hash-utils.h> +#include <libedataserverui/e-name-selector.h> +#include "exchange-config-listener.h" + + +static void +user_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (name_selector_dialog)); +} + +static void +user_clicked (GtkWidget *button, ENameSelector *name_selector) +{ + ENameSelectorDialog *name_selector_dialog; + + name_selector_dialog = e_name_selector_peek_dialog (name_selector); + gtk_window_set_modal (GTK_WINDOW (name_selector_dialog), TRUE); + gtk_widget_show (GTK_WIDGET (name_selector_dialog)); +} + + +static GtkWidget * +setup_name_selector (GladeXML *glade_xml, ENameSelector **name_selector_ret) +{ + ENameSelector *name_selector; + ENameSelectorModel *name_selector_model; + ENameSelectorDialog *name_selector_dialog; + GtkWidget *placeholder; + GtkWidget *widget; + GtkWidget *button; + + placeholder = glade_xml_get_widget (glade_xml, "user-picker-placeholder"); + g_assert (GTK_IS_CONTAINER (placeholder)); + + name_selector = e_name_selector_new (); + + name_selector_model = e_name_selector_peek_model (name_selector); + /* FIXME Limit to one user */ + e_name_selector_model_add_section (name_selector_model, "User", "User", NULL); + + /* Listen for responses whenever the dialog is shown */ + name_selector_dialog = e_name_selector_peek_dialog (name_selector); + g_signal_connect (name_selector_dialog, "response", + G_CALLBACK (user_response), name_selector); + + widget = GTK_WIDGET (e_name_selector_peek_section_entry (name_selector, "User")); + gtk_widget_show (widget); + + button = glade_xml_get_widget (glade_xml, "button-user"); + g_signal_connect (button, "clicked", G_CALLBACK (user_clicked), name_selector); + gtk_box_pack_start (GTK_BOX (placeholder), widget, TRUE, TRUE, 6); + *name_selector_ret = name_selector; + + return widget; +} + +static void +setup_folder_name_combo (GladeXML *glade_xml) +{ + GtkWidget *combo; + GList *string_list; + char *strings[] = { + "Calendar", + "Inbox", + "Contacts", + "Tasks", + NULL + /* FIXME: Should these be translated? */ + }; + int i; + + combo = glade_xml_get_widget (glade_xml, "folder-name-combo"); + g_assert (GTK_IS_COMBO (combo)); + + string_list = NULL; + for (i = 0; strings[i] != NULL; i ++) + string_list = g_list_append (string_list, strings[i]); + gtk_combo_set_popdown_strings (GTK_COMBO (combo), string_list); + g_list_free (string_list); + + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), "Calendar"); +} + +static void +folder_name_entry_changed_callback (GtkEditable *editable, + void *data) +{ + GtkDialog *dialog = GTK_DIALOG (data); + const char *folder_name_text = gtk_entry_get_text (GTK_ENTRY (editable)); + + if (*folder_name_text == '\0') + gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE); + else + gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, TRUE); +} + +static void +setup_server_option_menu (GladeXML *glade_xml, gchar *mail_account) +{ + GtkWidget *widget; + GtkWidget *menu; + GtkWidget *menu_item; + + widget = glade_xml_get_widget (glade_xml, "server-option-menu"); + g_return_if_fail (GTK_IS_OPTION_MENU (widget)); + + menu = gtk_menu_new (); + gtk_widget_show (menu); + + menu_item = gtk_menu_item_new_with_label (mail_account); + + gtk_widget_show (menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + + + gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu); + + /* FIXME: Default to the current storage in the shell view. */ +} + + +gboolean +create_folder_subscription_dialog (gchar *mail_account, gchar **user_email_address_ret, gchar **folder_name_ret) +{ + ENameSelector *name_selector; + GladeXML *glade_xml; + GtkWidget *dialog; + GtkWidget *name_selector_widget; + GtkWidget *folder_name_entry; + char *user_email_address = NULL; + int response; + EDestinationStore *destination_store; + GList *destinations; + EDestination *destination; + gchar *temp; + + + glade_xml = glade_xml_new (CONNECTOR_GLADEDIR "/e-foreign-folder-dialog.glade", + NULL, NULL); + g_return_val_if_fail (glade_xml != NULL, FALSE); + + dialog = glade_xml_get_widget (glade_xml, "dialog"); + g_return_val_if_fail (dialog != NULL, FALSE); + + name_selector_widget = setup_name_selector (glade_xml, &name_selector); + setup_server_option_menu (glade_xml, mail_account); + setup_folder_name_combo (glade_xml); + folder_name_entry = glade_xml_get_widget (glade_xml, "folder-name-entry"); + + /* Connect the callback to set the OK button insensitive when there is + no text in the folder_name_entry. Notice that we put a value there + by default so the OK button is sensitive by default. */ + g_signal_connect (folder_name_entry, "changed", + G_CALLBACK (folder_name_entry_changed_callback), dialog); + + while (TRUE) { + response = gtk_dialog_run (GTK_DIALOG (dialog)); + if (response == GTK_RESPONSE_CANCEL) { + gtk_widget_destroy (dialog); + g_object_unref (name_selector); + return FALSE; + } + destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY (GTK_ENTRY (name_selector_widget))); + destinations = e_destination_store_list_destinations (destination_store); + if (!destinations) { + gtk_widget_destroy (dialog); + g_object_unref (name_selector); + return FALSE; + } + destination = destinations->data; + user_email_address = g_strdup (e_destination_get_email (destination)); + g_list_free (destinations); + + if (user_email_address != NULL && *user_email_address != '\0') + break; + + /* It would be nice to insensitivize the OK button appropriately instead of doing this, but unfortunately we can't do this for the + Bonobo control. */ + e_notice (dialog, GTK_MESSAGE_ERROR, ("Please select a user.")); + + + } + gtk_widget_show_all (dialog); + + if (user_email_address) + *user_email_address_ret = user_email_address; + *folder_name_ret = g_strdup (gtk_entry_get_text (GTK_ENTRY (folder_name_entry))); + + gtk_widget_destroy (dialog); + g_object_unref (name_selector); + return TRUE; + +} + diff --git a/plugins/exchange-operations/exchange-folder-subscription.h b/plugins/exchange-operations/exchange-folder-subscription.h new file mode 100644 index 0000000000..f8722ba49b --- /dev/null +++ b/plugins/exchange-operations/exchange-folder-subscription.h @@ -0,0 +1,4 @@ +#ifndef __EXCHANGE_FOLDER_SUBSCRIPTION_H__ +#define __EXCHANGE_FOLDER_SUBSCRIPTION_H__ + +#endif diff --git a/plugins/exchange-operations/exchange-folder.c b/plugins/exchange-operations/exchange-folder.c new file mode 100644 index 0000000000..ac9269902a --- /dev/null +++ b/plugins/exchange-operations/exchange-folder.c @@ -0,0 +1,417 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Shakti Sen <shprasad@novell.com> + * Copyright (C) 2005 Novell, Inc. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <gtk/gtkdialog.h> +#include <gconf/gconf-client.h> +#include <exchange-hierarchy.h> +#include <calendar/gui/e-cal-popup.h> +#include <mail/em-popup.h> +#include <mail/em-menu.h> +#include "exchange-operations.h" +#include "addressbook/gui/widgets/eab-popup.h" + + +void org_gnome_folder_subscription (EPlugin *ep, EMMenuTargetSelect *target); +void org_gnome_check_subscribed (EPlugin *ep, ECalPopupTargetSource *target); +void org_gnome_folder_unsubscribe (EPlugin *ep, EPopupItem *p, void *data); +void org_gnome_check_address_book_subscribed (EPlugin *ep, EABPopupTargetSource *target); +void org_gnome_folder_ab_unsubscribe (EPlugin *ep, EPopupItem *p, void *data); +void org_gnome_check_inbox_subscribed (EPlugin *ep, EMPopupTargetFolder *target); +void org_gnome_folder_inbox_unsubscribe (EPlugin *ep, EPopupItem *p, void *data); +void popup_free (EPopup *ep, GSList *items, void *data); +void popup_inbox_free (EPopup *ep, GSList *items, void *data); +void popup_ab_free (EPopup *ep, GSList *items, void *data); + +#define CONF_KEY_SELECTED_CAL_SOURCES "/apps/evolution/calendar/display/selected_calendars" + + +static EPopupItem popup_inbox_items[] = { + { E_POPUP_ITEM, "29.inbox_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_inbox_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS } +}; + +void +popup_inbox_free (EPopup *ep, GSList *items, void *data) +{ + g_slist_free (items); +} + +void +org_gnome_folder_inbox_unsubscribe (EPlugin *ep, EPopupItem *p, void *data) +{ + // To be done: +} + +void +org_gnome_check_inbox_subscribed (EPlugin *ep, EMPopupTargetFolder *target) +{ + GSList *menus = NULL; + int i = 0; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + gchar *path = NULL; + gchar *sub_folder = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + path = g_strdup_printf (target->uri + strlen ("exchange://") + strlen (account->account_filename)); + sub_folder = strchr (path, '@'); + + if (!sub_folder) + return; + + for (i = 0; i < sizeof (popup_inbox_items) / sizeof (popup_inbox_items[0]); i++) + menus = g_slist_prepend (menus, &popup_inbox_items[i]); + + e_popup_add_items (target->target.popup, menus, NULL, popup_inbox_free, target); + g_free (path); +} + +static EPopupItem popup_items[] = { + { E_POPUP_ITEM, "29.calendar_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS } +}; + +void +popup_free (EPopup *ep, GSList *items, void *data) +{ + g_slist_free (items); +} + +static EPopupItem popup_ab_items[] = { + { E_POPUP_ITEM, "29.address_book_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_ab_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS } +}; + +void +popup_ab_free (EPopup *ep, GSList *items, void *data) +{ + g_slist_free (items); +} + +void +org_gnome_check_address_book_subscribed (EPlugin *ep, EABPopupTargetSource *target) +{ + GSList *menus = NULL; + int i = 0; + ESource *source = NULL; + gchar *uri = NULL; + gchar *path = NULL; + char *sub_folder = NULL; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + source = e_source_selector_peek_primary_selection (target->selector); + uri = e_source_get_uri (source); + path = g_strdup_printf (uri + strlen ("exchange://") + strlen (account->account_filename)); + sub_folder = strchr (path, '@'); + + if (!sub_folder) + return; + + for (i = 0; i < sizeof (popup_ab_items) / sizeof (popup_ab_items[0]); i++) + menus = g_slist_prepend (menus, &popup_ab_items[i]); + + e_popup_add_items (target->target.popup, menus, NULL, popup_ab_free, target); + g_free (path); + +} + +void +org_gnome_check_subscribed (EPlugin *ep, ECalPopupTargetSource *target) +{ + GSList *menus = NULL; + int i = 0; + ESource *source = NULL; + gchar *ruri = NULL; + gchar *path = NULL; + char *sub_folder = NULL; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + source = e_source_selector_peek_primary_selection (target->selector); + ruri = e_source_peek_relative_uri (source); + path = g_strdup_printf (ruri + strlen (account->account_filename)); + sub_folder = strchr (path, '@'); + + if (!sub_folder) + return; + + for (i = 0; i < sizeof (popup_items) / sizeof (popup_items[0]); i++) + menus = g_slist_prepend (menus, &popup_items[i]); + + e_popup_add_items (target->target.popup, menus, NULL, popup_free, target); + g_free (path); +} + +static void +unsubscribe_dialog_ab_response (GtkDialog *dialog, int response, gpointer data) +{ + + if (response == GTK_RESPONSE_OK) { + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + gchar *path = NULL; + gchar *uri = NULL; + const char *source_uid = NULL; + GConfClient *client; + ESourceGroup *source_group = NULL; + ESource *source = NULL; + EABPopupTargetSource *target = data; + + client = gconf_client_get_default (); + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + source = e_source_selector_peek_primary_selection (target->selector); + uri = e_source_get_uri (source); + path = g_strdup_printf (uri + strlen ("exchange://") + strlen (account->account_filename)); + source_uid = e_source_peek_uid (source); + + exchange_account_remove_shared_folder (account, path); + + source_group = e_source_peek_group (source); + e_source_group_remove_source_by_uid (source_group, source_uid); + g_free (path); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + if (response == GTK_RESPONSE_CANCEL) + gtk_widget_destroy (GTK_WIDGET (dialog)); + if (response == GTK_RESPONSE_DELETE_EVENT) + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void +unsubscribe_dialog_response (GtkDialog *dialog, int response, gpointer data) +{ + + if (response == GTK_RESPONSE_OK) { + GSList *accounts, *acc; + GSList *ids, *node_to_be_deleted; + ExchangeAccount *account = NULL; + gchar *path = NULL; + gchar *ruri = NULL; + const char *source_uid = NULL; + GConfClient *client; + ESourceGroup *source_group = NULL; + ESource *source = NULL; + ECalPopupTargetSource *target = data; + + client = gconf_client_get_default (); + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + source = e_source_selector_peek_primary_selection (target->selector); + ruri = e_source_peek_relative_uri (source); + source_uid = e_source_peek_uid (source); + + path = g_strdup_printf (ruri + strlen (account->account_filename)); + exchange_account_remove_shared_folder (account, path); + ids = gconf_client_get_list (client, + CONF_KEY_SELECTED_CAL_SOURCES, + GCONF_VALUE_STRING, NULL); + if (ids) { + node_to_be_deleted = g_slist_find_custom ( + ids, + source_uid, + (GCompareFunc) strcmp); + if (node_to_be_deleted) { + g_free (node_to_be_deleted->data); + ids = g_slist_delete_link (ids, + node_to_be_deleted); + gconf_client_set_list (client, + CONF_KEY_SELECTED_CAL_SOURCES, + GCONF_VALUE_STRING, ids, NULL); + } + g_slist_foreach (ids, (GFunc) g_free, NULL); + g_slist_free (ids); + } + + source_group = e_source_peek_group (source); + e_source_group_remove_source_by_uid (source_group, source_uid); + g_free (path); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + if (response == GTK_RESPONSE_CANCEL) + gtk_widget_destroy (GTK_WIDGET (dialog)); + if (response == GTK_RESPONSE_DELETE_EVENT) + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +void +org_gnome_folder_ab_unsubscribe (EPlugin *ep, EPopupItem *p, void *data) +{ + GtkWidget *dialog = NULL; + EABPopupTargetSource *target = data; + ESource *source = NULL; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + gchar *title = NULL; + gchar *displayed_folder_name = NULL; + gint response; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + source = e_source_selector_peek_primary_selection (target->selector); + displayed_folder_name = e_source_peek_name (source); + dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("Really unsubscribe from folder \"%s\"?"), + displayed_folder_name); + + gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 6); + + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6); + + title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name); + gtk_window_set_title (GTK_WINDOW (dialog), title); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + g_free (title); + g_free (displayed_folder_name); + + gtk_widget_show (dialog); + unsubscribe_dialog_ab_response (dialog, response, data); +} +void +org_gnome_folder_unsubscribe (EPlugin *ep, EPopupItem *p, void *data) +{ + GtkWidget *dialog = NULL; + ECalPopupTargetSource *target = data; + ESource *source = NULL; + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + gchar *title = NULL; + gchar *displayed_folder_name = NULL; + gint response; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + source = e_source_selector_peek_primary_selection (target->selector); + displayed_folder_name = e_source_peek_name (source); + dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("Really unsubscribe from folder \"%s\"?"), + displayed_folder_name); + + gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 6); + + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6); + + title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name); + gtk_window_set_title (GTK_WINDOW (dialog), title); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + g_free (title); + g_free (displayed_folder_name); + + gtk_widget_show (dialog); + unsubscribe_dialog_response (dialog, response, data); +} + + +void +org_gnome_folder_subscription (EPlugin *ep, EMMenuTargetSelect *target) +{ + GSList *accounts, *acc; + ExchangeAccount *account = NULL; + EFolder *folder = NULL; + ExchangeHierarchy *hier; + ExchangeAccountFolderResult result; + gchar *folder_display_name = NULL; + gchar *folder_type = NULL; + gchar *physical_uri = NULL; + gchar *user_email_address = NULL, *storage_name, *folder_name = NULL; + + accounts = exchange_config_listener_get_accounts (exchange_global_config_listener); + for (acc = accounts; acc; acc = acc->next) { + account = acc->data; + } + + create_folder_subscription_dialog (account->account_name, &user_email_address, &folder_name); + + if (user_email_address && folder_name) + result = exchange_account_discover_shared_folder (account, user_email_address, folder_name, &folder); + + if (!folder) { + return; + } + + hier = e_folder_exchange_get_hierarchy (folder); + folder_display_name = g_strdup_printf ("%s's %s", hier->owner_name, folder_name); + folder_type = e_folder_get_type_string (folder); + physical_uri = e_folder_get_physical_uri (folder); + if (!(strcmp (folder_type, "calendar")) || + !(strcmp (folder_type, "calendar/public"))) { + add_folder_esource (account, EXCHANGE_CALENDAR_FOLDER, folder_display_name, physical_uri); + } + else if (!(strcmp (folder_type, "tasks")) || + !(strcmp (folder_type, "tasks/public"))) { + add_folder_esource (account, EXCHANGE_TASKS_FOLDER, folder_display_name, physical_uri); + } + else if (!(strcmp (folder_type, "contacts")) || + !(strcmp (folder_type, "contacts/public")) || + !(strcmp (folder_type, "contacts/ldap"))) { + add_folder_esource (account, EXCHANGE_CONTACTS_FOLDER, folder_display_name, physical_uri); +} + +g_free (folder_display_name); +exchange_account_open_folder (account, g_strdup_printf ("/%s", user_email_address)); +} + diff --git a/plugins/exchange-operations/exchange-permissions-dialog.c b/plugins/exchange-operations/exchange-permissions-dialog.c new file mode 100644 index 0000000000..7274061e6f --- /dev/null +++ b/plugins/exchange-operations/exchange-permissions-dialog.c @@ -0,0 +1,786 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Copyright (C) 2002-2004 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "exchange-permissions-dialog.h" +#include "exchange-hierarchy.h" + +#include "e2k-context.h" +#include "e2k-global-catalog.h" +#include "e2k-propnames.h" +#include "e2k-sid.h" +#include "e2k-security-descriptor.h" +#include "e2k-user-dialog.h" +#include "e2k-uri.h" +#include "e2k-utils.h" +#include "e-folder-exchange.h" +#include "exchange-account.h" + +#include <e-util/e-dialog-utils.h> +#include <glade/glade-xml.h> +#include <gtk/gtkbox.h> +#include <gtk/gtkcellrenderertext.h> +#include <gtk/gtkliststore.h> +#include <gtk/gtkmenuitem.h> +#include <gtk/gtkmenushell.h> +#include <gtk/gtkstock.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtk.h> + +#undef GTK_DISABLE_DEPRECATED + +struct _ExchangePermissionsDialogPrivate { + ExchangeAccount *account; + char *base_uri, *folder_path; + E2kSecurityDescriptor *sd; + gboolean changed; + gboolean frozen; + + /* The user list */ + GtkTreeView *list_view; + GtkListStore *list_store; + GtkTreeSelection *list_selection; + E2kSid *selected_sid; + + /* The Role menu */ + GtkComboBox *role_optionmenu; + + GtkWidget *separator, *custom; + E2kPermissionsRole selected_role; + + /* The toggles */ + GtkToggleButton *read_items_check, *create_items_check; + GtkToggleButton *create_subfolders_check, *folder_visible_check; + GtkToggleButton *folder_owner_check, *folder_contact_check; + GtkToggleButton *edit_none_radio, *edit_own_radio, *edit_all_radio; + GtkToggleButton *delete_none_radio, *delete_own_radio, *delete_all_radio; + guint32 selected_perms; +}; + +enum { + EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN, + EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN, + EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, + + EXCHANGE_PERMISSIONS_DIALOG_NUM_COLUMNS +}; + +#define PARENT_TYPE GTK_TYPE_DIALOG +static GtkDialogClass *parent_class = NULL; + +static void +finalize (GObject *object) +{ + ExchangePermissionsDialog *dialog = + EXCHANGE_PERMISSIONS_DIALOG (object); + + g_free (dialog->priv->base_uri); + g_free (dialog->priv->folder_path); + + if (dialog->priv->sd) + g_object_unref (dialog->priv->sd); + + g_free (dialog->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +class_init (GObjectClass *object_class) +{ + parent_class = g_type_class_ref (PARENT_TYPE); + + /* virtual method override */ + object_class->finalize = finalize; +} + +static void +init (GObject *object) +{ + ExchangePermissionsDialog *dialog = + EXCHANGE_PERMISSIONS_DIALOG (object); + + dialog->priv = g_new0 (ExchangePermissionsDialogPrivate, 1); +} + +E2K_MAKE_TYPE (exchange_permissions_dialog, ExchangePermissionsDialog, class_init, init, PARENT_TYPE) + + + +static void get_widgets (ExchangePermissionsDialog *dialog, + GladeXML *xml); +static void setup_user_list (ExchangePermissionsDialog *dialog); +static void display_permissions (ExchangePermissionsDialog *dialog); +static void dialog_response (ExchangePermissionsDialog *dialog, + int response, gpointer user_data); + +static const char *sd_props[] = { + E2K_PR_EXCHANGE_SD_BINARY, + E2K_PR_EXCHANGE_SD_XML +}; +static const int n_sd_props = sizeof (sd_props) / sizeof (sd_props[0]); + +/** + * exchange_permissions_dialog_new: + * @account: an account + * @folder: the folder whose permissions are to be editted + * @parent: a widget in the dialog's parent window + * + * Creates and displays a modeless permissions editor dialog for @folder. + **/ +void +exchange_permissions_dialog_new (ExchangeAccount *account, + EFolder *folder, + GtkWidget *parent) +{ + ExchangePermissionsDialog *dialog; + const char *base_uri, *folder_uri, *folder_path; + E2kContext *ctx; + ExchangeHierarchy *hier; + GladeXML *xml; + GtkWidget *box; + char *title; + E2kHTTPStatus status; + E2kResult *results; + int nresults; + xmlNode *xml_form; + GByteArray *binary_form; + + ctx = exchange_account_get_context (account); + g_return_if_fail (ctx); + xml = glade_xml_new ( + CONNECTOR_GLADEDIR "/exchange-permissions-dialog.glade", + "permissions_vbox", PACKAGE); + g_return_if_fail (xml != NULL); + + /* Create the dialog */ + dialog = g_object_new (EXCHANGE_TYPE_PERMISSIONS_DIALOG, NULL); + + title = g_strdup_printf (_("Permissions for %s"), + e_folder_get_name (folder)); + gtk_window_set_title (GTK_WINDOW (dialog), title); + g_free (title); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + g_signal_connect (dialog, "response", + G_CALLBACK (dialog_response), NULL); + + dialog->priv->changed = FALSE; + + /* Put the widgets from the glade file into it */ + box = glade_xml_get_widget (xml, "permissions_vbox"); + g_object_ref (box); + gtk_widget_unparent (box); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + box, TRUE, TRUE, 0); + g_object_unref (box); + + get_widgets (dialog, xml); + g_object_unref (xml); + + dialog->priv->account = account; + g_object_ref (account); + + hier = e_folder_exchange_get_hierarchy (folder); + base_uri = e_folder_exchange_get_internal_uri (hier->toplevel); + dialog->priv->base_uri = g_strdup (base_uri); + folder_uri = e_folder_exchange_get_internal_uri (folder); + folder_path = e2k_uri_relative (dialog->priv->base_uri, folder_uri); + dialog->priv->folder_path = g_strdup (folder_path); + + /* And fetch the security descriptor */ + status = e2k_context_propfind (ctx, NULL, folder_uri, + sd_props, n_sd_props, + &results, &nresults); + if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || nresults < 1) { + lose: + e_notice (parent, GTK_MESSAGE_ERROR, + _("Could not read folder permissions")); + gtk_widget_destroy (GTK_WIDGET (dialog)); + return; + } + + xml_form = e2k_properties_get_prop (results[0].props, + E2K_PR_EXCHANGE_SD_XML); + binary_form = e2k_properties_get_prop (results[0].props, + E2K_PR_EXCHANGE_SD_BINARY); + if (!xml_form || !binary_form) + goto lose; + + dialog->priv->sd = e2k_security_descriptor_new (xml_form, binary_form); + if (!dialog->priv->sd) + goto lose; + + setup_user_list (dialog); + gtk_widget_show (GTK_WIDGET (dialog)); +} + +static void +dialog_response (ExchangePermissionsDialog *dialog, int response, + gpointer user_data) +{ + E2kContext *ctx; + GByteArray *binsd; + E2kProperties *props; + E2kResultIter *iter; + E2kResult *result; + E2kHTTPStatus status; + + if (response != GTK_RESPONSE_OK || !dialog->priv->changed) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + return; + } + + ctx = exchange_account_get_context (dialog->priv->account); + g_return_if_fail (ctx != NULL); + + binsd = e2k_security_descriptor_to_binary (dialog->priv->sd); + if (!binsd) { + e_notice (dialog, GTK_MESSAGE_ERROR, + _("Could not update folder permissions.")); + return; + } + + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); + + props = e2k_properties_new (); + e2k_properties_set_binary (props, E2K_PR_EXCHANGE_SD_BINARY, binsd); + + /* We use BPROPPATCH here instead of PROPPATCH, because + * PROPPATCH seems to mysteriously fail in someone else's + * folder hierarchy. #29726 + */ + iter = e2k_context_bproppatch_start (ctx, NULL, dialog->priv->base_uri, + (const char **)&dialog->priv->folder_path, 1, + props, FALSE); + e2k_properties_free (props); + + result = e2k_result_iter_next (iter); + if (result) { + status = result->status; + e2k_result_iter_free (iter); + } else + status = e2k_result_iter_free (iter); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog), TRUE); + + if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) { + e_notice (dialog, GTK_MESSAGE_ERROR, + _("Could not update folder permissions. %s"), + status == E2K_HTTP_UNAUTHORIZED ? + _("(Permission denied.)") : ""); + return; + } + + if (response == GTK_RESPONSE_OK) + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + + +static void +set_permissions (ExchangePermissionsDialog *dialog, guint32 perms) +{ + dialog->priv->selected_perms = perms; + dialog->priv->selected_role = e2k_permissions_role_find (perms); + e2k_security_descriptor_set_permissions (dialog->priv->sd, + dialog->priv->selected_sid, + dialog->priv->selected_perms); + + dialog->priv->changed = TRUE; +} + + +/* User list functions */ + +static void +list_view_selection_changed (GtkTreeSelection *selection, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + GtkTreeModel *model; + GtkTreeIter iter; + E2kSid *sid; + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + gtk_tree_model_get (model, &iter, + EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid, + -1); + + dialog->priv->selected_sid = sid; + dialog->priv->selected_perms = + e2k_security_descriptor_get_permissions (dialog->priv->sd, sid); + dialog->priv->selected_role = + e2k_permissions_role_find (dialog->priv->selected_perms); + + /* "Default" or "Anonymous" can't be a Folder contact, but any + * real person can. + */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->folder_contact_check), + e2k_sid_get_sid_type (sid) != E2K_SID_TYPE_WELL_KNOWN_GROUP); + + /* Update role menu and permissions checkboxes */ + display_permissions (dialog); +} + +static void +add_user_to_list (ExchangePermissionsDialog *dialog, E2kSid *sid, gboolean select) +{ + guint32 perms; + E2kPermissionsRole role; + GtkTreeIter iter; + + perms = e2k_security_descriptor_get_permissions (dialog->priv->sd, + sid); + role = e2k_permissions_role_find (perms); + + if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP) + gtk_list_store_insert (dialog->priv->list_store, &iter, 1); + else + gtk_list_store_append (dialog->priv->list_store, &iter); + + gtk_list_store_set (dialog->priv->list_store, &iter, + EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN, + e2k_sid_get_display_name (sid), + EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN, + e2k_permissions_role_get_name (role), + EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, + sid, + -1); + + if (select) + gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter); +} + +static void +add_clicked (GtkButton *button, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + GtkWidget *user_dialog; + E2kGlobalCatalog *gc; + E2kGlobalCatalogStatus status; + E2kGlobalCatalogEntry *entry; + E2kSid *sid2; + const guint8 *bsid, *bsid2; + char *email = NULL; + int result; + gboolean valid; + GtkTreeIter iter; + + gc = exchange_account_get_global_catalog (dialog->priv->account); + if (!gc) { + e_notice (dialog, GTK_MESSAGE_ERROR, + _("Unable to add user to access control list:\n" + "No Global Catalog server is configured for this account.")); + return; + } + + //FIXME: to get the email + if (email == NULL) + return; + + status = e2k_global_catalog_lookup ( + gc, NULL, /* FIXME: cancellable */ + E2K_GLOBAL_CATALOG_LOOKUP_BY_EMAIL, email, + E2K_GLOBAL_CATALOG_LOOKUP_SID, &entry); + switch (status) { + case E2K_GLOBAL_CATALOG_OK: + break; + case E2K_GLOBAL_CATALOG_NO_SUCH_USER: + e_notice (dialog, GTK_MESSAGE_ERROR, + _("No such user %s"), email); + break; + case E2K_GLOBAL_CATALOG_NO_DATA: + e_notice (dialog, GTK_MESSAGE_ERROR, + _("%s cannot be added to an access control list"), + email); + break; + default: + e_notice (dialog, GTK_MESSAGE_ERROR, + _("Unknown error looking up %s"), email); + break; + } + g_free (email); + if (status != E2K_GLOBAL_CATALOG_OK) + return; + + /* Make sure the user isn't already there. */ + bsid = e2k_sid_get_binary_sid (entry->sid); + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->priv->list_store), &iter); + while (valid) { + gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store), &iter, + EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid2, + -1); + bsid2 = e2k_sid_get_binary_sid (sid2); + if (e2k_sid_binary_sid_equal (bsid, bsid2)) { + e_notice (dialog, GTK_MESSAGE_ERROR, + _("%s is already in the list"), + entry->display_name); + e2k_global_catalog_entry_free (gc, entry); + gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter); + return; + } + + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->priv->list_store), &iter); + } + + add_user_to_list (dialog, entry->sid, TRUE); + + /* Calling set_permissions will cause the sd to take a + * ref on the sid, allowing us to unref it. + */ + set_permissions (dialog, 0); + e2k_global_catalog_entry_free (gc, entry); +} + +static void +remove_clicked (GtkButton *button, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + E2kSid *sid; + GdkModifierType modifiers; + GtkTreeModel *model; + GtkTreeIter iter; + + if (!gtk_tree_selection_get_selected (dialog->priv->list_selection, + &model, &iter)) + return; + gtk_tree_model_get (model, &iter, + EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid, + -1); + gdk_window_get_pointer (NULL, NULL, NULL, &modifiers); + + if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP && + !(modifiers & GDK_SHIFT_MASK)) { + /* You shouldn't normally delete "Default" or "Anonymous". */ + set_permissions (dialog, 0); + } else { + gtk_list_store_remove (dialog->priv->list_store, &iter); + e2k_security_descriptor_remove_sid (dialog->priv->sd, sid); + + if (!gtk_list_store_iter_is_valid (dialog->priv->list_store, &iter)) { + /* Select the new last row. Love that API... */ + gtk_tree_model_iter_nth_child (model, &iter, NULL, + gtk_tree_model_iter_n_children (model, NULL) - 1); + } + gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter); + + dialog->priv->changed = TRUE; + } +} + +static void +setup_user_list (ExchangePermissionsDialog *dialog) +{ + E2kSecurityDescriptor *sd = dialog->priv->sd; + E2kSid *default_entry; + GList *sids; + + /* FIXME */ + /* gtk_clist_freeze (dialog->priv->clist); */ + + /* Always put "Default" first. */ + default_entry = e2k_security_descriptor_get_default (sd); + add_user_to_list (dialog, default_entry, TRUE); + + sids = e2k_security_descriptor_get_sids (sd); + while (sids) { + if (sids->data != default_entry) + add_user_to_list (dialog, sids->data, FALSE); + sids = sids->next; + } + g_list_free (sids); + + /* gtk_clist_thaw (dialog->priv->clist); */ +} + + +/* Role option menu functions */ + +static void +role_changed (GtkWidget *role_combo, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + int role; + + if (dialog->priv->frozen) + return; + + role = gtk_combo_box_get_active (GTK_COMBO_BOX (role_combo)); + if (role == dialog->priv->selected_role) + return; + if (role >= E2K_PERMISSIONS_ROLE_NUM_ROLES) { + /* The user selected "Custom". Since "Custom" will + * only be there to select when it's already + * selected, this is a no-op. + */ + return; + } + + set_permissions (dialog, e2k_permissions_role_get_perms (role)); + display_permissions (dialog); +} + +static void +display_role (ExchangePermissionsDialog *dialog) +{ + int role = dialog->priv->selected_role; + GtkTreeModel *model; + GtkTreeIter iter; + + if (!gtk_tree_selection_get_selected (dialog->priv->list_selection, + &model, &iter)) + return; + gtk_list_store_set (dialog->priv->list_store, &iter, + EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN, + e2k_permissions_role_get_name (role), + -1); + + if (role == E2K_PERMISSIONS_ROLE_CUSTOM) { + gtk_widget_show (dialog->priv->separator); + gtk_widget_show (dialog->priv->custom); + role = E2K_PERMISSIONS_ROLE_NUM_ROLES + 1; + } + gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->role_optionmenu), role); +} + + + +/* Toggle buttons */ +static void +check_toggled (GtkToggleButton *toggle, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + ExchangePermissionsDialogPrivate *priv = dialog->priv; + guint32 new_perms, value; + + if (dialog->priv->frozen) + return; + + value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_permission")); + + if (gtk_toggle_button_get_active (toggle)) + new_perms = priv->selected_perms | value; + else + new_perms = priv->selected_perms & ~value; + + if (new_perms == priv->selected_perms) + return; + + set_permissions (dialog, new_perms); + display_role (dialog); +} + +static void +radio_toggled (GtkToggleButton *toggle, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + ExchangePermissionsDialogPrivate *priv = dialog->priv; + guint32 new_perms, value, mask; + + if (dialog->priv->frozen || !gtk_toggle_button_get_active (toggle)) + return; + + value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_permission")); + mask = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_mask")); + + new_perms = (priv->selected_perms & ~mask) | value; + if (new_perms == priv->selected_perms) + return; + + set_permissions (dialog, new_perms); + display_role (dialog); +} + +static void +rv_toggle (GtkToggleButton *toggled, gpointer user_data) +{ + ExchangePermissionsDialog *dialog = user_data; + GtkToggleButton *visible = dialog->priv->folder_visible_check; + GtkToggleButton *read = dialog->priv->read_items_check; + + if (dialog->priv->frozen) + return; + + /* If you turn off "Folder visible", then "Read items" turns + * off too. Contrariwise, if you turn on "Read items", then + * "Folder visible" turns on too. + */ + if (toggled == visible && !gtk_toggle_button_get_active (toggled)) + gtk_toggle_button_set_active (read, FALSE); + else if (toggled == read && gtk_toggle_button_get_active (toggled)) + gtk_toggle_button_set_active (visible, TRUE); +} + +static void +display_permissions (ExchangePermissionsDialog *dialog) +{ + GtkToggleButton *radio; + guint32 perms = dialog->priv->selected_perms; + + dialog->priv->frozen = TRUE; + + /* Set up check boxes */ + gtk_toggle_button_set_active (dialog->priv->read_items_check, + perms & E2K_PERMISSION_READ_ANY); + gtk_toggle_button_set_active (dialog->priv->create_items_check, + perms & E2K_PERMISSION_CREATE); + gtk_toggle_button_set_active (dialog->priv->create_subfolders_check, + perms & E2K_PERMISSION_CREATE_SUBFOLDER); + gtk_toggle_button_set_active (dialog->priv->folder_owner_check, + perms & E2K_PERMISSION_OWNER); + gtk_toggle_button_set_active (dialog->priv->folder_contact_check, + (perms & E2K_PERMISSION_CONTACT) && + GTK_WIDGET_SENSITIVE (dialog->priv->folder_contact_check)); + gtk_toggle_button_set_active (dialog->priv->folder_visible_check, + perms & E2K_PERMISSION_FOLDER_VISIBLE); + + /* Set up radio buttons */ + if (perms & E2K_PERMISSION_EDIT_ANY) + radio = dialog->priv->edit_all_radio; + else if (perms & E2K_PERMISSION_EDIT_OWNED) + radio = dialog->priv->edit_own_radio; + else + radio = dialog->priv->edit_none_radio; + gtk_toggle_button_set_active (radio, TRUE); + + if (perms & E2K_PERMISSION_DELETE_ANY) + radio = dialog->priv->delete_all_radio; + else if (perms & E2K_PERMISSION_DELETE_OWNED) + radio = dialog->priv->delete_own_radio; + else + radio = dialog->priv->delete_none_radio; + gtk_toggle_button_set_active (radio, TRUE); + + /* And role menu */ + display_role (dialog); + + dialog->priv->frozen = FALSE; +} + + + +static void +get_widgets (ExchangePermissionsDialog *dialog, GladeXML *xml) +{ + GtkWidget *button; + GtkTreeViewColumn *column; + +#define GET_WIDGET(name, type) dialog->priv->name = type (glade_xml_get_widget (xml, #name)) + + GET_WIDGET (list_view, GTK_TREE_VIEW); + column = gtk_tree_view_column_new_with_attributes ( + _("Name"), gtk_cell_renderer_text_new (), + "text", EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN, NULL); + gtk_tree_view_append_column (dialog->priv->list_view, column); + column = gtk_tree_view_column_new_with_attributes ( + _("Role"), gtk_cell_renderer_text_new (), + "text", EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN, NULL); + gtk_tree_view_append_column (dialog->priv->list_view, column); + + dialog->priv->list_selection = gtk_tree_view_get_selection (dialog->priv->list_view); + gtk_tree_selection_set_mode (dialog->priv->list_selection, + GTK_SELECTION_SINGLE); + g_signal_connect (dialog->priv->list_selection, "changed", + G_CALLBACK (list_view_selection_changed), dialog); + + dialog->priv->list_store = gtk_list_store_new ( + EXCHANGE_PERMISSIONS_DIALOG_NUM_COLUMNS, + G_TYPE_STRING, G_TYPE_STRING, E2K_TYPE_SID); + gtk_tree_view_set_model (dialog->priv->list_view, + GTK_TREE_MODEL (dialog->priv->list_store)); + + button = glade_xml_get_widget (xml, "add_button"); + g_signal_connect (button, "clicked", + G_CALLBACK (add_clicked), dialog); + button = glade_xml_get_widget (xml, "remove_button"); + g_signal_connect (button, "clicked", + G_CALLBACK (remove_clicked), dialog); + + GET_WIDGET (role_optionmenu, GTK_COMBO_BOX); + g_signal_connect (dialog->priv->role_optionmenu, "changed", + G_CALLBACK (role_changed), dialog); + +#define GET_TOGGLE(name, value, callback) \ + GET_WIDGET (name, GTK_TOGGLE_BUTTON); \ + g_object_set_data (G_OBJECT (dialog->priv->name), \ + "mapi_permission", \ + GUINT_TO_POINTER (value)); \ + g_signal_connect (dialog->priv->name, "toggled", \ + G_CALLBACK (callback), dialog) + +#define GET_CHECK(name, value) \ + GET_TOGGLE (name, value, check_toggled) + +#define GET_RADIO(name, value, mask) \ + GET_TOGGLE (name, value, radio_toggled); \ + g_object_set_data (G_OBJECT (dialog->priv->name), \ + "mapi_mask", \ + GUINT_TO_POINTER (mask)) + + GET_CHECK (read_items_check, E2K_PERMISSION_READ_ANY); + GET_CHECK (create_items_check, E2K_PERMISSION_CREATE); + GET_RADIO (edit_none_radio, 0, E2K_PERMISSION_EDIT_MASK); + GET_RADIO (delete_none_radio, 0, E2K_PERMISSION_DELETE_MASK); + GET_RADIO (edit_own_radio, E2K_PERMISSION_EDIT_OWNED, E2K_PERMISSION_EDIT_MASK); + GET_RADIO (delete_own_radio, E2K_PERMISSION_DELETE_OWNED, E2K_PERMISSION_DELETE_MASK); + GET_RADIO (edit_all_radio, (E2K_PERMISSION_EDIT_ANY | E2K_PERMISSION_EDIT_OWNED), E2K_PERMISSION_EDIT_MASK); + GET_RADIO (delete_all_radio, (E2K_PERMISSION_DELETE_ANY | E2K_PERMISSION_DELETE_OWNED), E2K_PERMISSION_DELETE_MASK); + GET_CHECK (create_subfolders_check, E2K_PERMISSION_CREATE_SUBFOLDER); + GET_CHECK (folder_owner_check, E2K_PERMISSION_OWNER); + GET_CHECK (folder_contact_check, E2K_PERMISSION_CONTACT); + GET_CHECK (folder_visible_check, E2K_PERMISSION_FOLDER_VISIBLE); + + g_signal_connect (dialog->priv->folder_visible_check, + "toggled", G_CALLBACK (rv_toggle), dialog); + g_signal_connect (dialog->priv->read_items_check, + "toggled", G_CALLBACK (rv_toggle), dialog); +} + +GtkWidget *exchange_permissions_role_optionmenu_new (char *widget_name, char *string1, char *string2, int int1, int int2); + +GtkWidget * +exchange_permissions_role_optionmenu_new (char *widget_name, char *string1, char *string2, int int1, int int2) +{ + GtkWidget *menu; + const char **roles; + int role; + + menu = gtk_combo_box_new_text (); + roles = g_new (const char *, E2K_PERMISSIONS_ROLE_NUM_ROLES + 1); + for (role = 0; role < E2K_PERMISSIONS_ROLE_NUM_ROLES; role++) { + roles[role] = e2k_permissions_role_get_name (role); + gtk_combo_box_append_text (GTK_COMBO_BOX (menu), roles[role]); + } + + roles[role] = NULL; + + g_free (roles); + + gtk_widget_show (menu); + return menu; +} diff --git a/plugins/exchange-operations/exchange-permissions-dialog.glade b/plugins/exchange-operations/exchange-permissions-dialog.glade new file mode 100644 index 0000000000..348531cd11 --- /dev/null +++ b/plugins/exchange-operations/exchange-permissions-dialog.glade @@ -0,0 +1,578 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> +<requires lib="gnome"/> + +<widget class="GtkWindow" id="window1"> + <property name="visible">True</property> + <property name="title" translatable="yes">window1</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkVBox" id="permissions_vbox"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="list_view"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox1"> + <property name="border_width">4</property> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_SPREAD</property> + <property name="spacing">10</property> + + <child> + <widget class="GtkButton" id="add_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-add</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="remove_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkTable" id="table2"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="homogeneous">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">0</property> + + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes"> </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="label" translatable="yes"> </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Permissions</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes">Role: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="Custom" id="role_optionmenu"> + <property name="visible">True</property> + <property name="creation_function">exchange_permissions_role_optionmenu_new</property> + <property name="int1">0</property> + <property name="int2">0</property> + <property name="last_modification_time">Tue, 06 Aug 2002 20:48:43 GMT</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">True</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkVBox" id="vbox8"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkCheckButton" id="create_items_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Create items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="read_items_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Read items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="create_subfolders_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Create subfolders</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox9"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkRadioButton" id="edit_none_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Cannot Edit</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="edit_own_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Edit Own Items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">edit_none_radio</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="edit_all_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Edit Any Items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">edit_none_radio</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkVBox" id="vbox10"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkCheckButton" id="folder_owner_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Folder owner</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="folder_contact_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Folder contact</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="folder_visible_check"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Folder visible</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox11"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkRadioButton" id="delete_none_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Cannot Delete</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">True</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="delete_own_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Delete Own Items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">delete_none_radio</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="delete_all_radio"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Delete Any Items</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">delete_none_radio</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/plugins/exchange-operations/exchange-permissions-dialog.h b/plugins/exchange-operations/exchange-permissions-dialog.h new file mode 100644 index 0000000000..11598a5e62 --- /dev/null +++ b/plugins/exchange-operations/exchange-permissions-dialog.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* Copyright (C) 2001-2004 Novell, Inc. */ + +#ifndef __EXCHANGE_PERMISSIONS_DIALOG_H__ +#define __EXCHANGE_PERMISSIONS_DIALOG_H__ + +#include <gtk/gtkdialog.h> +#include "e-folder.h" +#include "exchange-types.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define EXCHANGE_TYPE_PERMISSIONS_DIALOG (exchange_permissions_dialog_get_type ()) +#define EXCHANGE_PERMISSIONS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG, ExchangePermissionsDialog)) +#define EXCHANGE_PERMISSIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_PERMISSIONS_DIALOG, ExchangePermissionsDialogClass)) +#define EXCHANGE_IS_PERMISSIONS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG)) +#define EXCHANGE_IS_PERMISSIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG)) + +struct _ExchangePermissionsDialog { + GtkDialog parent; + + ExchangePermissionsDialogPrivate *priv; +}; + +struct _ExchangePermissionsDialogClass { + GtkDialogClass parent_class; + +}; + +GType exchange_permissions_dialog_get_type (void); + +void exchange_permissions_dialog_new (ExchangeAccount *account, + EFolder *folder, + GtkWidget *parent); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXCHANGE_PERMISSIONS_DIALOG_H__ */ diff --git a/plugins/exchange-operations/org-gnome-folder-permissions.xml b/plugins/exchange-operations/org-gnome-folder-permissions.xml new file mode 100644 index 0000000000..eb35bd89d4 --- /dev/null +++ b/plugins/exchange-operations/org-gnome-folder-permissions.xml @@ -0,0 +1,17 @@ +<Root> + <commands> + <cmd name="CheckFolderPermission" _label="Permissions..." + _tip="Check folder permissions"/> + </commands> + + <menu> + <placeholder name="FolderPlaceholder"> + <submenu name="Folder"> + <placeholder name="MessagesInFolder"> + <separator f="" name="emaillist5"/> + <menuitem name="CheckFolderPermission" verb=""/> + </placeholder> + </submenu> + </placeholder> + </menu> +</Root> diff --git a/plugins/exchange-operations/org-gnome-folder-subscription.xml b/plugins/exchange-operations/org-gnome-folder-subscription.xml new file mode 100644 index 0000000000..6831902612 --- /dev/null +++ b/plugins/exchange-operations/org-gnome-folder-subscription.xml @@ -0,0 +1,17 @@ +<Root> + <commands> + <cmd name="FolderSubscription" _label="Subscribe to Other User's Folder" + _tip="Subscribe to Other User's Folder"/> + </commands> + + <menu> + <placeholder name="FolderPlaceholder"> + <submenu name="Folder"> + <placeholder name="MessagesInFolder"> + <separator f="" name="emaillist5"/> + <menuitem name="FolderSubscription" verb=""/> + </placeholder> + </submenu> + </placeholder> + </menu> +</Root> |