evolution r36876 - in branches/kill-bonobo: mail shell



Author: mbarnes
Date: Sun Dec 14 04:06:26 2008
New Revision: 36876
URL: http://svn.gnome.org/viewvc/evolution?rev=36876&view=rev

Log:
- Get offline synchronization working in the mailer (I think).


Modified:
   branches/kill-bonobo/mail/e-mail-shell-module.c
   branches/kill-bonobo/mail/mail-component.c
   branches/kill-bonobo/shell/e-shell.c

Modified: branches/kill-bonobo/mail/e-mail-shell-module.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-module.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-module.c	Sun Dec 14 04:06:26 2008
@@ -20,6 +20,8 @@
  */
 
 #include <glib/gi18n.h>
+#include <camel/camel-disco-store.h>
+#include <camel/camel-offline-store.h>
 #include <camel/camel-session.h>
 #include <camel/camel-url.h>
 
@@ -48,6 +50,7 @@
 #include "mail-config.h"
 #include "mail-folder-cache.h"
 #include "mail-mt.h"
+#include "mail-ops.h"
 #include "mail-send-recv.h"
 #include "mail-session.h"
 #include "mail-vfolder.h"
@@ -461,6 +464,17 @@
 		500);
 }
 
+static void
+mail_shell_module_notify_online_mode_cb (EShell *shell,
+                                         GParamSpec *pspec,
+                                         EShellModule *shell_module)
+{
+	gboolean online;
+
+	online = e_shell_get_online_mode (shell);
+	camel_session_set_online (session, online);
+}
+
 static gboolean
 mail_shell_module_handle_uri_cb (EShell *shell,
                                  const gchar *uri,
@@ -470,6 +484,80 @@
 	return FALSE;
 }
 
+/* Helper for mail_shell_module_prepare_for_[off|on]line_cb() */
+static void
+mail_shell_store_line_transition_done_cb (CamelStore *store,
+                                          gpointer user_data)
+{
+	EActivity *activity = user_data;
+
+	g_object_unref (activity);
+}
+
+/* Helper for mail_shell_module_prepare_for_offline_cb() */
+static void
+mail_shell_store_prepare_for_offline_cb (CamelService *service,
+                                         gpointer unused,
+                                         EActivity *activity)
+{
+	if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+		mail_store_set_offline (
+			CAMEL_STORE (service), TRUE,
+			mail_shell_store_line_transition_done_cb,
+			g_object_ref (activity));
+}
+
+static void
+mail_shell_module_prepare_for_offline_cb (EShell *shell,
+                                          EActivity *activity,
+                                          EShellModule *shell_module)
+{
+	GtkWidget *parent;
+	gboolean synchronize = FALSE;
+
+	parent = e_shell_get_focused_window (shell);
+
+	if (e_shell_get_network_available (shell))
+		synchronize = em_utils_prompt_user (
+			GTK_WINDOW (parent),
+			"/apps/evolution/mail/prompts/quick_offline",
+			"mail:ask-quick-offline", NULL);
+
+	if (!synchronize) {
+		mail_cancel_all ();
+		camel_session_set_network_state (session, FALSE);
+	}
+
+	e_mail_shell_module_stores_foreach (
+		shell_module, (GHFunc)
+		mail_shell_store_prepare_for_offline_cb, activity);
+}
+
+/* Helper for mail_shell_module_prepare_for_online_cb() */
+static void
+mail_shell_store_prepare_for_online_cb (CamelService *service,
+                                        gpointer unused,
+                                        EActivity *activity)
+{
+	if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+		mail_store_set_offline (
+			CAMEL_STORE (service), FALSE,
+			mail_shell_store_line_transition_done_cb,
+			g_object_ref (activity));
+}
+
+static void
+mail_shell_module_prepare_for_online_cb (EShell *shell,
+                                         EActivity *activity,
+                                         EShellModule *shell_module)
+{
+	camel_session_set_online (session, TRUE);
+
+	e_mail_shell_module_stores_foreach (
+		shell_module, (GHFunc)
+		mail_shell_store_prepare_for_online_cb, activity);
+}
+
 static void
 mail_shell_module_send_receive_cb (EShell *shell,
                                    GtkWindow *parent,
@@ -559,11 +647,26 @@
 	folder_tree_model = em_folder_tree_model_new (shell_module);
 
 	g_signal_connect (
+		shell, "notify::online-mode",
+		G_CALLBACK (mail_shell_module_notify_online_mode_cb),
+		shell_module);
+
+	g_signal_connect (
 		shell, "handle-uri",
 		G_CALLBACK (mail_shell_module_handle_uri_cb),
 		shell_module);
 
 	g_signal_connect (
+		shell, "prepare-for-offline",
+		G_CALLBACK (mail_shell_module_prepare_for_offline_cb),
+		shell_module);
+
+	g_signal_connect (
+		shell, "prepare-for-online",
+		G_CALLBACK (mail_shell_module_prepare_for_online_cb),
+		shell_module);
+
+	g_signal_connect (
 		shell, "send-receive",
 		G_CALLBACK (mail_shell_module_send_receive_cb),
 		shell_module);

Modified: branches/kill-bonobo/mail/mail-component.c
==============================================================================
--- branches/kill-bonobo/mail/mail-component.c	(original)
+++ branches/kill-bonobo/mail/mail-component.c	Sun Dec 14 04:06:26 2008
@@ -1126,104 +1126,104 @@
 	return !camel_application_is_exiting;
 }
 
