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



commit d67bdb7d79be73fcb2b0d32ca7f4efe0b459b3b0
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-folder.c        |   49 ++++
 camel/providers/imapx/camel-imapx-server.c        |  270 +++++++++++++++++++-
 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 +-
 6 files changed, 340 insertions(+), 17 deletions(-)
---
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 8907c70..4b59f44 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -197,6 +197,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
@@ -268,6 +269,8 @@ struct _CamelIMAPXJob {
 			/* used for biulding uidset stuff */
 			gint index;
 			gint last_index;
+			gint fetch_msg_limit;
+			CamelFetchType fetch_type;
 			gboolean update_unseen;
 			struct _uidset_state uidset;
 			/* changes during refresh */
@@ -650,7 +653,7 @@ imapx_command_addv (CamelIMAPXCommand *ic,
 					s = va_arg (ap, gchar *);
 					c(ic->is->tagprefix, "got string '%s'\n", g_str_has_prefix (fmt, "LOGIN") ? "***" : s);
 				output_string:
-					if (*s) {
+					if (s && *s) {
 						guchar mask = imapx_is_mask (s);
 
 						if (mask & IMAPX_TYPE_ATOM_CHAR)
@@ -942,10 +945,10 @@ static gboolean duplicate_fetch_or_refresh (CamelIMAPXServer *is, CamelIMAPXComm
 	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;
 	}
@@ -1205,6 +1208,7 @@ imapx_job_matches (CamelFolder *folder,
 			break;
 		case IMAPX_JOB_FETCH_NEW_MESSAGES:
 		case IMAPX_JOB_REFRESH_INFO:
+		case IMAPX_JOB_FETCH_MESSAGES:
 		case IMAPX_JOB_SYNC_CHANGES:
 		case IMAPX_JOB_EXPUNGE:
 			if (folder == job->folder)
@@ -1314,7 +1318,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);
 
@@ -1547,7 +1551,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 */
@@ -1616,7 +1620,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 */
@@ -2532,6 +2536,7 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
 	job->noreply = async;
 	job->u.refresh_info.changes = camel_folder_change_info_new ();
 	job->u.refresh_info.update_unseen = update_unseen;
+	job->u.refresh_info.fetch_msg_limit = -1;
 
 	success = imapx_submit_job (is, job, error);
 
@@ -3978,6 +3983,17 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 	CamelIMAPXJob *job = ic->job;
 	gint i = job->u.refresh_info.index;
 	GArray *infos = job->u.refresh_info.infos;
+	CamelSettings *settings;
+	CamelService *service;
+	guint batch_count;
+	gboolean mobile_mode;
+	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));
 
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		propagate_ic_error (job, ic, "Error fetching message headers");
@@ -3993,6 +4009,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 	camel_folder_change_info_clear (job->u.refresh_info.changes);
 
 	if (i < infos->len) {
+		int total = camel_folder_summary_count (job->folder->summary);
+		int fetch_limit = job->u.refresh_info.fetch_msg_limit;
+
 		imapx_command_unref (ic);
 
 		ic = imapx_command_new (
@@ -4003,7 +4022,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 		ic->pri = job->pri - 1;
 		job->u.refresh_info.last_index = i;
 
-		for (; i < 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 < 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 (infos, struct _refresh_info, i);
 
@@ -4018,7 +4039,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 			}
 		}
 
-		job->u.refresh_info.index = i;
+		e('S', "Existing : %d Gonna fetch in %s for %d/%d\n", total, camel_folder_get_full_name(job->folder), i, infos->len);
+		job->u.refresh_info.index = infos->len;
+
 		if (imapx_uidset_done (&job->u.refresh_info.uidset, ic)) {
 			imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)");
 			imapx_command_queue (is, ic);
@@ -4050,7 +4073,7 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 		g_free (r->uid);
 	}
 	g_array_free (job->u.refresh_info.infos, TRUE);
-	if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES)
+	if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES || job->type == IMAPX_JOB_FETCH_MESSAGES)
 		camel_folder_change_info_free (job->u.refresh_info.changes);
 
 	imapx_job_done (is, job);
@@ -4092,12 +4115,15 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 	gint i;
 	GArray *infos = job->u.refresh_info.infos;
 	guint uidset_size;
+	gboolean mobile_mode;
 
 	service = CAMEL_SERVICE (is->store);
 	settings = camel_service_get_settings (service);
 
 	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 (ic->error == NULL && ic->status->result == IMAPX_OK) {
 		GCompareDataFunc uid_cmp = imapx_uid_cmp;
@@ -4241,8 +4267,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 (job->u.refresh_info.infos, TRUE);
 	imapx_job_done (is, job);
@@ -4254,6 +4284,7 @@ imapx_job_scan_changes_start (CamelIMAPXServer *is,
                               CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
+	gchar *uid = imapx_get_uid_from_index (job->folder->summary, 0);
 
 	job->pop_operation_msg = TRUE;
 
@@ -4262,14 +4293,16 @@ imapx_job_scan_changes_start (CamelIMAPXServer *is,
 		_("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 = imapx_command_new (
 		is, "FETCH", job->folder, job->cancellable,
-		"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;
 	job->u.refresh_info.infos = g_array_new (0, 0, sizeof (struct _refresh_info));
 	imapx_command_queue (is, ic);
+	g_free (uid);
 }
 
 static void
@@ -4394,6 +4427,115 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is,
 }
 
 static void
+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;
+
+	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 = job->u.refresh_info.fetch_type;
+	fetch_limit = job->u.refresh_info.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 = 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 while fetching messages: %s");
+			}
+			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 = imapx_command_new (
+			is, "FETCH", job->folder, job->cancellable,
+			"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 = imapx_command_new (is, "FETCH", job->folder, job->cancellable,
+						"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)
 {
@@ -4405,6 +4547,14 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
 	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);
 
@@ -4495,6 +4645,25 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
 		    (!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)
@@ -4897,6 +5066,14 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
 	CamelStore *parent_store;
 	const gchar *full_name;
 	gboolean failed = 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));
 
 	job->commands--;
 
@@ -4958,7 +5135,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);
 				}
 
@@ -5727,7 +5905,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;
 	}
@@ -6141,6 +6321,68 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is,
 	return success;
 }
 
+gboolean	
+camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
+				   CamelFolder *folder,
+				   CamelFetchType type,
+				   int limit,
+				   GCancellable *cancellable,
+				   GError **error)
+{
+	CamelIMAPXJob *job;
+	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;
+	}
+
+	job = imapx_job_new (cancellable);
+	job->type = IMAPX_JOB_FETCH_MESSAGES;
+	job->start = imapx_job_fetch_messages_start;
+	job->folder = folder;
+	job->u.refresh_info.changes = camel_folder_change_info_new();
+	job->u.refresh_info.fetch_msg_limit = limit;
+	job->u.refresh_info.fetch_type = type;
+	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;
+
+	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);
+
+	camel_folder_change_info_free (job->u.refresh_info.changes);
+
+	uid = imapx_get_uid_from_index (folder->summary, 0);
+	newfirstuid = strtoull(uid, NULL, 10);
+	g_free (uid);
+
+	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 7aa0e17..c5cc2d3 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -166,6 +166,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 a9cf44c..c103bc5 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"
@@ -320,9 +321,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) {
@@ -332,7 +340,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]