* maintain the osso_context_t ptr in modest_maemo_utils,
[modest] / src / maemo / modest-platform.c
index c1143f4..aa0ef8d 100644 (file)
 #include <modest-hildon-includes.h>
 #include <modest-maemo-utils.h>
 #include <dbus_api/modest-dbus-callbacks.h>
-#include <libosso-abook/osso-abook.h>
 #include <maemo/modest-osso-autosave-callbacks.h>
 #include <libosso.h>
-#include <alarmd/alarm_event.h> /* For alarm_event_add(), etc. */
 #include <tny-maemo-conic-device.h>
 #include <tny-simple-list.h>
 #include <tny-folder.h>
 #include <string.h>
 #include <libgnomevfs/gnome-vfs-mime-utils.h>
 
+#ifdef MODEST_HAVE_ABOOK
+#include <libosso-abook/osso-abook.h>
+#endif /*MODEST_HAVE_ABOOK*/
 
-#define HILDON_OSSO_URI_ACTION "uri-action"
-#define URI_ACTION_COPY "copy:"
+#ifdef MODEST_HAVE_LIBALARM
+#include <alarmd/alarm_event.h> /* For alarm_event_add(), etc. */
+#endif /*MODEST_HAVE_LIBALARM*/
 
-/* The maximun number of notifications that could be shown in the
-   desktop. It's specified by the specs and limited by the screen
-   size */
-#define MAX_NOTIFICATIONS 6
 
-static osso_context_t *osso_context = NULL;
+#define HILDON_OSSO_URI_ACTION "uri-action"
+#define URI_ACTION_COPY "copy:"
 
 static void    
 on_modest_conf_update_interval_changed (ModestConf* self, 
@@ -73,6 +72,8 @@ on_modest_conf_update_interval_changed (ModestConf* self,
                                        ModestConfNotificationId id, 
                                        gpointer user_data)
 {
+       g_return_if_fail (key);
+       
        if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
                const guint update_interval_minutes = 
                        modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
@@ -101,31 +102,32 @@ check_required_files (void)
 }
 
 
-
+/* the gpointer here is the osso_context. */
 gboolean
 modest_platform_init (int argc, char *argv[])
 {
+       osso_context_t *osso_context;
+       
        osso_hw_state_t hw_state = { 0 };
        DBusConnection *con;    
-
+       GSList *acc_names;
+       
        if (!check_required_files ()) {
                g_printerr ("modest: missing required files\n");
                return FALSE;
        }
-
        
-       osso_context =
-               osso_initialize(PACKAGE,PACKAGE_VERSION,
-                               FALSE, NULL);   
+       osso_context =  osso_initialize(PACKAGE,PACKAGE_VERSION,
+                                       FALSE, NULL);   
        if (!osso_context) {
                g_printerr ("modest: failed to acquire osso context\n");
                return FALSE;
        }
+       modest_maemo_utils_set_osso_context (osso_context);
 
        if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
                g_printerr ("modest: could not get dbus connection\n");
                return FALSE;
-
        }
 
        /* Add a D-Bus handler to be used when the main osso-rpc 
@@ -150,20 +152,9 @@ modest_platform_init (int argc, char *argv[])
                                modest_dbus_req_handler, NULL /* user_data */);
        if (result != OSSO_OK) {
                        g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
-                       return FALSE;
+               return FALSE;
        }
 
-       /* Add handler for Exit D-BUS messages.
-        * Not used because osso_application_set_exit_cb() is deprecated and obsolete:
-       result = osso_application_set_exit_cb(osso_context,
-                                          modest_dbus_exit_event_handler,
-                                          (gpointer) NULL);
-       if (result != OSSO_OK) {
-               g_print("Error setting exit callback (%d)\n", result);
-               return OSSO_ERROR;
-       }
-       */
-
        /* Register hardware event dbus callback: */
        hw_state.shutdown_ind = TRUE;
        osso_hw_set_event_cb(osso_context, NULL,/*&hw_state*/ modest_osso_cb_hw_state_handler, NULL);
@@ -190,20 +181,43 @@ modest_platform_init (int argc, char *argv[])
                          "key_changed",
                          G_CALLBACK (on_modest_conf_update_interval_changed), 
                          NULL);
-                         
-       /* Get the initial update interval from gconf: */
-       on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
-                                              MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
 