-struct _setline_data {
-	GNOME_Evolution_Listener listener;
-	CORBA_boolean status;
-	int pending;
-};
-
-static void
-setline_done(CamelStore *store, void *data)
-{
-	struct _setline_data *sd = data;
-
-	g_return_if_fail (sd->pending > 0);
-
-	sd->pending--;
-	if (sd->pending == 0) {
-		CORBA_Environment ev = { NULL };
-
-		GNOME_Evolution_Listener_complete(sd->listener, &ev);
-		CORBA_exception_free(&ev);
-		CORBA_Object_release(sd->listener, &ev);
-		CORBA_exception_free(&ev);
-		if (!sd->status)
-			camel_session_set_online(session, sd->status);
-		g_free(sd);
-	}
-}
-
-static void
-setline_check(void *key, void *value, void *data)
-{
-	CamelService *service = key;
-	struct _setline_data *sd = data;
-
-	if (CAMEL_IS_DISCO_STORE(service)
-	    || CAMEL_IS_OFFLINE_STORE(service)) {
-		sd->pending++;
-		mail_store_set_offline((CamelStore *)service, !sd->status, setline_done, sd);
-	}
-}
-
-int
-status_check (GNOME_Evolution_ShellState shell_state)
-{
-	int status = 0;
-
-	switch (shell_state)
-	{
-	    case GNOME_Evolution_USER_OFFLINE:
-		    status = OFFLINE;
-		    if (em_utils_prompt_user (NULL, "/apps/evolution/mail/prompts/quick_offline", "mail:ask-quick-offline", NULL))
-		    	break;
-	    case GNOME_Evolution_FORCED_OFFLINE:
-		    /*Network is down so change network state on the camel session*/
-		    status = OFFLINE;
-		    /* Cancel all operations as they wont happen anyway cos Network is down*/
-		    mail_cancel_all ();
-		    camel_session_set_network_state (session, FALSE);
-		    break;
-	    case GNOME_Evolution_USER_ONLINE:
-		    camel_session_set_network_state (session, TRUE);
-		    status = ONLINE;
-	}
+//struct _setline_data {
+//	GNOME_Evolution_Listener listener;
+//	CORBA_boolean status;
+//	int pending;
+//};
+
+//static void
+//setline_done(CamelStore *store, void *data)
+//{
+//	struct _setline_data *sd = data;
+//
+//	g_return_if_fail (sd->pending > 0);
+//
+//	sd->pending--;
+//	if (sd->pending == 0) {
+//		CORBA_Environment ev = { NULL };
+//
+//		GNOME_Evolution_Listener_complete(sd->listener, &ev);
+//		CORBA_exception_free(&ev);
+//		CORBA_Object_release(sd->listener, &ev);
+//		CORBA_exception_free(&ev);
+//		if (!sd->status)
+//			camel_session_set_online(session, sd->status);
+//		g_free(sd);
+//	}
+//}
 
-	return status;
-}
+//static void
+//setline_check(void *key, void *value, void *data)
+//{
+//	CamelService *service = key;
+//	struct _setline_data *sd = data;
+//
+//	if (CAMEL_IS_DISCO_STORE(service)
+//	    || CAMEL_IS_OFFLINE_STORE(service)) {
+//		sd->pending++;
+//		mail_store_set_offline((CamelStore *)service, !sd->status, setline_done, sd);
+//	}
+//}
 
