Do ignore empty recipients when checking names
[modest] / src / modest-search.c
index 3c0effc..d206df7 100644 (file)
 
 typedef struct 
 {
-       guint folder_count;
-       guint folder_total;
+       guint pending_calls;
        GList *msg_hits;
        ModestSearch *search;
        ModestSearchCallback callback;
        gpointer user_data;
+       TnyList *all_folders;
 } SearchHelper;
 
 static SearchHelper *create_helper (ModestSearchCallback callback, 
                                    ModestSearch *search,
                                    gpointer user_data);
 
-static void          check_search_finished (SearchHelper *helper);
+static void          _search_folder (TnyFolder *folder, 
+                                    SearchHelper *helper);
 
 static gchar *
 g_strdup_or_null (const gchar *str)
@@ -91,9 +92,9 @@ add_hit (GList *list, TnyHeader *header, TnyFolder *folder)
        TnyHeaderFlags   flags;
        char            *furl;
        char            *msg_url;
-       const char      *uid;
-       const char      *subject;
-       const char      *sender;
+       char      *uid;
+       char      *subject;
+       char      *sender;
 
        hit = g_slice_new0 (ModestSearchResultHit);
 
@@ -107,22 +108,25 @@ add_hit (GList *list, TnyHeader *header, TnyFolder *folder)
         * and/or find out what UID form is used when finding, in camel_data_cache_get().
         * so we can find what we get. Philip is working on this.
         */
-       uid = tny_header_get_uid (header);
-       if (!furl) {
-               g_warning ("%s: tny_header_get_uid(): returned NULL for message with subject=%s\n", __FUNCTION__, tny_header_get_subject (header));
+       uid = tny_header_dup_uid (header);
+       if (!uid) {
+               gchar *subject = tny_header_dup_subject (header);
+               g_warning ("%s: tny_header_get_uid(): returned NULL for message with subject=%s\n", __FUNCTION__, subject);
+               g_free (subject);
        }
        
        msg_url = g_strdup_printf ("%s/%s", furl, uid);
        g_free (furl);
+       g_free (uid);
        
-       subject = tny_header_get_subject (header);
-       sender = tny_header_get_from (header);
+       subject = tny_header_dup_subject (header);
+       sender = tny_header_dup_from (header);
        
        flags = tny_header_get_flags (header);
 
        hit->msgid = msg_url;
-       hit->subject = g_strdup_or_null (subject);
-       hit->sender = g_strdup_or_null (sender);
+       hit->subject = subject;
+       hit->sender = sender;
        hit->folder = g_strdup_or_null (tny_folder_get_name (folder));
        hit->msize = tny_header_get_message_size (header);
        hit->has_attachment = flags & TNY_HEADER_FLAG_ATTACHMENTS;
@@ -239,8 +243,8 @@ search_mime_part_strcmp (TnyMimePart *part, ModestSearch *search)
        len = (sizeof (buffer) - 1) / 2;
 
        if (strlen (search->body) > len) {
-               g_warning ("Search term bigger then chunk."
-                          "We might not find everything");     
+               g_debug ("Search term bigger then chunk."
+                        "We might not find everything");       
        }
 
        stream = tny_mime_part_get_stream (part);
@@ -342,7 +346,7 @@ search_mime_part_and_child_parts (TnyMimePart *part, ModestSearch *search)
        gboolean found = FALSE;
 
        /* Do not search into attachments */
-       if (modest_tny_mime_part_is_attachment_for_modest (part))
+       if (modest_tny_mime_part_is_attachment_for_modest (part) && !TNY_IS_MSG (part))
                return FALSE;
 
        #ifdef MODEST_HAVE_OGS
@@ -377,6 +381,18 @@ search_mime_part_and_child_parts (TnyMimePart *part, ModestSearch *search)
        return found;
 }
 
