[evolution-mapi] Partially implement add/remove of ESource-s



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]