-static void
-impl_setLineStatus(PortableServer_Servant servant, GNOME_Evolution_ShellState shell_state, GNOME_Evolution_Listener listener, CORBA_Environment *ev)
-{
-	struct _setline_data *sd;
-	int status = status_check(shell_state);
+//int
+//status_check (GNOME_Evolution_ShellState shell_state)
+//{
+//	int status = 0;
+//
+//	switch (shell_state)
+//	{
+//	    case GNOME_Evolution_USER_OFFLINE:
+//		    status = OFFLINE;
+//		    if (em_utils_prompt_user (NULL, "/apps/evolution/mail/prompts/quick_offline", "mail:ask-quick-offline", NULL))
+//		    	break;
+//	    case GNOME_Evolution_FORCED_OFFLINE:
+//		    /*Network is down so change network state on the camel session*/
+//		    status = OFFLINE;
+//		    /* Cancel all operations as they wont happen anyway cos Network is down*/
+//		    mail_cancel_all ();
+//		    camel_session_set_network_state (session, FALSE);
+//		    break;
+//	    case GNOME_Evolution_USER_ONLINE:
+//		    camel_session_set_network_state (session, TRUE);
+//		    status = ONLINE;
+//	}
+//
+//	return status;
+//}
 
-	/* This will dis/enable further auto-mail-check action. */
-	/* FIXME: If send/receive active, wait for it to finish? */
-	if (status)
-		camel_session_set_online(session, status);
-
-	sd = g_malloc0(sizeof(*sd));
-	sd->status = status;
-	sd->listener = CORBA_Object_duplicate(listener, ev);
-	if (ev->_major == CORBA_NO_EXCEPTION)
-		mail_component_stores_foreach(mail_component_peek(), setline_check, sd);
-	else
-		CORBA_exception_free(ev);
-
-	if (sd->pending == 0) {
-		if (sd->listener) {
-			CORBA_Object_release(sd->listener, ev);
-			CORBA_exception_free(ev);
-		}
-
-		g_free(sd);
-
-		if (!status)
-			camel_session_set_online(session, status);
-		GNOME_Evolution_Listener_complete(listener, ev);
-	}
-}
+//static void
+//impl_setLineStatus(PortableServer_Servant servant, GNOME_Evolution_ShellState shell_state, GNOME_Evolution_Listener listener, CORBA_Environment *ev)
+//{
+//	struct _setline_data *sd;
+//	int status = status_check(shell_state);
+//
+//	/* This will dis/enable further auto-mail-check action. */
+//	/* FIXME: If send/receive active, wait for it to finish? */
+//	if (status)
+//		camel_session_set_online(session, status);
+//
+//	sd = g_malloc0(sizeof(*sd));
+//	sd->status = status;
+//	sd->listener = CORBA_Object_duplicate(listener, ev);
+//	if (ev->_major == CORBA_NO_EXCEPTION)
+//		mail_component_stores_foreach(mail_component_peek(), setline_check, sd);
+//	else
+//		CORBA_exception_free(ev);
+//
+//	if (sd->pending == 0) {
+//		if (sd->listener) {
+//			CORBA_Object_release(sd->listener, ev);
+//			CORBA_exception_free(ev);
+//		}
+//
+//		g_free(sd);
+//
+//		if (!status)
+//			camel_session_set_online(session, status);
+//		GNOME_Evolution_Listener_complete(listener, ev);
+//	}
+//}
 
 static void
 impl_mail_test(PortableServer_Servant servant, CORBA_Environment *ev)
