Implemented correct number of unread messages for multi-mailbox accounts
[modest] / src / dbus_api / modest-dbus-callbacks.c
index 10920ea..90bc890 100644 (file)
@@ -1900,6 +1900,9 @@ headers_cmp (TnyHeader *a, TnyHeader *b)
        return date_a - date_b;
 }
 
+/**
+  * The helper structure for handling GetUnreadMessages DBus request
+  */
 typedef struct {
        TnyList *accounts_list;
        TnyList *inboxes_list;
@@ -1908,6 +1911,8 @@ typedef struct {
        DBusMessage *message;
        GList *account_hits_list;
        ModestMailOperation *mail_op;
+       guint folder_requests_total; /**< Total get-folder requests number for multi-mailbox accounts */
+       guint folder_requests_done; /**< Done get-folder requests number for multi-mailbox accounts */
 } GetUnreadMessagesHelper;
 
 typedef struct {
@@ -1973,7 +1978,7 @@ static void return_results (GetUnreadMessagesHelper *helper)
                        for (result_node = ah->header_list; result_node != NULL; result_node = g_list_next (result_node)) {
                                TnyHeader *header = (TnyHeader *) result_node->data;
                                DBusMessageIter sh_struct_iter;
-                               gint64 ts = MIN (tny_header_get_date_received (header), tny_header_get_date_sent (header));
+                               gint64 ts = tny_header_get_date_received (header);
                                gchar *subject = tny_header_dup_subject (header);
 
                                dbus_message_iter_open_container (&sh_array_iter,
@@ -2039,6 +2044,7 @@ static void get_unread_messages_get_headers_cb (TnyFolder *self,
        ModestProtocolType store_protocol_type;
        ModestProtocol *store_protocol;
        gint unread_count;
+       ModestProtocolRegistry *registry;
 
        acc_iterator = tny_list_create_iterator (helper->accounts_list);
        account = TNY_ACCOUNT (tny_iterator_get_current (acc_iterator));
@@ -2067,12 +2073,18 @@ static void get_unread_messages_get_headers_cb (TnyFolder *self,
        }
        g_object_unref (headers_iterator);
 
+       registry = modest_runtime_get_protocol_registry ();
+       store_protocol_type = modest_tny_account_get_protocol_type (account);
+
+       /* Get the number of unread messages for plug-in based accounts */
+       if (modest_protocol_registry_protocol_type_is_provider (registry, store_protocol_type)) {
+               unread_count = tny_folder_get_unread_count (self);
+       }
+
        account_hits = g_slice_new (AccountHits);
        account_hits->account_id = g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (account));
        account_hits->account_name = g_strdup (tny_account_get_name (account));
-       store_protocol_type = modest_tny_account_get_protocol_type (account);
-       store_protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), 
-                                                                       store_protocol_type);
+       store_protocol = modest_protocol_registry_get_protocol_by_type (registry, store_protocol_type);
        account_hits->store_protocol = g_strdup (modest_protocol_get_name (store_protocol));
        account_hits->header_list = result_list;
        account_hits->mailbox_id = NULL;
@@ -2136,7 +2148,6 @@ static void get_account_folders_cb (TnyFolderStore *self, gboolean cancelled, Tn
        GetUnreadMessagesHelper *helper = (GetUnreadMessagesHelper *) user_data;
        TnyIterator *iterator;
 
-       helper->inboxes_list =  TNY_LIST (tny_simple_list_new ());
        iterator = tny_list_create_iterator (list);
        while (!tny_iterator_is_done (iterator)) {
                TnyFolder *folder;
@@ -2155,6 +2166,92 @@ static void get_account_folders_cb (TnyFolderStore *self, gboolean cancelled, Tn
        get_unread_messages_get_headers (helper);
 }
 
+static void get_multi_mailbox_account_folders_cb (TnyFolderStore *self, gboolean cancelled, TnyList *list, GError *err, gpointer user_data)
+{
+       GetUnreadMessagesHelper *helper = (GetUnreadMessagesHelper *) user_data;
+       TnyIterator *iterator;
+
+       /* another request has been finished */
+       helper->folder_requests_done += 1;
+
+       /* analize the folders we got */
+       iterator = tny_list_create_iterator (list);
+       while (!tny_iterator_is_done (iterator)) {
+               TnyFolder *folder;
+
+               folder = TNY_FOLDER (tny_iterator_get_current (iterator));
+               if (tny_folder_get_folder_type (folder) == TNY_FOLDER_TYPE_INBOX) {
+                       tny_list_prepend (helper->inboxes_list, G_OBJECT (folder));
+               }
+
+               /* Try to check if we have inbox sub-folders in this folder */
+               if (TNY_IS_FOLDER_STORE (folder)) {
+                       TnyFolderStore *folder_store;
+
+                       folder_store = TNY_FOLDER_STORE (folder);
+                       if (folder_store) {
+                               TnyList *folders_list;
+
+                               helper->folder_requests_total += 1;
+                               folders_list = tny_simple_list_new ();
+                               tny_folder_store_get_folders_async (folder_store, folders_list,
+                                       NULL, FALSE, get_multi_mailbox_account_folders_cb, NULL, helper);
+                               g_object_unref (folders_list);
+                       }
+               }
+               g_object_unref (folder);
+               tny_iterator_next (iterator);
+       }
+       g_object_unref (iterator);
+
+       /* Check if we have handled all the inbox folders for multi-mailbox accounts */
+       if (helper->folder_requests_done == helper->folder_requests_total) {
+               TnyIterator *inboxes_it;
+               TnyIterator *accounts_it;
+               TnyAccount *account;
+               guint unread_messages;
+               AccountHits* account_hits;
+               ModestProtocol *store_protocol;
+               ModestProtocolType store_protocol_type;
+
+               /* Store the number of unread messages for the handled account */
+               unread_messages = 0;
+               accounts_it = tny_list_create_iterator (helper->accounts_list);
+               account = TNY_ACCOUNT (tny_iterator_get_current (accounts_it));
+               g_object_unref (accounts_it);
+               inboxes_it = tny_list_create_iterator (helper->inboxes_list);
+               while (!tny_iterator_is_done (inboxes_it)) {
+                       TnyFolder *folder;
+
+                       folder = TNY_FOLDER (tny_iterator_get_current (inboxes_it));
+                       if (folder) {
+                               unread_messages += tny_folder_get_unread_count (folder);
+                       }
+                       tny_iterator_next (inboxes_it);
+               }
+               g_object_unref (inboxes_it);
+               g_object_unref (helper->inboxes_list);
+               helper->inboxes_list = NULL;
+               account_hits = g_slice_new (AccountHits);
+               account_hits->account_id = g_strdup (
+                       modest_tny_account_get_parent_modest_account_name_for_server_account (account));
+               account_hits->account_name = g_strdup (tny_account_get_name (account));
+               store_protocol_type = modest_tny_account_get_protocol_type (account);
+               store_protocol = modest_protocol_registry_get_protocol_by_type (
+                       modest_runtime_get_protocol_registry (), store_protocol_type);
+               account_hits->store_protocol = g_strdup (modest_protocol_get_name (store_protocol));
+               account_hits->mailbox_id = NULL;
+               account_hits->header_list = NULL;
+               account_hits->unread_count = unread_messages;
+               helper->account_hits_list = g_list_prepend (helper->account_hits_list, account_hits);
+
+               /* remove the handled account from the accounts_list */
+               tny_list_remove (helper->accounts_list, G_OBJECT (account));
+               g_object_unref (account);
+
+               get_unread_messages_get_account (helper);
+       }
+}
 
 static void
 get_unread_messages_get_account (GetUnreadMessagesHelper *helper)
@@ -2167,19 +2264,35 @@ get_unread_messages_get_account (GetUnreadMessagesHelper *helper)
                /* all results, then finish */
                return_results (helper);
        } else {
-               TnyAccount *account = NULL;
+               TnyAccount *account;
                TnyList *folders_list;
+               ModestProtocolType protocol_type;
 
                account = TNY_ACCOUNT (tny_iterator_get_current (iterator));
-               folders_list = TNY_LIST (tny_simple_list_new ());
-               tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account), folders_list, NULL,
-                                                   FALSE, get_account_folders_cb, NULL, helper);
+               protocol_type = modest_tny_account_get_protocol_type (account);
+
+               folders_list = tny_simple_list_new ();
+               helper->inboxes_list =  tny_simple_list_new ();
+               if (MODEST_PROTOCOL_REGISTRY_TYPE_INVALID != protocol_type &&
+                       modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
+                               protocol_type, MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS)) {
+                       /* For multi-mailbox protocols we only can get the number of unread messages,
+                          we will not even try to get their email headers */
+                       helper->folder_requests_done = 0;
+                       helper->folder_requests_total = 1;
+                       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account),
+                               folders_list, NULL, FALSE, get_multi_mailbox_account_folders_cb, NULL, helper);
+               }
+               else {
+                       /* For non-multi-mailbox protocols we will get their email headers */
+                       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account),
+                               folders_list, NULL, FALSE, get_account_folders_cb, NULL, helper);
+               }
                g_object_unref (folders_list);
                g_object_unref (account);
 
        }
        g_object_unref (iterator);
-
 }
 
 static gboolean