X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-search.c;h=841fa52ba97a6c9436358d3e3573fbd7c010cf0b;hp=3c0effcdcc980b9ac05373e742fb5d3a8b0f66b9;hb=6f7aa1b5e15f3024db75ccfe3138f520c607dc5d;hpb=3202e152f26d1cd47e4e2d1c03a71ffe308b06ee diff --git a/src/modest-search.c b/src/modest-search.c index 3c0effc..841fa52 100644 --- a/src/modest-search.c +++ b/src/modest-search.c @@ -58,19 +58,20 @@ 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); + uid = tny_header_dup_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)); + 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; @@ -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, @@ -418,15 +434,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 +452,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 +481,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 +508,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 +595,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 +647,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 +718,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 +749,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); - } -}