@@ -1484,27 +1484,27 @@
 //	return g_hash_table_size (component->priv->store_hash);
 //}
 
-/* need to map from internal struct to external api */
-struct _store_foreach_data {
-	GHFunc func;
-	void *data;
-};
-
-static void
-mc_stores_foreach(CamelStore *store, struct _store_info *si, struct _store_foreach_data *data)
-{
-	data->func((void *)store, (void *)si->name, data->data);
-}
-
-void
-mail_component_stores_foreach (MailComponent *component, GHFunc func, void *user_data)
-{
-	struct _store_foreach_data data = { func, user_data };
+///* need to map from internal struct to external api */
+//struct _store_foreach_data {
+//	GHFunc func;
+//	void *data;
+//};
 
-	MAIL_COMPONENT_DEFAULT(component);
+//static void
+//mc_stores_foreach(CamelStore *store, struct _store_info *si, struct _store_foreach_data *data)
+//{
+//	data->func((void *)store, (void *)si->name, data->data);
+//}
 
-	g_hash_table_foreach (component->priv->store_hash, (GHFunc)mc_stores_foreach, &data);
-}
+//void
+//mail_component_stores_foreach (MailComponent *component, GHFunc func, void *user_data)
+//{
+//	struct _store_foreach_data data = { func, user_data };
+//
+//	MAIL_COMPONENT_DEFAULT(component);
+//
+//	g_hash_table_foreach (component->priv->store_hash, (GHFunc)mc_stores_foreach, &data);
+//}
 
 //void
 //mail_component_remove_folder (MailComponent *component, CamelStore *store, const char *path)

Modified: branches/kill-bonobo/shell/e-shell.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell.c	(original)
+++ branches/kill-bonobo/shell/e-shell.c	Sun Dec 14 04:06:26 2008
@@ -46,7 +46,7 @@
 	GHashTable *modules_by_name;
 	GHashTable *modules_by_scheme;
 
-	gpointer preparing_for_offline;  /* weak pointer */
+	gpointer preparing_for_line_change;  /* weak pointer */
 
 	guint auto_reconnect	: 1;
 	guint network_available	: 1;
@@ -65,6 +65,7 @@
 	EVENT,
 	HANDLE_URI,
 	PREPARE_FOR_OFFLINE,
+	PREPARE_FOR_ONLINE,
 	SEND_RECEIVE,
 	WINDOW_CREATED,
 	WINDOW_DESTROYED,
@@ -164,27 +165,74 @@
 shell_prepare_for_offline (EShell *shell)
 {
 	/* Are preparations already in progress? */
-	if (shell->priv->preparing_for_offline != NULL)
+	if (shell->priv->preparing_for_line_change != NULL)
 		return;
 
 	g_message ("Preparing for offline mode...");
 
-	shell->priv->preparing_for_offline =
+	shell->priv->preparing_for_line_change =
 		e_activity_new (_("Preparing to go offline..."));
 
 	g_object_add_toggle_ref (
-		G_OBJECT (shell->priv->preparing_for_offline),
+		G_OBJECT (shell->priv->preparing_for_line_change),
 		(GToggleNotify) shell_ready_for_offline, shell);
 
 	g_object_add_weak_pointer (
-		G_OBJECT (shell->priv->preparing_for_offline),
-		&shell->priv->preparing_for_offline);
+		G_OBJECT (shell->priv->preparing_for_line_change),
+		&shell->priv->preparing_for_line_change);
 
 	g_signal_emit (
 		shell, signals[PREPARE_FOR_OFFLINE], 0,
-		shell->priv->preparing_for_offline);
+		shell->priv->preparing_for_line_change);
 
