[evolution-data-server] Add CamelOfflineSettings.



commit 6642b17a078206d3ef85b25b0b85b620ce211a9f
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Jun 10 14:05:06 2011 -0400

    Add CamelOfflineSettings.
    
    CamelOfflineSettings replaces the "sync_offline" URL parameter used in
    CamelOfflineStore and the "offline_sync" URL parameter used in
    CamelDiscoStore with a "stay-synchronized" GObject boolean property.
    
    Adapt various providers to use CamelOfflineSettings.

 camel/Makefile.am                                  |    2 +
 camel/camel-disco-folder.c                         |   24 ++-
 camel/camel-disco-store.c                          |  132 +++++++++-----
 camel/camel-disco-store.h                          |    2 +
 camel/camel-offline-folder.c                       |   18 ++-
 camel/camel-offline-settings.c                     |  146 ++++++++++++++++
 camel/camel-offline-settings.h                     |   72 ++++++++
 camel/camel-offline-store.c                        |  182 +++++++++++---------
 camel/camel.h                                      |    1 +
 camel/providers/imap/camel-imap-wrapper.c          |   19 ++-
 docs/reference/camel/camel-docs.sgml               |    1 +
 docs/reference/camel/camel-sections.txt            |   20 ++
 docs/reference/camel/camel.types                   |    1 +
 .../camel/tmpl/camel-offline-settings.sgml         |   51 ++++++
 docs/reference/camel/tmpl/camel-unused.sgml        |   44 +++++
 15 files changed, 565 insertions(+), 150 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index f3ee64a..f27f128 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -67,6 +67,7 @@ libcamel_provider_1_2_la_SOURCES = 		\
 	camel-network-service.c			\
 	camel-offline-folder.c			\
 	camel-offline-journal.c			\
+	camel-offline-settings.c		\
 	camel-offline-store.c			\
 	camel-provider.c			\
 	camel-sasl-anonymous.c			\
@@ -118,6 +119,7 @@ libcamel_providerinclude_HEADERS =		\
 	camel-network-service.h			\
 	camel-offline-folder.h			\
 	camel-offline-journal.h			\
+	camel-offline-settings.h		\
 	camel-offline-store.h			\
 	camel-provider.h			\
 	camel-sasl-anonymous.h			\
diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index a179e50..81e54a86 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -30,6 +30,7 @@
 #include "camel-debug.h"
 #include "camel-disco-folder.h"
 #include "camel-disco-store.h"
