[evolution-ews] Be able to read/write folder permissions
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Be able to read/write folder permissions
- Date: Tue, 31 Jul 2012 14:21:20 +0000 (UTC)
commit aca6b4852df17b500e5b36f823c130cfee10d56e
Author: Milan Crha <mcrha redhat com>
Date: Tue Jul 31 16:20:18 2012 +0200
Be able to read/write folder permissions
po/POTFILES.in | 3 +
src/addressbook/e-book-backend-ews.c | 6 +-
src/camel/camel-ews-store.c | 4 +-
src/configuration/Makefile.am | 8 +
src/configuration/e-ews-config-ui-extension.c | 154 +++
src/configuration/e-ews-config-ui-extension.h | 47 +
src/configuration/e-ews-config-utils.c | 1049 +++++++++++++++++
src/configuration/e-ews-config-utils.h | 69 ++
src/configuration/e-ews-edit-folder-permissions.c | 1254 +++++++++++++++++++++
src/configuration/e-ews-edit-folder-permissions.h | 43 +
src/configuration/e-ews-search-user.c | 548 +++++++++
src/configuration/e-ews-search-user.h | 37 +
src/configuration/module-ews-configuration.c | 6 +
src/server/e-ews-connection.c | 364 ++++++-
src/server/e-ews-connection.h | 40 +
src/server/e-ews-folder.c | 18 +-
src/server/e-ews-folder.h | 5 +-
src/server/e-ews-item.c | 342 ++++++
src/server/e-ews-item.h | 47 +
src/server/e-source-ews-folder.c | 18 +-
src/server/e-source-ews-folder.h | 4 +
src/server/tests/test-createfolder.c | 2 +-
src/server/tests/test-libews.c | 2 +-
src/utils/ews-test-finditem-query.c | 6 +-
24 files changed, 4061 insertions(+), 15 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 65eeb97..6066ad0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,6 +11,9 @@ src/camel/camel-ews-transport.c
src/camel/camel-ews-utils.c
src/collection/e-ews-backend.c
src/collection/module-ews-backend.c
+src/configuration/e-ews-config-utils.c
+src/configuration/e-ews-edit-folder-permissions.c
+src/configuration/e-ews-search-user.c
src/configuration/e-mail-config-ews-autodiscover.c
src/configuration/e-mail-config-ews-backend.c
src/configuration/e-mail-config-ews-gal.c
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 34592bd..86b3977 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -1431,7 +1431,7 @@ e_book_backend_ews_get_contact_list (EBookBackend *backend,
convert_error_to_edb_error (&error);
e_data_book_respond_get_contact_list (book, opid, error, vcard_list);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
g_slist_foreach (vcard_list, (GFunc) g_free, NULL);
g_slist_free (vcard_list);
return;
@@ -2556,7 +2556,7 @@ e_book_backend_ews_start_book_view (EBookBackend *backend,
&includes_last_item, cancellable, &error);
g_free (auto_comp_str);
g_hash_table_remove (priv->ops, book_view);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
if (error != NULL) {
e_data_book_view_notify_complete (book_view, error);
e_data_book_view_unref (book_view);
@@ -2973,7 +2973,7 @@ book_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
connection, EWS_PRIORITY_MEDIUM, "Default",
NULL, ids, &folders, cancellable, &local_error);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
g_slist_free (ids);
ids = NULL;
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 2fa85a8..19c76d3 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -458,7 +458,7 @@ ews_authenticate_sync (CamelService *service,
d(printf ("folders for respective distinguished ids don't exist"));
g_slist_foreach (folders, (GFunc) g_object_unref, NULL);
- g_slist_foreach (folder_ids, (GFunc) e_ews_folder_free_fid, NULL);
+ g_slist_foreach (folder_ids, (GFunc) e_ews_folder_id_free, NULL);
g_slist_free (folders);
g_slist_free (folder_ids);
g_clear_error (&folder_err);
@@ -774,7 +774,7 @@ ews_create_folder_sync (CamelStore *store,
EWS_FOLDER_TYPE_MAILBOX,
0, 0);
fi = camel_ews_utils_build_folder_info (ews_store, folder_id->id);
- e_ews_folder_free_fid (folder_id);
+ e_ews_folder_id_free (folder_id);
camel_store_folder_created (store, fi);
diff --git a/src/configuration/Makefile.am b/src/configuration/Makefile.am
index 60a54a0..b5c384f 100644
--- a/src/configuration/Makefile.am
+++ b/src/configuration/Makefile.am
@@ -27,6 +27,14 @@ module_ews_configuration_la_SOURCES = \
e-mail-config-ews-oal-combo-box.h \
e-mail-config-ews-ooo-page.c \
e-mail-config-ews-ooo-page.h \
+ e-ews-config-ui-extension.c \
+ e-ews-config-ui-extension.h \
+ e-ews-config-utils.c \
+ e-ews-config-utils.h \
+ e-ews-edit-folder-permissions.c \
+ e-ews-edit-folder-permissions.h \
+ e-ews-search-user.c \
+ e-ews-search-user.h \
$(NULL)
module_ews_configuration_la_LIBADD = \
diff --git a/src/configuration/e-ews-config-ui-extension.c b/src/configuration/e-ews-config-ui-extension.c
new file mode 100644
index 0000000..5a11cdd
--- /dev/null
+++ b/src/configuration/e-ews-config-ui-extension.c
@@ -0,0 +1,154 @@
+/*
+ * e-ews-config-ui-extension.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+
+#include "e-ews-config-utils.h"
+
+#include "e-ews-config-ui-extension.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EEwsConfigUIExtension,
+ e_ews_config_ui_extension,
+ E_TYPE_EXTENSION)
+
+static void
+e_ews_config_ui_extension_shell_view_toggled_cb (EShellView *shell_view,
+ EEwsConfigUIExtension *ui_ext)
+{
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ gpointer key = NULL, value = NULL;
+ const gchar *ui_def;
+ gboolean is_active, need_update;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (ui_ext != NULL);
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_if_fail (shell_view_class != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ need_update = ui_ext->current_ui_id != 0;
+ if (ui_ext->current_ui_id) {
+ gtk_ui_manager_remove_ui (ui_manager, ui_ext->current_ui_id);
+ ui_ext->current_ui_id = 0;
+ }
+
+ is_active = e_shell_view_is_active (shell_view);
+ if (!is_active) {
+ if (need_update)
+ gtk_ui_manager_ensure_update (ui_manager);
+
+ return;
+ }
+
+ if (!g_hash_table_lookup_extended (ui_ext->ui_definitions, shell_view_class->ui_manager_id, &key, &value)) {
+ gchar *ui_definition = NULL;
+
+ e_ews_config_utils_init_ui (shell_view, shell_view_class->ui_manager_id, &ui_definition);
+ g_hash_table_insert (ui_ext->ui_definitions, g_strdup (shell_view_class->ui_manager_id), ui_definition);
+ }
+
+ ui_def = g_hash_table_lookup (ui_ext->ui_definitions, shell_view_class->ui_manager_id);
+ if (ui_def) {
+ GError *error = NULL;
+
+ ui_ext->current_ui_id = gtk_ui_manager_add_ui_from_string (ui_manager, ui_def, -1, &error);
+ need_update = TRUE;
+
+ if (error) {
+ g_warning ("%s: Failed to add ui definition: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
+
+ if (need_update)
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+static void
+e_ews_config_ui_extension_constructed (GObject *object)
+{
+ EExtension *extension;
+ EExtensible *extensible;
+
+ extension = E_EXTENSION (object);
+ extensible = e_extension_get_extensible (extension);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_ews_config_ui_extension_parent_class)->constructed (object);
+
+ g_signal_connect (E_SHELL_VIEW (extensible), "toggled", G_CALLBACK (e_ews_config_ui_extension_shell_view_toggled_cb), extension);
+}
+
+static void
+e_ews_config_ui_extension_finalize (GObject *object)
+{
+ EEwsConfigUIExtension *ui_ext = (EEwsConfigUIExtension *) object;
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_ews_config_ui_extension_parent_class)->finalize (object);
+
+ g_hash_table_destroy (ui_ext->ui_definitions);
+}
+
+static void
+e_ews_config_ui_extension_class_init (EEwsConfigUIExtensionClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = e_ews_config_ui_extension_constructed;
+ object_class->finalize = e_ews_config_ui_extension_finalize;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_SHELL_VIEW;
+}
+
+static void
+e_ews_config_ui_extension_class_finalize (EEwsConfigUIExtensionClass *class)
+{
+}
+
+static void
+e_ews_config_ui_extension_init (EEwsConfigUIExtension *extension)
+{
+ extension->current_ui_id = 0;
+ extension->ui_definitions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+void
+e_ews_config_ui_extension_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_ews_config_ui_extension_register_type (type_module);
+}
diff --git a/src/configuration/e-ews-config-ui-extension.h b/src/configuration/e-ews-config-ui-extension.h
new file mode 100644
index 0000000..39e3ba0
--- /dev/null
+++ b/src/configuration/e-ews-config-ui-extension.h
@@ -0,0 +1,47 @@
+/*
+ * e-ews-config-ui-extension.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_EWS_CONFIG_UI_EXTENSION_H
+#define E_EWS_CONFIG_UI_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EEwsConfigUIExtension EEwsConfigUIExtension;
+typedef struct _EEwsConfigUIExtensionClass EEwsConfigUIExtensionClass;
+
+struct _EEwsConfigUIExtension
+{
+ EExtension parent;
+
+ guint current_ui_id;
+ GHashTable *ui_definitions;
+};
+
+struct _EEwsConfigUIExtensionClass
+{
+ EExtensionClass parent;
+};
+
+GType e_ews_config_ui_extension_get_type (void);
+void e_ews_config_ui_extension_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_EWS_CONFIG_UI_EXTENSION_H */
diff --git a/src/configuration/e-ews-config-utils.c b/src/configuration/e-ews-config-utils.c
new file mode 100644
index 0000000..2021586
--- /dev/null
+++ b/src/configuration/e-ews-config-utils.c
@@ -0,0 +1,1049 @@
+/*
+ * e-ews-config-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-util.h>
+#include <mail/em-folder-tree.h>
+#include <misc/e-book-source-config.h>
+#include <misc/e-cal-source-config.h>
+#include <shell/e-shell.h>
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window.h>
+
+#include "server/e-ews-connection.h"
+#include "server/e-source-ews-folder.h"
+
+#include "e-ews-edit-folder-permissions.h"
+
+#include "camel/camel-ews-store.h"
+#include "camel/camel-ews-store-summary.h"
+
+#include "e-ews-config-utils.h"
+#include "e-ews-search-user.h"
+
+struct RunWithFeedbackData
+{
+ GtkWindow *parent;
+ GtkWidget *dialog;
+ GCancellable *cancellable;
+ GObject *with_object;
+ EEwsSetupFunc thread_func;
+ EEwsSetupFunc idle_func;
+ gpointer user_data;
+ GDestroyNotify free_user_data;
+ GError *error;
+ gboolean run_modal;
+};
+
+static void
+free_run_with_feedback_data (gpointer ptr)
+{
+ struct RunWithFeedbackData *rfd = ptr;
+
+ if (!rfd)
+ return;
+
+ if (rfd->dialog)
+ gtk_widget_destroy (rfd->dialog);
+
+ g_object_unref (rfd->cancellable);
+ g_object_unref (rfd->with_object);
+
+ if (rfd->free_user_data)
+ rfd->free_user_data (rfd->user_data);
+
+ g_clear_error (&rfd->error);
+
+ g_free (rfd);
+}
+
+static gboolean
+run_with_feedback_idle (gpointer user_data)
+{
+ struct RunWithFeedbackData *rfd = user_data;
+ gboolean was_cancelled = FALSE;
+
+ g_return_val_if_fail (rfd != NULL, FALSE);
+
+ if (!g_cancellable_is_cancelled (rfd->cancellable)) {
+ if (rfd->idle_func && !rfd->error)
+ rfd->idle_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+ was_cancelled = g_cancellable_is_cancelled (rfd->cancellable);
+
+ if (rfd->dialog) {
+ gtk_widget_destroy (rfd->dialog);
+ rfd->dialog = NULL;
+ }
+ } else {
+ was_cancelled = TRUE;
+ }
+
+ if (!was_cancelled) {
+ if (rfd->error)
+ e_notice (rfd->parent, GTK_MESSAGE_ERROR, "%s", rfd->error->message);
+ }
+
+ free_run_with_feedback_data (rfd);
+
+ return FALSE;
+}
+
+static gpointer
+run_with_feedback_thread (gpointer user_data)
+{
+ struct RunWithFeedbackData *rfd = user_data;
+
+ g_return_val_if_fail (rfd != NULL, NULL);
+ g_return_val_if_fail (rfd->thread_func != NULL, NULL);
+
+ if (!g_cancellable_is_cancelled (rfd->cancellable))
+ rfd->thread_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+ g_idle_add (run_with_feedback_idle, rfd);
+
+ return NULL;
+}
+
+static void
+run_with_feedback_response_cb (GtkWidget *dialog,
+ gint resonse_id,
+ struct RunWithFeedbackData *rfd)
+{
+ g_return_if_fail (rfd != NULL);
+
+ rfd->dialog = NULL;
+
+ g_cancellable_cancel (rfd->cancellable);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+e_ews_config_utils_run_in_thread_with_feedback_general (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EEwsSetupFunc thread_func,
+ EEwsSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data,
+ gboolean run_modal)
+{
+ GtkWidget *dialog, *label, *content, *spinner, *box;
+ struct RunWithFeedbackData *rfd;
+
+ g_return_if_fail (with_object != NULL);
+ g_return_if_fail (description != NULL);
+ g_return_if_fail (thread_func != NULL);
+
+ dialog = gtk_dialog_new_with_buttons ("",
+ parent,
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ NULL);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+ spinner = gtk_spinner_new ();
+ gtk_spinner_start (GTK_SPINNER (spinner));
+ gtk_box_pack_start (GTK_BOX (box), spinner, FALSE, FALSE, 0);
+
+ label = gtk_label_new (description);
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+
+ gtk_widget_show_all (box);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_container_add (GTK_CONTAINER (content), box);
+ gtk_container_set_border_width (GTK_CONTAINER (content), 12);
+
+ rfd = g_new0 (struct RunWithFeedbackData, 1);
+ rfd->parent = parent;
+ rfd->dialog = dialog;
+ rfd->cancellable = g_cancellable_new ();
+ rfd->with_object = g_object_ref (with_object);
+ rfd->thread_func = thread_func;
+ rfd->idle_func = idle_func;
+ rfd->user_data = user_data;
+ rfd->free_user_data = free_user_data;
+ rfd->error = NULL;
+ rfd->run_modal = run_modal;
+
+ g_signal_connect (dialog, "response", G_CALLBACK (run_with_feedback_response_cb), rfd);
+
+ if (run_modal) {
+ GCancellable *cancellable;
+
+ cancellable = g_object_ref (rfd->cancellable);
+
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ g_cancellable_cancel (cancellable);
+ g_object_unref (cancellable);
+ } else {
+ gtk_widget_show (dialog);
+
+ g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+ }
+}
+
+void
+e_ews_config_utils_run_in_thread_with_feedback (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EEwsSetupFunc thread_func,
+ EEwsSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data)
+{
+ e_ews_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, FALSE);
+}
+
+void
+e_ews_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EEwsSetupFunc thread_func,
+ EEwsSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data)
+{
+ e_ews_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, TRUE);
+}
+
+typedef struct _EEwsConfigUtilsAuthenticator EEwsConfigUtilsAuthenticator;
+typedef struct _EEwsConfigUtilsAuthenticatorClass EEwsConfigUtilsAuthenticatorClass;
+
+struct _EEwsConfigUtilsAuthenticator {
+ GObject parent;
+
+ ESourceRegistry *registry;
+ CamelEwsSettings *ews_settings;
+ EEwsConnection *conn;
+};
+
+struct _EEwsConfigUtilsAuthenticatorClass {
+ GObjectClass parent_class;
+};
+
+static ESourceAuthenticationResult
+ews_config_utils_authenticator_try_password_sync (ESourceAuthenticator *auth,
+ const GString *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EEwsConfigUtilsAuthenticator *authenticator = (EEwsConfigUtilsAuthenticator *) auth;
+ CamelNetworkSettings *network_settings;
+ gchar *hosturl, *user;
+ EwsFolderId *fid;
+ GSList *ids = NULL, *folders = NULL;
+ GError *local_error = NULL;
+
+ network_settings = CAMEL_NETWORK_SETTINGS (authenticator->ews_settings);
+
+ hosturl = camel_ews_settings_dup_hosturl (authenticator->ews_settings);
+ user = camel_network_settings_dup_user (network_settings);
+
+ authenticator->conn = e_ews_connection_new (
+ hosturl, user, password->str,
+ camel_network_settings_get_auth_mechanism (network_settings),
+ camel_ews_settings_get_timeout (authenticator->ews_settings),
+ NULL, NULL, &local_error);
+
+ g_free (hosturl);
+ g_free (user);
+
+ if (local_error) {
+ g_warn_if_fail (!authenticator->conn);
+ authenticator->conn = NULL;
+
+ g_propagate_error (error, local_error);
+
+ return E_SOURCE_AUTHENTICATION_ERROR;
+ }
+
+ g_warn_if_fail (authenticator->conn);
+
+ /* test whether connection works with some simple operation */
+ fid = g_new0 (EwsFolderId, 1);
+ fid->id = g_strdup ("inbox");
+ fid->is_distinguished_id = TRUE;
+ ids = g_slist_append (ids, fid);
+
+ e_ews_connection_get_folder_sync (
+ authenticator->conn, EWS_PRIORITY_MEDIUM, "Default",
+ NULL, ids, &folders, cancellable, &local_error);
+
+ e_ews_folder_id_free (fid);
+ g_slist_free (ids);
+ g_slist_free_full (folders, g_object_unref);
+
+ if (local_error) {
+ g_object_unref (authenticator->conn);
+ authenticator->conn = NULL;
+
+ if (g_error_matches (
+ local_error, EWS_CONNECTION_ERROR,
+ EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
+ g_clear_error (&local_error);
+ return E_SOURCE_AUTHENTICATION_REJECTED;
+ }
+
+ g_propagate_error (error, local_error);
+
+ return E_SOURCE_AUTHENTICATION_ERROR;
+ }
+
+ return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+#define E_TYPE_EWS_CONFIG_UTILS_AUTHENTICATOR (e_ews_config_utils_authenticator_get_type ())
+
+GType e_ews_config_utils_authenticator_get_type (void) G_GNUC_CONST;
+
+static void e_ews_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_EXTENDED (EEwsConfigUtilsAuthenticator, e_ews_config_utils_authenticator, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_ews_config_utils_authenticator_authenticator_init))
+
+static void
+ews_config_utils_authenticator_finalize (GObject *object)
+{
+ EEwsConfigUtilsAuthenticator *authenticator = (EEwsConfigUtilsAuthenticator *) object;
+
+ g_object_unref (authenticator->registry);
+ g_object_unref (authenticator->ews_settings);
+ if (authenticator->conn)
+ g_object_unref (authenticator->conn);
+
+ G_OBJECT_CLASS (e_ews_config_utils_authenticator_parent_class)->finalize (object);
+}
+
+static void
+e_ews_config_utils_authenticator_class_init (EEwsConfigUtilsAuthenticatorClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = ews_config_utils_authenticator_finalize;
+}
+
+static void
+e_ews_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+ interface->try_password_sync = ews_config_utils_authenticator_try_password_sync;
+}
+
+static void
+e_ews_config_utils_authenticator_init (EEwsConfigUtilsAuthenticator *authenticator)
+{
+}
+
+EEwsConnection *
+e_ews_config_utils_open_connection_for (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelEwsSettings *ews_settings,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ EEwsConnection *conn = NULL;
+ CamelNetworkSettings *network_settings;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (registry != NULL, NULL);
+ g_return_val_if_fail (source != NULL, NULL);
+ g_return_val_if_fail (ews_settings != NULL, NULL);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (ews_settings);
+
+ /* use the one from mailer, if there, otherwise open new */
+ conn = e_ews_connection_find (
+ camel_ews_settings_get_hosturl (ews_settings),
+ camel_network_settings_get_user (network_settings));
+ if (conn)
+ return conn;
+
+ while (!conn && !g_cancellable_is_cancelled (cancellable) && !local_error) {
+ EEwsConfigUtilsAuthenticator *authenticator = g_object_new (E_TYPE_EWS_CONFIG_UTILS_AUTHENTICATOR, NULL);
+
+ authenticator->ews_settings = g_object_ref (ews_settings);
+ authenticator->registry = g_object_ref (registry);
+
+ e_source_registry_authenticate_sync (
+ registry, source, E_SOURCE_AUTHENTICATOR (authenticator),
+ cancellable, &local_error);
+
+ if (authenticator->conn)
+ conn = g_object_ref (authenticator->conn);
+
+ g_object_unref (authenticator);
+ }
+
+ if (local_error)
+ g_propagate_error (perror, local_error);
+
+ return conn;
+}
+
+static gboolean
+get_ews_store_from_folder_tree (EShellView *shell_view,
+ gchar **pfolder_path,
+ CamelStore **pstore)
+{
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ gchar *selected_path = NULL;
+ CamelStore *selected_store = NULL;
+ gboolean found = FALSE;
+
+ /* Get hold of Folder Tree */
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+ if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+ em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+ if (selected_store) {
+ CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+ if (provider && g_ascii_strcasecmp (provider->protocol, "ews") == 0) {
+ found = TRUE;
+
+ if (pstore)
+ *pstore = g_object_ref (selected_store);
+
+ if (pfolder_path)
+ *pfolder_path = selected_path;
+ else
+ g_free (selected_path);
+
+ selected_path = NULL;
+ }
+
+ g_object_unref (selected_store);
+ }
+
+ g_free (selected_path);
+ }
+
+ g_object_unref (folder_tree);
+
+ return found;
+}
+
+/* static void
+action_subscribe_foreign_folder_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ GtkWindow *parent;
+ EShellBackend *backend;
+ CamelSession *session = NULL;
+ CamelStore *store = NULL;
+
+ if (!get_ews_store_from_folder_tree (shell_view, NULL, &store))
+ return;
+
+ parent = GTK_WINDOW (e_shell_view_get_shell_window (shell_view));
+ backend = e_shell_view_get_shell_backend (shell_view);
+ g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+ e_ews_subscribe_foreign_folder (parent, session, store);
+
+ g_object_unref (session);
+ g_object_unref (store);
+ g_free (profile);
+} */
+
+static void
+action_folder_permissions_mail_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ gchar *folder_path = NULL;
+ EShellWindow *shell_window;
+ GtkWindow *parent;
+ CamelStore *store = NULL;
+ CamelEwsStore *ews_store;
+ CamelNetworkSettings *network_settings;
+ gchar *str_folder_id;
+
+ if (!get_ews_store_from_folder_tree (shell_view, &folder_path, &store))
+ return;
+
+ ews_store = CAMEL_EWS_STORE (store);
+ g_return_if_fail (ews_store != NULL);
+ g_return_if_fail (folder_path != NULL);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+ g_return_if_fail (network_settings != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ parent = GTK_WINDOW (shell_window);
+
+ str_folder_id = camel_ews_store_summary_get_folder_id_from_name (ews_store->summary, folder_path);
+ if (!str_folder_id) {
+ e_notice (parent, GTK_MESSAGE_ERROR, _("Cannot edit permissions of folder '%s', choose other folder."), folder_path);
+ } else {
+ ESourceRegistry *registry = e_shell_get_registry (e_shell_window_get_shell (shell_window));
+ ESource *source;
+ EwsFolderId *folder_id;
+ gchar *str_change_key;
+
+ source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
+ g_return_if_fail (source != NULL);
+
+ str_change_key = camel_ews_store_summary_get_change_key (ews_store->summary, str_folder_id, NULL);
+
+ folder_id = e_ews_folder_id_new (str_folder_id, str_change_key, FALSE);
+
+ e_ews_edit_folder_permissions (parent,
+ registry,
+ source,
+ CAMEL_EWS_SETTINGS (network_settings),
+ camel_service_get_display_name (CAMEL_SERVICE (store)),
+ folder_path,
+ folder_id,
+ EWS_FOLDER_TYPE_MAILBOX);
+
+ g_object_unref (source);
+ g_free (str_folder_id);
+ g_free (str_change_key);
+ e_ews_folder_id_free (folder_id);
+ }
+
+ g_object_unref (store);
+ g_free (folder_path);
+}
+
+static void
+ews_ui_enable_actions (GtkActionGroup *action_group,
+ const GtkActionEntry *entries,
+ guint n_entries,
+ gboolean can_show,
+ gboolean is_online)
+{
+ gint ii;
+
+ g_return_if_fail (action_group != NULL);
+ g_return_if_fail (entries != NULL);
+
+ for (ii = 0; ii < n_entries; ii++) {
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (action_group, entries[ii].name);
+ if (!action)
+ continue;
+
+ gtk_action_set_visible (action, can_show);
+ if (can_show)
+ gtk_action_set_sensitive (action, is_online);
+ }
+}
+
+/*static GtkActionEntry mail_account_context_entries[] = {
+
+ { "mail-ews-subscribe-foreign-folder",
+ NULL,
+ N_("Subscribe to folder of other user..."),
+ NULL,
+ NULL, / * XXX Add a tooltip! * /
+ G_CALLBACK (action_subscribe_foreign_folder_cb) }
+};*/
+
+static GtkActionEntry mail_folder_context_entries[] = {
+ { "mail-ews-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit EWS folder permissions"),
+ G_CALLBACK (action_folder_permissions_mail_cb) }
+};
+
+static const gchar *ews_ui_mail_def =
+ "<popup name=\"mail-folder-popup\">\n"
+ " <placeholder name=\"mail-folder-popup-actions\">\n"
+ /*" <menuitem action=\"mail-ews-subscribe-foreign-folder\"/>\n"*/
+ " <menuitem action=\"mail-ews-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+ews_ui_update_actions_mail_cb (EShellView *shell_view,
+ GtkActionEntry *entries)
+{
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ CamelStore *selected_store = NULL;
+ gchar *selected_path = NULL;
+ gboolean account_node = FALSE, folder_node = FALSE;
+ gboolean online = FALSE;
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+ if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+ em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+ if (selected_store) {
+ CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+ if (provider && g_ascii_strcasecmp (provider->protocol, "ews") == 0) {
+ account_node = !selected_path || !*selected_path;
+ folder_node = !account_node;
+ }
+
+ g_object_unref (selected_store);
+ }
+ }
+ g_object_unref (folder_tree);
+
+ g_free (selected_path);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ action_group = e_lookup_action_group (ui_manager, "mail");
+
+ if (account_node || folder_node) {
+ EShellBackend *backend;
+ CamelSession *session = NULL;
+
+ backend = e_shell_view_get_shell_backend (shell_view);
+ g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+ online = session && camel_session_get_online (session);
+
+ if (session)
+ g_object_unref (session);
+ }
+
+ /* ews_ui_enable_actions (action_group, mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), account_node, online); */
+ ews_ui_enable_actions (action_group, mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), folder_node, online);
+}
+
+static void
+ews_ui_init_mail (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (ews_ui_mail_def);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+ /* Add actions to the "mail" action group. */
+ /*e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+ mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), shell_view);*/
+ e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+ mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), shell_view);
+
+ /* Decide whether we want this option to be visible or not */
+ g_signal_connect (shell_view, "update-actions",
+ G_CALLBACK (ews_ui_update_actions_mail_cb),
+ shell_view);
+
+ g_object_unref (action_group);
+}
+
+static gboolean
+get_selected_ews_source (EShellView *shell_view,
+ ESource **selected_source,
+ ESourceRegistry **registry)
+{
+ ESource *source;
+ EShellSidebar *shell_sidebar;
+ ESourceSelector *selector = NULL;
+
+ g_return_val_if_fail (shell_view != NULL, FALSE);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_return_val_if_fail (shell_sidebar != NULL, FALSE);
+
+ g_object_get (shell_sidebar, "selector", &selector, NULL);
+ g_return_val_if_fail (selector != NULL, FALSE);
+
+ source = e_source_selector_ref_primary_selection (selector);
+ if (source) {
+ ESourceBackend *backend_ext = NULL;
+
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MEMO_LIST);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT))
+ backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+
+ if (!backend_ext ||
+ g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "ews") != 0) {
+ g_object_unref (source);
+ source = NULL;
+ }
+ }
+
+ if (source && registry)
+ *registry = g_object_ref (e_source_selector_get_registry (selector));
+
+ g_object_unref (selector);
+
+ if (selected_source)
+ *selected_source = source;
+ else if (source)
+ g_object_unref (source);
+
+ return source != NULL;
+}
+
+/* how many menu entries are defined; all calendar/tasks/memos/contacts
+ actions should have same count */
+#define EWS_ESOURCE_NUM_ENTRIES 1
+
+static void
+update_ews_source_entries_cb (EShellView *shell_view,
+ GtkActionEntry *entries)
+{
+ GtkActionGroup *action_group;
+ EShell *shell;
+ EShellWindow *shell_window;
+ const gchar *group;
+ gboolean is_ews_source, is_online;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (entries != NULL);
+
+ if (strstr (entries->name, "calendar"))
+ group = "calendar";
+ else if (strstr (entries->name, "tasks"))
+ group = "tasks";
+ else if (strstr (entries->name, "memos"))
+ group = "memos";
+ else if (strstr (entries->name, "contacts"))
+ group = "contacts";
+ else
+ g_return_if_reached ();
+
+ is_ews_source = get_selected_ews_source (shell_view, NULL, NULL);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ is_online = shell && e_shell_get_online (shell);
+ action_group = e_shell_window_get_action_group (shell_window, group);
+
+ ews_ui_enable_actions (action_group, entries, EWS_ESOURCE_NUM_ENTRIES, is_ews_source, is_online);
+}
+
+static void
+setup_ews_source_actions (EShellView *shell_view,
+ GtkUIManager *ui_manager,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ EShellWindow *shell_window;
+ const gchar *group;
+
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (ui_manager != NULL);
+ g_return_if_fail (entries != NULL);
+ g_return_if_fail (n_entries > 0);
+ g_return_if_fail (n_entries == EWS_ESOURCE_NUM_ENTRIES);
+
+ if (strstr (entries->name, "calendar"))
+ group = "calendar";
+ else if (strstr (entries->name, "tasks"))
+ group = "tasks";
+ else if (strstr (entries->name, "memos"))
+ group = "memos";
+ else if (strstr (entries->name, "contacts"))
+ group = "contacts";
+ else
+ g_return_if_reached ();
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ e_action_group_add_actions_localized (
+ e_shell_window_get_action_group (shell_window, group), GETTEXT_PACKAGE,
+ entries, EWS_ESOURCE_NUM_ENTRIES, shell_view);
+
+ g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_ews_source_entries_cb), entries);
+}
+
+static void
+action_folder_permissions_source_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ ESourceRegistry *registry = NULL;
+ ESource *source = NULL, *parent_source;
+ ESourceEwsFolder *folder_ext;
+ ESourceCamel *extension;
+ CamelSettings *settings;
+ const gchar *extension_name;
+ EwsFolderId *folder_id;
+ EwsFolderType folder_type;
+
+ g_return_if_fail (action != NULL);
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (get_selected_ews_source (shell_view, &source, ®istry));
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (e_source_has_extension (source, E_SOURCE_EXTENSION_EWS_FOLDER));
+ g_return_if_fail (gtk_action_get_name (action) != NULL);
+
+ folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_EWS_FOLDER);
+ folder_id = e_source_ews_folder_dup_folder_id (folder_ext);
+ g_return_if_fail (folder_id != NULL);
+
+ parent_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+
+ extension_name = e_source_camel_get_extension_name ("ews");
+ extension = e_source_get_extension (parent_source, extension_name);
+ settings = e_source_camel_get_settings (extension);
+
+ folder_type = EWS_FOLDER_TYPE_MAILBOX;
+ if (strstr (gtk_action_get_name (action), "calendar") != NULL)
+ folder_type = EWS_FOLDER_TYPE_CALENDAR;
+ else if (strstr (gtk_action_get_name (action), "contacts") != NULL)
+ folder_type = EWS_FOLDER_TYPE_CONTACTS;
+ else if (strstr (gtk_action_get_name (action), "tasks") != NULL)
+ folder_type = EWS_FOLDER_TYPE_TASKS;
+
+ e_ews_edit_folder_permissions (NULL,
+ registry,
+ source,
+ CAMEL_EWS_SETTINGS (settings),
+ e_source_get_display_name (parent_source),
+ e_source_get_display_name (source),
+ folder_id,
+ folder_type);
+
+ g_object_unref (source);
+ g_object_unref (parent_source);
+ g_object_unref (registry);
+ e_ews_folder_id_free (folder_id);
+}
+
+static GtkActionEntry calendar_context_entries[] = {
+
+ { "calendar-ews-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit EWS calendar permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *ews_ui_cal_def =
+ "<popup name=\"calendar-popup\">\n"
+ " <placeholder name=\"calendar-popup-actions\">\n"
+ " <menuitem action=\"calendar-ews-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+ews_ui_init_calendar (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (ews_ui_cal_def);
+
+ setup_ews_source_actions (shell_view, ui_manager,
+ calendar_context_entries, G_N_ELEMENTS (calendar_context_entries));
+}
+
+static GtkActionEntry tasks_context_entries[] = {
+
+ { "tasks-ews-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit EWS tasks permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *ews_ui_task_def =
+ "<popup name=\"task-list-popup\">\n"
+ " <placeholder name=\"task-list-popup-actions\">\n"
+ " <menuitem action=\"tasks-ews-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+ews_ui_init_tasks (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (ews_ui_task_def);
+
+ setup_ews_source_actions (shell_view, ui_manager,
+ tasks_context_entries, G_N_ELEMENTS (tasks_context_entries));
+}
+
+static GtkActionEntry memos_context_entries[] = {
+
+ { "memos-ews-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit EWS memos permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *ews_ui_memo_def =
+ "<popup name=\"memo-list-popup\">\n"
+ " <placeholder name=\"memo-list-popup-actions\">\n"
+ " <menuitem action=\"memos-ews-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+ews_ui_init_memos (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (ews_ui_memo_def);
+
+ setup_ews_source_actions (shell_view, ui_manager,
+ memos_context_entries, G_N_ELEMENTS (memos_context_entries));
+}
+
+static GtkActionEntry contacts_context_entries[] = {
+
+ { "contacts-ews-folder-permissions",
+ "folder-new",
+ N_("Permissions..."),
+ NULL,
+ N_("Edit EWS contacts permissions"),
+ G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *ews_ui_book_def =
+ "<popup name=\"address-book-popup\">\n"
+ " <placeholder name=\"address-book-popup-actions\">\n"
+ " <menuitem action=\"contacts-ews-folder-permissions\"/>\n"
+ " </placeholder>\n"
+ "</popup>\n";
+
+static void
+ews_ui_init_contacts (GtkUIManager *ui_manager,
+ EShellView *shell_view,
+ gchar **ui_definition)
+{
+ g_return_if_fail (ui_definition != NULL);
+
+ *ui_definition = g_strdup (ews_ui_book_def);
+
+ setup_ews_source_actions (shell_view, ui_manager,
+ contacts_context_entries, G_N_ELEMENTS (contacts_context_entries));
+}
+
+void
+e_ews_config_utils_init_ui (EShellView *shell_view,
+ const gchar *ui_manager_id,
+ gchar **ui_definition)
+{
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+
+ g_return_if_fail (shell_view != NULL);
+ g_return_if_fail (ui_manager_id != NULL);
+ g_return_if_fail (ui_definition != NULL);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.mail") == 0)
+ ews_ui_init_mail (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.calendars") == 0)
+ ews_ui_init_calendar (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.tasks") == 0)
+ ews_ui_init_tasks (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.memos") == 0)
+ ews_ui_init_memos (ui_manager, shell_view, ui_definition);
+ else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.contacts") == 0)
+ ews_ui_init_contacts (ui_manager, shell_view, ui_definition);
+}
+
+gboolean
+e_ews_config_utils_is_online (void)
+{
+ EShell *shell;
+
+ shell = e_shell_get_default ();
+
+ return shell && e_shell_get_online (shell);
+}
+
+GtkWindow *
+e_ews_config_utils_get_widget_toplevel_window (GtkWidget *widget)
+{
+ if (!widget)
+ return NULL;
+
+ if (!GTK_IS_WINDOW (widget))
+ widget = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (widget))
+ return GTK_WINDOW (widget);
+
+ return NULL;
+}
+
+static gpointer
+ews_config_utils_unref_in_thread (gpointer user_data)
+{
+ g_object_unref (user_data);
+
+ return NULL;
+}
+
+void
+e_ews_config_utils_unref_in_thread (GObject *object)
+{
+ GThread *thread;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (G_IS_OBJECT (object));
+
+ thread = g_thread_new (NULL, ews_config_utils_unref_in_thread, object);
+ g_thread_unref (thread);
+}
diff --git a/src/configuration/e-ews-config-utils.h b/src/configuration/e-ews-config-utils.h
new file mode 100644
index 0000000..e4f1207
--- /dev/null
+++ b/src/configuration/e-ews-config-utils.h
@@ -0,0 +1,69 @@
+/*
+ * e-ews-config-utils.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_EWS_CONFIG_UTILS_H
+#define E_EWS_CONFIG_UTILS_H
+
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+#include <misc/e-source-config.h>
+#include <misc/e-source-config-backend.h>
+
+#include "server/e-ews-connection.h"
+#include "server/camel-ews-settings.h"
+
+typedef void (* EEwsSetupFunc) (GObject *with_object,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror);
+
+void e_ews_config_utils_run_in_thread_with_feedback (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EEwsSetupFunc thread_func,
+ EEwsSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data);
+
+void e_ews_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
+ GObject *with_object,
+ const gchar *description,
+ EEwsSetupFunc thread_func,
+ EEwsSetupFunc idle_func,
+ gpointer user_data,
+ GDestroyNotify free_user_data);
+
+EEwsConnection * e_ews_config_utils_open_connection_for (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelEwsSettings *ews_settings,
+ GCancellable *cancellable,
+ GError **perror);
+
+void e_ews_config_utils_init_ui (EShellView *shell_view,
+ const gchar *ui_manager_id,
+ gchar **ui_definition);
+
+gboolean e_ews_config_utils_is_online (void);
+
+GtkWindow * e_ews_config_utils_get_widget_toplevel_window (GtkWidget *widget);
+
+void e_ews_config_utils_unref_in_thread (GObject *object);
+
+#endif /* E_EWS_CONFIG_UTILS */
diff --git a/src/configuration/e-ews-edit-folder-permissions.c b/src/configuration/e-ews-edit-folder-permissions.c
new file mode 100644
index 0000000..c272d7b
--- /dev/null
+++ b/src/configuration/e-ews-edit-folder-permissions.c
@@ -0,0 +1,1254 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Milan Crha <mcrha redhat com>
+ *
+ * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "e-ews-config-utils.h"
+#include "e-ews-edit-folder-permissions.h"
+#include "e-ews-search-user.h"
+
+#define E_EWS_PERM_DLG_WIDGETS "e-ews-perm-dlg-widgets"
+
+enum {
+ COL_NAME = 0,
+ COL_PERMISSION_LEVEL,
+ COL_E_EWS_PERMISSION,
+ COL_E_EWS_PERMISSION_USER_TYPE,
+ COL_IS_NEW
+};
+
+struct EEwsPermissionsDialogWidgets
+{
+ ESourceRegistry *registry;
+ ESource *source;
+ CamelEwsSettings *ews_settings;
+ EwsFolderId *folder_id;
+ EwsFolderType folder_type;
+
+ EEwsConnection *conn;
+
+ guint updating;
+
+ GtkWidget *dialog;
+ GtkWidget *tree_view;
+
+ GtkWidget *add_button;
+ GtkWidget *remove_button;
+ GtkWidget *level_combo;
+
+ GtkWidget *read_none_radio;
+ GtkWidget *read_full_radio;
+ GtkWidget *read_fb_time_radio;
+ GtkWidget *read_fb_detail_radio;
+
+ GtkWidget *write_create_items_check;
+ GtkWidget *write_create_subfolders_check;
+ GtkWidget *write_edit_own_check;
+ GtkWidget *write_edit_all_check;
+
+ GtkWidget *delete_none_radio;
+ GtkWidget *delete_own_radio;
+ GtkWidget *delete_all_radio;
+
+ GtkWidget *other_folder_owner_check;
+ GtkWidget *other_folder_contact_check;
+ GtkWidget *other_folder_visible_check;
+};
+
+static const struct EEwsPredefinedLevels {
+ const gchar *name;
+ uint32_t rights;
+} predefined_levels[] = {
+ { NC_("PermissionsLevel", "None"), 0 },
+ { NC_("PermissionsLevel", "Owner"), E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_OWNER |
+ E_EWS_PERMISSION_BIT_FOLDER_CONTACT |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Publishing Editor"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Editor"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Publishing Author"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Author"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Nonediting Author"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Reviewer"),
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Contributor"),
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { NC_("PermissionsLevel", "Free/Busy time"),
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE },
+ { NC_("PermissionsLevel", "Free/Busy time, subject, location"),
+ E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED },
+ { NC_("PermissionsLevel", "Custom"), ~0 } /* make sure 'Custom' is always the last */
+};
+
+static void
+edit_permissions_widgets_free (gpointer ptr)
+{
+ struct EEwsPermissionsDialogWidgets *widgets = ptr;
+
+ if (!widgets)
+ return;
+
+ g_object_unref (widgets->registry);
+ g_object_unref (widgets->source);
+ g_object_unref (widgets->ews_settings);
+ e_ews_folder_id_free (widgets->folder_id);
+ if (widgets->conn)
+ e_ews_config_utils_unref_in_thread (G_OBJECT (widgets->conn));
+ g_free (widgets);
+}
+
+static void
+folder_permissions_clear_all_permissions (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->tree_view != NULL);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widgets->tree_view));
+ g_return_if_fail (model != NULL);
+
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return;
+
+ do {
+ EEwsPermission *perm = NULL;
+
+ gtk_tree_model_get (model, &iter, COL_E_EWS_PERMISSION, &perm, -1);
+
+ e_ews_permission_free (perm);
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+}
+
+static void
+write_folder_permissions_thread (GObject *dialog,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ const GSList *permissions = user_data;
+
+ g_return_if_fail (dialog != NULL);
+
+ if (g_cancellable_is_cancelled (cancellable))
+ return;
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->conn != NULL);
+
+ e_ews_connection_set_folder_permissions_sync (widgets->conn,
+ G_PRIORITY_DEFAULT, widgets->folder_id, widgets->folder_type, permissions, cancellable, perror);
+}
+
+static void
+write_folder_permissions_idle (GObject *dialog,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ /* does this only if no error was raised from the thread function */
+ folder_permissions_clear_all_permissions (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+edit_permissions_response_cb (GObject *dialog,
+ gint response_id)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ GSList *write_permissions = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (dialog != NULL);
+
+ if (response_id != GTK_RESPONSE_OK) {
+ folder_permissions_clear_all_permissions (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ return;
+ }
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->tree_view != NULL);
+ g_return_if_fail (widgets->conn != NULL);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widgets->tree_view));
+ g_return_if_fail (model != NULL);
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ EEwsPermission *perm = NULL;
+
+ gtk_tree_model_get (model, &iter, COL_E_EWS_PERMISSION, &perm, -1);
+
+ if (perm)
+ write_permissions = g_slist_prepend (write_permissions, perm);
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ write_permissions = g_slist_reverse (write_permissions);
+ }
+
+ e_ews_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+ _("Writing folder permissions, please wait..."),
+ write_folder_permissions_thread,
+ write_folder_permissions_idle,
+ write_permissions, (GDestroyNotify) g_slist_free);
+}
+
+static void
+enable_all_widgets (struct EEwsPermissionsDialogWidgets *widgets,
+ gboolean enabled)
+{
+ g_return_if_fail (widgets != NULL);
+
+ gtk_widget_set_sensitive (widgets->add_button, enabled || gtk_widget_get_sensitive (widgets->tree_view));
+ gtk_widget_set_sensitive (widgets->remove_button, enabled);
+ gtk_widget_set_sensitive (widgets->level_combo, enabled);
+ gtk_widget_set_sensitive (widgets->read_none_radio, enabled);
+ gtk_widget_set_sensitive (widgets->read_full_radio, enabled);
+ if (widgets->read_fb_time_radio)
+ gtk_widget_set_sensitive (widgets->read_fb_time_radio, enabled);
+ if (widgets->read_fb_detail_radio)
+ gtk_widget_set_sensitive (widgets->read_fb_detail_radio, enabled);
+ gtk_widget_set_sensitive (widgets->write_create_items_check, enabled);
+ gtk_widget_set_sensitive (widgets->write_create_subfolders_check, enabled);
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, enabled);
+ gtk_widget_set_sensitive (widgets->write_edit_all_check, enabled);
+ gtk_widget_set_sensitive (widgets->delete_none_radio, enabled);
+ gtk_widget_set_sensitive (widgets->delete_own_radio, enabled);
+ gtk_widget_set_sensitive (widgets->delete_all_radio, enabled);
+ gtk_widget_set_sensitive (widgets->other_folder_owner_check, enabled);
+ gtk_widget_set_sensitive (widgets->other_folder_contact_check, enabled);
+ gtk_widget_set_sensitive (widgets->other_folder_visible_check, enabled);
+}
+
+static uint32_t
+folder_permissions_dialog_to_rights (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ uint32_t rights;
+
+ g_return_val_if_fail (dialog != NULL, 0);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_val_if_fail (widgets != NULL, 0);
+
+ #define set_bit_by_active(x, bt) G_STMT_START { \
+ if (widgets->x && \
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->x)) && \
+ gtk_widget_get_sensitive (widgets->x)) { \
+ rights |= bt; \
+ } } G_STMT_END
+
+ rights = 0;
+
+ set_bit_by_active (read_none_radio, 0);
+ set_bit_by_active (read_full_radio, E_EWS_PERMISSION_BIT_READ_ANY);
+ set_bit_by_active (read_fb_time_radio, E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE);
+ set_bit_by_active (read_fb_detail_radio, E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED);
+ set_bit_by_active (write_create_items_check, E_EWS_PERMISSION_BIT_CREATE);
+ set_bit_by_active (write_create_subfolders_check, E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER);
+ set_bit_by_active (write_edit_own_check, E_EWS_PERMISSION_BIT_EDIT_OWNED);
+ set_bit_by_active (write_edit_all_check, E_EWS_PERMISSION_BIT_EDIT_ANY | E_EWS_PERMISSION_BIT_EDIT_OWNED);
+ set_bit_by_active (delete_none_radio, 0);
+ set_bit_by_active (delete_own_radio, E_EWS_PERMISSION_BIT_DELETE_OWNED);
+ set_bit_by_active (delete_all_radio, E_EWS_PERMISSION_BIT_DELETE_ANY | E_EWS_PERMISSION_BIT_DELETE_OWNED);
+ set_bit_by_active (other_folder_owner_check, E_EWS_PERMISSION_BIT_FOLDER_OWNER);
+ set_bit_by_active (other_folder_contact_check, E_EWS_PERMISSION_BIT_FOLDER_CONTACT);
+ set_bit_by_active (other_folder_visible_check, E_EWS_PERMISSION_BIT_FOLDER_VISIBLE);
+
+ #undef set_bit_by_active
+
+ return rights;
+}
+
+static void
+update_folder_permissions_sensitivity (GObject *dialog,
+ gboolean member_valid,
+ EEwsPermissionUserType user_type)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ enable_all_widgets (widgets, member_valid);
+
+ if (user_type == E_EWS_PERMISSION_USER_TYPE_DEFAULT ||
+ user_type == E_EWS_PERMISSION_USER_TYPE_ANONYMOUS)
+ gtk_widget_set_sensitive (widgets->other_folder_contact_check, FALSE);
+
+ if (member_valid)
+ gtk_widget_set_sensitive (widgets->remove_button,
+ user_type != E_EWS_PERMISSION_USER_TYPE_DEFAULT &&
+ user_type != E_EWS_PERMISSION_USER_TYPE_ANONYMOUS);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_all_check))) {
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widgets->write_edit_own_check), TRUE);
+ }
+}
+
+static void
+update_folder_permissions_by_rights (GObject *dialog,
+ uint32_t rights)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ #define set_active(x, act) G_STMT_START { if (widgets->x) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widgets->x), act); } G_STMT_END
+ #define set_active_by_bit(x, bt) set_active (x, (rights & (bt)) != 0)
+
+ widgets->updating++;
+
+ set_active (read_none_radio, TRUE);
+ set_active_by_bit (read_full_radio, E_EWS_PERMISSION_BIT_READ_ANY);
+ set_active_by_bit (read_fb_time_radio, E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE);
+ set_active_by_bit (read_fb_detail_radio, E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED);
+ set_active_by_bit (write_create_items_check, E_EWS_PERMISSION_BIT_CREATE);
+ set_active_by_bit (write_create_subfolders_check, E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER);
+ set_active_by_bit (write_edit_own_check, E_EWS_PERMISSION_BIT_EDIT_OWNED | E_EWS_PERMISSION_BIT_EDIT_ANY);
+ set_active_by_bit (write_edit_all_check, E_EWS_PERMISSION_BIT_EDIT_ANY);
+ set_active (delete_none_radio, TRUE);
+ set_active_by_bit (delete_own_radio, E_EWS_PERMISSION_BIT_DELETE_OWNED);
+ set_active_by_bit (delete_all_radio, E_EWS_PERMISSION_BIT_DELETE_ANY);
+ set_active_by_bit (other_folder_owner_check, E_EWS_PERMISSION_BIT_FOLDER_OWNER);
+ set_active_by_bit (other_folder_contact_check, E_EWS_PERMISSION_BIT_FOLDER_CONTACT);
+ set_active_by_bit (other_folder_visible_check, E_EWS_PERMISSION_BIT_FOLDER_VISIBLE);
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_all_check)) &&
+ gtk_widget_get_sensitive (widgets->write_edit_all_check)) {
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, TRUE);
+ } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_all_check))) {
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widgets->write_edit_own_check), TRUE);
+ }
+
+ widgets->updating--;
+
+ #undef set_active_by_bit
+ #undef set_active
+}
+
+static void
+update_folder_permissions_tree_view (GObject *dialog,
+ struct EEwsPermissionsDialogWidgets *widgets)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ uint32_t rights;
+
+ g_return_if_fail (dialog != NULL);
+ g_return_if_fail (widgets != NULL);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widgets->tree_view));
+ if (selection && gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gchar *combo_text;
+ EEwsPermission *perm = NULL;
+
+ combo_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widgets->level_combo));
+ rights = folder_permissions_dialog_to_rights (dialog);
+
+ gtk_tree_model_get (model, &iter, COL_E_EWS_PERMISSION, &perm, -1);
+
+ if (perm) {
+ if (!widgets->read_fb_time_radio)
+ rights = rights | (perm->rights & (E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED | E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE));
+
+ perm->rights = rights;
+
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_PERMISSION_LEVEL, combo_text, -1);
+ }
+
+ g_free (combo_text);
+ }
+}
+
+static void
+update_permission_level_combo_by_dialog (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ uint32_t rights;
+ gint ii;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ if (widgets->updating)
+ return;
+
+ rights = folder_permissions_dialog_to_rights (dialog);
+ if (!widgets->read_fb_time_radio)
+ rights = rights & ~(E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED |
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE);
+
+ for (ii = 0; ii < G_N_ELEMENTS (predefined_levels) - 1; ii++) {
+ if (predefined_levels[ii].rights == rights) {
+ break;
+ }
+ }
+
+ if (!widgets->read_fb_time_radio && ii > G_N_ELEMENTS (predefined_levels) - 3)
+ ii = G_N_ELEMENTS (predefined_levels) - 3;
+
+ /* ii points to the matched or the last item, which is 'Custom' */
+ widgets->updating++;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widgets->level_combo), ii);
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_all_check)) &&
+ gtk_widget_get_sensitive (widgets->write_edit_all_check)) {
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, TRUE);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_own_check))) {
+ rights |= E_EWS_PERMISSION_BIT_EDIT_OWNED;
+
+ for (ii = 0; ii < G_N_ELEMENTS (predefined_levels) - 1; ii++) {
+ if (predefined_levels[ii].rights == rights) {
+ break;
+ }
+ }
+
+ if (!widgets->read_fb_time_radio && ii > G_N_ELEMENTS (predefined_levels) - 3)
+ ii = G_N_ELEMENTS (predefined_levels) - 3;
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widgets->level_combo), ii);
+ }
+ } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widgets->write_edit_all_check))) {
+ gtk_widget_set_sensitive (widgets->write_edit_own_check, FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widgets->write_edit_own_check), TRUE);
+ }
+
+ update_folder_permissions_tree_view (dialog, widgets);
+
+ widgets->updating--;
+}
+
+static void
+update_permission_dialog_by_level_combo (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ uint32_t rights;
+ gint ii;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ if (widgets->updating)
+ return;
+
+ ii = gtk_combo_box_get_active (GTK_COMBO_BOX (widgets->level_combo));
+ /* out of bounds or 'Customs' level, or 'Custom' without free/busy checks */
+ if (ii < 0 || ii >= G_N_ELEMENTS (predefined_levels) - 1 ||
+ (!widgets->read_fb_time_radio && ii >= G_N_ELEMENTS (predefined_levels) - 3))
+ return;
+
+ rights = folder_permissions_dialog_to_rights (dialog);
+ rights = predefined_levels[ii].rights | (rights & (E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED |
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE));
+
+ widgets->updating++;
+ update_folder_permissions_by_rights (dialog, rights);
+ update_folder_permissions_tree_view (dialog, widgets);
+ widgets->updating--;
+}
+
+static void
+add_button_clicked_cb (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ gchar *display_name = NULL;
+ gchar *primary_smtp = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ if (widgets->updating)
+ return;
+
+ g_return_if_fail (widgets->tree_view != NULL);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widgets->tree_view));
+ g_return_if_fail (model != NULL);
+
+ if (e_ews_search_user_modal (GTK_WINDOW (dialog), widgets->conn, NULL, &display_name, &primary_smtp)) {
+ EEwsPermission *perm;
+ GtkTreeSelection *selection;
+ gboolean found = FALSE;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widgets->tree_view));
+ g_return_if_fail (selection != NULL);
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ EEwsPermissionUserType ut = E_EWS_PERMISSION_USER_TYPE_NONE;
+
+ perm = NULL;
+
+ gtk_tree_model_get (model, &iter,
+ COL_E_EWS_PERMISSION, &perm,
+ COL_E_EWS_PERMISSION_USER_TYPE, &ut,
+ -1);
+
+ if (ut == E_EWS_PERMISSION_USER_TYPE_REGULAR && perm && g_strcmp0 (perm->primary_smtp, primary_smtp)) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ found = TRUE;
+ break;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ if (!found) {
+ GtkListStore *store = GTK_LIST_STORE (model);
+
+ perm = e_ews_permission_new (E_EWS_PERMISSION_USER_TYPE_REGULAR,
+ display_name, primary_smtp, NULL,
+ widgets->read_fb_time_radio ? E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE : 0);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_NAME, perm->display_name,
+ COL_PERMISSION_LEVEL, g_dgettext ("PermissionsLevel", predefined_levels[0].name),
+ COL_E_EWS_PERMISSION, perm,
+ COL_E_EWS_PERMISSION_USER_TYPE, E_EWS_PERMISSION_USER_TYPE_REGULAR,
+ COL_IS_NEW, TRUE,
+ -1);
+
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+ }
+
+ g_free (display_name);
+ g_free (primary_smtp);
+}
+
+static void
+remove_button_clicked_cb (GObject *dialog)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model = NULL;
+ GtkTreeIter iter;
+
+ g_return_if_fail (dialog != NULL);
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+
+ if (widgets->updating)
+ return;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widgets->tree_view));
+ if (selection && gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ GtkTreeIter select;
+ gboolean can_select = FALSE;
+ EEwsPermission *perm = NULL;
+
+ select = iter;
+ can_select = gtk_tree_model_iter_next (model, &select);
+ if (!can_select) {
+ select = iter;
+ can_select = gtk_tree_model_iter_previous (model, &select);
+ }
+
+ if (can_select)
+ gtk_tree_selection_select_iter (selection, &select);
+
+ gtk_tree_model_get (model, &iter, COL_E_EWS_PERMISSION, &perm, -1);
+
+ if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter))
+ e_ews_permission_free (perm);
+ }
+}
+
+static void
+folder_permissions_free_found_permissions (gpointer ptr)
+{
+ GSList **ppermissions = ptr;
+
+ if (!ppermissions)
+ return;
+
+ e_ews_permissions_free (*ppermissions);
+ *ppermissions = NULL;
+ g_free (ppermissions);
+}
+
+static void
+read_folder_permissions_thread (GObject *dialog,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ GSList **ppermissions = user_data;
+
+ g_return_if_fail (dialog != NULL);
+ g_return_if_fail (ppermissions != NULL);
+
+ if (g_cancellable_is_cancelled (cancellable))
+ return;
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->registry != NULL);
+ g_return_if_fail (widgets->source != NULL);
+ g_return_if_fail (widgets->ews_settings != NULL);
+
+ widgets->conn = e_ews_config_utils_open_connection_for (GTK_WINDOW (dialog),
+ widgets->registry,
+ widgets->source,
+ widgets->ews_settings,
+ cancellable,
+ perror);
+
+ if (!widgets->conn)
+ g_cancellable_cancel (cancellable);
+
+ if (g_cancellable_is_cancelled (cancellable))
+ return;
+
+ e_ews_connection_get_folder_permissions_sync (widgets->conn,
+ G_PRIORITY_DEFAULT, widgets->folder_id, ppermissions, cancellable, perror);
+}
+
+static void
+read_folder_permissions_idle (GObject *dialog,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **perror)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ GSList **ppermissions = user_data;
+ GSList *permiter;
+ GtkListStore *store;
+ GtkTreeIter iter;
+
+ g_return_if_fail (dialog != NULL);
+ g_return_if_fail (ppermissions != NULL);
+
+ if (g_cancellable_is_cancelled (cancellable))
+ return;
+
+ widgets = g_object_get_data (dialog, E_EWS_PERM_DLG_WIDGETS);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->tree_view != NULL);
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widgets->tree_view)));
+ g_return_if_fail (store != NULL);
+
+ for (permiter = *ppermissions; permiter; permiter = permiter->next) {
+ EEwsPermission *perm = permiter->data;
+ const gchar *perm_level;
+ uint32_t rights;
+ gint ii;
+
+ if (!perm)
+ continue;
+
+ /* steal the perm */
+ permiter->data = NULL;
+
+ rights = perm->rights;
+ if (!widgets->read_fb_time_radio) {
+ rights = rights & ~(E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED |
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE);
+ }
+
+ for (ii = 0; ii < G_N_ELEMENTS (predefined_levels) - 1; ii++) {
+ if (predefined_levels[ii].rights == rights) {
+ break;
+ }
+ }
+
+ if (perm->user_type == E_EWS_PERMISSION_USER_TYPE_ANONYMOUS) {
+ g_free (perm->display_name);
+ perm->display_name = g_strdup (C_("User", "Anonymous"));
+ } else if (perm->user_type == E_EWS_PERMISSION_USER_TYPE_DEFAULT) {
+ g_free (perm->display_name);
+ perm->display_name = g_strdup (C_("User", "Default"));
+ } else if (!perm->display_name || !*perm->display_name) {
+ const gchar *display_name;
+
+ if (!display_name)
+ display_name = perm->primary_smtp;
+ if (!display_name)
+ display_name = C_("User", "Unknown");
+
+ g_free (perm->display_name);
+ perm->display_name = g_strdup (display_name);
+ }
+
+ perm_level = g_dgettext ("PermissionsLevel", predefined_levels[ii].name);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_NAME, perm->display_name,
+ COL_PERMISSION_LEVEL, perm_level,
+ COL_E_EWS_PERMISSION, perm,
+ COL_E_EWS_PERMISSION_USER_TYPE, perm->user_type,
+ COL_IS_NEW, FALSE,
+ -1);
+ }
+
+ gtk_widget_set_sensitive (widgets->add_button, TRUE);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (widgets->dialog), GTK_RESPONSE_OK, TRUE);
+}
+
+static void
+folder_permissions_tree_selection_changed_cb (GtkTreeSelection *selection,
+ struct EEwsPermissionsDialogWidgets *widgets)
+{
+ GObject *dialog;
+ GtkTreeModel *model = NULL;
+ GtkTreeIter iter;
+ gboolean has_selected;
+
+ g_return_if_fail (selection != NULL);
+ g_return_if_fail (widgets != NULL);
+ g_return_if_fail (widgets->dialog != NULL);
+ g_return_if_fail (widgets->add_button != NULL);
+ g_return_if_fail (widgets->remove_button != NULL);
+
+ dialog = G_OBJECT (widgets->dialog);
+ has_selected = gtk_tree_selection_get_selected (selection, &model, &iter);
+
+ gtk_widget_set_sensitive (widgets->add_button, TRUE);
+ gtk_widget_set_sensitive (widgets->remove_button, has_selected);
+
+ if (has_selected) {
+ EEwsPermissionUserType user_type = E_EWS_PERMISSION_USER_TYPE_NONE;
+ EEwsPermission *perm = NULL;
+
+ gtk_tree_model_get (model, &iter,
+ COL_E_EWS_PERMISSION, &perm,
+ COL_E_EWS_PERMISSION_USER_TYPE, &user_type,
+ -1);
+
+ update_folder_permissions_sensitivity (dialog, perm != NULL, user_type);
+ update_folder_permissions_by_rights (dialog, perm ? perm->rights : 0);
+ } else {
+ update_folder_permissions_sensitivity (dialog, FALSE, E_EWS_PERMISSION_USER_TYPE_NONE);
+ update_folder_permissions_by_rights (dialog, 0);
+ }
+
+ update_permission_level_combo_by_dialog (dialog);
+}
+
+static GtkWidget *
+create_permissions_tree_view (GObject *dialog,
+ struct EEwsPermissionsDialogWidgets *widgets)
+{
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ gint pos;
+
+ g_return_val_if_fail (widgets != NULL, NULL);
+
+ tree_view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (
+ GTK_TREE_MODEL (gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_BOOLEAN))));
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "editable", FALSE, NULL);
+ pos = gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("Name"), renderer, "text", COL_NAME, NULL);
+ column = gtk_tree_view_get_column (tree_view, pos - 1);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "editable", FALSE, NULL);
+ gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("Permission level"), renderer, "text", COL_PERMISSION_LEVEL, NULL);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ g_signal_connect (selection, "changed", G_CALLBACK (folder_permissions_tree_selection_changed_cb), widgets);
+
+ widgets->tree_view = GTK_WIDGET (tree_view);
+
+ return widgets->tree_view;
+}
+
+/* Opens dialog to subscribe to folders of other
+ users in the given store */
+void
+e_ews_edit_folder_permissions (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelEwsSettings *ews_settings,
+ const gchar *account_name,
+ const gchar *folder_name,
+ const EwsFolderId *folder_id,
+ EwsFolderType folder_type)
+{
+ struct EEwsPermissionsDialogWidgets *widgets;
+ PangoAttrList *attrs;
+ GObject *dialog;
+ GtkWidget *content;
+ GtkWidget *label, *widget, *button, *frame, *hvbox;
+ GtkScrolledWindow *scrolled_window;
+ GtkComboBoxText *combo_text;
+ GtkGrid *grid;
+ GSList *radio_group, **found_permissions;
+ gboolean with_freebusy;
+ gint row, ii;
+
+ g_return_if_fail (registry != NULL);
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (ews_settings != NULL);
+ g_return_if_fail (account_name != NULL);
+ g_return_if_fail (folder_name != NULL);
+ g_return_if_fail (folder_id != NULL);
+
+ with_freebusy = folder_type == EWS_FOLDER_TYPE_CALENDAR;
+
+ widgets = g_new0 (struct EEwsPermissionsDialogWidgets, 1);
+ widgets->registry = g_object_ref (registry);
+ widgets->source = g_object_ref (source);
+ widgets->ews_settings = g_object_ref (ews_settings);
+ widgets->folder_id = e_ews_folder_id_new (folder_id->id, folder_id->change_key, folder_id->is_distinguished_id);
+ widgets->folder_type = folder_type;
+
+ widgets->dialog = gtk_dialog_new_with_buttons (
+ _("Edit EWS folder permissions..."),
+ parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ dialog = G_OBJECT (widgets->dialog);
+ g_signal_connect (dialog, "response", G_CALLBACK (edit_permissions_response_cb), NULL);
+ g_object_set_data_full (dialog, E_EWS_PERM_DLG_WIDGETS, widgets, edit_permissions_widgets_free);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, FALSE);
+ gtk_grid_set_row_spacing (grid, 6);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
+ gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (grid));
+
+ row = 0;
+
+ label = gtk_label_new (_("Account:"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ "halign", GTK_ALIGN_START,
+ NULL);
+
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+ widget = gtk_label_new (account_name);
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ "use-underline", FALSE,
+ "attributes", attrs,
+ "xalign", 0.0,
+ "halign", GTK_ALIGN_START,
+ NULL);
+ pango_attr_list_unref (attrs);
+
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ label = gtk_label_new (_("Folder name:"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ widget = gtk_label_new (folder_name);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_MIDDLE);
+ gtk_widget_set_tooltip_text (widget, folder_name);
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ label = gtk_label_new (_("Folder ID:"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ widget = gtk_entry_new ();
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ "has-frame", FALSE,
+ "editable", FALSE,
+ "can-focus", FALSE,
+ "text", folder_id->id,
+ NULL);
+
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ gtk_scrolled_window_set_min_content_width (scrolled_window, 120);
+ gtk_scrolled_window_set_min_content_height (scrolled_window, 120);
+ gtk_container_add (GTK_CONTAINER (widget), create_permissions_tree_view (dialog, widgets));
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", TRUE,
+ "shadow-type", GTK_SHADOW_IN,
+ NULL);
+
+ gtk_grid_attach (grid, widget, 0, row, 2, 1);
+
+ row++;
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_HORIZONTAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 6);
+ gtk_grid_set_column_homogeneous (GTK_GRID (hvbox), TRUE);
+ g_object_set (G_OBJECT (hvbox),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "halign", GTK_ALIGN_END,
+ NULL);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ widgets->add_button = button;
+ gtk_container_add (GTK_CONTAINER (hvbox), button);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+ widgets->remove_button = button;
+ gtk_container_add (GTK_CONTAINER (hvbox), button);
+
+ gtk_grid_attach (grid, hvbox, 0, row, 2, 1);
+
+ row++;
+
+ widget = gtk_frame_new (_("Permissions"));
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ NULL);
+ gtk_grid_attach (grid, widget, 0, row, 2, 1);
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, FALSE);
+ gtk_grid_set_row_spacing (grid, 6);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (grid));
+
+ row = 0;
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_HORIZONTAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 6);
+
+ label = gtk_label_new_with_mnemonic (_("Permi_ssion level:"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ widget = GTK_WIDGET (g_object_new (gtk_combo_box_text_get_type (),
+ "has-entry", FALSE,
+ "entry-text-column", 0,
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ NULL));
+ widgets->level_combo = widget;
+
+ combo_text = GTK_COMBO_BOX_TEXT (widget);
+ for (ii = 0; ii < G_N_ELEMENTS (predefined_levels); ii++) {
+ if (with_freebusy ||
+ (predefined_levels[ii].rights != E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE &&
+ predefined_levels[ii].rights != E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED))
+ gtk_combo_box_text_append_text (combo_text, g_dgettext ("PermissionsLevel", predefined_levels[ii].name));
+ }
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo_text), 0);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+ gtk_container_add (GTK_CONTAINER (hvbox), label);
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ gtk_grid_attach (grid, hvbox, 0, row, 2, 1);
+
+ row++;
+
+ frame = gtk_frame_new (C_("Permissions", "Read"));
+ g_object_set (G_OBJECT (frame),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ NULL);
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_VERTICAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 2);
+ gtk_container_add (GTK_CONTAINER (frame), hvbox);
+
+ widget = gtk_radio_button_new_with_label (NULL, C_("Permissions", "None"));
+ widgets->read_none_radio = widget;
+ radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ if (with_freebusy) {
+ widget = gtk_radio_button_new_with_label (radio_group, C_("Permissions", "Free/Busy time"));
+ widgets->read_fb_time_radio = widget;
+ radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_radio_button_new_with_label (radio_group, C_("Permissions", "Free/Busy time, subject, location"));
+ widgets->read_fb_detail_radio = widget;
+ radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+ }
+
+ widget = gtk_radio_button_new_with_label (radio_group, C_("Permissions", "Full Details"));
+ widgets->read_full_radio = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ gtk_grid_attach (grid, frame, 0, row, 1, 1);
+
+ frame = gtk_frame_new (C_("Permissions", "Write"));
+ g_object_set (G_OBJECT (frame),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ NULL);
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_VERTICAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 2);
+ gtk_container_add (GTK_CONTAINER (frame), hvbox);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Create items"));
+ widgets->write_create_items_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Create subfolders"));
+ widgets->write_create_subfolders_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Edit own"));
+ widgets->write_edit_own_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Edit all"));
+ widgets->write_edit_all_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ gtk_grid_attach (grid, frame, 1, row, 1, 1);
+
+ row++;
+
+ frame = gtk_frame_new (C_("Permissions", "Delete items"));
+ g_object_set (G_OBJECT (frame),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ NULL);
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_VERTICAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 2);
+ gtk_container_add (GTK_CONTAINER (frame), hvbox);
+
+ widget = gtk_radio_button_new_with_label (NULL, C_("Permissions", "None"));
+ widgets->delete_none_radio = widget;
+ radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_radio_button_new_with_label (radio_group, C_("Permissions", "Own"));
+ widgets->delete_own_radio = widget;
+ radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_radio_button_new_with_label (radio_group, C_("Permissions", "All"));
+ widgets->delete_all_radio = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ gtk_grid_attach (grid, frame, 0, row, 1, 1);
+
+ frame = gtk_frame_new (C_("Permissions", "Other"));
+ g_object_set (G_OBJECT (frame),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ NULL);
+
+ hvbox = gtk_grid_new ();
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hvbox), GTK_ORIENTATION_VERTICAL);
+ gtk_grid_set_column_spacing (GTK_GRID (hvbox), 2);
+ gtk_container_add (GTK_CONTAINER (frame), hvbox);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Folder owner"));
+ widgets->other_folder_owner_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Folder contact"));
+ widgets->other_folder_contact_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ widget = gtk_check_button_new_with_label (C_("Permissions", "Folder visible"));
+ widgets->other_folder_visible_check = widget;
+ gtk_container_add (GTK_CONTAINER (hvbox), widget);
+
+ gtk_grid_attach (grid, frame, 1, row, 1, 1);
+
+ row++;
+
+ g_signal_connect_swapped (widgets->add_button,
+ "clicked", G_CALLBACK (add_button_clicked_cb), dialog);
+ g_signal_connect_swapped (widgets->remove_button,
+ "clicked", G_CALLBACK (remove_button_clicked_cb), dialog);
+ g_signal_connect_swapped (widgets->level_combo,
+ "changed", G_CALLBACK (update_permission_dialog_by_level_combo), dialog);
+ g_signal_connect_swapped (widgets->read_none_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->read_full_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ if (widgets->read_fb_time_radio)
+ g_signal_connect_swapped (widgets->read_fb_time_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ if (widgets->read_fb_detail_radio)
+ g_signal_connect_swapped (widgets->read_fb_detail_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->write_create_items_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->write_create_subfolders_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->write_edit_own_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->write_edit_all_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->delete_none_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->delete_own_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->delete_all_radio,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->other_folder_owner_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->other_folder_contact_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+ g_signal_connect_swapped (widgets->other_folder_visible_check,
+ "toggled", G_CALLBACK (update_permission_level_combo_by_dialog), dialog);
+
+ enable_all_widgets (widgets, FALSE);
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (widgets->dialog), GTK_RESPONSE_OK, FALSE);
+
+ gtk_widget_show_all (content);
+ gtk_widget_show (GTK_WIDGET (dialog));
+
+ found_permissions = g_new0 (GSList *, 1);
+
+ e_ews_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+ _("Reading folder permissions, please wait..."),
+ read_folder_permissions_thread,
+ read_folder_permissions_idle,
+ found_permissions, folder_permissions_free_found_permissions);
+}
diff --git a/src/configuration/e-ews-edit-folder-permissions.h b/src/configuration/e-ews-edit-folder-permissions.h
new file mode 100644
index 0000000..2940bcf
--- /dev/null
+++ b/src/configuration/e-ews-edit-folder-permissions.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Milan Crha <mcrha redhat com>
+ *
+ * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
+ *
+ */
+
+#ifndef E_EWS_EDIT_FOLDER_PERMISSIONS_H
+#define E_EWS_EDIT_FOLDER_PERMISSIONS_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+
+#include "server/e-ews-item.h"
+#include "server/e-ews-folder.h"
+#include "server/camel-ews-settings.h"
+
+void e_ews_edit_folder_permissions (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ CamelEwsSettings *ews_settings,
+ const gchar *account_name,
+ const gchar *folder_name,
+ const EwsFolderId *folder_id,
+ EwsFolderType folder_type);
+
+#endif /* E_EWS_EDIT_FOLDER_PERMISSIONS_H */
diff --git a/src/configuration/e-ews-search-user.c b/src/configuration/e-ews-search-user.c
new file mode 100644
index 0000000..7ec355b
--- /dev/null
+++ b/src/configuration/e-ews-search-user.c
@@ -0,0 +1,548 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Milan Crha <mcrha redhat com>
+ *
+ * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "e-ews-config-utils.h"
+#include "e-ews-search-user.h"
+
+#define E_EWS_SEARCH_DLG_DATA "e-ews-search-dlg-data"
+
+enum {
+ COL_DISPLAY_NAME = 0,
+ COL_EMAIL
+};
+
+struct EEwsSearchUserData
+{
+ EEwsConnection *conn;
+ GCancellable *cancellable;
+ gchar *search_text;
+ GtkWidget *tree_view;
+ GtkWidget *info_label;
+ guint schedule_search_id;
+};
+
+static void
+e_ews_search_user_data_free (gpointer ptr)
+{
+ struct EEwsSearchUserData *pgu = ptr;
+
+ if (!pgu)
+ return;
+
+ if (pgu->schedule_search_id) {
+ g_source_remove (pgu->schedule_search_id);
+ pgu->schedule_search_id = 0;
+ }
+ if (pgu->cancellable) {
+ g_cancellable_cancel (pgu->cancellable);
+ g_object_unref (pgu->cancellable);
+ pgu->cancellable = NULL;
+ }
+ g_object_unref (pgu->conn);
+ g_free (pgu->search_text);
+ g_free (pgu);
+}
+
+struct EEwsSearchUser
+{
+ gchar *display_name;
+ gchar *email;
+};
+
+static struct EEwsSearchUser *
+e_ews_search_user_new (const gchar *display_name,
+ const gchar *email)
+{
+ struct EEwsSearchUser *user;
+
+ if (!display_name)
+ display_name = email;
+
+ user = g_new0 (struct EEwsSearchUser, 1);
+ user->display_name = g_strdup (display_name);
+ user->email = g_strdup (email);
+
+ return user;
+}
+
+static void
+e_ews_search_user_free (gpointer ptr)
+{
+ struct EEwsSearchUser *user = ptr;
+
+ if (!user)
+ return;
+
+ g_free (user->display_name);
+ g_free (user->email);
+ g_free (user);
+}
+
+struct EEwsSearchIdleData
+{
+ EEwsConnection *conn;
+ gchar *search_text;
+ GCancellable *cancellable;
+
+ GObject *dialog;
+ GSList *found_users; /* struct EEwsSearchUser * */
+ gboolean includes_last_item;
+};
+
+static void
+e_ews_search_idle_data_free (gpointer ptr)
+{
+ struct EEwsSearchIdleData *sid = ptr;
+
+ if (!sid)
+ return;
+
+ g_object_unref (sid->conn);
+ g_object_unref (sid->cancellable);
+ g_free (sid->search_text);
+ g_slist_free_full (sid->found_users, e_ews_search_user_free);
+ g_free (sid);
+}
+
+static void
+empty_search_tree_view (GtkWidget *tree_view)
+{
+ GtkListStore *store;
+ GtkTreeModel *model;
+
+ g_return_if_fail (tree_view != NULL);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+ g_return_if_fail (model != NULL);
+
+ store = GTK_LIST_STORE (model);
+ g_return_if_fail (store != NULL);
+
+ gtk_list_store_clear (store);
+}
+
+static void
+search_add_user (GtkListStore *store,
+ const gchar *display_name,
+ const gchar *email)
+{
+ GtkTreeIter iter;
+
+ g_return_if_fail (store != NULL);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_DISPLAY_NAME, display_name,
+ COL_EMAIL, email,
+ -1);
+}
+
+static gboolean
+search_finish_idle (gpointer user_data)
+{
+ struct EEwsSearchIdleData *sid = user_data;
+
+ g_return_val_if_fail (sid != NULL, FALSE);
+ g_return_val_if_fail (sid->dialog != NULL, FALSE);
+
+ if (!g_cancellable_is_cancelled (sid->cancellable)) {
+ struct EEwsSearchUserData *pgu;
+ GtkListStore *store;
+ guint added = 0;
+ GSList *fu;
+
+ pgu = g_object_get_data (sid->dialog, E_EWS_SEARCH_DLG_DATA);
+ g_return_val_if_fail (pgu != NULL, FALSE);
+ g_return_val_if_fail (pgu->tree_view != NULL, FALSE);
+ g_return_val_if_fail (pgu->info_label != NULL, FALSE);
+
+ empty_search_tree_view (pgu->tree_view);
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pgu->tree_view)));
+ g_return_val_if_fail (store != NULL, FALSE);
+
+ for (fu = sid->found_users; fu; fu = fu->next) {
+ struct EEwsSearchUser *user = fu->data;
+
+ if (!user)
+ continue;
+
+ search_add_user (store, user->display_name, user->email);
+
+ added++;
+ }
+
+ if (!added) {
+ gtk_label_set_text (GTK_LABEL (pgu->info_label), _("No users found"));
+ } else if (sid->includes_last_item) {
+ gchar *str;
+ str = g_strdup_printf (ngettext ("Found one user", "Found %d users", added), added);
+ gtk_label_set_text (GTK_LABEL (pgu->info_label), str);
+ g_free (str);
+ } else {
+ gchar *str;
+ str = g_strdup_printf (ngettext ("Found more than 100 users, but showing only first %d", "Found more than 100 users, but showing only first %d", added), added);
+ gtk_label_set_text (GTK_LABEL (pgu->info_label), str);
+ g_free (str);
+ }
+ }
+
+ e_ews_search_idle_data_free (sid);
+
+ return FALSE;
+}
+
+static gpointer
+search_thread (gpointer user_data)
+{
+ struct EEwsSearchIdleData *sid = user_data;
+
+ g_return_val_if_fail (sid != NULL, NULL);
+
+ if (!g_cancellable_is_cancelled (sid->cancellable)) {
+ GSList *mailboxes = NULL;
+ GError *error = NULL;
+
+ if (e_ews_connection_resolve_names_sync (
+ sid->conn, EWS_PRIORITY_MEDIUM, sid->search_text,
+ EWS_SEARCH_AD, NULL, FALSE, &mailboxes, NULL,
+ &sid->includes_last_item, sid->cancellable, &error)) {
+ GSList *iter;
+
+ for (iter = mailboxes; iter != NULL; iter = iter->next) {
+ EwsMailbox *mb = iter->data;
+
+ if (!mb || !mb->email || !*mb->email)
+ continue;
+
+ sid->found_users = g_slist_prepend (sid->found_users,
+ e_ews_search_user_new (mb->name, mb->email));
+ }
+
+ sid->found_users = g_slist_reverse (sid->found_users);
+ }
+
+ g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
+
+ if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("%s: Failed to search user: %s", G_STRFUNC, error->message);
+
+ g_clear_error (&error);
+
+ g_idle_add (search_finish_idle, sid);
+ } else {
+ e_ews_search_idle_data_free (sid);
+ }
+
+ return NULL;
+}
+
+static gboolean
+schedule_search_cb (gpointer user_data)
+{
+ struct EEwsSearchIdleData *sid = user_data;
+
+ g_return_val_if_fail (sid != NULL, FALSE);
+ g_return_val_if_fail (sid->dialog != NULL, FALSE);
+
+ if (!g_cancellable_is_cancelled (sid->cancellable)) {
+ struct EEwsSearchUserData *pgu;
+ GError *error = NULL;
+
+ pgu = g_object_get_data (sid->dialog, E_EWS_SEARCH_DLG_DATA);
+ g_return_val_if_fail (pgu != NULL, FALSE);
+ g_return_val_if_fail (pgu->tree_view != NULL, FALSE);
+
+ pgu->schedule_search_id = 0;
+ sid->conn = g_object_ref (pgu->conn);
+ sid->search_text = g_strdup (pgu->search_text);
+
+ if (g_thread_create (search_thread, sid, FALSE, &error)) {
+ sid = NULL;
+ } else {
+ g_object_unref (sid->conn);
+ g_warning ("%s: Failed to create search thread: %s", G_STRFUNC, error ? error->message : "Unknown error");
+ }
+
+ g_clear_error (&error);
+ }
+
+ e_ews_search_idle_data_free (sid);
+
+ return FALSE;
+}
+
+static void
+search_term_changed_cb (GtkEntry *entry,
+ GObject *dialog)
+{
+ struct EEwsSearchUserData *pgu;
+
+ g_return_if_fail (dialog != NULL);
+
+ pgu = g_object_get_data (dialog, E_EWS_SEARCH_DLG_DATA);
+ g_return_if_fail (pgu != NULL);
+ g_return_if_fail (pgu->tree_view != NULL);
+
+ if (pgu->schedule_search_id) {
+ g_source_remove (pgu->schedule_search_id);
+ pgu->schedule_search_id = 0;
+ }
+
+ if (pgu->cancellable) {
+ g_cancellable_cancel (pgu->cancellable);
+ g_object_unref (pgu->cancellable);
+ }
+
+ pgu->cancellable = g_cancellable_new ();
+
+ if (entry) {
+ g_free (pgu->search_text);
+ pgu->search_text = g_strdup (gtk_entry_get_text (entry));
+ }
+
+ empty_search_tree_view (pgu->tree_view);
+
+ if (!pgu->search_text || !*pgu->search_text) {
+ gtk_label_set_text (GTK_LABEL (pgu->info_label), _("Search for a user"));
+ } else {
+ struct EEwsSearchIdleData *sid;
+
+ sid = g_new0 (struct EEwsSearchIdleData, 1);
+ sid->cancellable = g_object_ref (pgu->cancellable);
+ sid->dialog = dialog;
+
+ gtk_label_set_text (GTK_LABEL (pgu->info_label), _("Searching..."));
+ pgu->schedule_search_id = g_timeout_add (333, schedule_search_cb, sid);
+ }
+}
+
+static void
+dialog_realized_cb (GObject *dialog)
+{
+ struct EEwsSearchUserData *pgu;
+
+ g_return_if_fail (dialog != NULL);
+
+ pgu = g_object_get_data (dialog, E_EWS_SEARCH_DLG_DATA);
+ g_return_if_fail (pgu != NULL);
+ g_return_if_fail (pgu->tree_view != NULL);
+
+ if (pgu->cancellable)
+ return;
+
+ search_term_changed_cb (NULL, dialog);
+}
+
+static void
+search_user_selection_changed_cb (GtkTreeSelection *selection,
+ GtkDialog *dialog)
+{
+ g_return_if_fail (selection != NULL);
+ g_return_if_fail (dialog != NULL);
+
+ gtk_dialog_set_response_sensitive (dialog,
+ GTK_RESPONSE_OK,
+ gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static void
+search_user_row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GtkDialog *dialog)
+{
+ g_return_if_fail (tree_view != NULL);
+ g_return_if_fail (dialog != NULL);
+
+ if (path && column)
+ gtk_dialog_response (dialog, GTK_RESPONSE_OK);
+}
+
+static GtkWidget *
+create_users_tree_view (GtkWidget *dialog,
+ struct EEwsSearchUserData *pgu)
+{
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ gint pos;
+
+ g_return_val_if_fail (dialog != NULL, NULL);
+ g_return_val_if_fail (pgu != NULL, NULL);
+
+ tree_view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (
+ GTK_TREE_MODEL (gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT))));
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "editable", FALSE, NULL);
+ pos = gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("Name"), renderer, "text", COL_DISPLAY_NAME, NULL);
+ column = gtk_tree_view_get_column (tree_view, pos - 1);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "editable", FALSE, NULL);
+ gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("E-mail"), renderer, "text", COL_EMAIL, NULL);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ search_user_selection_changed_cb (selection, GTK_DIALOG (dialog));
+ g_signal_connect (selection, "changed", G_CALLBACK (search_user_selection_changed_cb), dialog);
+
+ g_signal_connect (tree_view, "row-activated", G_CALLBACK (search_user_row_activated_cb), dialog);
+
+ pgu->tree_view = GTK_WIDGET (tree_view);
+
+ return pgu->tree_view;
+}
+
+gboolean
+e_ews_search_user_modal (GtkWindow *parent,
+ EEwsConnection *conn,
+ const gchar *search_this,
+ gchar **display_name,
+ gchar **email)
+{
+ gboolean res = FALSE;
+ struct EEwsSearchUserData *pgu;
+ GtkWidget *dialog;
+ GtkWidget *content, *label, *widget;
+ GtkGrid *grid;
+ GtkScrolledWindow *scrolled_window;
+ gint row;
+
+ g_return_val_if_fail (conn != NULL, FALSE);
+ g_return_val_if_fail (display_name || email, FALSE);
+
+ pgu = g_new0 (struct EEwsSearchUserData, 1);
+ pgu->conn = g_object_ref (conn);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Choose EWS user..."),
+ parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ g_object_set_data_full (G_OBJECT (dialog), E_EWS_SEARCH_DLG_DATA, pgu, e_ews_search_user_data_free);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, FALSE);
+ gtk_grid_set_row_spacing (grid, 6);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
+ gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (grid));
+
+ row = 0;
+
+ label = gtk_label_new_with_mnemonic (_("_Search:"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", FALSE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ widget = gtk_entry_new ();
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ NULL);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+ if (search_this && *search_this) {
+ gtk_entry_set_text (GTK_ENTRY (widget), search_this);
+ pgu->search_text = g_strdup (search_this);
+ }
+
+ g_signal_connect (widget, "changed", G_CALLBACK (search_term_changed_cb), dialog);
+
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ gtk_scrolled_window_set_min_content_width (scrolled_window, 120);
+ gtk_scrolled_window_set_min_content_height (scrolled_window, 120);
+ gtk_container_add (GTK_CONTAINER (widget), create_users_tree_view (dialog, pgu));
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "vexpand", TRUE,
+ "shadow-type", GTK_SHADOW_IN,
+ NULL);
+
+ gtk_grid_attach (grid, widget, 0, row, 2, 1);
+
+ row++;
+
+ label = gtk_label_new (_("Search for a user"));
+ g_object_set (G_OBJECT (label),
+ "hexpand", TRUE,
+ "vexpand", FALSE,
+ "xalign", 0.0,
+ NULL);
+
+ pgu->info_label = label;
+
+ gtk_grid_attach (grid, label, 0, row, 2, 1);
+
+ row++;
+
+ gtk_widget_show_all (content);
+
+ g_signal_connect (dialog, "realize", G_CALLBACK (dialog_realized_cb), NULL);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ GtkTreeSelection *selection;
+ GtkTreeModel *model = NULL;
+ GtkTreeIter iter;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pgu->tree_view));
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ if (display_name)
+ gtk_tree_model_get (model, &iter, COL_DISPLAY_NAME, display_name, -1);
+ if (email)
+ gtk_tree_model_get (model, &iter, COL_EMAIL, email, -1);
+
+ res = TRUE;
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+
+ return res;
+}
diff --git a/src/configuration/e-ews-search-user.h b/src/configuration/e-ews-search-user.h
new file mode 100644
index 0000000..f4a9109
--- /dev/null
+++ b/src/configuration/e-ews-search-user.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Milan Crha <mcrha redhat com>
+ *
+ * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
+ *
+ */
+
+#ifndef E_EWS_SEARCH_USER_H
+#define E_EWS_SEARCH_USER_H
+
+#include <gtk/gtk.h>
+#include "server/e-ews-connection.h"
+#include "server/e-ews-item.h"
+
+gboolean e_ews_search_user_modal (GtkWindow *parent,
+ EEwsConnection *conn,
+ const gchar *search_this,
+ gchar **display_name,
+ gchar **email);
+
+#endif /* E_EWS_SEARCH_USER_H */
diff --git a/src/configuration/module-ews-configuration.c b/src/configuration/module-ews-configuration.c
index 344d453..f71a263 100644
--- a/src/configuration/module-ews-configuration.c
+++ b/src/configuration/module-ews-configuration.c
@@ -25,6 +25,9 @@
#include "e-mail-config-ews-oal-combo-box.h"
#include "e-mail-config-ews-ooo-page.h"
+#include "e-ews-config-ui-extension.h"
+#include "server/e-source-ews-folder.h"
+
/* Module Entry Points */
void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module);
@@ -40,6 +43,9 @@ e_module_load (GTypeModule *type_module)
e_mail_config_ews_notebook_type_register (type_module);
e_mail_config_ews_oal_combo_box_type_register (type_module);
e_mail_config_ews_ooo_page_type_register (type_module);
+ e_ews_config_ui_extension_type_register (type_module);
+
+ e_source_ews_folder_type_register (type_module);
}
G_MODULE_EXPORT void
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 7f3e441..de4baa2 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -4546,9 +4546,9 @@ e_ews_connection_get_folder (EEwsConnection *cnc,
e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
e_ews_message_write_string_parameter (msg, "BaseShape", NULL, folder_shape);
- e_soap_message_end_element (msg);
ews_append_additional_props_to_msg (msg, add_props);
+ e_soap_message_end_element (msg);
if (folder_ids) {
e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
@@ -6085,6 +6085,368 @@ e_ews_connection_get_delegate_sync (EEwsConnection *cnc,
e_async_closure_free (closure);
return success;
+}
+
+static void
+get_folder_permissions_response_cb (ESoapResponse *response,
+ GSimpleAsyncResult *simple)
+{
+ EwsAsyncData *async_data;
+ ESoapParameter *param;
+ ESoapParameter *subparam;
+ GError *error = NULL;
+
+ async_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ param = e_soap_response_get_first_parameter_by_name (
+ response, "ResponseMessages", &error);
+
+ /* Sanity check */
+ g_return_if_fail (
+ (param != NULL && error == NULL) ||
+ (param == NULL && error != NULL));
+
+ if (error != NULL) {
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ subparam = e_soap_parameter_get_first_child (param);
+
+ while (subparam != NULL) {
+ const gchar *name = (const gchar *) subparam->name;
+
+ if (!ews_get_response_status (subparam, &error)) {
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ if (CHECK_ELEMENT (name, "GetFolderResponseMessage")) {
+ ESoapParameter *node;
+
+ node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
+ if (node) {
+ subparam = node;
+
+ node = e_soap_parameter_get_first_child (subparam);
+ if (node && node->name && g_str_has_suffix ((const gchar *) node->name, "Folder")) {
+ node = e_soap_parameter_get_first_child_by_name (node, "PermissionSet");
+ if (node) {
+ async_data->items = e_ews_permissions_from_soap_param (node);
+ }
+ }
+ }
+
+ break;
+ }
+
+ subparam = e_soap_parameter_get_next_child (subparam);
+ }
+}
+
+void
+e_ews_connection_get_folder_permissions (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ESoapMessage *msg;
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+ GSList *folder_ids;
+
+ g_return_if_fail (cnc != NULL);
+ g_return_if_fail (folder_id != NULL);
+
+ msg = e_ews_message_new_with_header (cnc->priv->uri, "GetFolder",
+ NULL, NULL, EWS_EXCHANGE_2007_SP1);
+
+ e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
+ e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "IdOnly");
+ e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
+ e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", "folder:PermissionSet");
+ e_soap_message_end_element (msg); /* AdditionalProperties */
+ e_soap_message_end_element (msg); /* FolderShape */
+
+ folder_ids = g_slist_append (NULL, folder_id);
+ e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
+ ews_append_folder_ids_to_msg (msg, cnc->priv->email, folder_ids);
+ e_soap_message_end_element (msg);
+ g_slist_free (folder_ids);
+
+ e_ews_message_write_footer (msg);
+
+ simple = g_simple_async_result_new (G_OBJECT (cnc),
+ callback,
+ user_data,
+ e_ews_connection_get_folder_permissions);
+
+ async_data = g_new0 (EwsAsyncData, 1);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_data, (GDestroyNotify) async_data_free);
+
+ e_ews_connection_queue_request (
+ cnc, msg, get_folder_permissions_response_cb,
+ pri, cancellable, simple);
+
+ g_object_unref (simple);
+}
+
+/* free permissions with e_ews_permissions_free() */
+gboolean
+e_ews_connection_get_folder_permissions_finish (EEwsConnection *cnc,
+ GAsyncResult *result,
+ GSList **permissions,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ g_return_val_if_fail (cnc != NULL, FALSE);
+ g_return_val_if_fail (permissions != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (cnc), e_ews_connection_get_folder_permissions),
+ FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ *permissions = async_data->items;
+
+ return TRUE;
+}
+
+/* free permissions with e_ews_permissions_free() */
+gboolean
+e_ews_connection_get_folder_permissions_sync (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ GSList **permissions,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (folder_id != NULL, FALSE);
+ g_return_val_if_fail (permissions != NULL, FALSE);
+
+ closure = e_async_closure_new ();
+
+ e_ews_connection_get_folder_permissions (
+ cnc, pri, folder_id, cancellable,
+ e_async_closure_callback, closure);
+
+ result = e_async_closure_wait (closure);
+
+ success = e_ews_connection_get_folder_permissions_finish (
+ cnc, result, permissions, error);
+
+ e_async_closure_free (closure);
+
+ return success;
+}
+
+void
+e_ews_connection_set_folder_permissions (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ EwsFolderType folder_type,
+ const GSList *permissions,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ESoapMessage *msg;
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+ const GSList *iter;
+
+ g_return_if_fail (cnc != NULL);
+ g_return_if_fail (folder_id != NULL);
+ g_return_if_fail (permissions != NULL);
+
+ msg = e_ews_message_new_with_header (cnc->priv->uri, "UpdateFolder",
+ NULL, NULL, EWS_EXCHANGE_2007_SP1);
+ e_soap_message_start_element (msg, "FolderChanges", "messages", NULL);
+ e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_FOLDER,
+ folder_id->id, folder_id->change_key, 0);
+
+ e_soap_message_start_element (msg, "SetFolderField", NULL, NULL);
+ e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", "folder:PermissionSet");
+
+ switch (folder_type) {
+ default:
+ case EWS_FOLDER_TYPE_MAILBOX:
+ e_soap_message_start_element (msg, "Folder", NULL, NULL);
+ break;
+ case EWS_FOLDER_TYPE_CALENDAR:
+ e_soap_message_start_element (msg, "CalendarFolder", NULL, NULL);
+ break;
+ case EWS_FOLDER_TYPE_CONTACTS:
+ e_soap_message_start_element (msg, "ContactsFolder", NULL, NULL);
+ break;
+ case EWS_FOLDER_TYPE_QUERY:
+ e_soap_message_start_element (msg, "SearchFolder", NULL, NULL);
+ break;
+ case EWS_FOLDER_TYPE_TASKS:
+ e_soap_message_start_element (msg, "TasksFolder", NULL, NULL);
+ break;
+ }
+
+ e_soap_message_start_element (msg, "PermissionSet", NULL, NULL);
+ e_soap_message_start_element (msg, "Permissions", NULL, NULL);
+
+ for (iter = permissions; iter; iter = iter->next) {
+ EEwsPermission *perm = iter->data;
+ const gchar *perm_level_name;
+
+ if (!perm)
+ continue;
+
+ if (folder_type == EWS_FOLDER_TYPE_CALENDAR)
+ e_soap_message_start_element (msg, "CalendarPermission", NULL, NULL);
+ else
+ e_soap_message_start_element (msg, "Permission", NULL, NULL);
+
+ e_soap_message_start_element (msg, "UserId", NULL, NULL);
+
+ switch (perm->user_type) {
+ case E_EWS_PERMISSION_USER_TYPE_NONE:
+ g_return_if_reached ();
+ break;
+ case E_EWS_PERMISSION_USER_TYPE_ANONYMOUS:
+ e_ews_message_write_string_parameter (msg, "DistinguishedUser", NULL, "Anonymous");
+ break;
+ case E_EWS_PERMISSION_USER_TYPE_DEFAULT:
+ e_ews_message_write_string_parameter (msg, "DistinguishedUser", NULL, "Default");
+ break;
+ case E_EWS_PERMISSION_USER_TYPE_REGULAR:
+ e_ews_message_write_string_parameter (msg, "PrimarySmtpAddress", NULL, perm->primary_smtp);
+ break;
+ }
+
+ e_soap_message_end_element (msg); /* UserId */
+
+ e_ews_permission_rights_to_level_name (perm->rights);
+
+ perm_level_name = e_ews_permission_rights_to_level_name (perm->rights);
+
+ if (g_strcmp0 (perm_level_name, "Custom") == 0) {
+ e_ews_message_write_string_parameter (msg, "CanCreateItems", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_CREATE) != 0 ? "true" : "false");
+ e_ews_message_write_string_parameter (msg, "CanCreateSubFolders", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER) != 0 ? "true" : "false");
+ e_ews_message_write_string_parameter (msg, "IsFolderOwner", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_OWNER) != 0 ? "true" : "false");
+ e_ews_message_write_string_parameter (msg, "IsFolderVisible", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_VISIBLE) != 0 ? "true" : "false");
+ e_ews_message_write_string_parameter (msg, "IsFolderContact", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_CONTACT) != 0 ? "true" : "false");
+ e_ews_message_write_string_parameter (msg, "EditItems", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_EDIT_ANY) != 0 ? "All" :
+ (perm->rights & E_EWS_PERMISSION_BIT_EDIT_OWNED) != 0 ? "Owned" : "None");
+ e_ews_message_write_string_parameter (msg, "DeleteItems", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_DELETE_ANY) != 0 ? "All" :
+ (perm->rights & E_EWS_PERMISSION_BIT_DELETE_OWNED) != 0 ? "Owned" : "None");
+ if (folder_type == EWS_FOLDER_TYPE_CALENDAR)
+ e_ews_message_write_string_parameter (msg, "ReadItems", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_READ_ANY) != 0 ? "FullDetails" :
+ (perm->rights & E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED) != 0 ? "TimeAndSubjectAndLocation" :
+ (perm->rights & E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE) != 0 ? "TimeOnly" : "None");
+ else
+ e_ews_message_write_string_parameter (msg, "ReadItems", NULL,
+ (perm->rights & E_EWS_PERMISSION_BIT_READ_ANY) != 0 ? "FullDetails" : "None");
+ }
+
+ e_ews_message_write_string_parameter (msg,
+ folder_type == EWS_FOLDER_TYPE_CALENDAR ? "CalendarPermissionLevel" : "PermissionLevel", NULL,
+ perm_level_name);
+
+ e_soap_message_end_element (msg); /* Permission/CalendarPermission */
+ }
+
+ e_soap_message_end_element (msg); /* Permissions */
+ e_soap_message_end_element (msg); /* PermissionSet */
+ e_soap_message_end_element (msg); /* Folder/CalendarFolder/... */
+ e_soap_message_end_element (msg); /* SetFolderField */
+
+ e_ews_message_end_item_change (msg);
+
+ e_ews_message_write_footer (msg);
+
+ simple = g_simple_async_result_new (G_OBJECT (cnc),
+ callback,
+ user_data,
+ e_ews_connection_set_folder_permissions);
+
+ async_data = g_new0 (EwsAsyncData, 1);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_data, (GDestroyNotify) async_data_free);
+
+ e_ews_connection_queue_request (
+ cnc, msg, update_folder_response_cb,
+ pri, cancellable, simple);
+
+ g_object_unref (simple);
+}
+
+gboolean
+e_ews_connection_set_folder_permissions_finish (EEwsConnection *cnc,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (cnc != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (cnc), e_ews_connection_set_folder_permissions),
+ FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ return !g_simple_async_result_propagate_error (simple, error);
}
+gboolean
+e_ews_connection_set_folder_permissions_sync (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ EwsFolderType folder_type,
+ const GSList *permissions,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (folder_id != NULL, FALSE);
+ g_return_val_if_fail (permissions != NULL, FALSE);
+
+ closure = e_async_closure_new ();
+
+ e_ews_connection_set_folder_permissions (
+ cnc, pri, folder_id, folder_type, permissions, cancellable,
+ e_async_closure_callback, closure);
+
+ result = e_async_closure_wait (closure);
+
+ success = e_ews_connection_set_folder_permissions_finish (
+ cnc, result, error);
+
+ e_async_closure_free (closure);
+
+ return success;
+}
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index e799d3e..6bc2387 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -807,6 +807,46 @@ gboolean e_ews_connection_get_delegate_sync
EwsDelegateInfo **get_delegate,
GCancellable *cancellable,
GError **error);
+void e_ews_connection_get_folder_permissions
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_ews_connection_get_folder_permissions_finish
+ (EEwsConnection *cnc,
+ GAsyncResult *result,
+ GSList **permissions,
+ GError **error);
+gboolean e_ews_connection_get_folder_permissions_sync
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ GSList **permissions,
+ GCancellable *cancellable,
+ GError **error);
+void e_ews_connection_set_folder_permissions
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ EwsFolderType folder_type,
+ const GSList *permissions,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_ews_connection_set_folder_permissions_finish
+ (EEwsConnection *cnc,
+ GAsyncResult *result,
+ GError **error);
+gboolean e_ews_connection_set_folder_permissions_sync
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *folder_id,
+ EwsFolderType folder_type,
+ const GSList *permissions,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/server/e-ews-folder.c b/src/server/e-ews-folder.c
index 22adea4..ee5c227 100644
--- a/src/server/e-ews-folder.c
+++ b/src/server/e-ews-folder.c
@@ -207,8 +207,23 @@ e_ews_folder_new_from_soap_parameter (ESoapParameter *param)
return folder;
}
+EwsFolderId *
+e_ews_folder_id_new (const gchar *id,
+ const gchar *change_key,
+ gboolean is_distinguished_id)
+{
+ EwsFolderId *fid;
+
+ fid = g_new0 (EwsFolderId, 1);
+ fid->id = g_strdup (id);
+ fid->change_key = g_strdup (change_key);
+ fid->is_distinguished_id = is_distinguished_id;
+
+ return fid;
+}
+
void
-e_ews_folder_free_fid (EwsFolderId *fid)
+e_ews_folder_id_free (EwsFolderId *fid)
{
if (fid) {
g_free (fid->id);
@@ -319,4 +334,3 @@ e_ews_folder_get_child_count (EEwsFolder *folder)
return folder->priv->child_count;
}
-
diff --git a/src/server/e-ews-folder.h b/src/server/e-ews-folder.h
index 6272971..47127b3 100644
--- a/src/server/e-ews-folder.h
+++ b/src/server/e-ews-folder.h
@@ -76,7 +76,10 @@ void e_ews_folder_set_is_writable (EEwsFolder *folder, gboolean writable);
EwsFolderType e_ews_folder_get_folder_type (EEwsFolder *folder);
void e_ews_folder_set_folder_type (EEwsFolder *folder, EwsFolderType folder_type);
-void e_ews_folder_free_fid (EwsFolderId *fid);
+EwsFolderId * e_ews_folder_id_new (const gchar *id,
+ const gchar *change_key,
+ gboolean is_distinguished_id);
+void e_ews_folder_id_free (EwsFolderId *fid);
G_END_DECLS
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index 3ba2653..2266396 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -21,6 +21,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
#include <string.h>
#include <errno.h>
#include <sys/types.h>
@@ -1949,3 +1950,344 @@ e_ews_free_resolve_contact (gpointer rc)
g_hash_table_unref (resc->email_addresses);
g_free (resc);
}
+
+/* free returned pointer with e_ews_permission_free() */
+EEwsPermission *
+e_ews_permission_new (EEwsPermissionUserType user_type,
+ const gchar *display_name,
+ const gchar *primary_smtp,
+ const gchar *sid,
+ guint32 rights)
+{
+ EEwsPermission *perm;
+
+ perm = g_new0 (EEwsPermission, 1);
+ perm->user_type = user_type;
+ perm->display_name = g_strdup (display_name);
+ perm->primary_smtp = g_strdup (primary_smtp);
+ perm->sid = g_strdup (sid);
+ perm->rights = rights;
+
+ return perm;
+}
+
+void
+e_ews_permission_free (EEwsPermission *perm)
+{
+ if (!perm)
+ return;
+
+ g_free (perm->display_name);
+ g_free (perm->primary_smtp);
+ g_free (perm->sid);
+ g_free (perm);
+}
+
+static void
+ews_level_rights_converter (const gchar **plevel_name,
+ guint32 *prights,
+ gboolean level_to_rights)
+{
+ struct _known {
+ const gchar *level_name;
+ guint32 rights;
+ } known[] = {
+ { "None", 0 },
+ { "Owner", E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_OWNER |
+ E_EWS_PERMISSION_BIT_FOLDER_CONTACT |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "PublishingEditor",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "Editor",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_EDIT_ANY |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "PublishingAuthor",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "Author",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_EDIT_OWNED |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "NoneditingAuthor",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_DELETE_OWNED |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "Reviewer",
+ E_EWS_PERMISSION_BIT_READ_ANY |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "Contributor",
+ E_EWS_PERMISSION_BIT_CREATE |
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE },
+ { "FreeBusyTimeOnly",
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE },
+ { "FreeBusyTimeAndSubjectAndLocation",
+ E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED }
+
+ };
+ gint ii;
+ guint32 rights;
+
+ g_return_if_fail (plevel_name != NULL);
+ g_return_if_fail (prights != NULL);
+
+ rights = (*prights) & ~(E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE | E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED);
+
+ for (ii = 0; ii < G_N_ELEMENTS (known); ii++) {
+ if (level_to_rights) {
+ if (g_strcmp0 (*plevel_name, known[ii].level_name) == 0) {
+ *prights = known[ii].rights;
+ return;
+ }
+ } else {
+ if (*prights == known[ii].rights || (rights && rights == known[ii].rights)) {
+ *plevel_name = known[ii].level_name;
+ return;
+ }
+ }
+ }
+
+ /* here lefts only "Custom" */
+ if (level_to_rights)
+ *prights = 0;
+ else
+ *plevel_name = "Custom";
+}
+
+/* converts user rights to level name suitable for PermissionLevel/CalendarPermissionLevel */
+const gchar *
+e_ews_permission_rights_to_level_name (guint32 rights)
+{
+ const gchar *level_name = NULL;
+
+ ews_level_rights_converter (&level_name, &rights, FALSE);
+
+ return level_name;
+}
+
+/* converts PermissionLevel/CalendarPermissionLevel name to user rights */
+guint32
+e_ews_permission_level_name_to_rights (const gchar *level_name)
+{
+ guint32 rights = 0;
+
+ ews_level_rights_converter (&level_name, &rights, TRUE);
+
+ return rights;
+}
+
+static EEwsPermission *
+ews_permissions_parse (ESoapParameter *param)
+{
+ EEwsPermission *res;
+ ESoapParameter *node, *subnode;
+ EEwsPermissionUserType user_type;
+ gchar *value, *display_name = NULL, *primary_smtp = NULL, *sid = NULL;
+ guint32 rights = 0;
+
+ g_return_val_if_fail (param != NULL, NULL);
+
+ node = e_soap_parameter_get_first_child_by_name (param, "UserId");
+ if (!node)
+ return NULL;
+
+ subnode = e_soap_parameter_get_first_child_by_name (node, "DistinguishedUser");
+ if (subnode) {
+ value = e_soap_parameter_get_string_value (subnode);
+ if (g_strcmp0 (value, "Anonymous") == 0) {
+ user_type = E_EWS_PERMISSION_USER_TYPE_ANONYMOUS;
+ } else if (g_strcmp0 (value, "Default") == 0) {
+ user_type = E_EWS_PERMISSION_USER_TYPE_DEFAULT;
+ } else {
+ g_free (value);
+ return NULL;
+ }
+
+ g_free (value);
+ } else {
+ user_type = E_EWS_PERMISSION_USER_TYPE_REGULAR;
+ }
+
+ subnode = e_soap_parameter_get_first_child_by_name (node, "SID");
+ if (subnode)
+ sid = e_soap_parameter_get_string_value (subnode);
+
+ subnode = e_soap_parameter_get_first_child_by_name (node, "PrimarySmtpAddress");
+ if (subnode)
+ primary_smtp = e_soap_parameter_get_string_value (subnode);
+
+ subnode = e_soap_parameter_get_first_child_by_name (node, "DisplayName");
+ if (subnode)
+ display_name = e_soap_parameter_get_string_value (subnode);
+
+ node = e_soap_parameter_get_first_child_by_name (param, "PermissionLevel");
+ if (!node)
+ node = e_soap_parameter_get_first_child_by_name (param, "CalendarPermissionLevel");
+
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ rights = e_ews_permission_level_name_to_rights (value);
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "CanCreateItems");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "true") == 0)
+ rights |= E_EWS_PERMISSION_BIT_CREATE;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "CanCreateSubFolders");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "true") == 0)
+ rights |= E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "IsFolderOwner");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "true") == 0)
+ rights |= E_EWS_PERMISSION_BIT_FOLDER_OWNER;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "IsFolderVisible");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "true") == 0)
+ rights |= E_EWS_PERMISSION_BIT_FOLDER_VISIBLE;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "IsFolderContact");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "true") == 0)
+ rights |= E_EWS_PERMISSION_BIT_FOLDER_CONTACT;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "EditItems");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "None") == 0)
+ rights |= 0;
+ else if (g_strcmp0 (value, "Owned") == 0)
+ rights |= E_EWS_PERMISSION_BIT_EDIT_OWNED;
+ else if (g_strcmp0 (value, "All") == 0)
+ rights |= E_EWS_PERMISSION_BIT_EDIT_ANY;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "DeleteItems");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "None") == 0)
+ rights |= 0;
+ else if (g_strcmp0 (value, "Owned") == 0)
+ rights |= E_EWS_PERMISSION_BIT_DELETE_OWNED;
+ else if (g_strcmp0 (value, "All") == 0)
+ rights |= E_EWS_PERMISSION_BIT_DELETE_ANY;
+ g_free (value);
+ }
+
+ node = e_soap_parameter_get_first_child_by_name (param, "ReadItems");
+ if (node) {
+ value = e_soap_parameter_get_string_value (node);
+ if (g_strcmp0 (value, "None") == 0)
+ rights |= 0;
+ else if (g_strcmp0 (value, "TimeOnly") == 0)
+ rights |= E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE;
+ else if (g_strcmp0 (value, "TimeAndSubjectAndLocation") == 0)
+ rights |= E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED;
+ else if (g_strcmp0 (value, "FullDetails") == 0)
+ rights |= E_EWS_PERMISSION_BIT_READ_ANY;
+ g_free (value);
+ }
+
+ res = e_ews_permission_new (user_type, display_name, primary_smtp, sid, rights);
+
+ g_free (display_name);
+ g_free (primary_smtp);
+ g_free (sid);
+
+ return res;
+}
+
+/* Returns GSList of EEwsPermission * objects, as read from @param.
+ Returned GSList should be freed with e_ews_permissions_free()
+ when done with it. Returns NULL when no permissions recognized
+ from @param.
+*/
+GSList *
+e_ews_permissions_from_soap_param (ESoapParameter *param)
+{
+ GSList *perms = NULL;
+ ESoapParameter *node;
+ const gchar *name;
+
+ g_return_val_if_fail (param != NULL, NULL);
+
+ name = e_soap_parameter_get_name (param);
+ if (g_ascii_strcasecmp (name, "Permissions") == 0 ||
+ g_ascii_strcasecmp (name, "CalendarPermissions") == 0) {
+ node = param;
+ } else {
+ node = e_soap_parameter_get_first_child_by_name (param, "Permissions");
+ if (!node)
+ node = e_soap_parameter_get_first_child_by_name (param, "CalendarPermissions");
+ if (!node)
+ return NULL;
+ }
+
+ for (node = e_soap_parameter_get_first_child (node);
+ node;
+ node = e_soap_parameter_get_next_child (node)) {
+ name = e_soap_parameter_get_name (node);
+ if (g_ascii_strcasecmp (name, "Permission") == 0 ||
+ g_ascii_strcasecmp (name, "CalendarPermission") == 0) {
+ EEwsPermission *perm;
+
+ perm = ews_permissions_parse (node);
+ if (perm) {
+ perms = g_slist_prepend (perms, perm);
+ }
+ }
+ }
+
+ return perms ? g_slist_reverse (perms) : NULL;
+}
+
+void
+e_ews_permissions_free (GSList *permissions)
+{
+ g_slist_free_full (permissions, (GDestroyNotify) e_ews_permission_free);
+}
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index 47db6de..cd2bfab 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -112,6 +112,36 @@ typedef struct {
gchar *postal_code;
} EwsAddress;
+typedef enum {
+ E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED = 0x00001000,
+ E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE = 0x00000800,
+ E_EWS_PERMISSION_BIT_FOLDER_VISIBLE = 0x00000400,
+ E_EWS_PERMISSION_BIT_FOLDER_CONTACT = 0x00000200,
+ E_EWS_PERMISSION_BIT_FOLDER_OWNER = 0x00000100,
+ E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER = 0x00000080,
+ E_EWS_PERMISSION_BIT_DELETE_ANY = 0x00000040,
+ E_EWS_PERMISSION_BIT_EDIT_ANY = 0x00000020,
+ E_EWS_PERMISSION_BIT_DELETE_OWNED = 0x00000010,
+ E_EWS_PERMISSION_BIT_EDIT_OWNED = 0x00000008,
+ E_EWS_PERMISSION_BIT_CREATE = 0x00000002,
+ E_EWS_PERMISSION_BIT_READ_ANY = 0x00000001
+} EEwsPermissionBits;
+
+typedef enum {
+ E_EWS_PERMISSION_USER_TYPE_NONE = 0,
+ E_EWS_PERMISSION_USER_TYPE_ANONYMOUS = 1 << 1, /* anonymous user */
+ E_EWS_PERMISSION_USER_TYPE_DEFAULT = 1 << 2, /* default rights for any users */
+ E_EWS_PERMISSION_USER_TYPE_REGULAR = 1 << 3 /* regular user, the EEwsPermission::user_smtp member is valid */
+} EEwsPermissionUserType;
+
+typedef struct {
+ EEwsPermissionUserType user_type; /* whether is distinguished name, if 'true' */
+ gchar *display_name; /* display name for a user */
+ gchar *primary_smtp; /* valid only for E_EWS_PERMISSION_USER_TYPE_REGULAR */
+ gchar *sid; /* security identifier (SID), if any */
+ guint32 rights; /* EEwsPermissionBits for the user */
+} EEwsPermission;
+
GType e_ews_item_get_type (void);
EEwsItem * e_ews_item_new_from_soap_parameter
(ESoapParameter *param);
@@ -230,6 +260,23 @@ gboolean e_ews_item_task_has_complete_date
gboolean * has_date);
const gchar * e_ews_item_get_tzid (EEwsItem *item);
+/* Folder Permissions */
+EEwsPermission *e_ews_permission_new (EEwsPermissionUserType user_type,
+ const gchar *display_name,
+ const gchar *primary_smtp,
+ const gchar *sid,
+ guint32 rights);
+void e_ews_permission_free (EEwsPermission *perm);
+
+const gchar * e_ews_permission_rights_to_level_name
+ (guint32 rights);
+guint32 e_ews_permission_level_name_to_rights
+ (const gchar *level_name);
+
+GSList * e_ews_permissions_from_soap_param
+ (ESoapParameter *param);
+void e_ews_permissions_free (GSList *permissions);
+
G_END_DECLS
#endif
diff --git a/src/server/e-source-ews-folder.c b/src/server/e-source-ews-folder.c
index 7a632dc..dcdc6b5 100644
--- a/src/server/e-source-ews-folder.c
+++ b/src/server/e-source-ews-folder.c
@@ -186,7 +186,7 @@ e_source_ews_folder_dup_change_key (ESourceEwsFolder *extension)
g_mutex_lock (extension->priv->property_lock);
- protected = e_source_ews_folder_get_id (extension);
+ protected = e_source_ews_folder_get_change_key (extension);
duplicate = g_strdup (protected);
g_mutex_unlock (extension->priv->property_lock);
@@ -262,3 +262,19 @@ e_source_ews_folder_set_id (ESourceEwsFolder *extension,
g_object_notify (G_OBJECT (extension), "id");
}
+/* free returned pointer with e_ews_folder_id_free() */
+EwsFolderId *
+e_source_ews_folder_dup_folder_id (ESourceEwsFolder *extension)
+{
+ EwsFolderId *folder_id;
+
+ g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), NULL);
+
+ g_mutex_lock (extension->priv->property_lock);
+
+ folder_id = e_ews_folder_id_new (extension->priv->id, extension->priv->change_key, FALSE);
+
+ g_mutex_unlock (extension->priv->property_lock);
+
+ return folder_id;
+}
diff --git a/src/server/e-source-ews-folder.h b/src/server/e-source-ews-folder.h
index 65e8035..f6202bd 100644
--- a/src/server/e-source-ews-folder.h
+++ b/src/server/e-source-ews-folder.h
@@ -20,6 +20,7 @@
#define E_SOURCE_EWS_FOLDER_H
#include <libedataserver/libedataserver.h>
+#include "server/e-ews-folder.h"
/* Standard GObject macros */
#define E_TYPE_SOURCE_EWS_FOLDER \
@@ -72,6 +73,9 @@ gchar * e_source_ews_folder_dup_id (ESourceEwsFolder *extension);
void e_source_ews_folder_set_id (ESourceEwsFolder *extension,
const gchar *id);
+EwsFolderId * e_source_ews_folder_dup_folder_id
+ (ESourceEwsFolder *extension);
+
G_END_DECLS
#endif /* E_SOURCE_EWS_FOLDER_H */
diff --git a/src/server/tests/test-createfolder.c b/src/server/tests/test-createfolder.c
index 6742f95..9eb46b7 100644
--- a/src/server/tests/test-createfolder.c
+++ b/src/server/tests/test-createfolder.c
@@ -63,7 +63,7 @@ create_folder_cb (GObject *object,
folder_id->id = g_strdup (fid->id);
folder_id->change_key = g_strdup (fid->change_key);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
quit:
g_main_loop_quit (main_loop);
diff --git a/src/server/tests/test-libews.c b/src/server/tests/test-libews.c
index 5fdced4..4675d58 100644
--- a/src/server/tests/test-libews.c
+++ b/src/server/tests/test-libews.c
@@ -23,7 +23,7 @@ static void
finalize_test_data ()
{
if (folder_id) {
- e_ews_folder_free_fid (folder_id);
+ e_ews_folder_id_free (folder_id);
folder_id = NULL;
}
}
diff --git a/src/utils/ews-test-finditem-query.c b/src/utils/ews-test-finditem-query.c
index 6d0a2ee..b6e6609 100644
--- a/src/utils/ews-test-finditem-query.c
+++ b/src/utils/ews-test-finditem-query.c
@@ -129,7 +129,7 @@ op_test_finditem_run (void)
"IdOnly", NULL, NULL, CONTACTS_QUERY,
folder_type, (EwsConvertQueryCallback) (e_ews_query_to_restriction),
cancellable, find_folder_item_callback, (gpointer) folder_name);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
/*Check for calendar folder*/
folder_name = "calendar";
@@ -143,7 +143,7 @@ op_test_finditem_run (void)
"IdOnly", NULL, NULL, CALENDAR_QUERY,
folder_type, (EwsConvertQueryCallback) (e_ews_query_to_restriction),
cancellable, find_folder_item_callback, (gpointer) folder_name);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
/*Check for mail folder*/
folder_name = "inbox";
@@ -157,7 +157,7 @@ op_test_finditem_run (void)
"IdOnly", NULL, NULL, MAIL_QUERY,
folder_type, (EwsConvertQueryCallback) (e_ews_query_to_restriction),
cancellable, find_folder_item_callback, (gpointer) folder_name);
- e_ews_folder_free_fid (fid);
+ e_ews_folder_id_free (fid);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]