[evolution-ews] Bug #685795 - Option to subscribe to other user's folder with subfolders
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #685795 - Option to subscribe to other user's folder with subfolders
- Date: Fri, 16 Nov 2012 16:17:36 +0000 (UTC)
commit fc96af8bdd9160b01188f642069443c499454d6e
Author: Milan Crha <mcrha redhat com>
Date: Fri Nov 16 17:16:26 2012 +0100
Bug #685795 - Option to subscribe to other user's folder with subfolders
src/camel/camel-ews-store-summary.c | 78 ++++++++
src/camel/camel-ews-store-summary.h | 11 ++
src/camel/camel-ews-store.c | 184 ++++++++++++++++++++
src/configuration/e-ews-subscribe-foreign-folder.c | 21 ++-
src/server/e-ews-connection.c | 180 +++++++++++++++++++-
src/server/e-ews-connection.h | 20 ++
src/server/e-ews-folder.c | 18 ++-
src/server/e-ews-folder.h | 2 +
src/server/e-source-ews-folder.c | 52 ++++++-
src/server/e-source-ews-folder.h | 5 +
10 files changed, 564 insertions(+), 7 deletions(-)
---
diff --git a/src/camel/camel-ews-store-summary.c b/src/camel/camel-ews-store-summary.c
index 978fba8..45549ef 100644
--- a/src/camel/camel-ews-store-summary.c
+++ b/src/camel/camel-ews-store-summary.c
@@ -562,6 +562,21 @@ camel_ews_store_summary_set_foreign (CamelEwsStoreSummary *ews_summary,
}
void
+camel_ews_store_summary_set_foreign_subfolders (CamelEwsStoreSummary *ews_summary,
+ const gchar *folder_id,
+ gboolean foreign_subfolders)
+{
+ S_LOCK (ews_summary);
+
+ g_key_file_set_boolean (
+ ews_summary->priv->key_file,
+ folder_id, "ForeignSubfolders", foreign_subfolders);
+ ews_summary->priv->dirty = TRUE;
+
+ S_UNLOCK (ews_summary);
+}
+
+void
camel_ews_store_summary_store_string_val (CamelEwsStoreSummary *ews_summary,
const gchar *key,
const gchar *value)
@@ -765,6 +780,23 @@ camel_ews_store_summary_get_foreign (CamelEwsStoreSummary *ews_summary,
return ret;
}
+gboolean
+camel_ews_store_summary_get_foreign_subfolders (CamelEwsStoreSummary *ews_summary,
+ const gchar *folder_id,
+ GError **error)
+{
+ gboolean ret;
+
+ S_LOCK (ews_summary);
+
+ ret = g_key_file_get_boolean (
+ ews_summary->priv->key_file, folder_id, "ForeignSubfolders", error);
+
+ S_UNLOCK (ews_summary);
+
+ return ret;
+}
+
gchar *
camel_ews_store_summary_get_string_val (CamelEwsStoreSummary *ews_summary,
const gchar *key,
@@ -822,6 +854,52 @@ camel_ews_store_summary_get_folders (CamelEwsStoreSummary *ews_summary,
return folders;
}
+/* get list of folder IDs, which are foreign folders */
+GSList *
+camel_ews_store_summary_get_foreign_folders (CamelEwsStoreSummary *ews_summary,
+ const gchar *prefix)
+{
+ GSList *folders = NULL;
+ gchar **groups = NULL;
+ gsize length;
+ gint prefixlen = 0;
+ gint i;
+
+ if (prefix)
+ prefixlen = strlen (prefix);
+
+ S_LOCK (ews_summary);
+
+ groups = g_key_file_get_groups (ews_summary->priv->key_file, &length);
+
+ S_UNLOCK (ews_summary);
+
+ for (i = 0; i < length; i++) {
+ if (!g_ascii_strcasecmp (groups[i], STORE_GROUP_NAME))
+ continue;
+
+ if (!camel_ews_store_summary_get_foreign (ews_summary, groups[i], NULL))
+ continue;
+
+ if (prefixlen) {
+ const gchar *fname;
+
+ fname = g_hash_table_lookup (
+ ews_summary->priv->id_fname_hash, groups[i]);
+
+ if (!fname || strncmp (fname, prefix, prefixlen) ||
+ (fname[prefixlen] && fname[prefixlen] != '/'))
+ continue;
+ }
+
+ folders = g_slist_append (folders, g_strdup (groups[i]));
+ }
+
+ g_strfreev (groups);
+
+ return folders;
+}
+
gboolean
camel_ews_store_summary_remove_folder (CamelEwsStoreSummary *ews_summary,
const gchar *folder_id,
diff --git a/src/camel/camel-ews-store-summary.h b/src/camel/camel-ews-store-summary.h
index 47e68eb..a1231dc 100644
--- a/src/camel/camel-ews-store-summary.h
+++ b/src/camel/camel-ews-store-summary.h
@@ -93,6 +93,10 @@ void camel_ews_store_summary_set_foreign
(CamelEwsStoreSummary *ews_summary,
const gchar *folder_id,
gboolean is_foreign);
+void camel_ews_store_summary_set_foreign_subfolders
+ (CamelEwsStoreSummary *ews_summary,
+ const gchar *folder_id,
+ gboolean foreign_subfolders);
gchar * camel_ews_store_summary_get_folder_name
(CamelEwsStoreSummary *ews_summary,
@@ -134,10 +138,17 @@ gboolean camel_ews_store_summary_get_foreign
(CamelEwsStoreSummary *ews_summary,
const gchar *folder_id,
GError **error);
+gboolean camel_ews_store_summary_get_foreign_subfolders
+ (CamelEwsStoreSummary *ews_summary,
+ const gchar *folder_id,
+ GError **error);
GSList * camel_ews_store_summary_get_folders
(CamelEwsStoreSummary *ews_summary,
const gchar *prefix);
+GSList * camel_ews_store_summary_get_foreign_folders
+ (CamelEwsStoreSummary *ews_summary,
+ const gchar *prefix);
void camel_ews_store_summary_store_string_val
(CamelEwsStoreSummary *ews_summary,
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 3301689..e46515f 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -526,6 +526,166 @@ ews_store_forget_all_folders (CamelEwsStore *ews_store)
g_slist_free_full (folders, g_free);
}
+struct EwsUpdateForeignSubfoldersData
+{
+ CamelEwsStore *ews_store;
+ gchar *folder_id;
+};
+
+static void
+ews_update_foreign_subfolders_data_free (gpointer data)
+{
+ struct EwsUpdateForeignSubfoldersData *euf = data;
+
+ if (euf) {
+ g_object_unref (euf->ews_store);
+ g_free (euf->folder_id);
+ g_free (euf);
+ }
+}
+
+static void
+ews_store_update_foreign_subfolders (CamelSession *session,
+ GCancellable *cancellable,
+ gpointer user_data,
+ GError **error)
+{
+ struct EwsUpdateForeignSubfoldersData *euf = user_data;
+ CamelEwsStore *ews_store;
+ EEwsConnection *conn;
+ GSList *tocheck = NULL, *remote_folders = NULL, *local_folders = NULL;
+ const gchar *fid;
+ GError *local_error = NULL;
+
+ g_return_if_fail (euf != NULL);
+
+ ews_store = euf->ews_store;
+ fid = euf->folder_id;
+
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (ews_store)))
+ return;
+
+ conn = camel_ews_store_ref_connection (ews_store);
+ g_return_if_fail (conn != NULL);
+
+ camel_operation_push_message (cancellable, _("Updating foreign folder structure"));
+
+ /* read remote folder structure at the server */
+ while (fid && !g_cancellable_is_cancelled (cancellable) && !local_error) {
+ gboolean includes_last_item = FALSE;
+ EwsFolderId *folder_id = e_ews_folder_id_new (fid, NULL, FALSE);
+
+ while (!includes_last_item && !g_cancellable_is_cancelled (cancellable) && !local_error) {
+ GSList *folders = NULL, *ff;
+
+ if (!e_ews_connection_find_folder_sync (conn, EWS_PRIORITY_MEDIUM, folder_id,
+ &includes_last_item, &folders, cancellable, &local_error))
+ break;
+
+ for (ff = folders; ff != NULL; ff = ff->next) {
+ EEwsFolder *folder = ff->data;
+
+ e_ews_folder_set_parent_id (folder, e_ews_folder_id_new (fid, NULL, FALSE));
+
+ remote_folders = g_slist_prepend (remote_folders, folder);
+
+ if (e_ews_folder_get_child_count (folder) > 0 && e_ews_folder_get_id (folder))
+ tocheck = g_slist_prepend (tocheck, e_ews_folder_get_id (folder)->id);
+ }
+ }
+
+ e_ews_folder_id_free (folder_id);
+
+ if (tocheck) {
+ fid = g_slist_last (tocheck)->data;
+ tocheck = g_slist_remove (tocheck, fid);
+ } else {
+ fid = NULL;
+ }
+ }
+
+ /* get local folder structure */
+ if (!local_error && !g_cancellable_is_cancelled (cancellable)) {
+ gchar *full_name = camel_ews_store_summary_get_folder_full_name (ews_store->summary, euf->folder_id, NULL);
+ if (full_name) {
+ local_folders = camel_ews_store_summary_get_folders (ews_store->summary, full_name);
+ }
+ g_free (full_name);
+ }
+
+ /* merge local and remote folder structures */
+ if (!local_error && !g_cancellable_is_cancelled (cancellable)) {
+ GHashTable *locals = g_hash_table_new (g_str_hash, g_str_equal);
+ GSList *ii;
+
+ remote_folders = g_slist_reverse (remote_folders);
+
+ for (ii = local_folders; ii; ii = ii->next) {
+ g_hash_table_insert (locals, ii->data, ii->data);
+ }
+
+ for (ii = remote_folders; ii; ii = ii->next) {
+ EEwsFolder *folder = ii->data;
+ const EwsFolderId *folder_id = e_ews_folder_get_id (folder);
+ const EwsFolderId *parent_fid = e_ews_folder_get_parent_id (folder);
+
+ if (e_ews_folder_get_folder_type (folder) == E_EWS_FOLDER_TYPE_MAILBOX &&
+ folder_id && folder_id->id) {
+ if (!g_hash_table_remove (locals, folder_id->id)) {
+ CamelFolderInfo *fi;
+
+ /* it's a new folder, add it */
+ camel_ews_store_summary_new_folder (
+ ews_store->summary,
+ folder_id->id, parent_fid ? parent_fid->id : euf->folder_id, folder_id->change_key,
+ e_ews_folder_get_name (folder), E_EWS_FOLDER_TYPE_MAILBOX,
+ CAMEL_FOLDER_SUBSCRIBED, e_ews_folder_get_total_count (folder), TRUE);
+
+ fi = camel_ews_utils_build_folder_info (ews_store, folder_id->id);
+ camel_store_folder_created (CAMEL_STORE (ews_store), fi);
+ camel_subscribable_folder_subscribed (CAMEL_SUBSCRIBABLE (ews_store), fi);
+ camel_folder_info_free (fi);
+ }
+ }
+ }
+
+ /* to not remove the parent */
+ g_hash_table_remove (locals, euf->folder_id);
+
+ /* and now the locals contains only folders which were removed */
+ if (g_hash_table_size (locals) > 0) {
+ CamelSubscribable *subscribable = CAMEL_SUBSCRIBABLE (ews_store);
+ CamelStore *store = CAMEL_STORE (ews_store);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, locals);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ CamelFolderInfo *fi;
+
+ fi = camel_ews_utils_build_folder_info (ews_store, key);
+ camel_subscribable_folder_unsubscribed (subscribable, fi);
+ camel_store_folder_deleted (store, fi);
+ camel_folder_info_free (fi);
+ }
+ }
+
+ g_hash_table_destroy (locals);
+
+ camel_ews_store_summary_save (ews_store->summary, &local_error);
+ }
+
+ if (local_error)
+ g_propagate_error (error, local_error);
+
+ camel_operation_pop_message (cancellable);
+
+ g_slist_free_full (remote_folders, g_object_unref);
+ g_slist_free_full (local_folders, g_free);
+ g_slist_free (tocheck);
+ g_object_unref (conn);
+}
+
static CamelAuthenticationResult
ews_authenticate_sync (CamelService *service,
const gchar *mechanism,
@@ -605,6 +765,9 @@ ews_authenticate_sync (CamelService *service,
}
if (local_error == NULL) {
+ GSList *foreign_fids, *ff;
+ CamelSession *session;
+
g_mutex_lock (&ews_store->priv->connection_lock);
if (ews_store->priv->connection != NULL)
g_object_unref (ews_store->priv->connection);
@@ -615,6 +778,27 @@ ews_authenticate_sync (CamelService *service,
ews_update_folder_hierarchy (
ews_store, new_sync_state, includes_last_folder,
folders_created, folders_deleted, folders_updated);
+
+ /* Also update folder structures of foreign folders,
+ those which are subscribed with subfolders */
+ session = camel_service_get_session (service);
+ foreign_fids = camel_ews_store_summary_get_foreign_folders (ews_store->summary, NULL);
+ for (ff = foreign_fids; ff != NULL; ff = ff->next) {
+ const gchar *fid = ff->data;
+
+ if (camel_ews_store_summary_get_foreign_subfolders (ews_store->summary, fid, NULL)) {
+ struct EwsUpdateForeignSubfoldersData *euf;
+
+ euf = g_new0 (struct EwsUpdateForeignSubfoldersData, 1);
+ euf->ews_store = g_object_ref (ews_store);
+ euf->folder_id = g_strdup (fid);
+
+ camel_session_submit_job (session, ews_store_update_foreign_subfolders,
+ euf, ews_update_foreign_subfolders_data_free);
+ }
+ }
+
+ g_slist_free_full (foreign_fids, g_free);
} else {
g_mutex_lock (&ews_store->priv->connection_lock);
if (ews_store->priv->connection != NULL) {
diff --git a/src/configuration/e-ews-subscribe-foreign-folder.c b/src/configuration/e-ews-subscribe-foreign-folder.c
index 5523270..35b07fc 100644
--- a/src/configuration/e-ews-subscribe-foreign-folder.c
+++ b/src/configuration/e-ews-subscribe-foreign-folder.c
@@ -41,6 +41,7 @@
#define STR_USER_NAME_SELECTOR_ENTRY "e-ews-name-selector-entry"
#define STR_FOLDER_NAME_COMBO "e-ews-folder-name-combo"
+#define STR_SUBFOLDERS_CHECK "e-ews-subfolders-check"
#define STR_EWS_CAMEL_SESSION "e-ews-camel-session"
#define STR_EWS_CAMEL_STORE "e-ews-camel-store"
#define STR_EWS_DIRECT_EMAIL "e-ews-direct-email"
@@ -65,6 +66,7 @@ static gboolean
add_foreign_folder_to_camel (CamelEwsStore *ews_store,
const gchar *foreign_email,
EEwsFolder *folder,
+ gboolean include_subfolders,
const gchar *display_username,
const gchar *display_foldername,
GError **perror)
@@ -142,6 +144,8 @@ add_foreign_folder_to_camel (CamelEwsStore *ews_store,
}
camel_ews_store_ensure_virtual_folders (ews_store);
+ camel_ews_store_summary_set_foreign_subfolders (ews_store->summary, fid->id, include_subfolders);
+ camel_ews_store_summary_save (ews_store->summary, perror);
announce_new_folder (ews_store, EWS_FOREIGN_FOLDER_ROOT_ID);
announce_new_folder (ews_store, foreign_mailbox_id);
@@ -196,7 +200,8 @@ name_entry_changed_cb (GObject *dialog)
}
static void
-folder_name_combo_changed_cb (GObject *dialog)
+folder_name_combo_changed_cb (GObject *dialog,
+ GtkComboBox *combo)
{
enable_ok_button_by_data (dialog);
}
@@ -204,6 +209,7 @@ folder_name_combo_changed_cb (GObject *dialog)
struct EEwsCheckForeignFolderData
{
GtkWidget *dialog;
+ gboolean include_subfolders;
gchar *email;
gchar *direct_email;
gchar *user_displayname;
@@ -422,6 +428,7 @@ check_foreign_folder_idle (GObject *with_object,
!add_foreign_folder_to_camel (ews_store,
cffd->email,
cffd->folder,
+ cffd->include_subfolders,
base_username,
base_foldername,
perror)) ||
@@ -429,6 +436,7 @@ check_foreign_folder_idle (GObject *with_object,
camel_ews_settings_get_hosturl (ews_settings),
camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (ews_settings)),
cffd->folder,
+ cffd->include_subfolders,
TRUE,
0,
cancellable,
@@ -450,6 +458,7 @@ subscribe_foreign_response_cb (GObject *dialog,
struct EEwsCheckForeignFolderData *cffd;
ENameSelectorEntry *entry;
GtkComboBoxText *combo_text;
+ GtkToggleButton *subfolders_check;
EDestinationStore *dest_store;
CamelStore *cstore;
gchar *description;
@@ -465,6 +474,7 @@ subscribe_foreign_response_cb (GObject *dialog,
entry = g_object_get_data (dialog, STR_USER_NAME_SELECTOR_ENTRY);
combo_text = g_object_get_data (dialog, STR_FOLDER_NAME_COMBO);
+ subfolders_check = g_object_get_data (dialog, STR_SUBFOLDERS_CHECK);
cstore = g_object_get_data (dialog, STR_EWS_CAMEL_STORE);
g_return_if_fail (entry != NULL);
@@ -518,6 +528,7 @@ subscribe_foreign_response_cb (GObject *dialog,
cffd->direct_email = g_strdup (g_object_get_data (G_OBJECT (entry), STR_EWS_DIRECT_EMAIL));
cffd->orig_foldername = orig_foldername;
cffd->use_foldername = use_foldername;
+ cffd->include_subfolders = gtk_toggle_button_get_active (subfolders_check);
cffd->folder = NULL;
description = g_strdup_printf (
@@ -587,7 +598,7 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
ENameSelectorDialog *name_selector_dialog;
GObject *dialog;
GtkWidget *content;
- GtkWidget *label, *widget, *entry;
+ GtkWidget *label, *widget, *entry, *check;
GtkGrid *grid;
GtkComboBoxText *combo_text;
gint row;
@@ -714,9 +725,15 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
gtk_grid_attach (grid, label, 0, row, 1, 1);
gtk_grid_attach (grid, widget, 1, row, 2, 1);
+ row++;
+
+ check = gtk_check_button_new_with_mnemonic (_("Include _subfolders"));
+ gtk_grid_attach (grid, check, 1, row, 2, 1);
+
/* remember widgets for later use */
g_object_set_data (dialog, STR_USER_NAME_SELECTOR_ENTRY, entry);
g_object_set_data (dialog, STR_FOLDER_NAME_COMBO, widget);
+ g_object_set_data (dialog, STR_SUBFOLDERS_CHECK, check);
g_object_set_data_full (dialog, STR_EWS_CAMEL_SESSION, g_object_ref (session), g_object_unref);
g_object_set_data_full (dialog, STR_EWS_CAMEL_STORE, g_object_ref (store), g_object_unref);
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index b9c74ff..fee4ea0 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -808,8 +808,8 @@ get_folder_response_cb (ESoapResponse *response,
}
static void
-ews_handle_root_folder_param (ESoapParameter *subparam,
- EwsAsyncData *async_data)
+ews_handle_root_folder_param_items (ESoapParameter *subparam,
+ EwsAsyncData *async_data)
{
ESoapParameter *node, *subparam1;
gchar *last, *total;
@@ -872,7 +872,7 @@ find_folder_items_response_cb (ESoapResponse *response,
}
if (CHECK_ELEMENT (name, "FindItemResponseMessage"))
- ews_handle_root_folder_param (subparam, async_data);
+ ews_handle_root_folder_param_items (subparam, async_data);
subparam = e_soap_parameter_get_next_child (subparam);
}
@@ -7588,3 +7588,177 @@ e_ews_connection_get_folder_info_sync (EEwsConnection *cnc,
return success;
}
+
+static void
+ews_handle_root_folder_param_folders (ESoapParameter *subparam,
+ EwsAsyncData *async_data)
+{
+ ESoapParameter *node, *subparam1;
+ gchar *last, *total;
+ gint total_items;
+ EEwsFolder *folder;
+ gboolean includes_last_item = FALSE;
+
+ node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
+ total = e_soap_parameter_get_property (node, "TotalItemsInView");
+ total_items = atoi (total);
+ g_free (total);
+ last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
+ if (!strcmp (last, "true"))
+ includes_last_item = TRUE;
+ g_free (last);
+
+ node = e_soap_parameter_get_first_child_by_name (node, "Folders");
+ for (subparam1 = e_soap_parameter_get_first_child (node);
+ subparam1; subparam1 = e_soap_parameter_get_next_child (subparam1)) {
+ folder = e_ews_folder_new_from_soap_parameter (subparam1);
+ if (!folder) continue;
+ async_data->items = g_slist_append (async_data->items, folder);
+ }
+ async_data->total_items = total_items;
+ async_data->includes_last_item = includes_last_item;
+}
+
+static void
+find_folder_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, "FindFolderResponseMessage"))
+ ews_handle_root_folder_param_folders (subparam, async_data);
+
+ subparam = e_soap_parameter_get_next_child (subparam);
+ }
+}
+
+void
+e_ews_connection_find_folder (EEwsConnection *cnc,
+ gint pri,
+ const EwsFolderId *fid,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ESoapMessage *msg;
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ g_return_if_fail (cnc != NULL);
+
+ msg = e_ews_message_new_with_header (cnc->priv->uri, cnc->priv->impersonate_user, "FindFolder", "Traversal", "Shallow", EWS_EXCHANGE_2007_SP1);
+ e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
+ e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "Default");
+ e_soap_message_end_element (msg);
+
+ e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL);
+
+ if (fid->is_distinguished_id)
+ e_ews_message_write_string_parameter_with_attribute (msg, "DistinguishedFolderId", NULL, NULL, "Id", fid->id);
+ else
+ e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", fid->id);
+
+ e_soap_message_end_element (msg);
+
+ /* Complete the footer and print the request */
+ e_ews_message_write_footer (msg);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (cnc), callback, user_data,
+ e_ews_connection_find_folder);
+
+ 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, find_folder_response_cb,
+ pri, cancellable, simple);
+
+ g_object_unref (simple);
+}
+
+gboolean
+e_ews_connection_find_folder_finish (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gboolean *includes_last_item,
+ GSList **folders,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ 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_find_folder),
+ 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;
+
+ *includes_last_item = async_data->includes_last_item;
+ *folders = async_data->items;
+
+ return TRUE;
+}
+
+gboolean
+e_ews_connection_find_folder_sync (EEwsConnection *cnc,
+ gint pri,
+ const EwsFolderId *fid,
+ gboolean *includes_last_item,
+ GSList **folders,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ gboolean success;
+
+ g_return_val_if_fail (cnc != NULL, FALSE);
+
+ closure = e_async_closure_new ();
+
+ e_ews_connection_find_folder (cnc, pri, fid, cancellable, e_async_closure_callback, closure);
+
+ result = e_async_closure_wait (closure);
+
+ success = e_ews_connection_find_folder_finish (
+ cnc, result, includes_last_item, folders, 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 93b571f..e3732b9 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -967,6 +967,26 @@ gboolean e_ews_connection_get_folder_info_sync
EEwsFolder **folder,
GCancellable *cancellable,
GError **error);
+void e_ews_connection_find_folder (EEwsConnection *cnc,
+ gint pri,
+ const EwsFolderId *fid,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_ews_connection_find_folder_finish
+ (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gboolean *includes_last_item,
+ GSList **folders,
+ GError **error);
+gboolean e_ews_connection_find_folder_sync
+ (EEwsConnection *cnc,
+ gint pri,
+ const EwsFolderId *fid,
+ gboolean *includes_last_item,
+ GSList **folders,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/server/e-ews-folder.c b/src/server/e-ews-folder.c
index 50bf832..6551b80 100644
--- a/src/server/e-ews-folder.c
+++ b/src/server/e-ews-folder.c
@@ -147,7 +147,19 @@ e_ews_folder_set_from_soap_parameter (EEwsFolder *folder,
g_return_val_if_fail (param != NULL, FALSE);
- if ((node = e_soap_parameter_get_first_child_by_name (param, "Folder")))
+ if (g_strcmp0 (e_soap_parameter_get_name (param), "Folder") == 0) {
+ node = param;
+ priv->folder_type = E_EWS_FOLDER_TYPE_MAILBOX;
+ } else if (g_strcmp0 (e_soap_parameter_get_name (param), "CalendarFolder") == 0) {
+ node = param;
+ priv->folder_type = E_EWS_FOLDER_TYPE_CALENDAR;
+ } else if (g_strcmp0 (e_soap_parameter_get_name (param), "ContactsFolder") == 0) {
+ node = param;
+ priv->folder_type = E_EWS_FOLDER_TYPE_CONTACTS;
+ } else if (g_strcmp0 (e_soap_parameter_get_name (param), "TasksFolder") == 0) {
+ node = param;
+ priv->folder_type = E_EWS_FOLDER_TYPE_TASKS;
+ } else if ((node = e_soap_parameter_get_first_child_by_name (param, "Folder")))
priv->folder_type = E_EWS_FOLDER_TYPE_MAILBOX;
else if ((node = e_soap_parameter_get_first_child_by_name (param, "CalendarFolder")))
priv->folder_type = E_EWS_FOLDER_TYPE_CALENDAR;
@@ -467,6 +479,7 @@ e_ews_folder_utils_populate_esource (ESource *source,
const gchar *master_hosturl,
const gchar *master_username,
EEwsFolder *folder,
+ gboolean include_subfolders,
gboolean offline_sync,
gint color_seed,
GCancellable *cancellable,
@@ -518,6 +531,7 @@ e_ews_folder_utils_populate_esource (ESource *source,
e_source_ews_folder_set_id (folder_ext, folder_id->id);
e_source_ews_folder_set_change_key (folder_ext, NULL);
e_source_ews_folder_set_foreign (folder_ext, e_ews_folder_get_foreign (folder));
+ e_source_ews_folder_set_foreign_subfolders (folder_ext, include_subfolders);
offline_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
e_source_offline_set_stay_synchronized (offline_ext, offline_sync);
@@ -553,6 +567,7 @@ e_ews_folder_utils_add_as_esource (ESourceRegistry *pregistry,
const gchar *master_hosturl,
const gchar *master_username,
EEwsFolder *folder,
+ gboolean include_subfolders,
gboolean offline_sync,
gint color_seed,
GCancellable *cancellable,
@@ -589,6 +604,7 @@ e_ews_folder_utils_add_as_esource (ESourceRegistry *pregistry,
master_hosturl,
master_username,
folder,
+ include_subfolders,
offline_sync,
color_seed,
cancellable,
diff --git a/src/server/e-ews-folder.h b/src/server/e-ews-folder.h
index 2cec0c4..53d6fca 100644
--- a/src/server/e-ews-folder.h
+++ b/src/server/e-ews-folder.h
@@ -87,6 +87,7 @@ gboolean e_ews_folder_utils_populate_esource (ESource *source,
const gchar *master_hosturl,
const gchar *master_username,
EEwsFolder *folder,
+ gboolean include_subfolders,
gboolean offline_sync,
gint color_seed,
GCancellable *cancellable,
@@ -95,6 +96,7 @@ gboolean e_ews_folder_utils_add_as_esource (ESourceRegistry *pregistry,
const gchar *master_hosturl,
const gchar *master_username,
EEwsFolder *folder,
+ gboolean include_subfolders,
gboolean offline_sync,
gint color_seed,
GCancellable *cancellable,
diff --git a/src/server/e-source-ews-folder.c b/src/server/e-source-ews-folder.c
index ba9cd4e..4eb6961 100644
--- a/src/server/e-source-ews-folder.c
+++ b/src/server/e-source-ews-folder.c
@@ -31,13 +31,15 @@ struct _ESourceEwsFolderPrivate {
gchar *change_key;
gchar *id;
gboolean foreign;
+ gboolean foreign_subfolders;
};
enum {
PROP_0,
PROP_CHANGE_KEY,
PROP_ID,
- PROP_FOREIGN
+ PROP_FOREIGN,
+ PROP_FOREIGN_SUBFOLDERS
};
G_DEFINE_DYNAMIC_TYPE (
@@ -69,6 +71,12 @@ source_ews_folder_set_property (GObject *object,
E_SOURCE_EWS_FOLDER (object),
g_value_get_boolean (value));
return;
+
+ case PROP_FOREIGN_SUBFOLDERS:
+ e_source_ews_folder_set_foreign_subfolders (
+ E_SOURCE_EWS_FOLDER (object),
+ g_value_get_boolean (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -101,6 +109,13 @@ source_ews_folder_get_property (GObject *object,
e_source_ews_folder_get_foreign (
E_SOURCE_EWS_FOLDER (object)));
return;
+
+ case PROP_FOREIGN_SUBFOLDERS:
+ g_value_set_boolean (
+ value,
+ e_source_ews_folder_get_foreign_subfolders (
+ E_SOURCE_EWS_FOLDER (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -177,6 +192,19 @@ e_source_ews_folder_class_init (ESourceEwsFolderClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS |
E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FOREIGN_SUBFOLDERS,
+ g_param_spec_boolean (
+ "foreign-subfolders",
+ "ForeignSubfolders",
+ "Whether to search for subfolders of (this) foreign folder",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
@@ -333,3 +361,25 @@ e_source_ews_folder_set_foreign (ESourceEwsFolder *extension,
g_object_notify (G_OBJECT (extension), "foreign");
}
+
+gboolean
+e_source_ews_folder_get_foreign_subfolders (ESourceEwsFolder *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), FALSE);
+
+ return extension->priv->foreign_subfolders;
+}
+
+void
+e_source_ews_folder_set_foreign_subfolders (ESourceEwsFolder *extension,
+ gboolean foreign_subfolders)
+{
+ g_return_if_fail (E_IS_SOURCE_EWS_FOLDER (extension));
+
+ if ((extension->priv->foreign_subfolders ? 1 : 0) == (foreign_subfolders ? 1 : 0))
+ return;
+
+ extension->priv->foreign_subfolders = foreign_subfolders;
+
+ g_object_notify (G_OBJECT (extension), "foreign-subfolders");
+}
diff --git a/src/server/e-source-ews-folder.h b/src/server/e-source-ews-folder.h
index e15b7a9..ad0f284 100644
--- a/src/server/e-source-ews-folder.h
+++ b/src/server/e-source-ews-folder.h
@@ -79,6 +79,11 @@ EwsFolderId * e_source_ews_folder_dup_folder_id
gboolean e_source_ews_folder_get_foreign (ESourceEwsFolder *extension);
void e_source_ews_folder_set_foreign (ESourceEwsFolder *extension,
gboolean is_foreign);
+gboolean e_source_ews_folder_get_foreign_subfolders
+ (ESourceEwsFolder *extension);
+void e_source_ews_folder_set_foreign_subfolders
+ (ESourceEwsFolder *extension,
+ gboolean foreign_subfolders);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]