+#include "camel-offline-settings.h"
 #include "camel-session.h"
 
 struct _CamelDiscoFolderPrivate {
@@ -97,23 +98,26 @@ static void
 cdf_folder_changed (CamelFolder *folder,
                     CamelFolderChangeInfo *changes)
 {
-	CamelService *parent_service;
-	CamelStore *parent_store;
+	CamelService *service;
 	CamelSession *session;
-	CamelURL *url;
-	gboolean offline_sync;
+	CamelSettings *settings;
+	CamelStore *parent_store;
+	gboolean sync_folder;
+	gboolean sync_store;
 
 	parent_store = camel_folder_get_parent_store (folder);
 
-	parent_service = CAMEL_SERVICE (parent_store);
-	url = camel_service_get_camel_url (parent_service);
-	session = camel_service_get_session (parent_service);
+	service = CAMEL_SERVICE (parent_store);
+	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
 
-	offline_sync = camel_disco_folder_get_offline_sync (
+	sync_folder = camel_disco_folder_get_offline_sync (
 		CAMEL_DISCO_FOLDER (folder));
 
-	if (changes->uid_added->len > 0 && (offline_sync
-		|| camel_url_get_param (url, "offline_sync"))) {
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
+
+	if (changes->uid_added->len > 0 && (sync_folder || sync_store)) {
 		struct _cdf_sync_data *data;
 
 		data = g_slice_new0 (struct _cdf_sync_data);
diff --git a/camel/camel-disco-store.c b/camel/camel-disco-store.c
index a237d50..329af8d 100644
--- a/camel/camel-disco-store.c
+++ b/camel/camel-disco-store.c
@@ -32,6 +32,7 @@
 #include "camel-disco-diary.h"
 #include "camel-disco-folder.h"
 #include "camel-disco-store.h"
+#include "camel-offline-settings.h"
 #include "camel-session.h"
 
 #define d(x)
@@ -255,9 +256,14 @@ disco_store_set_status (CamelDiscoStore *disco_store,
                         GCancellable *cancellable,
                         GError **error)
 {
+	CamelStore *store;
 	CamelService *service;
 	CamelSession *session;
+	CamelSettings *settings;
+	gboolean going_offline;
 	gboolean network_available;
+	gboolean store_is_online;
+	gboolean sync_store;
 
 	if (disco_store->status == status)
 		return TRUE;
@@ -265,33 +271,45 @@ disco_store_set_status (CamelDiscoStore *disco_store,
 	/* Sync the folder fully if we've been told to sync online
 	 * for this store or this folder and we're going offline. */
 
+	store = CAMEL_STORE (disco_store);
 	service = CAMEL_SERVICE (disco_store);
 	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
+
 	network_available = camel_session_get_network_available (session);
+	store_is_online = (disco_store->status == CAMEL_DISCO_STORE_ONLINE);
+	going_offline = (status == CAMEL_DISCO_STORE_OFFLINE);
+
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
 
 	if (network_available) {
-		if (disco_store->status == CAMEL_DISCO_STORE_ONLINE
-		    && status == CAMEL_DISCO_STORE_OFFLINE) {
-			if (((CamelStore *) disco_store)->folders) {
-				GPtrArray *folders;
-				CamelFolder *folder;
-				CamelURL *url;
-				gint i, sync;
-
-				url = camel_service_get_camel_url (service);
-				sync =  camel_url_get_param (url, "offline_sync") != NULL;
-
-				folders = camel_object_bag_list (((CamelStore *) disco_store)->folders);
-				for (i=0;i<folders->len;i++) {
-					folder = folders->pdata[i];
-					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER)
-					    && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) {
-						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "", cancellable, NULL);
-					}
-					g_object_unref (folder);
-				}
-				g_ptr_array_free (folders, TRUE);
+		if (store_is_online && going_offline && store->folders != NULL) {
+			GPtrArray *folders;
+			gint ii;
+
+			folders = camel_object_bag_list (store->folders);
+
+			for (ii = 0; ii < folders->len; ii++) {
+				CamelFolder *folder = folders->pdata[ii];
+				gboolean sync_folder;
+
+				if (!CAMEL_IS_DISCO_FOLDER (folder))
+					continue;
+
+				sync_folder =
+					camel_disco_folder_get_offline_sync (
+					CAMEL_DISCO_FOLDER (folder));
+
+				if (sync_store || sync_folder)
+					camel_disco_folder_prepare_for_offline (
+						CAMEL_DISCO_FOLDER (folder),
+						"", cancellable, NULL);
 			}
+
+			g_ptr_array_foreach (
+				folders, (GFunc) g_object_unref, NULL);
+			g_ptr_array_free (folders, TRUE);
 		}
 
 		camel_store_synchronize_sync (
@@ -319,6 +337,7 @@ camel_disco_store_class_init (CamelDiscoStoreClass *class)
 	object_class->constructed = disco_store_constructed;
 
 	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->settings_type = CAMEL_TYPE_OFFLINE_SETTINGS;
 	service_class->cancel_connect = disco_store_cancel_connect;
 	service_class->connect_sync = disco_store_connect_sync;
 	service_class->disconnect_sync = disco_store_disconnect_sync;
@@ -443,43 +462,60 @@ camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store,
                                        GCancellable *cancellable,
                                        GError **error)
 {
+	CamelStore *store;
 	CamelService *service;
 	CamelSession *session;
+	CamelSettings *settings;
+	gboolean store_is_online;
+	gboolean sync_store;
 
 	g_return_if_fail (CAMEL_IS_DISCO_STORE (disco_store));
 
+	store = CAMEL_STORE (disco_store);
 	service = CAMEL_SERVICE (disco_store);
 	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
+
+	/* We can't prepare for offline if we're already offline. */
+	if (!camel_session_get_network_available (session))
+		return;
 
 	/* Sync the folder fully if we've been told to
-	 * sync online for this store or this folder. */
-
-	if (camel_session_get_network_available (session)) {
-		if (disco_store->status == CAMEL_DISCO_STORE_ONLINE) {
-			if (((CamelStore *) disco_store)->folders) {
-				GPtrArray *folders;
-				CamelFolder *folder;
-				CamelURL *url;
-				gint i, sync;
-
-				url = camel_service_get_camel_url (service);
-				sync = camel_url_get_param (url, "offline_sync") != NULL;
-
-				folders = camel_object_bag_list (((CamelStore *) disco_store)->folders);
-				for (i=0;i<folders->len;i++) {
-					folder = folders->pdata[i];
-					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER)
-					    && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) {
-						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "(match-all)", cancellable, NULL);
-					}
-					g_object_unref (folder);
-				}
-				g_ptr_array_free (folders, TRUE);
-			}
+	 * sync offline for this store or this folder. */
+
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
+
+	store_is_online = (disco_store->status == CAMEL_DISCO_STORE_ONLINE);
+
+	if (store_is_online && store->folders != NULL) {
+		GPtrArray *folders;
+		guint ii;
+
+		folders = camel_object_bag_list (store->folders);
+
+		for (ii = 0; ii < folders->len; ii++) {
+			CamelFolder *folder = folders->pdata[ii];
+			gboolean sync_folder;
+
+			if (!CAMEL_IS_DISCO_FOLDER (folder))
+				continue;
+
+			sync_folder =
+				camel_disco_folder_get_offline_sync (
+				CAMEL_DISCO_FOLDER (folder));
+
+			if (sync_store || sync_folder)
+				camel_disco_folder_prepare_for_offline (
+					CAMEL_DISCO_FOLDER (folder),
+					"(match-all)", cancellable, NULL);
 		}
 
-		camel_store_synchronize_sync (
-			CAMEL_STORE (disco_store),
-			FALSE, cancellable, NULL);
+		g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+		g_ptr_array_free (folders, TRUE);
 	}
+
+	camel_store_synchronize_sync (
+		CAMEL_STORE (disco_store),
+		FALSE, cancellable, NULL);
 }
diff --git a/camel/camel-disco-store.h b/camel/camel-disco-store.h
index 566ae86..5b2d3af 100644
--- a/camel/camel-disco-store.h
+++ b/camel/camel-disco-store.h
@@ -57,6 +57,7 @@ struct _CamelDiscoDiary;
 
 typedef struct _CamelDiscoStore CamelDiscoStore;
 typedef struct _CamelDiscoStoreClass CamelDiscoStoreClass;
+typedef struct _CamelDiscoStorePrivate CamelDiscoStorePrivate;
 
 typedef enum {
 	CAMEL_DISCO_STORE_ONLINE,
@@ -66,6 +67,7 @@ typedef enum {
 
 struct _CamelDiscoStore {
 	CamelStore parent;
+	CamelDiscoStorePrivate *priv;
 
 	CamelDiscoStoreStatus status;
 	struct _CamelDiscoDiary *diary;
diff --git a/camel/camel-offline-folder.c b/camel/camel-offline-folder.c
index 7e7ff2a..a993ad5 100644
--- a/camel/camel-offline-folder.c
+++ b/camel/camel-offline-folder.c
@@ -28,10 +28,10 @@
 
 #include "camel-debug.h"
 #include "camel-offline-folder.h"
+#include "camel-offline-settings.h"
+#include "camel-offline-store.h"
 #include "camel-operation.h"
-#include "camel-service.h"
 #include "camel-session.h"
-#include "camel-store.h"
 
 typedef struct _AsyncContext AsyncContext;
 typedef struct _OfflineDownsyncData OfflineDownsyncData;
@@ -123,19 +123,23 @@ offline_folder_changed (CamelFolder *folder,
 	CamelStore *parent_store;
 	CamelService *service;
 	CamelSession *session;
-	CamelURL *url;
-	gboolean offline_sync;
+	CamelSettings *settings;
+	gboolean sync_store;
+	gboolean sync_folder;
 
 	parent_store = camel_folder_get_parent_store (folder);
 
 	service = CAMEL_SERVICE (parent_store);
-	url = camel_service_get_camel_url (service);
 	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
+
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
 
-	offline_sync = camel_offline_folder_get_offline_sync (
+	sync_folder = camel_offline_folder_get_offline_sync (
 		CAMEL_OFFLINE_FOLDER (folder));
 
-	if (changes->uid_added->len > 0 && (offline_sync || camel_url_get_param (url, "sync_offline"))) {
+	if (changes->uid_added->len > 0 && (sync_store || sync_folder)) {
 		OfflineDownsyncData *data;
 
 		data = g_slice_new0 (OfflineDownsyncData);
diff --git a/camel/camel-offline-settings.c b/camel/camel-offline-settings.c
new file mode 100644
index 0000000..7411fee
--- /dev/null
+++ b/camel/camel-offline-settings.c
@@ -0,0 +1,146 @@
+/*
+ * camel-offline-settings.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/>
+ *
+ */
+
+#include "camel-offline-settings.h"
+
+#include <camel/camel-store-settings.h>
+
+#define CAMEL_OFFLINE_SETTINGS_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), CAMEL_TYPE_OFFLINE_SETTINGS, CamelOfflineSettingsPrivate))
+
+struct _CamelOfflineSettingsPrivate {
+	gboolean stay_synchronized;
+};
+
+enum {
+	PROP_0,
+	PROP_STAY_SYNCHRONIZED
+};
+
+G_DEFINE_TYPE (
+	CamelOfflineSettings,
+	camel_offline_settings,
+	CAMEL_TYPE_STORE_SETTINGS)
+
+static void
+offline_settings_set_property (GObject *object,
+                             guint property_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_STAY_SYNCHRONIZED:
+			camel_offline_settings_set_stay_synchronized (
+				CAMEL_OFFLINE_SETTINGS (object),
+				g_value_get_boolean (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+offline_settings_get_property (GObject *object,
+                             guint property_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_STAY_SYNCHRONIZED:
+			g_value_set_boolean (
+				value,
+				camel_offline_settings_get_stay_synchronized (
+				CAMEL_OFFLINE_SETTINGS (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+camel_offline_settings_class_init (CamelOfflineSettingsClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (CamelOfflineSettingsPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = offline_settings_set_property;
+	object_class->get_property = offline_settings_get_property;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_STAY_SYNCHRONIZED,
+		g_param_spec_boolean (
+			"stay-synchronized",
+			"Stay Synchronized",
+			"Stay synchronized with the remote server",
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT |
+			G_PARAM_STATIC_STRINGS));
+}
+
+static void
+camel_offline_settings_init (CamelOfflineSettings *settings)
+{
+	settings->priv = CAMEL_OFFLINE_SETTINGS_GET_PRIVATE (settings);
+}
+
+/**
+ * camel_offline_settings_get_stay_synchronized:
+ * @settings: a #CamelOfflineSettings
+ *
+ * Returns whether to synchronize the local cache with the remote server
+ * before switching to offline mode, so the store's content can still be
+ * read while offline.
+ *
+ * Returns: whether to stay synchronized with the remote server
+ *
+ * Since: 3.2
+ **/
+gboolean
+camel_offline_settings_get_stay_synchronized (CamelOfflineSettings *settings)
+{
+	g_return_val_if_fail (CAMEL_IS_OFFLINE_SETTINGS (settings), FALSE);
+
+	return settings->priv->stay_synchronized;
+}
+
+/**
+ * camel_offline_settings_set_stay_synchronized:
+ * @settings: a #CamelOfflineSettings
+ * @stay_synchronized: whether to stay synchronized with the remote server
+ *
+ * Sets whether to synchronize the local cache with the remote server before
+ * switching to offline mode, so the store's content can still be read while
+ * offline.
+ *
+ * Since: 3.2
+ **/
+void
+camel_offline_settings_set_stay_synchronized (CamelOfflineSettings *settings,
+                                       gboolean stay_synchronized)
+{
+	g_return_if_fail (CAMEL_IS_OFFLINE_SETTINGS (settings));
+
+	settings->priv->stay_synchronized = stay_synchronized;
+
+	g_object_notify (G_OBJECT (settings), "stay-synchronized");
+}
diff --git a/camel/camel-offline-settings.h b/camel/camel-offline-settings.h
new file mode 100644
index 0000000..27a9d53
--- /dev/null
+++ b/camel/camel-offline-settings.h
@@ -0,0 +1,72 @@
+/*
+ * camel-offline-settings.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/>
+ *
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_OFFLINE_SETTINGS_H
+#define CAMEL_OFFLINE_SETTINGS_H
+
+#include <camel/camel-store-settings.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_OFFLINE_SETTINGS \
+	(camel_offline_settings_get_type ())
+#define CAMEL_OFFLINE_SETTINGS(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), CAMEL_TYPE_OFFLINE_SETTINGS, CamelOfflineSettings))
+#define CAMEL_OFFLINE_SETTINGS_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), CAMEL_TYPE_OFFLINE_SETTINGS, CamelOfflineSettingsClass))
+#define CAMEL_IS_OFFLINE_SETTINGS(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), CAMEL_TYPE_OFFLINE_SETTINGS))
+#define CAMEL_IS_OFFLINE_SETTINGS_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), CAMEL_TYPE_OFFLINE_SETTINGS))
+#define CAMEL_OFFLINE_SETTINGS_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), CAMEL_TYPE_OFFLINE_SETTINGS, CamelOfflineSettingsClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelOfflineSettings CamelOfflineSettings;
+typedef struct _CamelOfflineSettingsClass CamelOfflineSettingsClass;
+typedef struct _CamelOfflineSettingsPrivate CamelOfflineSettingsPrivate;
+
+struct _CamelOfflineSettings {
+	CamelStoreSettings parent;
+	CamelOfflineSettingsPrivate *priv;
+};
+
+struct _CamelOfflineSettingsClass {
+	CamelStoreSettingsClass parent_class;
+};
+
+GType		camel_offline_settings_get_type
+					(void) G_GNUC_CONST;
+gboolean	camel_offline_settings_get_stay_synchronized
+					(CamelOfflineSettings *settings);
+void		camel_offline_settings_set_stay_synchronized
+					(CamelOfflineSettings *settings,
+					 gboolean stay_synchronized);
+
+G_END_DECLS
+
+#endif /* CAMEL_OFFLINE_SETTINGS_H */
diff --git a/camel/camel-offline-store.c b/camel/camel-offline-store.c
index e5f5b12..6c24ae7 100644
--- a/camel/camel-offline-store.c
+++ b/camel/camel-offline-store.c
@@ -28,6 +28,7 @@
 
 #include "camel-folder.h"
 #include "camel-offline-folder.h"
+#include "camel-offline-settings.h"
 #include "camel-offline-store.h"
 #include "camel-session.h"
 
@@ -61,11 +62,15 @@ static void
 camel_offline_store_class_init (CamelOfflineStoreClass *class)
 {
 	GObjectClass *object_class;
+	CamelServiceClass *service_class;
 
 	g_type_class_add_private (class, sizeof (CamelOfflineStorePrivate));
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->constructed = offline_store_constructed;
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->settings_type = CAMEL_TYPE_OFFLINE_SETTINGS;
 }
 
 static void
@@ -76,7 +81,7 @@ camel_offline_store_init (CamelOfflineStore *store)
 
 /**
  * camel_offline_store_get_online:
- * @store: a #CamelOfflineStore object
+ * @store: a #CamelOfflineStore
  * @error: return location for a #GError, or %NULL
  *
  * Returns %TRUE if @store is online.
@@ -93,7 +98,7 @@ camel_offline_store_get_online (CamelOfflineStore *store)
 
 /**
  * camel_offline_store_set_online_sync:
- * @store: a #CamelOfflineStore object
+ * @offline_store: a #CamelOfflineStore
  * @online: %TRUE for online, %FALSE for offline
  * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
@@ -101,74 +106,79 @@ camel_offline_store_get_online (CamelOfflineStore *store)
  * Sets the online/offline state of @store according to @online.
  **/
 gboolean
-camel_offline_store_set_online_sync (CamelOfflineStore *store,
+camel_offline_store_set_online_sync (CamelOfflineStore *offline_store,
                                      gboolean online,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-	CamelService *service = CAMEL_SERVICE (store);
+	CamelStore *store;
+	CamelService *service;
 	CamelSession *session;
+	CamelSettings *settings;
 	gboolean network_available;
+	gboolean store_is_online;
+	gboolean sync_store;
+	gboolean success;
 
-	g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE);
+	g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (offline_store), FALSE);
 
-	if (store->priv->online == online)
+	if (offline_store->priv->online == online)
 		return TRUE;
 
-	service = CAMEL_SERVICE (store);
+	store = CAMEL_STORE (offline_store);
+	service = CAMEL_SERVICE (offline_store);
 	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
+
 	network_available = camel_session_get_network_available (session);
+	store_is_online = camel_offline_store_get_online (offline_store);
 
-	if (store->priv->online) {
-		/* network available -> network unavailable */
-		if (network_available) {
-			if (((CamelStore *) store)->folders) {
-				GPtrArray *folders;
-				CamelFolder *folder;
-				CamelURL *url;
-				gint i, sync;
-
-				url = camel_service_get_camel_url (service);
-				sync = camel_url_get_param (url, "sync_offline") != NULL;
-
-				folders = camel_object_bag_list (((CamelStore *) store)->folders);
-				for (i = 0; i < folders->len; i++) {
-					folder = folders->pdata[i];
-
-					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER)
-					    && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) {
-						camel_offline_folder_downsync_sync (
-							(CamelOfflineFolder *) folder,
-							NULL, cancellable, NULL);
-					}
-
-					g_object_unref (folder);
-				}
-
-				g_ptr_array_free (folders, TRUE);
-			}
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
 
-			camel_store_synchronize_sync (
-				CAMEL_STORE (store),
-				FALSE, cancellable, NULL);
-		}
+	/* Returning to online mode is the simpler case. */
+	if (!store_is_online) {
+		offline_store->priv->online = online;
+		return camel_service_connect_sync (
+			CAMEL_SERVICE (store), error);
+	}
 
-		if (!camel_service_disconnect_sync (
-			CAMEL_SERVICE (store), network_available, error)) {
-			store->priv->online = online;
-			return FALSE;
-		}
-	} else {
-		store->priv->online = online;
-		/* network unavailable -> network available */
-		if (!camel_service_connect_sync (CAMEL_SERVICE (store), error)) {
-			return FALSE;
+	/* network available -> network unavailable */
+	if (network_available) {
+		GPtrArray *folders;
+		guint ii;
+
+		folders = camel_object_bag_list (store->folders);
+
+		for (ii = 0; ii < folders->len; ii++) {
+			CamelFolder *folder = folders->pdata[ii];
+			gboolean sync_folder;
+
+			if (!CAMEL_IS_OFFLINE_FOLDER (folder))
+				continue;
+
+			sync_folder =
+				camel_offline_folder_get_offline_sync (
+				CAMEL_OFFLINE_FOLDER (folder));
+
+			if (sync_store || sync_folder)
+				camel_offline_folder_downsync_sync (
+					CAMEL_OFFLINE_FOLDER (folder),
+					NULL, cancellable, NULL);
 		}
+
+		g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+		g_ptr_array_free (folders, TRUE);
+
+		camel_store_synchronize_sync (store, FALSE, cancellable, NULL);
 	}
 
-	store->priv->online = online;
+	success = camel_service_disconnect_sync (
+		CAMEL_SERVICE (store), network_available, error);
 
-	return TRUE;
+	offline_store->priv->online = online;
+
+	return success;
 }
 
 /**
@@ -177,47 +187,61 @@ camel_offline_store_set_online_sync (CamelOfflineStore *store,
  * Since: 2.22
  **/
 gboolean
-camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *store,
+camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *offline_store,
                                               GCancellable *cancellable,
                                               GError **error)
 {
+	CamelStore *store;
 	CamelService *service;
 	CamelSession *session;
+	CamelSettings *settings;
+	gboolean network_available;
+	gboolean store_is_online;
+	gboolean sync_store;
 
-	g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), FALSE);
+	g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (offline_store), FALSE);
 
-	service = CAMEL_SERVICE (store);
+	store = CAMEL_STORE (offline_store);
+	service = CAMEL_SERVICE (offline_store);
 	session = camel_service_get_session (service);
+	settings = camel_service_get_settings (service);
+
+	network_available = camel_session_get_network_available (session);
+	store_is_online = camel_offline_store_get_online (offline_store);
+
+	sync_store = camel_offline_settings_get_stay_synchronized (
+		CAMEL_OFFLINE_SETTINGS (settings));
 
-	if (camel_session_get_network_available (session)) {
-		if (store->priv->online) {
-			if (((CamelStore *) store)->folders) {
-				GPtrArray *folders;
-				CamelFolder *folder;
-				CamelURL *url;
-				gint i, sync;
-
-				url = camel_service_get_camel_url (service);
-				sync = camel_url_get_param (url, "sync_offline") != NULL;
-
-				folders = camel_object_bag_list (((CamelStore *) store)->folders);
-				for (i = 0; i < folders->len; i++) {
-					folder = folders->pdata[i];
-
-					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER)
-					    && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) {
-						camel_offline_folder_downsync_sync ((CamelOfflineFolder *) folder, NULL, cancellable, NULL);
-					}
-					g_object_unref (folder);
-				}
-				g_ptr_array_free (folders, TRUE);
+	if (network_available && store_is_online) {
+		GPtrArray *folders;
+		guint ii;
+
+		folders = camel_object_bag_list (store->folders);
+
+		for (ii = 0; ii < folders->len; ii++) {
+			CamelFolder *folder = folders->pdata[ii];
+			gboolean sync_folder;
+
+			if (!CAMEL_IS_OFFLINE_FOLDER (folder))
+				continue;
+
+			sync_folder =
+				camel_offline_folder_get_offline_sync (
+				CAMEL_OFFLINE_FOLDER (folder));
+
+			if (sync_store || sync_folder) {
+				camel_offline_folder_downsync_sync (
+					CAMEL_OFFLINE_FOLDER (folder),
+					NULL, cancellable, NULL);
 			}
 		}
 
-		camel_store_synchronize_sync (
-			CAMEL_STORE (store),
-			FALSE, cancellable, NULL);
+		g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+		g_ptr_array_free (folders, TRUE);
 	}
 
+	if (network_available)
+		camel_store_synchronize_sync (store, FALSE, cancellable, NULL);
+
 	return TRUE;
 }
diff --git a/camel/camel.h b/camel/camel.h
index da03896..8ee6c61 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -95,6 +95,7 @@
 #include <camel/camel-object-bag.h>
 #include <camel/camel-offline-folder.h>
 #include <camel/camel-offline-journal.h>
+#include <camel/camel-offline-settings.h>
 #include <camel/camel-offline-store.h>
 #include <camel/camel-operation.h>
 #include <camel/camel-partition-table.h>
diff --git a/camel/providers/imap/camel-imap-wrapper.c b/camel/providers/imap/camel-imap-wrapper.c
index de2890e..106f8ee 100644
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ b/camel/providers/imap/camel-imap-wrapper.c
@@ -157,20 +157,27 @@ camel_imap_wrapper_init (CamelImapWrapper *imap_wrapper)
 
 CamelDataWrapper *
 camel_imap_wrapper_new (CamelImapFolder *imap_folder,
-			CamelContentType *type, CamelTransferEncoding encoding,
-			const gchar *uid, const gchar *part_spec,
-			CamelMimePart *part)
+                        CamelContentType *type,
+                        CamelTransferEncoding encoding,
+                        const gchar *uid,
+                        const gchar *part_spec,
+                        CamelMimePart *part)
 {
 	CamelImapWrapper *imap_wrapper;
 	CamelStore *store;
 	CamelStream *stream;
-	CamelURL *url;
+	CamelService *service;
+	CamelSettings *settings;
 	gboolean sync_offline = FALSE;
 
 	store = camel_folder_get_parent_store (CAMEL_FOLDER (imap_folder));
-	url = camel_service_get_camel_url (CAMEL_SERVICE (store));
+
+	service = CAMEL_SERVICE (store);
+	settings = camel_service_get_settings (service);
+
 	sync_offline =
-		camel_url_get_param (url, "sync_offline") != NULL ||
+		camel_offline_settings_get_stay_synchronized (
+			CAMEL_OFFLINE_SETTINGS (settings)) ||
 		camel_offline_folder_get_offline_sync (
 			CAMEL_OFFLINE_FOLDER (imap_folder));
 
diff --git a/docs/reference/camel/camel-docs.sgml b/docs/reference/camel/camel-docs.sgml
index 6410847..3771324 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -97,6 +97,7 @@
       <xi:include href="xml/camel-transport.xml"/>
       <xi:include href="xml/camel-settings.xml"/>
       <xi:include href="xml/camel-store-settings.xml"/>
+      <xi:include href="xml/camel-offline-settings.xml"/>
     </chapter>
 
     <chapter id="Filters">
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 2f37711..5cc3642 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -385,6 +385,7 @@ CAMEL_IS_DISCO_STORE_CLASS
 CAMEL_DISCO_STORE_GET_CLASS
 CamelDiscoStoreClass
 <SUBSECTION Private>
+CamelDiscoStorePrivate
 camel_disco_store_get_type
 </SECTION>
 
@@ -1595,6 +1596,25 @@ camel_offline_journal_get_type
 </SECTION>
 
 <SECTION>
+<FILE>camel-offline-settings</FILE>
+<TITLE>CamelOfflineSettings</TITLE>
+CamelOfflineSettings
+camel_offline_settings_get_stay_synchronized
+camel_offline_settings_set_stay_synchronized
+<SUBSECTION Standard>
+CAMEL_OFFLINE_SETTINGS
+CAMEL_IS_OFFLINE_SETTINGS
+CAMEL_TYPE_OFFLINE_SETTINGS
+CAMEL_OFFLINE_SETTINGS_CLASS
+CAMEL_IS_OFFLINE_SETTINGS_CLASS
+CAMEL_OFFLINE_SETTINGS_GET_CLASS
+CamelOfflineSettingsClass
+<SUBSECTION Private>
+CamelOfflineSettingsPrivate
+camel_offline_settings_get_type
+</SECTION>
+
+<SECTION>
 <FILE>camel-offline-store</FILE>
 <TITLE>CamelOfflineStore</TITLE>
 CamelOfflineStore
diff --git a/docs/reference/camel/camel.types b/docs/reference/camel/camel.types
index dda2958..5af9182 100644
--- a/docs/reference/camel/camel.types
+++ b/docs/reference/camel/camel.types
@@ -51,6 +51,7 @@ camel_nntp_address_get_type
 camel_object_get_type
 camel_offline_folder_get_type
 camel_offline_journal_get_type
+camel_offline_settings_get_type
 camel_offline_store_get_type
 camel_partition_table_get_type
 camel_key_table_get_type
diff --git a/docs/reference/camel/tmpl/camel-offline-settings.sgml b/docs/reference/camel/tmpl/camel-offline-settings.sgml
new file mode 100644
index 0000000..fa6fd74
--- /dev/null
+++ b/docs/reference/camel/tmpl/camel-offline-settings.sgml
@@ -0,0 +1,51 @@
+<!-- ##### SECTION Title ##### -->
+CamelOfflineSettings
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### SECTION Image ##### -->
+
+
+<!-- ##### STRUCT CamelOfflineSettings ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG CamelOfflineSettings:stay-synchronized ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION camel_offline_settings_get_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ settings: 
+ Returns: 
+
+
+<!-- ##### FUNCTION camel_offline_settings_set_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ settings: 
+ stay_synchronized: 
+
+
diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml
index 7cfaad2..069eeb1 100644
--- a/docs/reference/camel/tmpl/camel-unused.sgml
+++ b/docs/reference/camel/tmpl/camel-unused.sgml
@@ -3262,6 +3262,12 @@ streams
 @CAMEL_DISCO_DIARY_ARG_UID: 
 @CAMEL_DISCO_DIARY_ARG_UID_LIST: 
 
+<!-- ##### ARG CamelDiscoStore:stay-synchronized ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### STRUCT CamelException ##### -->
 <para>
 
@@ -4260,6 +4266,12 @@ streams
 @CAMEL_IMAP_JOURNAL_ENTRY_APPEND: 
 @CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER: 
 
+<!-- ##### ARG CamelOfflineStore:stay-synchronized ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### USER_FUNCTION CamelOperationStatusFunc ##### -->
 <para>
 
@@ -5302,6 +5314,22 @@ streams
 
 @Returns: 
 
+<!-- ##### FUNCTION camel_disco_store_get_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ store: 
+ Returns: 
+
+<!-- ##### FUNCTION camel_disco_store_set_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ store: 
+ stay_synchronized: 
+
 <!-- ##### FUNCTION camel_exception_clear ##### -->
 <para>
 
@@ -8109,6 +8137,14 @@ streams
 @error: 
 @Returns: 
 
+<!-- ##### FUNCTION camel_offline_store_get_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ store: 
+ Returns: 
+
 <!-- ##### FUNCTION camel_offline_store_prepare_for_offline ##### -->
 <para>
 
@@ -8130,6 +8166,14 @@ streams
 @error: 
 @Returns: 
 
+<!-- ##### FUNCTION camel_offline_store_set_stay_synchronized ##### -->
+<para>
+
+</para>
+
+ store: 
+ stay_synchronized: 
+
 <!-- ##### FUNCTION camel_operation_cancel_block ##### -->
 <para>
 



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