+ modest_account_mgr_free_account_names (account_names);
+
+ g_printerr (str);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply) {
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send (con, reply, &serial);
+ dbus_connection_flush (con);
+ dbus_message_unref (reply);
+ }
+ g_free (str);
+
+ /* Let modest die */
+ g_idle_add (notify_error_in_dbus_callback, NULL);
+
+ return OSSO_OK;
+}
+
+static void
+on_send_receive_performer(gboolean canceled,
+ GError *err,
+ ModestWindow *parent_window,
+ TnyAccount *account,
+ gpointer user_data)
+{
+ SendReceivePerformerData *data = (SendReceivePerformerData *) user_data;
+
+ if (err || canceled || data == NULL) {
+ g_idle_add (notify_error_in_dbus_callback, NULL);
+ if (data) {
+ send_receive_performer_data_free (data);
+ }
+ return;
+ }
+
+ data->mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ data->mail_op);
+ if (data->manual) {
+ g_idle_add (on_idle_send_receive, data);
+ } else {
+ modest_heartbeat_add (on_idle_send_receive, data);
+ }
+}
+
+
+static gint
+on_send_receive(GArray *arguments, gpointer data, osso_rpc_t * retval)
+{
+ TnyDevice *device = modest_runtime_get_device ();
+ SendReceivePerformerData *srp_data;
+
+ srp_data = g_slice_new0 (SendReceivePerformerData);
+ srp_data->account_id = NULL;
+ srp_data->manual = FALSE;
+ srp_data->mail_op = NULL;
+
+ if (!tny_device_is_online (device))
+ modest_platform_connect_and_perform (NULL, FALSE, NULL, on_send_receive_performer, srp_data);
+ else
+ on_send_receive_performer (FALSE, NULL, NULL, NULL, srp_data);
+
+ return OSSO_OK;
+}
+
+static gint
+on_send_receive_full (GArray *arguments, gpointer data, osso_rpc_t * retval)
+{
+ osso_rpc_t val;
+ gchar *account_id;
+ gboolean manual;
+ TnyDevice *device;
+ SendReceivePerformerData *srp_data;
+
+ val = g_array_index (arguments, osso_rpc_t, MODEST_DBUS_SEND_RECEIVE_FULL_ARG_ACCOUNT_ID);
+ account_id = g_strdup (val.value.s);
+ val = g_array_index (arguments, osso_rpc_t, MODEST_DBUS_SEND_RECEIVE_FULL_ARG_MANUAL);
+ manual = val.value.b;
+
+ srp_data = g_slice_new0 (SendReceivePerformerData);
+ srp_data->manual = manual;
+ if (account_id && account_id[0] != '\0') {
+ srp_data->account_id = account_id;
+ } else {
+ srp_data->account_id = NULL;
+ g_free (account_id);
+ }
+ srp_data->mail_op = NULL;
+ device = modest_runtime_get_device ();
+ if (!tny_device_is_online (device))
+ modest_platform_connect_and_perform (NULL, FALSE, NULL, on_send_receive_performer, srp_data);
+ else
+ on_send_receive_performer (FALSE, NULL, NULL, NULL, srp_data);
+
+ return OSSO_OK;
+}
+
+static gboolean
+on_idle_update_folder_counts (gpointer userdata)
+{
+ ModestMailOperation *mail_op;
+ gchar *account_id = (gchar *) userdata;
+
+ mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ mail_op);
+ modest_mail_operation_update_folder_counts (mail_op, account_id);
+ g_object_unref (mail_op);
+ g_free (account_id);
+
+ return FALSE;
+
+}
+
+static gint
+on_update_folder_counts (GArray *arguments, gpointer data, osso_rpc_t * retval)
+{
+ osso_rpc_t val;
+ gchar *account_id;
+
+ val = g_array_index (arguments, osso_rpc_t, MODEST_DBUS_SEND_RECEIVE_FULL_ARG_ACCOUNT_ID);
+ account_id = g_strdup (val.value.s);
+
+ if (account_id != NULL) {
+ g_idle_add (on_idle_update_folder_counts, g_strdup (account_id));
+ }
+
+ g_free (account_id);
+
+ return OSSO_OK;
+}
+
+static gint
+on_open_default_inbox(GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+ g_idle_add(on_idle_top_application, NULL);
+
+ return OSSO_OK;
+}
+
+
+static gboolean
+on_idle_open_account (gpointer user_data)
+{
+ ModestWindow *top;
+ ModestWindowMgr *mgr;
+ gchar *acc_name;
+
+ gdk_threads_enter ();
+
+ acc_name = (gchar *) user_data;
+ mgr = modest_runtime_get_window_mgr ();
+
+ top = modest_window_mgr_get_current_top (mgr);
+ if (!top)
+ top = modest_window_mgr_show_initial_window (mgr);
+
+#ifdef MODEST_TOOLKIT_HILDON2
+ GtkWidget *new_window;
+ ModestProtocolType store_protocol;
+ gboolean mailboxes_protocol;
+
+ store_protocol = modest_account_mgr_get_store_protocol (modest_runtime_get_account_mgr (),
+ acc_name);
+ mailboxes_protocol =
+ modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
+ store_protocol,
+ MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS);
+
+ if (mailboxes_protocol) {
+ new_window = GTK_WIDGET (modest_mailboxes_window_new (acc_name));
+ } else {
+ new_window = GTK_WIDGET (modest_folder_window_new (NULL));
+ modest_folder_window_set_account (MODEST_FOLDER_WINDOW (new_window),
+ acc_name);
+ }
+
+ if (modest_window_mgr_register_window (mgr, MODEST_WINDOW (new_window), NULL)) {
+ gtk_widget_show (new_window);
+ } else {
+ gtk_widget_destroy (new_window);
+ new_window = NULL;
+ }
+#else
+ if (MODEST_IS_MAIN_WINDOW (top)) {
+ gchar *server_name;
+ GtkWidget *folder_view;
+
+ folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top),
+ MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
+ server_name = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
+ acc_name, TNY_ACCOUNT_TYPE_STORE);
+ if (server_name) {
+ modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (folder_view),
+ server_name);
+ g_free (server_name);
+ }
+ }
+#endif
+
+ gdk_threads_leave ();
+ g_free (acc_name);
+ return FALSE;
+}
+
+static gint
+on_open_account (GArray *arguments, gpointer data, osso_rpc_t *retval)
+{
+ osso_rpc_t val;
+ gchar *account_id;
+
+ /* Get the arguments: */
+ val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_OPEN_MESSAGE_ARG_URI);
+ account_id = g_strdup (val.value.s);
+
+ g_idle_add (on_idle_open_account, account_id);
+
+ return OSSO_OK;
+}
+
+#ifdef MODEST_TOOLKIT_HILDON2
+static gboolean
+on_idle_top_application (gpointer user_data)
+{
+ HildonWindowStack *stack;
+ GtkWidget *window;
+
+ /* This is a GDK lock because we are an idle callback and
+ * the code below is or does Gtk+ code */
+
+ gdk_threads_enter (); /* CHECKED */
+
+ stack = hildon_window_stack_get_default ();
+ window = GTK_WIDGET (hildon_window_stack_peek (stack));
+
+ if (window) {
+ gtk_window_present (GTK_WINDOW (window));
+ } else {
+ ModestWindowMgr *mgr;
+
+ mgr = modest_runtime_get_window_mgr ();
+ window = (GtkWidget *) modest_window_mgr_show_initial_window (mgr);
+ }
+
+ gdk_threads_leave (); /* CHECKED */
+
+ return FALSE; /* Do not call this callback again. */
+}
+#else
+static gboolean
+on_idle_top_application (gpointer user_data)
+{
+ ModestWindow *main_win;
+ gboolean new_window = FALSE;
+
+ /* This is a GDK lock because we are an idle callback and
+ * the code below is or does Gtk+ code */
+
+ gdk_threads_enter (); /* CHECKED */
+
+ main_win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
+ FALSE);
+
+ if (!main_win) {
+ main_win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
+ TRUE);
+ new_window = TRUE;
+ }
+
+ if (main_win) {
+ /* If we're showing an already existing window then
+ reselect the INBOX */
+ if (!new_window) {
+ GtkWidget *folder_view;
+ folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_win),
+ MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
+ modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
+ }
+ }
+
+ if (main_win) {
+ gtk_widget_show_all (GTK_WIDGET (main_win));
+ gtk_window_present (GTK_WINDOW (main_win));
+ }
+
+ gdk_threads_leave (); /* CHECKED */
+
+ return FALSE; /* Do not call this callback again. */
+}
+#endif
+
+static gint
+on_top_application(GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+ /* Use g_idle to context-switch into the application's thread: */
+ g_idle_add(on_idle_top_application, NULL);
+
+ return OSSO_OK;
+}
+
+static gboolean
+on_idle_open_edit_accounts_dialog (gpointer user_data)
+{
+ ModestWindow *top;
+ ModestWindowMgr *mgr;
+ gboolean closed;
+
+ /* This is a GDK lock because we are an idle callback and
+ * the code below is or does Gtk+ code */
+
+ gdk_threads_enter (); /* CHECKED */
+
+ mgr = modest_runtime_get_window_mgr ();
+ closed = modest_window_mgr_close_all_but_initial (mgr);
+ top = modest_window_mgr_get_current_top (mgr);
+
+ if (closed) {
+ /* Show edit accounts dialog */
+ modest_ui_actions_on_accounts (NULL, top);
+ } else {
+ gboolean has_accounts;
+
+ has_accounts = modest_account_mgr_has_accounts (modest_runtime_get_account_mgr (),
+ TRUE);
+
+ /* Present the current top window */
+ gdk_threads_leave ();
+ on_idle_top_application (NULL);
+ gdk_threads_enter ();
+
+ /* Show edit accounts dialog if we're launching the
+ program and there is no account (if there is at
+ least one account then on_idle_top_application will
+ show the accounts wizard */
+ if (!top && has_accounts) {
+ top = modest_window_mgr_get_current_top (mgr);
+ modest_ui_actions_on_accounts (NULL, top);
+ }
+ }
+
+ gdk_threads_leave (); /* CHECKED */
+
+ return FALSE; /* Do not call this callback again. */
+}
+
+static gint
+on_open_edit_accounts_dialog (GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+ /* Use g_idle to context-switch into the application's thread: */
+ g_idle_add (on_idle_open_edit_accounts_dialog, NULL);
+
+ return OSSO_OK;
+}
+
+static gboolean
+on_idle_show_memory_low (gpointer user_data)
+{
+ ModestWindow *main_win = NULL;
+
+ gdk_threads_enter ();
+ main_win = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
+ modest_platform_run_information_dialog (GTK_WINDOW (main_win),
+ dgettext("ke-recv","memr_ib_operation_disabled"),
+ TRUE);
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+static gboolean
+on_idle_present_modal (gpointer user_data)
+{
+ GtkWindow *current, *transient;
+ gdk_threads_enter ();
+ current = (GtkWindow *) user_data;
+ while (GTK_IS_DIALOG (current)) {
+ transient = gtk_window_get_transient_for (GTK_WINDOW (current));
+ if (transient == NULL)
+ break;
+ else
+ current = transient;
+ }
+ gtk_window_present (current);
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+/**
+ * This function checks if a modal dialog should be activated
+ * instead of other UI components on a DBus request, and if yes, starts the request
+ * @return TRUE if a modal dialog is about to be acitvated
+ * @note This function should be used before activating any Modest UI element on DBus request
+ */
+static gboolean
+modest_dbus_check_present_modal ()
+{
+ GtkWindow *dialog;
+
+ /* Check if there is already a dialog or note open */
+ dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
+ if (dialog) {
+ g_idle_add (on_idle_present_modal, dialog);
+ }
+
+ return (NULL != dialog);
+}
+
+/* Callback for normal D-BUS messages */
+gint
+modest_dbus_req_handler(const gchar * interface, const gchar * method,
+ GArray * arguments, gpointer data,
+ osso_rpc_t * retval)
+{
+ /* Check memory low conditions */
+ if (modest_platform_check_memory_low (NULL, FALSE)) {
+ g_idle_add (on_idle_show_memory_low, NULL);
+ goto param_error;
+ }
+
+ if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_MAIL_TO) == 0) {
+ if (arguments->len != MODEST_DBUS_MAIL_TO_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_mail_to (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_MESSAGE) == 0) {
+ if (arguments->len != MODEST_DBUS_OPEN_MESSAGE_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_open_message (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_ACCOUNT) == 0) {
+ if (arguments->len != MODEST_DBUS_OPEN_ACCOUNT_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_open_account (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_SEND_RECEIVE) == 0) {
+ if (arguments->len != 0)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_send_receive (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_SEND_RECEIVE_FULL) == 0) {
+ if (arguments->len != MODEST_DBUS_SEND_RECEIVE_FULL_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_send_receive_full (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_UPDATE_FOLDER_COUNTS) == 0) {
+ if (arguments->len != MODEST_DBUS_UPDATE_FOLDER_COUNTS_ARGS_COUNT)
+ goto param_error;
+ return on_update_folder_counts (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_COMPOSE_MAIL) == 0) {
+ if (arguments->len != MODEST_DBUS_COMPOSE_MAIL_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_compose_mail (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_DELETE_MESSAGE) == 0) {
+ if (arguments->len != MODEST_DBUS_DELETE_MESSAGE_ARGS_COUNT)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_delete_message (arguments,data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX) == 0) {
+ if (arguments->len != 0)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_open_default_inbox (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_TOP_APPLICATION) == 0) {
+ if (arguments->len != 0)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_top_application (arguments, data, retval);
+ } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_EDIT_ACCOUNTS_DIALOG) == 0) {
+ if (arguments->len != 0)
+ goto param_error;
+ return modest_dbus_check_present_modal () ? OSSO_OK : on_open_edit_accounts_dialog (arguments, data, retval);
+ } else {