-	g_object_unref (shell->priv->preparing_for_offline);
+	g_object_unref (shell->priv->preparing_for_line_change);
+}
+
+static void
+shell_ready_for_online (EShell *shell,
+                        EActivity *activity,
+                        gboolean is_last_ref)
+{
+	if (!is_last_ref)
+		return;
+
+	e_activity_complete (activity);
+
+	g_object_remove_toggle_ref (
+		G_OBJECT (activity), (GToggleNotify)
+		shell_ready_for_online, shell);
+
+	shell->priv->online_mode = TRUE;
+	g_object_notify (G_OBJECT (shell), "online-mode");
+
+	g_message ("Online preparations complete.");
+}
+
+static void
+shell_prepare_for_online (EShell *shell)
+{
+	/* Are preparations already in progress? */
+	if (shell->priv->preparing_for_line_change != NULL)
+		return;
+
+	g_message ("Preparing for online mode...");
+
+	shell->priv->preparing_for_line_change =
+		e_activity_new (_("Preparing to go online..."));
+
+	g_object_add_toggle_ref (
+		G_OBJECT (shell->priv->preparing_for_line_change),
+		(GToggleNotify) shell_ready_for_online, shell);
+
+	g_object_add_weak_pointer (
+		G_OBJECT (shell->priv->preparing_for_line_change),
+		&shell->priv->preparing_for_line_change);
+
+	g_signal_emit (
+		shell, signals[PREPARE_FOR_ONLINE], 0,
+		shell->priv->preparing_for_line_change);
+
+	g_object_unref (shell->priv->preparing_for_line_change);
 }
 
 /* Helper for shell_query_module() */
@@ -535,8 +583,8 @@
 	 * the #EShellModule should reference the @activity until
 	 * preparations are complete, and then unreference the @activity.
 	 * This will delay Evolution from actually going to offline mode
-	 * until the all modules have unreferenced @activity.
-	 */
+	 * until all modules have unreferenced @activity.
+	 **/
 	signals[PREPARE_FOR_OFFLINE] = g_signal_new (
 		"prepare-for-offline",
 		G_OBJECT_CLASS_TYPE (object_class),
@@ -547,6 +595,31 @@
 		E_TYPE_ACTIVITY);
 
 	/**
+	 * EShell:prepare-for-online
+	 * @shell: the #EShell which emitted the signal
+	 * @activity: the #EActivity for offline preparations
+	 *
+	 * Emitted when the user elects to work online.  An #EShellModule
+	 * should listen for this signal and make preparations for working
+	 * in online mode.
+	 *
+	 * If preparations for working online cannot immediately be
+	 * completed (such as when re-connecting to a remote server), the
+	 * #EShellModule should reference the @activity until preparations
+	 * are complete, and then unreference the @activity.  This will
+	 * delay Evolution from actually going to online mode until all
+	 * modules have unreferenced @activity.
+	 **/
+	signals[PREPARE_FOR_ONLINE] = g_signal_new (
+		"prepare-for-online",
+		G_OBJECT_CLASS_TYPE (object_class),
+		G_SIGNAL_RUN_FIRST,
+		0, NULL, NULL,
+		g_cclosure_marshal_VOID__OBJECT,
+		G_TYPE_NONE, 1,
+		E_TYPE_ACTIVITY);
+
+	/**
 	 * EShell:send-receive
 	 * @shell: the #EShell which emitted the signal
 	 * @parent: a parent #GtkWindow
@@ -957,7 +1030,7 @@
  * @shell: an #EShell
  * @online_mode: whether to put Evolution in online mode
  *
- * Puts Evolution in online or offline mode.
+ * Asynchronously places Evolution in online or offline mode.
  **/
 void
 e_shell_set_online_mode (EShell *shell,
@@ -968,20 +1041,10 @@
 	if (online_mode == shell->priv->online_mode)
 		return;
 
-	if (!online_mode && e_shell_get_network_available (shell))
+	if (online_mode)
+		shell_prepare_for_online (shell);
+	else
 		shell_prepare_for_offline (shell);
-	else {
-		EActivity *activity;
-
-		shell->priv->online_mode = online_mode;
-		g_object_notify (G_OBJECT (shell), "online-mode");
-
-		/* If we're being forced offline and we've already started
-		 * preparing for offline mode, cancel the preparations. */
-		activity = shell->priv->preparing_for_offline;
-		if (!online_mode && activity != NULL)
-			e_activity_cancel (activity);
-	}
 }
 
 GtkWidget *



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]