[evolution-mapi] Partially implement add/remove of ESource-s
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Partially implement add/remove of ESource-s
- Date: Fri, 17 Aug 2012 08:58:33 +0000 (UTC)
commit f367bd1769544dba7b49be56c0973a006a94aea7
Author: Milan Crha <mcrha redhat com>
Date: Fri Aug 17 10:57:28 2012 +0200
Partially implement add/remove of ESource-s
src/collection/e-mapi-backend.c | 125 +++++++++++++++++++++++++++++++
src/configuration/e-mapi-config-utils.c | 42 ++++++++---
2 files changed, 155 insertions(+), 12 deletions(-)
---
diff --git a/src/collection/e-mapi-backend.c b/src/collection/e-mapi-backend.c
index f207df3..3990ab1 100644
--- a/src/collection/e-mapi-backend.c
+++ b/src/collection/e-mapi-backend.c
@@ -78,6 +78,35 @@ mapi_backend_queue_auth_session (EMapiBackend *backend)
NULL, NULL, NULL);
}
+static void
+add_remote_sources (EMapiBackend *backend)
+{
+ GList *old_sources, *iter;
+ ESourceRegistryServer *registry;
+
+ registry = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
+ old_sources = e_collection_backend_claim_all_resources (E_COLLECTION_BACKEND (backend));
+ for (iter = old_sources; iter; iter = iter->next) {
+ ESource *source = iter->data;
+ ESourceMapiFolder *extension;
+ const gchar *foreign_username;
+
+ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER))
+ continue;
+
+ /* foreign folders are just added */
+ extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+ foreign_username = e_source_mapi_folder_get_foreign_username (extension);
+ if (e_source_mapi_folder_is_public (extension) || (foreign_username && *foreign_username)) {
+ e_server_side_source_set_writable (E_SERVER_SIDE_SOURCE (source), TRUE);
+ e_server_side_source_set_remote_deletable (E_SERVER_SIDE_SOURCE (source), TRUE);
+ e_source_registry_server_add_source (registry, source);
+ }
+ }
+ g_list_free_full (old_sources, g_object_unref);
+ g_object_unref (registry);
+}
+
struct SyndFoldersData
{
EMapiBackend *backend;
@@ -177,6 +206,8 @@ mapi_backend_sync_folders_idle_cb (gpointer user_data)
NULL,
NULL)) {
color_seed++;
+ e_server_side_source_set_writable (E_SERVER_SIDE_SOURCE (source), TRUE);
+ e_server_side_source_set_remote_deletable (E_SERVER_SIDE_SOURCE (source), TRUE);
e_source_registry_server_add_source (server, source);
}
@@ -257,6 +288,8 @@ mapi_backend_sync_folders_idle_cb (gpointer user_data)
g_object_unref (source);
}
+ add_remote_sources (backend);
+
g_list_free_full (configured, g_object_unref);
g_object_unref (server);
@@ -280,6 +313,23 @@ mapi_backend_source_changed_cb (ESource *source,
}
static void
+mapi_backend_constructed (GObject *object)
+{
+ ESource *source;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mapi_backend_parent_class)->constructed (object);
+
+ source = e_backend_get_source (E_BACKEND (object));
+
+ /* XXX Wondering if we ought to delay this until after folders
+ * are initially populated, just to remove the possibility
+ * of weird races with clients trying to create folders. */
+ e_server_side_source_set_remote_creatable (
+ E_SERVER_SIDE_SOURCE (source), TRUE);
+}
+
+static void
mapi_backend_dispose (GObject *object)
{
EMapiBackendPrivate *priv;
@@ -449,6 +499,78 @@ mapi_backend_child_removed (ECollectionBackend *backend,
child_removed (backend, child_source);
}
+static gboolean
+mapi_backend_create_resource_sync (ECollectionBackend *backend,
+ ESource *source,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESourceRegistryServer *server;
+ ESource *parent_source;
+ const gchar *cache_dir;
+ const gchar *parent_uid;
+
+ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Data source '%s' does not represent a MAPI folder"),
+ e_source_get_display_name (source));
+ return FALSE;
+ }
+
+ /* UI part takes care of the remote folder creation, if needed,
+ thus just accept the source here */
+
+ /* Configure the source as a collection member. */
+ parent_source = e_backend_get_source (E_BACKEND (backend));
+ parent_uid = e_source_get_uid (parent_source);
+ e_source_set_parent (source, parent_uid);
+
+ /* Changes should be written back to the cache directory. */
+ cache_dir = e_collection_backend_get_cache_dir (backend);
+ e_server_side_source_set_write_directory (
+ E_SERVER_SIDE_SOURCE (source), cache_dir);
+
+ /* Set permissions for clients. */
+ e_server_side_source_set_writable (
+ E_SERVER_SIDE_SOURCE (source), TRUE);
+ e_server_side_source_set_remote_deletable (
+ E_SERVER_SIDE_SOURCE (source), TRUE);
+
+ server = e_collection_backend_ref_server (backend);
+ e_source_registry_server_add_source (server, source);
+ g_object_unref (server);
+
+ return TRUE;
+}
+
+static gboolean
+mapi_backend_delete_resource_sync (ECollectionBackend *backend,
+ ESource *source,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESourceRegistryServer *server;
+
+ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER)) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Data source '%s' does not represent a MAPI folder"),
+ e_source_get_display_name (source));
+ return FALSE;
+ }
+
+ /* respective backends are taking care of cache removal
+ same as remote folder removal, if needed */
+ server = e_collection_backend_ref_server (backend);
+ e_source_registry_server_remove_source (server, source);
+ g_object_unref (server);
+
+ return TRUE;
+}
+
static ESourceAuthenticationResult
mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
const GString *password,
@@ -521,6 +643,7 @@ e_mapi_backend_class_init (EMapiBackendClass *class)
g_type_class_add_private (class, sizeof (EMapiBackendPrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = mapi_backend_constructed;
object_class->dispose = mapi_backend_dispose;
object_class->finalize = mapi_backend_finalize;
@@ -529,6 +652,8 @@ e_mapi_backend_class_init (EMapiBackendClass *class)
backend_class->dup_resource_id = mapi_backend_dup_resource_id;
backend_class->child_added = mapi_backend_child_added;
backend_class->child_removed = mapi_backend_child_removed;
+ backend_class->create_resource_sync = mapi_backend_create_resource_sync;
+ backend_class->delete_resource_sync = mapi_backend_delete_resource_sync;
/* This generates an ESourceCamel subtype for CamelMapiSettings. */
e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
diff --git a/src/configuration/e-mapi-config-utils.c b/src/configuration/e-mapi-config-utils.c
index 046090e..565825b 100644
--- a/src/configuration/e-mapi-config-utils.c
+++ b/src/configuration/e-mapi-config-utils.c
@@ -1456,6 +1456,7 @@ struct EMapiFolderStructureData
ESource *source;
ESource *child_source;
ESourceRegistry *registry;
+ ESourceConfig *config;
};
static void
@@ -1468,7 +1469,10 @@ e_mapi_folder_structure_data_free (gpointer ptr)
e_mapi_folder_free_list (fsd->folders);
g_object_unref (fsd->tree_view);
- g_object_unref (fsd->source);
+ if (fsd->source)
+ g_object_unref (fsd->source);
+ if (fsd->config)
+ g_object_unref (fsd->config);
g_object_unref (fsd->child_source);
g_object_unref (fsd->registry);
g_free (fsd);
@@ -1550,12 +1554,29 @@ e_mapi_download_folder_structure_thread (GObject *source_obj,
g_object_unref (conn);
}
-static gboolean
-e_mapi_invoke_folder_structure_download_idle (gpointer user_data)
+static void
+tree_view_mapped_cb (GObject *tree_view)
{
- struct EMapiFolderStructureData *fsd = user_data;
+ const struct EMapiFolderStructureData *old_fsd = g_object_get_data (tree_view, "mapi-fsd-pointer");
+ struct EMapiFolderStructureData *fsd;
+ GtkTreeViewColumn *column;
+ ESource *parent_source;
- g_return_val_if_fail (fsd != NULL, FALSE);
+ g_return_if_fail (old_fsd != NULL);
+
+ parent_source = e_source_config_get_collection_source (old_fsd->config);
+ g_return_if_fail (parent_source != NULL);
+
+ fsd = g_new0 (struct EMapiFolderStructureData, 1);
+ fsd->folder_type = old_fsd->folder_type;
+ fsd->folders = NULL;
+ fsd->tree_view = g_object_ref (old_fsd->tree_view);
+ fsd->source = g_object_ref (parent_source);
+ fsd->child_source = g_object_ref (old_fsd->child_source);
+ fsd->registry = g_object_ref (old_fsd->registry);
+
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0);
+ gtk_tree_view_column_set_title (column, e_source_get_display_name (parent_source));
e_mapi_config_utils_run_in_thread_with_feedback (e_mapi_config_utils_get_widget_toplevel_window (fsd->tree_view),
G_OBJECT (fsd->source),
@@ -1564,8 +1585,6 @@ e_mapi_invoke_folder_structure_download_idle (gpointer user_data)
e_mapi_download_folder_structure_idle,
fsd,
e_mapi_folder_structure_data_free);
-
- return FALSE;
}
void
@@ -1657,7 +1676,6 @@ e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
GtkTreeViewColumn *column;
GtkTreeStore *tree_store;
GtkWidget *tree_view, *scrolled_window;
- ESource *parent_source;
content_grid = GTK_GRID (gtk_grid_new ());
gtk_grid_set_row_spacing (content_grid, 2);
@@ -1670,9 +1688,8 @@ e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
tree_store = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_POINTER);
- parent_source = e_source_config_get_collection_source (config);
renderer = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes (e_source_get_display_name (parent_source), renderer, "text", NAME_COL, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("", renderer, "text", NAME_COL, NULL);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_set (tree_view, "expander-column", column, "headers-visible", TRUE, NULL);
@@ -1696,11 +1713,12 @@ e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
fsd->folder_type = folder_type;
fsd->folders = NULL;
fsd->tree_view = g_object_ref (tree_view);
- fsd->source = g_object_ref (parent_source);
+ fsd->config = g_object_ref (config);
fsd->child_source = g_object_ref (scratch_source);
fsd->registry = g_object_ref (e_source_config_get_registry (config));
- g_idle_add (e_mapi_invoke_folder_structure_download_idle, fsd);
+ g_signal_connect_after (tree_view, "map", G_CALLBACK (tree_view_mapped_cb), NULL);
+ g_object_set_data_full (G_OBJECT (tree_view), "mapi-fsd-pointer", fsd, e_mapi_folder_structure_data_free);
}
gtk_widget_set_hexpand (GTK_WIDGET (content_grid), TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]