+static void
+search_next_folder (SearchHelper *helper) 
+{
+       TnyIterator *iter = tny_list_create_iterator (helper->all_folders);
+       TnyFolder *first = TNY_FOLDER (tny_iterator_get_current (iter));
+       
+       _search_folder (first, helper);
+
+       g_object_unref (first);
+       g_object_unref (iter);
+}
+
 static void 
 modest_search_folder_get_headers_cb (TnyFolder *folder, 
                                     gboolean cancelled, 
@@ -397,14 +413,18 @@ modest_search_folder_get_headers_cb (TnyFolder *folder,
 
        while (!tny_iterator_is_done (iter)) {
 
-               TnyHeader *cur = (TnyHeader *) tny_iterator_get_current (iter);
-               const time_t t = tny_header_get_date_sent (cur);
-               gboolean found = FALSE;
-               
+               TnyHeader *cur;
+               time_t t;
+               gboolean found;
+
+               cur = (TnyHeader *) tny_iterator_get_current (iter);
+               t = tny_header_get_date_sent (cur);
+               found = FALSE;
+
                /* Ignore deleted (not yet expunged) emails: */
                if (tny_header_get_flags(cur) & TNY_HEADER_FLAG_DELETED)
                        goto go_next;
-                       
+
                if (helper->search->flags & MODEST_SEARCH_BEFORE)
                        if (!(t <= helper->search->end_date))
                                goto go_next;
@@ -418,15 +438,16 @@ modest_search_folder_get_headers_cb (TnyFolder *folder,
                                goto go_next;
 
                if (helper->search->flags & MODEST_SEARCH_SUBJECT) {
-                       const char *str = tny_header_get_subject (cur);
+                       char *str = tny_header_dup_subject (cur);
 
                        if ((found = search_string (helper->search->subject, str, helper->search))) {
                            helper->msg_hits = add_hit (helper->msg_hits, cur, folder);
                        }
+                       g_free (str);
                }
                
                if (!found && helper->search->flags & MODEST_SEARCH_SENDER) {
-                       char *str = g_strdup (tny_header_get_from (cur));
+                       char *str = tny_header_dup_from (cur);
 
                        if ((found = search_string (helper->search->from, (const gchar *) str, helper->search))) {
                                helper->msg_hits = add_hit (helper->msg_hits, cur, folder);
@@ -435,11 +456,12 @@ modest_search_folder_get_headers_cb (TnyFolder *folder,
                }
                
                if (!found && helper->search->flags & MODEST_SEARCH_RECIPIENT) {
-                       const char *str = tny_header_get_to (cur);
+                       char *str = tny_header_dup_to (cur);
 
                        if ((found = search_string (helper->search->recipient, str, helper->search))) {
                                helper->msg_hits = add_hit (helper->msg_hits, cur, folder);
                        }
+                       g_free (str);
                }
        
                if (!found && helper->search->flags & MODEST_SEARCH_BODY) {
@@ -463,7 +485,10 @@ modest_search_folder_get_headers_cb (TnyFolder *folder,
                                        g_object_unref (msg);
                                }
                        } else {        
-                               g_debug ("Searching in %s\n", tny_header_get_subject (cur));
+                               gchar *str;
+                               str = tny_header_dup_subject (cur);
+                               g_debug ("Searching in %s\n", str);
+                               g_free (str);
                        
                                found = search_mime_part_and_child_parts (TNY_MIME_PART (msg),
                                                                          helper->search);
@@ -487,8 +512,18 @@ modest_search_folder_get_headers_cb (TnyFolder *folder,
                g_object_unref (headers);
 
        /* Check search finished */
-       helper->folder_count++;
-       check_search_finished (helper);
+       tny_list_remove (helper->all_folders, G_OBJECT (folder));
+       if (tny_list_get_length (helper->all_folders) == 0) {
+               /* callback */
+               helper->callback (helper->msg_hits, helper->user_data);
+               
+               /* free helper */
+               g_object_unref (helper->all_folders);
+               g_list_free (helper->msg_hits);
+               g_slice_free (SearchHelper, helper);
+       } else {
+               search_next_folder (helper);
+       }
 }
 
 static void
@@ -564,25 +599,48 @@ modest_search_account_get_folders_cb (TnyFolderStore *self,
                goto end;
        }
 
+       /* IMPORTANT: We need to get the headers of the folders one by
+          one, because otherwise the get_headers_async calls are
+          often canceled. That's why we firstly retrieve all folders,
+          and then we search inside them one by one. sergio */
        iter = tny_list_create_iterator (folders);
        while (!tny_iterator_is_done (iter)) {
                TnyFolder *folder = NULL;
 
                /* Search into folder */
                folder = TNY_FOLDER (tny_iterator_get_current (iter));  
-               helper->folder_total++;
-               _search_folder (folder, (SearchHelper *) user_data);
-               g_object_unref (folder);
+               tny_list_append (helper->all_folders, G_OBJECT (folder));
+
+               /* Search into children. Could be a merge folder */
+               if (TNY_IS_FOLDER_STORE (folder)) {
+                       TnyList *children = tny_simple_list_new ();
+                       helper->pending_calls++;
+                       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (folder), children, NULL, 
+                                                           FALSE, modest_search_account_get_folders_cb, 
+                                                           NULL, helper);
+               }
 
+               g_object_unref (folder);
                tny_iterator_next (iter);
        }
        g_object_unref (iter);
  end:
+       /* Remove the "account" reference */
+       helper->pending_calls--;
+
        if (folders)
                g_object_unref (folders);
 
-       /* Check search finished */
-       check_search_finished (helper);
+       /* If there are not more folders, begin to search from the first one */
+       if (helper->pending_calls == 0) {
+               TnyIterator *iter = tny_list_create_iterator (helper->all_folders);
+               TnyFolder *first = TNY_FOLDER (tny_iterator_get_current (iter));
+
+               _search_folder (first, helper);
+
+               g_object_unref (first);
+               g_object_unref (iter);
+       }
 }
 
 static void
@@ -593,9 +651,14 @@ _search_account (TnyAccount *account,
 
        g_debug ("%s: Searching account %s", __FUNCTION__, tny_account_get_name (account));
 
+       /* Add a "reference" to the folder total. This allows the code
+          not to finalize the helper if an account is fully refreshed
+          before we get the folders of the others */
+       helper->pending_calls++;
+
        /* Get folders */
        tny_folder_store_get_folders_async (TNY_FOLDER_STORE (account), folders, NULL, 
-                                           modest_search_account_get_folders_cb, 
+                                           FALSE, modest_search_account_get_folders_cb, 
                                            NULL, helper);
 }
 
@@ -659,12 +722,12 @@ create_helper (ModestSearchCallback callback,
        SearchHelper *helper;
 
        helper = g_slice_new0 (SearchHelper);
-       helper->folder_count = 0;
-       helper->folder_total = 0;
+       helper->pending_calls = 0;
        helper->search = search;
        helper->callback = callback;
        helper->user_data = user_data;
        helper->msg_hits = NULL;
+       helper->all_folders = tny_simple_list_new ();
 
        return helper;
 }
@@ -690,17 +753,3 @@ modest_search_free (ModestSearch *search)
                ogs_text_searcher_free (search->text_searcher); 
 #endif
 }
-
-static void
-check_search_finished (SearchHelper *helper)
-{
-       /* If there are no more folders to check the account search has finished */
-       if (helper->folder_count == helper->folder_total) {
-               /* callback */
-               helper->callback (helper->msg_hits, helper->user_data);
-               
-               /* free helper */
-               g_list_free (helper->msg_hits);
-               g_slice_free (SearchHelper, helper);
-       }
-}