+       /* only force the setting of the default interval, if there are actually
+        * any accounts */
+       acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
+       if (acc_names) {
+               /* Get the initial update interval from gconf: */
+               on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
+                                                      MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
+               modest_account_mgr_free_account_names (acc_names);
+       }
+
+       
+#ifdef MODEST_HAVE_ABOOK
        /* initialize the addressbook */
        if (!osso_abook_init (&argc, &argv, osso_context)) {
                g_printerr ("modest: failed to initialized addressbook\n");
                return FALSE;
        }
-               
+#endif /*MODEST_HAVE_ABOOK*/
+
        return TRUE;
 }
 
+gboolean
+modest_platform_uninit (void)
+{
+       osso_context_t *osso_context =
+               modest_maemo_utils_get_osso_context ();
+       if (osso_context)
+               osso_deinitialize (osso_context);
+
+       return TRUE;
+}
+
+
+
+
 TnyDevice*
 modest_platform_get_new_device (void)
 {
@@ -293,7 +307,7 @@ modest_platform_activate_file (const gchar *path, const gchar *mime_type)
        gchar *uri_path = NULL;
 
        uri_path = g_strconcat ("file://", path, NULL); 
-       con = osso_get_dbus_connection (osso_context);
+       con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
        
        if (mime_type)
                result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
@@ -554,8 +568,9 @@ launch_sort_headers_dialog (GtkWindow *parent_window,
                header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
                                                                                      MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
        }
-       if (!header_view) return;
-
+       if (!header_view)
+               return;
+       
        /* Add sorting keys */
        cols = modest_header_view_get_columns (header_view);
        if (cols == NULL) return;
@@ -603,10 +618,11 @@ launch_sort_headers_dialog (GtkWindow *parent_window,
 
        sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
        sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
-       sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
+       sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY_MASK;
        priority_sort_id = sort_key;
-
-       sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
+       
+       sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model
+                                     (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
        /* Launch dialogs */
        if (!gtk_tree_sortable_get_sort_column_id (sortable,
                                                   &current_sort_colid, &current_sort_type)) {
@@ -617,7 +633,7 @@ launch_sort_headers_dialog (GtkWindow *parent_window,
                if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
                        gpointer flags_sort_type_pointer;
                        flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
-                       if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
+                       if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY_MASK)
                                hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
                        else
                                hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
@@ -925,44 +941,65 @@ modest_platform_run_information_dialog (GtkWindow *parent_window,
 
 
 
-typedef struct _UtilIdleData {
+typedef struct _ConnectAndWaitData {
        GMutex *mutex;
        GMainLoop *wait_loop;
        gboolean has_callback;
        gulong handler;
-} UtilIdleData;
+} ConnectAndWaitData;
+
+
+static void
+quit_wait_loop (TnyAccount *account,
+               ConnectAndWaitData *data) 
+{
+       /* Set the has_callback to TRUE (means that the callback was
+          executed and wake up every code waiting for cond to be
+          TRUE */
+       g_mutex_lock (data->mutex);
+       data->has_callback = TRUE;
+       if (data->wait_loop)
+               g_main_loop_quit (data->wait_loop);
+       g_mutex_unlock (data->mutex);
+}
 
 static void
 on_connection_status_changed (TnyAccount *account, 
                              TnyConnectionStatus status,
                              gpointer user_data)
 {
-       UtilIdleData *data = (UtilIdleData *) user_data;
        TnyConnectionStatus conn_status;
+       ConnectAndWaitData *data;
                        
+       /* Ignore if reconnecting or disconnected */
        conn_status = tny_account_get_connection_status (account);
        if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
            conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
                return;
 
        /* Remove the handler */
+       data = (ConnectAndWaitData *) user_data;
        g_signal_handler_disconnect (account, data->handler);
 
-       /* Set the has_callback to TRUE (means that the callback was
-          executed and wake up every code waiting for cond to be
-          TRUE */
-       g_mutex_lock (data->mutex);
-       data->has_callback = TRUE;
-       if (data->wait_loop)
-               g_main_loop_quit (data->wait_loop);
-       g_mutex_unlock (data->mutex);
+       /* Quit from wait loop */
+       quit_wait_loop (account, (ConnectAndWaitData *) user_data);
+}
+
+static void
+on_tny_camel_account_set_online_cb (TnyCamelAccount *account, 
+                                   gboolean canceled, 
+                                   GError *err, 
+                                   gpointer user_data)
+{
+       /* Quit from wait loop */
+       quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
 }
 
 gboolean 
 modest_platform_connect_and_wait (GtkWindow *parent_window, 
                                  TnyAccount *account)
 {
-       UtilIdleData *data = NULL;
+       ConnectAndWaitData *data = NULL;
        gboolean device_online;
        TnyDevice *device;
        TnyConnectionStatus conn_status;
@@ -983,12 +1020,13 @@ modest_platform_connect_and_wait (GtkWindow *parent_window,
        if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
                return TRUE;
 
+       /* Create the helper */
+       data = g_slice_new0 (ConnectAndWaitData);
+       data->mutex = g_mutex_new ();
+       data->has_callback = FALSE;
+
        /* Connect the device */
        if (!device_online) {
-               data = g_slice_new0 (UtilIdleData);
-               data->mutex = g_mutex_new ();
-               data->has_callback = FALSE;
-
                /* Track account connection status changes */
                data->handler = g_signal_connect (account, "connection-status-changed",                                     
                                                  G_CALLBACK (on_connection_status_changed),
@@ -999,6 +1037,10 @@ modest_platform_connect_and_wait (GtkWindow *parent_window,
                /* If the device connection failed then exit */
                if (!device_online && data->handler)
                        goto frees;
+       } else {
+               /* Force a reconnection of the account */
+               tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE, 
+                                             on_tny_camel_account_set_online_cb, data);
        }
 
        /* Wait until the callback is executed */
@@ -1019,7 +1061,7 @@ modest_platform_connect_and_wait (GtkWindow *parent_window,
                        g_signal_handler_disconnect (account, data->handler);
                g_mutex_free (data->mutex);
                g_main_loop_unref (data->wait_loop);
-               g_slice_free (UtilIdleData, data);
+               g_slice_free (ConnectAndWaitData, data);
        }
 
        conn_status = tny_account_get_connection_status (account);
@@ -1105,7 +1147,11 @@ modest_platform_run_sort_dialog (GtkWindow *parent_window,
        dialog = hildon_sort_dialog_new (parent_window);
        modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
                                     GTK_WINDOW (dialog));
-       
+
+       hildon_help_dialog_help_enable (GTK_DIALOG(dialog),
+                                       "applications_email_sort",
+                                       modest_maemo_utils_get_osso_context());
+
        /* Fill sort keys */
        switch (type) {
        case MODEST_SORT_HEADERS:
@@ -1122,6 +1168,8 @@ modest_platform_run_sort_dialog (GtkWindow *parent_window,
 gboolean 
 modest_platform_set_update_interval (guint minutes)
 {
+#ifdef MODEST_HAVE_LIBALARM
+       
        ModestConf *conf = modest_runtime_get_conf ();
        if (!conf)
                return FALSE;
@@ -1200,7 +1248,7 @@ modest_platform_set_update_interval (guint minutes)
            
            return FALSE;
        }
-       
+#endif /* MODEST_HAVE_LIBALARM */      
        return TRUE;
 }
 
@@ -1219,12 +1267,14 @@ modest_platform_on_new_headers_received (TnyList *header_list)
 
        iter = tny_list_create_iterator (header_list);
        while (!tny_iterator_is_done (iter)) {
-               gchar *url = NULL, *display_address = NULL, *display_date = NULL, *summary = NULL;
+               gchar *url = NULL, *display_address = NULL,  *summary = NULL;
+               const gchar *display_date;
                TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
                TnyFolder *folder = tny_header_get_folder (header);
                gboolean first_notification = TRUE;
                gint notif_id;
-       
+
+               /* constant string, don't free */
                display_date = modest_text_utils_get_display_date (tny_header_get_date_received (header));
 
                display_address = g_strdup(tny_header_get_from (header));
@@ -1235,7 +1285,6 @@ modest_platform_on_new_headers_received (TnyList *header_list)
                                                        tny_header_get_subject (header),
                                                        "qgn_list_messagin",
                                                        "email.arrive");
-               
                /* Create the message URL */
                url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder), 
                                       tny_header_get_uid (header));
@@ -1281,7 +1330,6 @@ modest_platform_on_new_headers_received (TnyList *header_list)
                   not to store the list in gconf */
        
                /* Free & carry on */
-               g_free (display_date);
                g_free (display_address);
                g_free (summary);
                g_free (url);
@@ -1353,12 +1401,11 @@ modest_platform_show_help (GtkWindow *parent_window,
                           const gchar *help_id)
 {
        osso_return_t result;
-
        g_return_if_fail (help_id);
-       g_return_if_fail (osso_context);
-
-       result = hildon_help_show (osso_context, help_id, HILDON_HELP_SHOW_DIALOG);
 
+       result = hildon_help_show (modest_maemo_utils_get_osso_context(),
+                                  help_id, HILDON_HELP_SHOW_DIALOG);
+       
        if (result != OSSO_OK) {
                gchar *error_msg;
                error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id); 
@@ -1369,28 +1416,14 @@ modest_platform_show_help (GtkWindow *parent_window,
        }
 }
 
-void
-modest_platform_set_dialog_help (GtkDialog *parent_window, 
-                                const gchar *help_id)
-{
-       gboolean result;
-       g_return_if_fail (help_id);
-       g_return_if_fail (osso_context);
-       g_return_if_fail (GTK_IS_DIALOG (parent_window));
-
-       result = hildon_help_dialog_help_enable (parent_window, help_id, osso_context);
-
-       if (!result)
-               g_warning ("Help topic %s not found", help_id);
-
-}
-
 void 
 modest_platform_show_search_messages (GtkWindow *parent_window)
 {
        osso_return_t result = OSSO_ERROR;
        
-       result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
+       result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
+                                            "osso_global_search",
+                                            "search_email", NULL, DBUS_TYPE_INVALID);
 
        if (result != OSSO_OK) {
                g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
@@ -1402,7 +1435,9 @@ modest_platform_show_addressbook (GtkWindow *parent_window)
 {
        osso_return_t result = OSSO_ERROR;
        
-       result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
+       result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
+                                            "osso_addressbook",
+                                            "top_application", NULL, DBUS_TYPE_INVALID);
 
        if (result != OSSO_OK) {
                g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
@@ -1464,18 +1499,11 @@ on_timeout_check_account_is_online(gpointer user_data)
 {
        printf ("DEBUG: %s:\n", __FUNCTION__);
        CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
+
+       g_return_val_if_fail (data && data->account, FALSE);
        
-       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));       
-       }
+       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 && 
@@ -1595,19 +1623,29 @@ on_cert_dialog_response (GtkDialog *dialog, gint response_id,  const gchar* cert
 
 
 gboolean
-modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
+modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
                                                     const gchar *certificate)
 {
        GtkWidget *note;
        gint response;
-       GtkWindow *main_win =
-               (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
+       ModestWindow *main_win;
+       
+       if (!modest_window_mgr_main_window_exists (modest_runtime_get_window_mgr())) {
+               g_warning ("%s: don't show dialogs if there's no main window; assuming 'Cancel'",
+                          __FUNCTION__);
+               return FALSE;
+       }
 
+       /* don't create it */
+       main_win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
+       g_return_val_if_fail (main_win, FALSE); /* should not happen */
+       
+       
        gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
                                           server_name);
        
        note = hildon_note_new_confirmation_add_buttons  (
-               main_win,
+               GTK_WINDOW(main_win),
                question,
                _("mcen_bd_dialog_ok"),     GTK_RESPONSE_OK,
                _("mcen_bd_view"),          GTK_RESPONSE_HELP,   /* abusing this... */
@@ -1625,7 +1663,7 @@ modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
        on_destroy_dialog (GTK_DIALOG(note));
        g_free (question);
        
-       return response;
+       return response == GTK_RESPONSE_OK;
 }
        
 
@@ -1634,8 +1672,16 @@ gboolean
 modest_platform_run_alert_dialog (const gchar* prompt, 
                                  gboolean is_question)
 {      
-       ModestWindow *main_window = 
-               modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
+       ModestWindow *main_win; 
+
+       if (!modest_window_mgr_main_window_exists (modest_runtime_get_window_mgr())) {
+               g_warning ("%s:\n'%s'\ndon't show dialogs if there's no main window;"
+                          " assuming 'Cancel' for questions, 'Ok' otherwise", prompt, __FUNCTION__);
+               return is_question ? FALSE : TRUE;
+       }
+
+       main_win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (), FALSE);
+       g_return_val_if_fail (main_win, FALSE); /* should not happen */
        
        gboolean retval = TRUE;
        if (is_question) {
@@ -1643,7 +1689,7 @@ modest_platform_run_alert_dialog (const gchar* prompt,
                 * when it is a question.
                 * Obviously, we need tinymail to use more specific error codes instead,
                 * so we know what buttons to show. */
-               GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window), 
+               GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_win), 
                                                                              prompt));
                modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
                                             GTK_WINDOW (dialog));
@@ -1654,7 +1700,7 @@ modest_platform_run_alert_dialog (const gchar* prompt,
                on_destroy_dialog (GTK_DIALOG(dialog));         
        } else {
                /* Just show the error text and use the default response: */
-               modest_platform_run_information_dialog (GTK_WINDOW (main_window), 
+               modest_platform_run_information_dialog (GTK_WINDOW (main_win), 
                                                        prompt);
        }
        return retval;