* it makes sense not to allow '&' and '#' in new folder names,
[modest] / src / modest-search.c
index 5f3cb45..761598c 100644 (file)
 #include <tny-camel-imap-store-account.h>
 #include <tny-camel-pop-store-account.h>
 
-#include <libmodest-dbus-client/libmodest-dbus-client.h>
-
 #include "modest-text-utils.h"
 #include "modest-account-mgr.h"
 #include "modest-tny-account-store.h"
 #include "modest-tny-account.h"
+#include "modest-tny-folder.h"
 #include "modest-search.h"
 #include "modest-runtime.h"
+#include "modest-platform.h"
 
 static gchar *
 g_strdup_or_null (const gchar *str)
@@ -67,133 +67,10 @@ g_strdup_or_null (const gchar *str)
        return string;
 }
 
-typedef struct
-{
-       GMainLoop* loop;
-       TnyAccount *account;
-       gboolean is_online;
-       gint count_tries;
-} UtilIdleData;
-
-#define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
-
-static gboolean 
-on_timeout_check_account_is_online(gpointer user_data)
-{
-       printf ("DEBUG: %s:\n", __FUNCTION__);
-       UtilIdleData *data = (UtilIdleData*)user_data;
-       
-       if (!data) {
-               g_warning ("%s: data is NULL.\n", __FUNCTION__);
-       }
-       
-       if (!(data->account)) {
-               g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
-       }
-       
-       if (data && data->account) {
-               printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));       
-       }
-       
-       gboolean stop_trying = FALSE;
-       if (data && data->account && 
-               /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
-                * after which the account is likely to be usable, or never likely to be usable soon: */
-               (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
-       {
-               data->is_online = TRUE;
-               
-               stop_trying = TRUE;
-       }
-       else {
-               /* Give up if we have tried too many times: */
-               if (data->count_tries >= NUMBER_OF_TRIES)
-               {
-                       stop_trying = TRUE;
-               }
-               else {
-                       /* Wait for another timeout: */
-                       ++(data->count_tries);
-               }
-       }
-       
-       if (stop_trying) {
-               /* Allow the function that requested this idle callback to continue: */
-               if (data->loop)
-                       g_main_loop_quit (data->loop);
-                       
-               if (data->account)
-                       g_object_unref (data->account);
-               
-               return FALSE; /* Don't call this again. */
-       } else {
-               return TRUE; /* Call this timeout callback again. */
-       }
-}
-
-/* Return TRUE immediately if the account is already online,
- * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as 
- * soon as the account is online, or FALSE if the account does 
- * not become online in the NUMBER_OF_TRIES seconds.
- * This is useful when the D-Bus method was run immediately after 
- * the application was started (when using D-Bus activation), 
- * because the account usually takes a short time to go online.
- * The return value is maybe not very useful.
- */
-static gboolean
-check_and_wait_for_account_is_online(TnyAccount *account)
-{
-       g_return_val_if_fail (account, FALSE);
-       
-       printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
-       
-       if (!tny_device_is_online (modest_runtime_get_device())) {
-               printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
-               return FALSE;
-       }
-       
-       /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
-        * so we avoid wait unnecessarily: */
-       if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) && 
-               !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
-               return TRUE;            
-       }
-               
-       printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (account));
-       
-       /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED, 
-        * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that 
-        * we want to avoid. */
-       if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
-               return TRUE;
-               
-       /* This blocks on the result: */
-       UtilIdleData *data = g_slice_new0 (UtilIdleData);
-       data->is_online = FALSE;
-       data->account = account;
-       g_object_ref (data->account);
-       data->count_tries = 0;
-               
-       GMainContext *context = NULL; /* g_main_context_new (); */
-       data->loop = g_main_loop_new (context, FALSE /* not running */);
-
-       g_timeout_add (1000, &on_timeout_check_account_is_online, data);
-
-       /* This main loop will run until the idle handler has stopped it: */
-       g_main_loop_run (data->loop);
-
-       g_main_loop_unref (data->loop);
-       /* g_main_context_unref (context); */
-
-       g_slice_free (UtilIdleData, data);
-       
-       return data->is_online; 
-}
-
 static GList*
 add_hit (GList *list, TnyHeader *header, TnyFolder *folder)
 {
-       ModestSearchHit *hit;
+       ModestSearchResultHit *hit;
        TnyHeaderFlags   flags;
        char            *furl;
        char            *msg_url;
@@ -201,7 +78,7 @@ add_hit (GList *list, TnyHeader *header, TnyFolder *folder)
        const char      *subject;
        const char      *sender;
 
-       hit = g_slice_new0 (ModestSearchHit);
+       hit = g_slice_new0 (ModestSearchResultHit);
 
        furl = tny_folder_get_url_string (folder);
        printf ("DEBUG: %s: folder URL=%s\n", __FUNCTION__, furl);
@@ -233,7 +110,7 @@ add_hit (GList *list, TnyHeader *header, TnyFolder *folder)
        hit->msize = tny_header_get_message_size (header);
        hit->has_attachment = flags & TNY_HEADER_FLAG_ATTACHMENTS;
        hit->is_unread = ! (flags & TNY_HEADER_FLAG_SEEN);
-       hit->timestamp = tny_header_get_date_received (header);
+       hit->timestamp = MIN (tny_header_get_date_received (header), tny_header_get_date_sent (header));
        
        return g_list_prepend (list, hit);
 }
@@ -419,7 +296,7 @@ search_mime_part_strcmp (TnyMimePart *part, ModestSearch *search)
                                                        buffer,
                                                        TRUE);
 
-               if (found) {
+               if ((found)||(nread == 0)) {
                        break;
                }
 
@@ -510,8 +387,15 @@ modest_search_folder (TnyFolder *folder, ModestSearch *search)
        /* Check that we should be searching this folder. */
        /* Note that we don't try to search sub-folders. 
         * Maybe we should, but that should be specified. */
-       if (search->folder && strlen (search->folder) && (strcmp (tny_folder_get_id (folder), search->folder) != 0))
-               return NULL;
+       if (search->folder && strlen (search->folder)) {
+               if (!strcmp (search->folder, "outbox")) {
+                       if (modest_tny_folder_guess_folder_type (folder) != TNY_FOLDER_TYPE_OUTBOX) {
+                               return NULL;
+                       }
+               } else if (strcmp (tny_folder_get_id (folder), search->folder) != 0) {
+                       return NULL;
+               }
+       }
        
        GList *retval = NULL;
        TnyIterator *iter = NULL;
@@ -716,7 +600,7 @@ modest_search_all_accounts (ModestSearch *search)
                        /* Give the account time to go online if necessary, 
                         * for instance if this is immediately after startup,
                         * after D-Bus activation: */
-                       check_and_wait_for_account_is_online (account);
+                       modest_platform_check_and_wait_for_account_is_online (account);
                        
                        /* Search: */
                        res = modest_search_account (account, search);