* src/modest-platform.h
[modest] / src / maemo / modest-platform.c
index cf31c38..cb07e6c 100644 (file)
@@ -51,6 +51,7 @@
 #include <gtk/gtkmenuitem.h>
 #include <gtk/gtkmain.h>
 #include <modest-text-utils.h>
+#include "modest-tny-folder.h"
 #include <string.h>
 
 
@@ -760,8 +761,46 @@ launch_sort_headers_dialog (GtkWindow *parent_window,
        g_list_free(cols);      
 }
 
+
+
+static void
+on_response (GtkDialog *dialog,
+            gint response,
+            gpointer user_data)
+{
+       GList *child_vbox, *child_hbox;
+       GtkWidget *hbox, *entry;
+       TnyFolderStore *parent;
+
+       if (response != GTK_RESPONSE_ACCEPT)
+               return;
+
+       /* Get entry */
+       child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
+       hbox = child_vbox->data;
+       child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
+       entry = child_hbox->next->data;
+
+       parent = TNY_FOLDER_STORE (user_data);
+
+       /* Look for another folder with the same name */
+       if (modest_tny_folder_has_subfolder_with_name (parent, 
+                                                      gtk_entry_get_text (GTK_ENTRY (entry)))) {
+               /* Show an error */
+               hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)), 
+                                               NULL, _CS("ckdg_ib_folder_already_exists"));
+               /* Select the text */
+               gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
+               gtk_widget_grab_focus (entry);
+               /* Do not close the dialog */
+               g_signal_stop_emission_by_name (dialog, "response");
+       }
+}
+
+
 static gint
 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
+                                       TnyFolderStore *parent,
                                        const gchar *dialog_title,
                                        const gchar *label_text,
                                        const gchar *suggested_name,
@@ -776,9 +815,9 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
        dialog = gtk_dialog_new_with_buttons (dialog_title,
                                              parent_window,
                                              GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                             GTK_STOCK_OK,
+                                             _("mcen_bd_dialog_ok"),
                                              GTK_RESPONSE_ACCEPT,
-                                             GTK_STOCK_CANCEL,
+                                             _("mcen_bd_dialog_cancel"),
                                              GTK_RESPONSE_REJECT,
                                              NULL);
 
@@ -797,6 +836,13 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
                gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
        gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
 
+       /* Connect to the response method to avoid closing the dialog
+          when an invalid name is selected*/
+       g_signal_connect (dialog,
+                         "response",
+                         G_CALLBACK (on_response),
+                         parent);
+
        /* Track entry changes */
        g_signal_connect (entry,
                          "insert-text",
@@ -819,6 +865,9 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
        gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
        
        gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
+
+
+
        result = gtk_dialog_run (GTK_DIALOG(dialog));
        if (result == GTK_RESPONSE_ACCEPT)
                *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
@@ -846,11 +895,8 @@ modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
                unsigned int i;
                gchar num_str[3];
 
-               for(i = 0; i < 100; ++ i)
-               {
-                       TnyList *list = tny_simple_list_new ();
-                       TnyFolderStoreQuery *query = tny_folder_store_query_new ();
-                       guint length;
+               for(i = 0; i < 100; ++ i) {
+                       gboolean exists = FALSE;
 
                        sprintf(num_str, "%.2u", i);
 
@@ -860,16 +906,10 @@ modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
                                real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
                                                                       num_str);
 
-                       tny_folder_store_query_add_item (query, real_suggested_name,
-                                                        TNY_FOLDER_STORE_QUERY_OPTION_MATCH_ON_NAME);
-
-                       tny_folder_store_get_folders (parent_folder, list, query, NULL);
-
-                       length = tny_list_get_length (list);
-                       g_object_unref (query);
-                       g_object_unref (list);
+                       exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
+                                                                           real_suggested_name);
 
-                       if (length == 0)
+                       if (!exists)
                                break;
 
                        g_free (real_suggested_name);
@@ -878,13 +918,12 @@ modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
                /* Didn't find a free number */
                if (i == 100)
                        real_suggested_name = g_strdup (default_name);
-       }
-       else
-       {
+       } else {
                real_suggested_name = suggested_name;
        }
 
        result = modest_platform_run_folder_name_dialog (parent_window, 
+                                                        parent_folder,
                                                         _("mcen_ti_new_folder"),
                                                         _("mcen_fi_new_folder_name"),
                                                         real_suggested_name,
@@ -897,13 +936,16 @@ modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
 
 gint
 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
-                                         TnyFolderStore *parent_folder,
-                                         const gchar *suggested_name,
-                                         gchar **folder_name)
+                                          TnyFolderStore *parent_folder,
+                                          const gchar *suggested_name,
+                                          gchar **folder_name)
 {
+       g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
+
        return modest_platform_run_folder_name_dialog (parent_window, 
-                                                      _("New folder name"),
-                                                      _("Enter new folder name:"),
+                                                      parent_folder,
+                                                      _HL("ckdg_ti_rename_folder"),
+                                                      _HL("ckdg_fi_rename_name"),
                                                       suggested_name,
                                                       folder_name);
 }
