[evolution-data-server/imap-pop-mobile: 4/12] Added Mobile support and specific apis to imapx.



commit 41f03db120e9f1eb90d871de15390ea227c64343
Author: Srinivasa Ragavan <sragavan gnome org>
Date:   Thu Jan 12 14:08:44 2012 +0530

    Added Mobile support and specific apis to imapx.

 camel/providers/imapx/camel-imapx-command.c       |    2 +-
 camel/providers/imapx/camel-imapx-folder.c        |   49 ++++
 camel/providers/imapx/camel-imapx-server.c        |  296 +++++++++++++++++++-
 camel/providers/imapx/camel-imapx-server.h        |    7 +
 camel/providers/imapx/camel-imapx-store-summary.c |    2 +-
 camel/providers/imapx/camel-imapx-store.c         |   15 +-
 camel/providers/imapx/camel-imapx-utils.c         |   14 +-
 7 files changed, 366 insertions(+), 19 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-command.c b/camel/providers/imapx/camel-imapx-command.c
index e8ba3cd..f648a03 100644
--- a/camel/providers/imapx/camel-imapx-command.c
+++ b/camel/providers/imapx/camel-imapx-command.c
@@ -276,7 +276,7 @@ camel_imapx_command_addv (CamelIMAPXCommand *ic,
 				s = va_arg (ap, gchar *);
 				c(ic->is->tagprefix, "got string '%s'\n", g_str_has_prefix (format, "LOGIN") ? "***" : s);
 			output_string:
-				if (*s) {
+				if (s && *s) {
 					guchar mask = imapx_is_mask (s);
 
 					if (mask & IMAPX_TYPE_ATOM_CHAR)
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 6197a57..81a4a66 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -378,6 +378,42 @@ imapx_expunge_sync (CamelFolder *folder,
 	return FALSE;
 }
 
+static gboolean
+imapx_fetch_messages_sync (CamelFolder *folder,
+			   CamelFetchType type,
+			   int limit,
+			   GCancellable *cancellable,
+			   GError **error)
+{
+	CamelStore *parent_store;
+	CamelIMAPXStore *istore;
+	CamelIMAPXServer *server;
+	gboolean success = FALSE;
+
+	parent_store = camel_folder_get_parent_store (folder);
+	istore = CAMEL_IMAPX_STORE (parent_store);
+
+	if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (istore))) {
+		g_set_error (
+			error, CAMEL_SERVICE_ERROR,
+			CAMEL_SERVICE_ERROR_UNAVAILABLE,
+			_("You must be working online to complete this operation"));
+		return FALSE;
+	}
+
+	if (!camel_service_connect_sync ((CamelService *) istore, error))
+		return FALSE;
+
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
+	if (server != NULL) {
+		success = camel_imapx_server_fetch_messages (server, folder, type, limit, cancellable, error);
+		camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
+		g_object_unref (server);
+	}
+
+	return success;
+}
+
 static CamelMimeMessage *
 imapx_get_message_sync (CamelFolder *folder,
                         const gchar *uid,
@@ -447,6 +483,17 @@ imapx_get_message_sync (CamelFolder *folder,
 }
 
 static gboolean
+imapx_purge_message_cache_sync (CamelFolder *folder,
+				gchar *start_uid,
+				gchar *end_uid,
+				GCancellable *cancellable,
+				GError **error)
+{
+	/* Not Implemented for now. */
+	return TRUE;
+}
+
+static gboolean
 imapx_refresh_info_sync (CamelFolder *folder,
                          GCancellable *cancellable,
                          GError **error)
@@ -607,7 +654,9 @@ camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
 	folder_class->get_filename = imapx_get_filename;
 	folder_class->append_message_sync = imapx_append_message_sync;
 	folder_class->expunge_sync = imapx_expunge_sync;
+	folder_class->fetch_messages_sync = imapx_fetch_messages_sync;
 	folder_class->get_message_sync = imapx_get_message_sync;
+	folder_class->purge_message_cache_sync = imapx_purge_message_cache_sync;
 	folder_class->refresh_info_sync = imapx_refresh_info_sync;
 	folder_class->synchronize_sync = imapx_synchronize_sync;
 	folder_class->synchronize_message_sync = imapx_synchronize_message_sync;
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 9eff1c2..6ffaa3f 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -102,6 +102,8 @@ struct _RefreshInfoData {
 	/* used for building uidset stuff */
 	gint index;
 	gint last_index;
+	gint fetch_msg_limit;
+	CamelFetchType fetch_type;
 	gboolean update_unseen;
 	struct _uidset_state uidset;
 	/* changes during refresh */
@@ -207,6 +209,7 @@ enum {
 	IMAPX_JOB_CREATE_FOLDER = 1 << 11,
 	IMAPX_JOB_DELETE_FOLDER = 1 << 12,
 	IMAPX_JOB_RENAME_FOLDER = 1 << 13,
+	IMAPX_JOB_FETCH_MESSAGES = 1 << 14,
 };
 
 /* Operations on the store (folder_tree) will have highest priority as we know for sure they are sync
@@ -558,10 +561,10 @@ duplicate_fetch_or_refresh (CamelIMAPXServer *is,
 	if (!ic->job)
 		return FALSE;
 
-	if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO)))
+	if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES)))
 		return FALSE;
 
-	if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL)) {
+	if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL)) {
 		c(is->tagprefix, "Not yet sending duplicate fetch/refresh %s command\n", ic->name);
 		return TRUE;
 	}
@@ -967,7 +970,7 @@ imapx_get_uid_from_index (CamelFolderSummary *summary,
                           guint id)
 {
 	GPtrArray *array;
-	gchar *uid;
+	gchar *uid = NULL;
 
 	g_return_val_if_fail (summary != NULL, NULL);
 
@@ -1204,7 +1207,7 @@ imapx_untagged (CamelIMAPXServer *is,
 		}
 
 		if ((finfo->got & FETCH_FLAGS) && !(finfo->got & FETCH_HEADER)) {
-			CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL);
+			CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL);
 			/* This is either a refresh_info job, check to see if it is and update
 			 * if so, otherwise it must've been an unsolicited response, so update
 			 * the summary to match */
@@ -1277,7 +1280,7 @@ imapx_untagged (CamelIMAPXServer *is,
 		}
 
 		if ((finfo->got & (FETCH_HEADER | FETCH_UID)) == (FETCH_HEADER | FETCH_UID)) {
-			CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL);
+			CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL);
 
 			/* This must be a refresh info job as well, but it has asked for
 			 * new messages to be added to the index */
@@ -2087,6 +2090,7 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
 	data = g_slice_new0 (RefreshInfoData);
 	data->changes = camel_folder_change_info_new ();
 	data->update_unseen = update_unseen;
+	data->fetch_msg_limit = -1;
 
 	job = camel_imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_FETCH_NEW_MESSAGES;
@@ -3609,10 +3613,22 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 	RefreshInfoData *data;
 	gint i;
 	gboolean success = TRUE;
+	CamelSettings *settings;
+	CamelService *service;
+	guint batch_count;
+	gboolean mobile_mode;
 
 	data = camel_imapx_job_get_data (job);
 	g_return_val_if_fail (data != NULL, FALSE);
 
+	service = CAMEL_SERVICE (is->store);
+	settings = camel_service_get_settings (service);
+
+	batch_count = camel_imapx_settings_get_batch_fetch_count (
+		CAMEL_IMAPX_SETTINGS (settings));
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
+
 	i = data->index;
 
 	if (camel_imapx_command_set_error_if_failed (ic, error)) {
@@ -3632,7 +3648,10 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 	camel_folder_change_info_clear (data->changes);
 
 	if (i < data->infos->len) {
-		camel_imapx_command_unref (ic);
+		int total = camel_folder_summary_count (job->folder->summary);
+		int fetch_limit = data->fetch_msg_limit;
+
+		imapx_command_unref (ic);
 
 		ic = camel_imapx_command_new (
 			is, "FETCH", job->folder, "UID FETCH ");
@@ -3641,7 +3660,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 		ic->pri = job->pri - 1;
 		data->last_index = i;
 
-		for (; i < data->infos->len; i++) {
+		/* If its mobile client and  when total=0 (new account setup) fetch only one batch of mails,
+ 		 * on futher attempts download all new mails as per the limit. */
+		for (; i < data->infos->len && (!mobile_mode || total || ((fetch_limit != -1 && i < fetch_limit) || (fetch_limit == -1 && i < batch_count))); i++) {
 			gint res;
 			struct _refresh_info *r = &g_array_index (data->infos, struct _refresh_info, i);
 
@@ -3656,7 +3677,8 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 			}
 		}
 
-		data->index = i;
+		e('S', "Existing : %d Gonna fetch in %s for %d/%d\n", total, camel_folder_get_full_name(job->folder), i, data->infos->len);
+		data->index = data->infos->len;
 		if (imapx_uidset_done (&data->uidset, ic)) {
 			camel_imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)");
 			imapx_command_queue (is, ic);
@@ -3732,6 +3754,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 	guint uidset_size;
 	gint i;
 	gboolean success = TRUE;
+	gboolean mobile_mode;
 
 	data = camel_imapx_job_get_data (job);
 	g_return_val_if_fail (data != NULL, FALSE);
@@ -3741,6 +3764,8 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 
 	uidset_size = camel_imapx_settings_get_batch_fetch_count (
 		CAMEL_IMAPX_SETTINGS (settings));
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
 
 	if (camel_imapx_command_set_error_if_failed (ic, error)) {
 		g_prefix_error (
@@ -3887,8 +3912,12 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 	}
 
 	/* There's no sane way to get the server-side unseen count on the
-	 * select mailbox. So just work it out from the flags */
-	((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
+	 * select mailbox. So just work it out from the flags if its not in
+	 * mobile mode. In mobile mode we would have this filled up already
+	 * with a STATUS command. 
+	 **/
+	if (!mobile_mode)
+		((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
 
 	g_array_free (data->infos, TRUE);
 	imapx_unregister_job (is, job);
@@ -3903,6 +3932,7 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
 {
 	CamelIMAPXCommand *ic;
 	RefreshInfoData *data;
+	gchar *uid = imapx_get_uid_from_index (job->folder->summary, 0);
 
 	data = camel_imapx_job_get_data (job);
 	g_return_if_fail (data != NULL);
@@ -3914,14 +3944,17 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
 		_("Scanning for changed messages in %s"),
 		camel_folder_get_display_name (job->folder));
 
+	e('E', "Scanning from %s in %s\n", uid, camel_folder_get_full_name (job->folder));	
 	ic = camel_imapx_command_new (
 		is, "FETCH", job->folder,
-		"UID FETCH 1:* (UID FLAGS)");
+		"UID FETCH %s:* (UID FLAGS)", uid ? uid : "1");
+
 	ic->job = job;
 	ic->complete = imapx_job_scan_changes_done;
 	ic->pri = job->pri;
 	data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
 	imapx_command_queue (is, ic);
+	g_free (uid);
 }
 
 static gboolean
@@ -4069,8 +4102,126 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
 }
 
 static void
-imapx_job_refresh_info_start (CamelIMAPXJob *job,
-                              CamelIMAPXServer *is)
+imapx_job_fetch_messages_start (CamelIMAPXServer *is, 
+				CamelIMAPXJob *job)
+{
+	CamelIMAPXCommand *ic;
+	CamelFolder *folder = job->folder;
+	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
+	guint32 total, diff;
+	gchar *start_uid = NULL, *end_uid = NULL;
+	CamelFetchType ftype;
+	gint fetch_limit;
+	CamelSortType fetch_order;
+	CamelService *service;
+	CamelSettings *settings;
+	guint uidset_size;
+        RefreshInfoData *data;
+
+        data = camel_imapx_job_get_data (job);
+        g_return_if_fail (data != NULL);
+
+	service = CAMEL_SERVICE (is->store);
+	settings = camel_service_get_settings (service);
+
+	fetch_order = camel_imapx_settings_get_fetch_order (
+		CAMEL_IMAPX_SETTINGS (settings));
+
+	total = camel_folder_summary_count (folder->summary);
+	diff = ifolder->exists_on_server - total;
+
+	ftype = data->fetch_type;
+	fetch_limit = data->fetch_msg_limit;
+
+	uidset_size = camel_imapx_settings_get_batch_fetch_count (
+		CAMEL_IMAPX_SETTINGS (settings));
+
+	if (ftype == CAMEL_FETCH_NEW_MESSAGES || 
+		(ftype ==  CAMEL_FETCH_OLD_MESSAGES && total <=0 )) {
+
+		char *uid;
+
+		if (total > 0) {
+			/* This means that we are fetching limited number of new mails */
+			uid = g_strdup_printf("%d", total);
+		} else {
+			/* For empty accounts, we always fetch the specified number of new mails independent of 
+			 * being asked to fetch old or new.
+			 */
+			uid = g_strdup ("1"); 
+		}
+
+		if (ftype == CAMEL_FETCH_NEW_MESSAGES) {
+			/* We need to issue Status command to get the total unread count */
+			ic = camel_imapx_command_new (
+				is, "STATUS", NULL, 
+				"STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
+
+			ic->job = job;
+			ic->pri = job->pri;
+
+			imapx_command_run_sync (is, ic);
+
+			if (ic->job->error == NULL)
+                                camel_imapx_command_set_error_if_failed (ic, &ic->job->error);
+
+                        g_prefix_error (
+                                &ic->job->error, "%s: ",
+                                _("Error while fetching messages"));
+
+			camel_imapx_command_unref (ic);
+		}
+
+		camel_operation_push_message (
+			job->cancellable, _("Fetching summary information for %d messages in %s"),
+			job->u.refresh_info.fetch_msg_limit, camel_folder_get_full_name (folder));		
+		/* New account and fetching old messages, we would return just the limited number of newest messages */
+		ic = camel_imapx_command_new (
+			is, "FETCH", job->folder, 
+			"UID FETCH %s:* (UID FLAGS)", uid);
+		imapx_uidset_init (&job->u.refresh_info.uidset, uidset_size, 0);
+		job->u.refresh_info.infos = g_array_new (0, 0, sizeof (struct _refresh_info));
+		ic->pri = job->pri;
+
+		if (fetch_order == CAMEL_SORT_DESCENDING)
+			ic->complete = imapx_command_fetch_new_uids_done;
+		else
+			ic->complete = imapx_command_step_fetch_done;
+
+		g_free (uid);
+		ic->job = job;
+		imapx_command_queue (is, ic);
+
+		return;
+	} else if (ftype == CAMEL_FETCH_OLD_MESSAGES && total > 0) {
+			unsigned long long uidl;
+			start_uid = imapx_get_uid_from_index (folder->summary, 0);
+			uidl = strtoull(start_uid, NULL, 10);
+			end_uid = g_strdup_printf("%lld", (((int)uidl)-fetch_limit > 0) ? (uidl-fetch_limit) : 1);
+
+			camel_operation_push_message(
+				job->cancellable, _("Fetching summary information for %d messages in %s"),
+				job->u.refresh_info.fetch_msg_limit, camel_folder_get_full_name (folder));		
+
+			ic = camel_imapx_command_new (is, "FETCH", job->folder,
+						"UID FETCH %s:%s (RFC822.SIZE RFC822.HEADER FLAGS)", start_uid, end_uid);
+			ic->pri = job->pri;
+			ic->complete = imapx_command_fetch_new_messages_done;
+
+			g_free (start_uid);
+			g_free (end_uid);
+
+			ic->job = job;
+			imapx_command_queue (is, ic);
+
+	} else {
+		g_error ("Shouldn't reach here. Incorrect fetch type");
+	}
+}
+
+static void
+imapx_job_refresh_info_start (CamelIMAPXServer *is,
+                              CamelIMAPXJob *job)
 {
 	guint32 total;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder;
@@ -4080,6 +4231,14 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
 	gboolean need_rescan = FALSE;
 	gboolean is_selected = FALSE;
 	gboolean can_qresync = FALSE;
+	CamelService *service;
+	CamelSettings *settings;
+	gboolean mobile_mode;
+
+	service = CAMEL_SERVICE (is->store);
+	settings = camel_service_get_settings (service);
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
 
 	full_name = camel_folder_get_full_name (folder);
 
@@ -4178,6 +4337,25 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
 		    (!is_selected && isum->modseq != ifolder->modseq_on_server))
 			need_rescan = TRUE;
 
+	} else if (mobile_mode) {
+		/* We need to issue Status command to get the total unread count */
+		CamelIMAPXCommand *ic;
+
+		ic = imapx_command_new (
+			is, "STATUS", NULL, job->cancellable, 
+			"STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
+
+		ic->job = job;
+		ic->pri = job->pri;
+
+		imapx_command_run_sync (is, ic);
+
+		if (ic->error != NULL || ic->status->result != IMAPX_OK) {
+			propagate_ic_error (job, ic, "Error refreshing folder: %s");
+			imapx_command_unref (ic);
+			goto done;
+		}
+		imapx_command_unref (ic);
 	}
 
 	if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server)
@@ -4681,11 +4859,19 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
 	CamelStore *parent_store;
 	SyncChangesData *data;
 	const gchar *full_name;
+	CamelService *service;
+	CamelSettings *settings;
+	gboolean mobile_mode;
 	gboolean success = TRUE;
 
 	data = camel_imapx_job_get_data (job);
 	g_return_val_if_fail (data != NULL, FALSE);
 
+	service = CAMEL_SERVICE (is->store);
+	settings = camel_service_get_settings (service);
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
+
 	job->commands--;
 
 	full_name = camel_folder_get_full_name (job->folder);
@@ -4741,7 +4927,8 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
 				if (si->total != camel_folder_summary_get_saved_count (job->folder->summary) ||
 				    si->unread != camel_folder_summary_get_unread_count (job->folder->summary)) {
 					si->total = camel_folder_summary_get_saved_count (job->folder->summary);
-					si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
+					if (!mobile_mode) /* Don't mess with server's unread count in mobile mode, as what we have downloaded is little */
+						si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
 					camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
 				}
 
@@ -5551,7 +5738,9 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is,
 
 	QUEUE_LOCK (is);
 
-	if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL)) {
+	/* Both RefreshInfo and Fetch messages can't operate simultaneously */
+	if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
+		imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
 		QUEUE_UNLOCK (is);
 		return TRUE;
 	}
@@ -6004,6 +6193,83 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is,
 	return success;
 }
 
+static gboolean
+imapx_job_fetch_messages_matches (CamelIMAPXJob *job,
+                                      CamelFolder *folder,
+                                      const gchar *uid)
+{
+        return (folder == job->folder);
+}
+
+gboolean	
+camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
+				   CamelFolder *folder,
+				   CamelFetchType type,
+				   int limit,
+				   GCancellable *cancellable,
+				   GError **error)
+{
+	CamelIMAPXJob *job;
+	RefreshInfoData *data;
+	gboolean registered = TRUE;
+	const gchar *full_name;
+	gboolean success = TRUE;
+	unsigned long long firstuid, newfirstuid;
+	gchar *uid;
+ 
+	uid = imapx_get_uid_from_index (folder->summary, 0);
+	firstuid = strtoull(uid, NULL, 10);
+	g_free (uid);
+
+	QUEUE_LOCK (is);
+
+	/* Both RefreshInfo and Fetch messages can't operate simultaneously */
+	if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
+		imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
+		QUEUE_UNLOCK (is);
+		return TRUE;
+	}
+
+
+	data = g_slice_new0 (RefreshInfoData);
+	data->changes = camel_folder_change_info_new ();
+	data->update_unseen = update_unseen;
+	data->fetch_msg_limit = limit;
+	data->fetch_type = type;
+
+	job = camel_imapx_job_new (cancellable);
+	job->type = IMAPX_JOB_FETCH_MESSAGES;
+	job->start = imapx_job_fetch_messages_start;
+	job->matches = imapx_job_fetch_messages_matches;
+	job->folder = folder;
+	job->pri = IMAPX_PRIORITY_NEW_MESSAGES;
+
+	full_name = camel_folder_get_full_name (folder);
+	
+	if (g_ascii_strcasecmp(full_name, "INBOX") == 0)
+		job->pri += 10;
+
+	camel_imapx_job_set_data (
+		job, data, (GDestroyNotify) refresh_info_data_free);
+
+	registered = imapx_register_job (is, job, error);
+
+	QUEUE_UNLOCK (is);
+
+	success = registered && imapx_run_job (is, job, error);
+
+	if (success && camel_folder_change_info_changed (job->u.refresh_info.changes))
+		camel_folder_changed (folder, job->u.refresh_info.changes);
+
+	uid = imapx_get_uid_from_index (folder->summary, 0);
+	newfirstuid = strtoull(uid, NULL, 10);
+	g_free (uid);
+
+	camel_imapx_job_unref (job);
+
+	return firstuid != newfirstuid;
+}
+
 gboolean
 camel_imapx_server_rename_folder (CamelIMAPXServer *is,
                                   const gchar *old_name,
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index d6921b3..61b02f1 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -167,6 +167,13 @@ gboolean	camel_imapx_server_expunge	(CamelIMAPXServer *is,
 						 CamelFolder *folder,
 						 GCancellable *cancellable,
 						 GError **error);
+gboolean	camel_imapx_server_fetch_messages 		
+						(CamelIMAPXServer *is,
+                                       		 CamelFolder *folder,
+						 CamelFetchType type,
+				       		 int limit,
+						 GCancellable *cancellable,
+                                       		 GError **error);
 gboolean	camel_imapx_server_noop		(CamelIMAPXServer *is,
 						 CamelFolder *folder,
 						 GCancellable *cancellable,
diff --git a/camel/providers/imapx/camel-imapx-store-summary.c b/camel/providers/imapx/camel-imapx-store-summary.c
index f881a17..c764106 100644
--- a/camel/providers/imapx/camel-imapx-store-summary.c
+++ b/camel/providers/imapx/camel-imapx-store-summary.c
@@ -146,7 +146,7 @@ camel_imapx_store_summary_full_to_path (CamelIMAPXStoreSummary *s,
 
 	p = path = g_strdup (full_name);
 
-	if (dir_sep != '/') {
+	if (dir_sep && dir_sep != '/') {
 		while (*p) {
 			if (*p == '/')
 				*p = dir_sep;
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 0ed414d..3b1d55c 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -392,6 +392,13 @@ fill_fi (CamelStore *store,
          guint32 flags)
 {
 	CamelFolder *folder;
+	CamelService *service = (CamelService *)store;
+	CamelSettings *settings;
+	gboolean mobile_mode;
+
+	settings = camel_service_get_settings (service);
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
 
 	folder = camel_object_bag_peek (store->folders, fi->full_name);
 	if (folder) {
@@ -402,7 +409,13 @@ fill_fi (CamelStore *store,
 		else
 			ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder);
 
-		fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+		/* Mobile clients would still love to see the total unread of actual mails
+		 * than what they just have downloaded. So we override that information by giving 
+		 * what the server has instead of what we have downloaded. */
+		if (mobile_mode)
+			fi->unread = ((CamelIMAPXFolder *) folder)->unread_on_server;
+		else
+			fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
 		fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
 
 		if (!folder->summary)
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index b04c01e..a7a0825 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "camel-imapx-folder.h"
+#include "camel-imapx-settings.h"
 #include "camel-imapx-stream.h"
 #include "camel-imapx-summary.h"
 #include "camel-imapx-store.h"
@@ -310,9 +311,16 @@ imapx_update_store_summary (CamelFolder *folder)
 	CamelStoreInfo *si;
 	CamelStore *parent_store;
 	const gchar *full_name;
+	CamelService *service;
+	CamelSettings *settings;
+	gboolean mobile_mode;
 
 	full_name = camel_folder_get_full_name (folder);
 	parent_store = camel_folder_get_parent_store (folder);
+	service = CAMEL_SERVICE (parent_store);
+	settings = camel_service_get_settings (service);
+	mobile_mode = camel_imapx_settings_get_mobile_mode (
+		CAMEL_IMAPX_SETTINGS (settings));
 
 	si = camel_store_summary_path ((CamelStoreSummary *) ((CamelIMAPXStore *) parent_store)->summary, full_name);
 	if (si) {
@@ -322,7 +330,11 @@ imapx_update_store_summary (CamelFolder *folder)
 		unread = camel_folder_summary_get_unread_count (folder->summary);
 
 		if (si->unread != unread || si->total != total) {
-			si->unread = unread;
+
+			if (!mobile_mode)
+				si->unread = unread;
+			else 
+				si->unread =  ((CamelIMAPXFolder *)folder)->unread_on_server;
 			si->total = total;
 
 			camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);



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