@@ -1107,10 +1149,11 @@ gboolean modest_platform_connect_and_wait (GtkWindow *parent_window, TnyAccount
 
        g_slice_free (UtilIdleData, data);
 
-       gboolean result = tny_device_is_online (device);
+       const gboolean result = tny_device_is_online (device);
 
-       if (result)
+       if (result) {
                set_account_to_online (account);
+       }
 
        return result;
 }
@@ -1149,6 +1192,38 @@ gboolean modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *par
        return result;
 }
 
+gboolean modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
+{
+        TnyAccount *account = NULL;
+        gboolean result = TRUE;
+
+        g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
+
+        if (TNY_IS_FOLDER (folder_store)) {
+                /* Get the folder's parent account: */
+                account = tny_folder_get_account(TNY_FOLDER(folder_store));
+        } else if (TNY_IS_ACCOUNT (folder_store)) {
+                account = TNY_ACCOUNT(folder_store);
+                g_object_ref(account);
+        }
+
+        if (account != NULL) {
+                if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
+                        if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
+                            !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
+                                /* This must be a maildir account, which does
+                                 * not require a connection: */
+                                result = FALSE;
+                        }
+                }
+                g_object_unref (account);
+        } else {
+                result = FALSE;
+        }
+
+        return result;
+}
+
 void
 modest_platform_run_sort_dialog (GtkWindow *parent_window,
                                 ModestSortDialogType type)
@@ -1268,17 +1343,26 @@ modest_platform_on_new_msg (void)
 #ifdef MODEST_HAVE_HILDON_NOTIFY
        HildonNotification *not;
 
-       /* Create a new notification. FIXME put the right values, need
-          some more specs */
+       /* Create a new notification. TODO: per-mail data needed */
        not = hildon_notification_new ("TODO: (new email) Summary",
                                       "TODO: (new email) Description",
-                                      "qgn_contact_group_chat_invitation",
-                                      "system.note.dialog");
-
-       /* Play sound SR-SND-18. TODO: play the right file */
-       /* TODO: Where is this declared? hildon_notification_set_sound (not, "/usr/share/sounds/ui-new_email.wav"); */
+                                      "qgn_list_messagin_mail_unread",
+                                      NULL);
+
+       hildon_notification_add_dbus_action(not,
+                                           "default",
+                                           "Cancel",
+                                           MODEST_DBUS_SERVICE,
+                                           MODEST_DBUS_OBJECT,
+                                           MODEST_DBUS_IFACE,
+                                           MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX,
+                                           -1);
+       
+       /* Play sound SR-SND-18 */
+       hildon_notification_set_sound (not, "/usr/share/sounds/ui-new_email.wav");
 
        /* Set the led pattern */
+        notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (not), "dialog-type", 4);
        notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (not), "led-pattern", 3);
 
        /* Notify. We need to do this in an idle because this function
@@ -1380,3 +1464,127 @@ modest_platform_animation_banner (GtkWidget *parent,
 
        return inf_note;
 }
+
+typedef struct
+{
+       GMainLoop* loop;
+       TnyAccount *account;
+       gboolean is_online;
+       gint count_tries;
+} CheckAccountIdleData;
+
+#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__);
+       CheckAccountIdleData *data = (CheckAccountIdleData*)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.
+ */
+gboolean
+modest_platform_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: */
+       CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
+       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 (CheckAccountIdleData, data);
+       
+       return data->is_online; 
+}
+