X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fhildon2%2Fmodest-hildon2-window-mgr.c;h=06ed06534ae7b6e06b7820266129aec105e57a3f;hp=ffa54a87bb55f2b3091d01381a09103350dbc6fe;hb=9c2f8007e10d401d50ce21d4ee8e49b116c5006b;hpb=837a00595080e7b3d8bf137b8afd468acf33ecd5 diff --git a/src/hildon2/modest-hildon2-window-mgr.c b/src/hildon2/modest-hildon2-window-mgr.c index ffa54a8..06ed065 100644 --- a/src/hildon2/modest-hildon2-window-mgr.c +++ b/src/hildon2/modest-hildon2-window-mgr.c @@ -29,9 +29,13 @@ #include #include +#include "modest-hildon2-window.h" #include "modest-hildon2-window-mgr.h" #include "modest-msg-edit-window.h" +#include "modest-mailboxes-window.h" +#include "modest-header-window.h" #include "modest-main-window.h" +#include "modest-window-mgr-priv.h" #include "modest-conf.h" #include "modest-defs.h" #include "modest-signal-mgr.h" @@ -42,6 +46,12 @@ #include "modest-tny-folder.h" #include "modest-folder-window.h" #include "modest-accounts-window.h" +#include "modest-maemo-utils.h" +#include "modest-utils.h" +#include "modest-tny-msg.h" +#include "modest-tny-account.h" +#include +#include /* 'private'/'protected' functions */ static void modest_hildon2_window_mgr_class_init (ModestHildon2WindowMgrClass *klass); @@ -72,11 +82,22 @@ static void modest_hildon2_window_mgr_set_modal (ModestWindowMgr *self, static gboolean modest_hildon2_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header, ModestWindow **win); +static gboolean modest_hildon2_window_mgr_find_registered_message_uid (ModestWindowMgr *self, + const gchar *msg_uid, + ModestWindow **win); static GList *modest_hildon2_window_mgr_get_window_list (ModestWindowMgr *self); static gboolean modest_hildon2_window_mgr_close_all_windows (ModestWindowMgr *self); -static gboolean window_can_close (ModestWindow *window); +static gboolean modest_hildon2_window_mgr_close_all_but_initial (ModestWindowMgr *self); static gboolean window_has_modals (ModestWindow *window); static ModestWindow *modest_hildon2_window_mgr_show_initial_window (ModestWindowMgr *self); +static ModestWindow *modest_hildon2_window_mgr_get_current_top (ModestWindowMgr *self); +static gboolean modest_hildon2_window_mgr_screen_is_on (ModestWindowMgr *self); +static void modest_hildon2_window_mgr_create_caches (ModestWindowMgr *self); +static void osso_display_event_cb (osso_display_state_t state, + gpointer data); +static void on_account_removed (TnyAccountStore *acc_store, + TnyAccount *account, + gpointer user_data); typedef struct _ModestHildon2WindowMgrPrivate ModestHildon2WindowMgrPrivate; struct _ModestHildon2WindowMgrPrivate { @@ -94,6 +115,11 @@ struct _ModestHildon2WindowMgrPrivate { GSList *modal_handler_uids; ModestWindow *current_top; + + gulong accounts_handler; + + /* Display state */ + osso_display_state_t display_state; }; #define MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_HILDON2_WINDOW_MGR, \ @@ -145,9 +171,14 @@ modest_hildon2_window_mgr_class_init (ModestHildon2WindowMgrClass *klass) mgr_class->get_modal = modest_hildon2_window_mgr_get_modal; mgr_class->set_modal = modest_hildon2_window_mgr_set_modal; mgr_class->find_registered_header = modest_hildon2_window_mgr_find_registered_header; + mgr_class->find_registered_message_uid = modest_hildon2_window_mgr_find_registered_message_uid; mgr_class->get_window_list = modest_hildon2_window_mgr_get_window_list; mgr_class->close_all_windows = modest_hildon2_window_mgr_close_all_windows; + mgr_class->close_all_but_initial = modest_hildon2_window_mgr_close_all_but_initial; mgr_class->show_initial_window = modest_hildon2_window_mgr_show_initial_window; + mgr_class->get_current_top = modest_hildon2_window_mgr_get_current_top; + mgr_class->screen_is_on = modest_hildon2_window_mgr_screen_is_on; + mgr_class->create_caches = modest_hildon2_window_mgr_create_caches; g_type_class_add_private (gobject_class, sizeof(ModestHildon2WindowMgrPrivate)); @@ -161,7 +192,6 @@ modest_hildon2_window_mgr_instance_init (ModestHildon2WindowMgr *obj) priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE(obj); priv->window_list = NULL; priv->fullscreen_mode = FALSE; - priv->current_top = NULL; priv->window_state_uids = NULL; priv->modal_windows = g_queue_new (); @@ -175,16 +205,32 @@ modest_hildon2_window_mgr_instance_init (ModestHildon2WindowMgr *obj) priv->closing_time = 0; priv->modal_handler_uids = NULL; + priv->display_state = OSSO_DISPLAY_ON; + + /* Listen for changes in the screen, we don't want to show a + led pattern when the display is on for example */ + osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (), + osso_display_event_cb, + obj); + } static void modest_hildon2_window_mgr_finalize (GObject *obj) { ModestHildon2WindowMgrPrivate *priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE(obj); + ModestTnyAccountStore *acc_store; modest_signal_mgr_disconnect_all_and_destroy (priv->window_state_uids); priv->window_state_uids = NULL; + osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (), + NULL, NULL); + + acc_store = modest_runtime_get_account_store (); + if (acc_store && g_signal_handler_is_connected (acc_store, priv->accounts_handler)) + g_signal_handler_disconnect (acc_store, priv->accounts_handler); + if (priv->window_list) { GList *iter = priv->window_list; /* unregister pending windows */ @@ -273,13 +319,34 @@ compare_msguids (ModestWindow *win, } else { msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win)); } - + if (msg_uid && uid &&!strcmp (msg_uid, uid)) return 0; else return 1; } +static gint +compare_headers (ModestWindow *win, + TnyHeader *header) +{ + TnyHeader *my_header; + gint result = 1; + + if (!MODEST_IS_MSG_VIEW_WINDOW (win)) + return 1; + + /* Get message uid from msg window */ + my_header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win)); + if (my_header) { + if (my_header == header) + result = 0; + g_object_unref (my_header); + } + return result; +} + + static gboolean modest_hildon2_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header, ModestWindow **win) @@ -316,6 +383,38 @@ modest_hildon2_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHead return has_header || has_window; } +static gboolean +modest_hildon2_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid, + ModestWindow **win) +{ + ModestHildon2WindowMgrPrivate *priv = NULL; + gboolean has_header, has_window = FALSE; + GList *item = NULL; + + g_return_val_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self), FALSE); + g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE); + + priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (self); + + has_header = MODEST_WINDOW_MGR_CLASS (parent_class)->find_registered_message_uid (self, msg_uid, win); + + item = g_list_find_custom (priv->window_list, msg_uid, (GCompareFunc) compare_msguids); + if (item) { + has_window = TRUE; + if (win) { + if ((!MODEST_IS_MSG_VIEW_WINDOW(item->data)) && + (!MODEST_IS_MSG_EDIT_WINDOW (item->data))) + g_debug ("not a valid window!"); + else { + g_debug ("found a window"); + *win = MODEST_WINDOW (item->data); + } + } + } + + return has_header || has_window; +} + static GList * modest_hildon2_window_mgr_get_window_list (ModestWindowMgr *self) { @@ -327,6 +426,25 @@ modest_hildon2_window_mgr_get_window_list (ModestWindowMgr *self) return g_list_copy (priv->window_list); } +static gint window_precedence (GtkWindow *window) +{ + if (MODEST_IS_ACCOUNTS_WINDOW (window)) { + return 10; + } else if (MODEST_IS_MAILBOXES_WINDOW (window)) { + return 20; + } else if (MODEST_IS_FOLDER_WINDOW (window)) { + return 30; + } else if (MODEST_IS_HEADER_WINDOW (window)) { + return 40; + } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + return 50; + } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) { + return 60; + } else { + return 100; + } +} + static gboolean modest_hildon2_window_mgr_register_window (ModestWindowMgr *self, ModestWindow *window, @@ -335,27 +453,134 @@ modest_hildon2_window_mgr_register_window (ModestWindowMgr *self, GList *win; ModestHildon2WindowMgrPrivate *priv; gint *handler_id; - HildonProgram *program; - GtkWidget *current_top; HildonWindowStack *stack; gboolean nested_msg = FALSE; + ModestWindow *current_top; + const gchar *acc_name, *toplevel_acc_name; g_return_val_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self), FALSE); g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (self); - program = hildon_program_get_instance (); + /* Try to close active modal dialogs */ + if (modest_window_mgr_get_num_windows (self) && + !_modest_window_mgr_close_active_modals (self)) + return FALSE; + + stack = hildon_window_stack_get_default (); + current_top = (ModestWindow *) hildon_window_stack_peek (stack); + win = g_list_find (priv->window_list, window); if (win) { - /* this is for the case we want to register the window and it was already - * registered. We leave silently, telling the operation was succesful. - */ - gtk_window_present (GTK_WINDOW (win)); - return TRUE; + /* this is for the case we want to register the window + and it was already registered */ + gtk_window_present (GTK_WINDOW (window)); + return FALSE; } - stack = hildon_window_stack_get_default (); + /* Do not allow standalone editors or standalone viewers */ + if (!current_top && + (MODEST_IS_MSG_VIEW_WINDOW (window) || + MODEST_IS_MSG_EDIT_WINDOW (window))) + modest_window_mgr_show_initial_window (self); + + if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + gchar *uid; + TnyHeader *header; + + uid = g_strdup (modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (window))); + + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window)); + + if (uid == NULL) + uid = modest_tny_folder_get_header_unique_id (header); + /* Embedded messages do not have uid */ + if (uid) { + if (g_list_find_custom (priv->window_list, uid, (GCompareFunc) compare_msguids)) { + g_debug ("%s found another view window showing the same header", __FUNCTION__); + g_free (uid); + g_object_unref (header); + return FALSE; + } + g_free (uid); + } else if (header) { + if (g_list_find_custom (priv->window_list, header, (GCompareFunc) compare_headers)) { + g_debug ("%s found another view window showing the same header", __FUNCTION__); + g_object_unref (header); + return FALSE; + } + } + if (header) + g_object_unref (header); + } + + /* Rules + * * toplevel = msg edit -> if not modified, close, if modified, stay + * * same account -> no action + * * window = accounts -> no action + * * window = folders, mailboxes, headers: close all up to accounts window + */ + + if (MODEST_IS_MSG_EDIT_WINDOW (current_top) && + !modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (current_top))) { + gboolean retval; + + g_signal_emit_by_name (G_OBJECT (current_top), "delete-event", NULL, &retval); + current_top = (ModestWindow *) hildon_window_stack_peek (stack); + } + + if (MODEST_IS_MSG_EDIT_WINDOW (current_top) || + (current_top && MODEST_IS_ACCOUNTS_WINDOW (window))) { + gtk_window_present (GTK_WINDOW (current_top)); + return FALSE; + } + + acc_name = modest_window_get_active_account (window); + + if (MODEST_IS_MSG_VIEW_WINDOW (current_top) || + MODEST_IS_HEADER_WINDOW (current_top) || + MODEST_IS_FOLDER_WINDOW (current_top) || + MODEST_IS_MAILBOXES_WINDOW (current_top)) { + toplevel_acc_name = modest_window_get_active_account (current_top); + + if (acc_name != NULL && g_strcmp0 (toplevel_acc_name, acc_name) == 0) { + /* Same account, no action */ + + if (window_precedence (GTK_WINDOW (current_top)) >= window_precedence (GTK_WINDOW (window))) { + if (!(MODEST_IS_MSG_VIEW_WINDOW (current_top) && MODEST_IS_MSG_VIEW_WINDOW (window))) { + gtk_window_present (GTK_WINDOW (current_top)); + return FALSE; + } + } + } else { + while (current_top && !MODEST_IS_ACCOUNTS_WINDOW (current_top)) { + gboolean retval; + g_signal_emit_by_name (G_OBJECT (current_top), "delete-event", NULL, &retval); + + if (retval) { + gtk_window_present (GTK_WINDOW (current_top)); + return FALSE; + } + current_top = (ModestWindow *) hildon_window_stack_peek (stack); + } + } + } + + /* Trying to open a folders window and a mailboxes window at + the same time from the accounts window is not allowed */ + if (MODEST_IS_MAILBOXES_WINDOW (current_top) && + MODEST_IS_FOLDER_WINDOW (window) && + MODEST_IS_ACCOUNTS_WINDOW (parent)) { + gtk_window_present (GTK_WINDOW (window)); + return FALSE; + } + + if (MODEST_IS_HEADER_WINDOW (current_top) && MODEST_IS_HEADER_WINDOW (window)) { + g_debug ("Trying to register a second header window is not allowed"); + gtk_window_present (GTK_WINDOW (current_top)); + return FALSE; + } if (!MODEST_WINDOW_MGR_CLASS (parent_class)->register_window (self, window, parent)) goto fail; @@ -364,8 +589,7 @@ modest_hildon2_window_mgr_register_window (ModestWindowMgr *self, g_object_ref (window); priv->window_list = g_list_prepend (priv->window_list, window); - current_top = hildon_window_stack_peek (stack); - nested_msg = MODEST_IS_MSG_VIEW_WINDOW (window) && + nested_msg = MODEST_IS_MSG_VIEW_WINDOW (window) && MODEST_IS_MSG_VIEW_WINDOW (parent); /* Close views if they're being shown. Nevertheless we must @@ -385,7 +609,7 @@ modest_hildon2_window_mgr_register_window (ModestWindowMgr *self, /* Close the current view */ g_signal_emit_by_name (G_OBJECT (current_top), "delete-event", NULL, &retval); - if (retval == TRUE) { + if (retval) { /* Cancelled closing top window, then we fail to register */ goto fail; } @@ -396,15 +620,33 @@ modest_hildon2_window_mgr_register_window (ModestWindowMgr *self, *handler_id = g_signal_connect (window, "delete-event", G_CALLBACK (on_window_destroy), self); g_hash_table_insert (priv->destroy_handlers, window, handler_id); + if (!MODEST_IS_MSG_EDIT_WINDOW (window) && + !MODEST_IS_ACCOUNTS_WINDOW (window)) { + acc_name = modest_window_get_active_account (window); + + if (acc_name) { + modest_platform_remove_new_mail_notifications (FALSE, acc_name); + modest_account_mgr_set_has_new_mails (modest_runtime_get_account_mgr (), + acc_name, + FALSE); + } + } + /* Show toolbar always */ - modest_window_show_toolbar (window, TRUE); + if (MODEST_IS_MSG_EDIT_WINDOW (window)) { + gboolean show_toolbar; + show_toolbar = modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL); + modest_window_show_toolbar (window, show_toolbar); + } else { + modest_window_show_toolbar (window, TRUE); + } return TRUE; fail: /* Add to list. Keep a reference to the window */ priv->window_list = g_list_remove (priv->window_list, window); g_object_unref (window); - current_top = hildon_window_stack_peek (stack); + current_top = (ModestWindow *) hildon_window_stack_peek (stack); if (current_top) gtk_window_present (GTK_WINDOW (current_top)); return FALSE; @@ -423,7 +665,9 @@ cancel_window_operations (ModestWindow *window) GSList* tmp_list = NULL; type = modest_mail_operation_get_type_operation (MODEST_MAIL_OPERATION (pending_ops->data)); - if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || type == MODEST_MAIL_OPERATION_TYPE_OPEN) { + if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || + type == MODEST_MAIL_OPERATION_TYPE_OPEN || + type == MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) { modest_mail_operation_cancel (pending_ops->data); } g_object_unref (G_OBJECT (pending_ops->data)); @@ -455,24 +699,14 @@ window_has_modals (ModestWindow *window) } static gboolean -window_can_close (ModestWindow *window) -{ - /* An editor can be always closed no matter the dialogs it has - * on top. */ - if (MODEST_IS_MSG_EDIT_WINDOW (window)) - return TRUE; - - return !window_has_modals (window); -} - -static gboolean on_window_destroy (ModestWindow *window, GdkEvent *event, ModestHildon2WindowMgr *self) { gboolean no_propagate = FALSE; - if (!window_can_close (window)) + /* Do not close the window if it has modals on top */ + if (!MODEST_IS_MSG_EDIT_WINDOW (window) && window_has_modals (window)) return TRUE; if (MODEST_IS_MSG_EDIT_WINDOW (window)) { @@ -480,9 +714,40 @@ on_window_destroy (ModestWindow *window, sent = modest_msg_edit_window_get_sent (MODEST_MSG_EDIT_WINDOW (window)); /* Save currently edited message to Drafts if it was not sent */ if (!sent && modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (window))) { - - if (!modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window))) - return TRUE; + ModestMsgEditWindow *edit_window; + MsgData *data; + + edit_window = MODEST_MSG_EDIT_WINDOW (window); + data = modest_msg_edit_window_get_msg_data (edit_window); + + if (data) { + gint parts_count; + guint64 parts_size, available_size, expected_size; + + available_size = modest_utils_get_available_space (NULL); + modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size); + expected_size = modest_tny_msg_estimate_size (data->plain_body, + data->html_body, + parts_count, + parts_size); + modest_msg_edit_window_free_msg_data (edit_window, data); + data = NULL; + + /* If there is not enough space + available for saving the message + then show an error and close the + window without saving */ + if (expected_size >= available_size) { + modest_platform_run_information_dialog (GTK_WINDOW (edit_window), + _("mail_in_ui_save_error"), + FALSE); + } else { + if (!modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window))) + return TRUE; + } + } else { + g_warning ("Edit window without message data. This is probably a bug"); + } } } @@ -500,7 +765,6 @@ modest_hildon2_window_mgr_unregister_window (ModestWindowMgr *self, GList *win; ModestHildon2WindowMgrPrivate *priv; gulong *tmp, handler_id; - gboolean check_close_all = FALSE; guint num_windows; g_return_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self)); @@ -510,14 +774,10 @@ modest_hildon2_window_mgr_unregister_window (ModestWindowMgr *self, win = g_list_find (priv->window_list, window); if (!win) { - g_warning ("Trying to unregister a window that has not being registered yet"); + g_debug ("Trying to unregister a window that has not being registered yet"); return; } - /* Remember this for the end of the method */ - if (MODEST_IS_FOLDER_WINDOW (window)) - check_close_all = TRUE; - /* Remove the viewer window handler from the hash table. The HashTable could not exist if the main window was closed when there were other windows remaining */ @@ -542,13 +802,6 @@ modest_hildon2_window_mgr_unregister_window (ModestWindowMgr *self, /* cancel open and receive operations */ cancel_window_operations (window); - /* Check if it's the topmost window, and remove the window from the stack. - * This is needed for the cases there's no other topmost window that will - * replace it in topmost handler. - */ - if (window == priv->current_top) - priv->current_top = NULL; - /* Disconnect the "window-state-event" handler, we won't need it anymore */ if (priv->window_state_uids) { priv->window_state_uids = @@ -570,15 +823,6 @@ modest_hildon2_window_mgr_unregister_window (ModestWindowMgr *self, emit the signal too many times */ num_windows = modest_window_mgr_get_num_windows (self); - /* Check if we have to destroy the accounts window as - well. This happens if we only have one or none remote - accounts */ - if (check_close_all) { - ModestTnyAccountStore *acc_store = modest_runtime_get_account_store (); - if (modest_tny_account_store_get_num_remote_accounts (acc_store) < 2) - modest_window_mgr_close_all_windows (self); - } - /* If there are no more windows registered emit the signal */ if (num_windows == 0) g_signal_emit_by_name (self, "window-list-empty"); @@ -644,32 +888,60 @@ modest_hildon2_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show) gtk_widget_show_all (GTK_WIDGET (result)); gtk_window_present (GTK_WINDOW (result)); } - + return result; } +static gint +look_for_transient (gconstpointer a, + gconstpointer b) +{ + GtkWindow *win, *child; + + if (a == b) + return 1; + + child = (GtkWindow *) b; + win = (GtkWindow *) a; + + if ((gtk_window_get_transient_for (win) == child) && + GTK_WIDGET_VISIBLE (win)) + return 0; + else + return 1; +} static GtkWindow * modest_hildon2_window_mgr_get_modal (ModestWindowMgr *self) { ModestHildon2WindowMgrPrivate *priv; GList *toplevel_list; - GtkWidget *toplevel; - + GtkWidget *current_top, *toplevel; + HildonWindowStack *stack; + g_return_val_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self), NULL); priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (self); - toplevel = NULL; + /* Get current top */ + stack = hildon_window_stack_get_default (); + current_top = hildon_window_stack_peek (stack); + toplevel = current_top; toplevel_list = gtk_window_list_toplevels (); - while (toplevel_list) { - if (gtk_window_is_active (toplevel_list->data)) { - toplevel = toplevel_list->data; + + while (toplevel) { + GList *parent_link; + + parent_link = g_list_find_custom (toplevel_list, toplevel, look_for_transient); + if (parent_link) + toplevel = (GtkWidget *) parent_link->data; + else break; - } - toplevel_list = g_list_next (toplevel_list); } - return NULL; + if (toplevel && GTK_WIDGET_VISIBLE (toplevel) && gtk_window_get_modal ((GtkWindow *) toplevel)) + return (GtkWindow *) toplevel; + else + return NULL; } @@ -684,44 +956,124 @@ modest_hildon2_window_mgr_set_modal (ModestWindowMgr *self, gtk_window_set_modal (window, TRUE); gtk_window_set_transient_for (window, parent); gtk_window_set_destroy_with_parent (window, TRUE); + + if (!gtk_window_has_toplevel_focus (window)) { + GList *toplevels, *node; + + toplevels = gtk_window_list_toplevels (); + for (node = toplevels; node != NULL; node = g_list_next (node)) { + if (gtk_window_has_toplevel_focus (GTK_WINDOW (node->data))) { + if (GTK_IS_DIALOG (node->data)) { + gtk_window_set_transient_for (window, GTK_WINDOW (node->data)); + } + break; + } + } + } +} + +static void +close_all_but_first (gpointer data) +{ + gint num_windows, i; + gboolean retval; + HildonWindowStack *stack; + + stack = hildon_window_stack_get_default (); + g_return_if_fail (stack); + + num_windows = hildon_window_stack_size (stack); + + for (i = 0; i < (num_windows - 1); i++) { + GtkWidget *current_top; + + /* Close window */ + current_top = hildon_window_stack_peek (stack); + g_signal_emit_by_name (G_OBJECT (current_top), "delete-event", NULL, &retval); + } +} + +static gboolean +on_idle_close_all_but_first (gpointer data) +{ + gdk_threads_enter (); + close_all_but_first (data); + gdk_threads_leave (); + + return FALSE; +} + +static void +on_account_removed (TnyAccountStore *acc_store, + TnyAccount *account, + gpointer user_data) +{ + HildonWindowStack *stack; + ModestWindow *current_top; + + /* Ignore transport account removals */ + if (TNY_IS_TRANSPORT_ACCOUNT (account)) + return; + + stack = hildon_window_stack_get_default (); + current_top = (ModestWindow *) hildon_window_stack_peek (stack); + + /* if we're showing the header view of the currently deleted + account, or the outbox and we deleted the last account, + then close the window */ + if (current_top && + (MODEST_IS_HEADER_WINDOW (current_top) || + MODEST_IS_FOLDER_WINDOW (current_top))) { + const gchar *acc_name; + + acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (account); + + /* We emit it in an idle, because sometimes this + function could called when the account settings + dialog is about to close but still there. That + modal dialog would otherwise, prevent the + windows from being closed */ + if (!strcmp (acc_name, modest_window_get_active_account (current_top))) + g_idle_add (on_idle_close_all_but_first, NULL); + } } static ModestWindow * modest_hildon2_window_mgr_show_initial_window (ModestWindowMgr *self) { ModestWindow *initial_window = NULL; - ModestTnyAccountStore *acc_store; + ModestHildon2WindowMgrPrivate *priv; + + priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (self); + + /* Connect to the account store "account-removed" signal". We + do this here because in the init the singletons are still + not initialized properly */ + if (!g_signal_handler_is_connected (modest_runtime_get_account_store (), + priv->accounts_handler)) { + priv->accounts_handler = g_signal_connect (modest_runtime_get_account_store (), + "account-removed", + G_CALLBACK (on_account_removed), + self); + } - /* Always create accounts window. We'll decide later if we - want to show it or not, depending the number of accounts */ + /* Return accounts window */ initial_window = MODEST_WINDOW (modest_accounts_window_new ()); modest_window_mgr_register_window (self, initial_window, NULL); - /* If there are less than 2 remote accounts then directly show - the folder window and do not show the accounts window */ - acc_store = modest_runtime_get_account_store (); - if (modest_tny_account_store_get_num_remote_accounts (acc_store) < 2) { - ModestAccountMgr *mgr; - - /* Show first the accounts window to add it to the - stack. This has to be changed when the new - stackable API is available. There will be a method - to show all the windows that will only show the - last one to the user. The current code shows both - windows, one after the other */ - gtk_widget_show (GTK_WIDGET (initial_window)); + return initial_window; +} - initial_window = MODEST_WINDOW (modest_folder_window_new (NULL)); - mgr = modest_runtime_get_account_mgr (); - modest_folder_window_set_account (MODEST_FOLDER_WINDOW (initial_window), - modest_account_mgr_get_default_account (mgr)); - modest_window_mgr_register_window (self, initial_window, NULL); - } - return initial_window; +static ModestWindow * +modest_hildon2_window_mgr_get_current_top (ModestWindowMgr *self) +{ + HildonWindowStack *stack; + stack = hildon_window_stack_get_default (); + return (ModestWindow *) hildon_window_stack_peek (stack); } -gint +static gint find_folder_window (gconstpointer a, gconstpointer b) { @@ -744,3 +1096,70 @@ modest_hildon2_window_mgr_get_folder_window (ModestHildon2WindowMgr *self) return (window != NULL) ? MODEST_WINDOW (window->data) : NULL; } + +static gboolean +modest_hildon2_window_mgr_screen_is_on (ModestWindowMgr *self) +{ + ModestHildon2WindowMgrPrivate *priv = NULL; + + g_return_val_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self), FALSE); + + priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (self); + + return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE; +} + +static void +modest_hildon2_window_mgr_create_caches (ModestWindowMgr *self) +{ + g_return_if_fail (MODEST_IS_HILDON2_WINDOW_MGR (self)); + + modest_accounts_window_pre_create (); + + MODEST_WINDOW_MGR_CLASS(parent_class)->create_caches (self); +} + +static void +osso_display_event_cb (osso_display_state_t state, + gpointer data) +{ + ModestHildon2WindowMgrPrivate *priv = MODEST_HILDON2_WINDOW_MGR_GET_PRIVATE (data); + + priv->display_state = state; + + /* Stop blinking if the screen becomes on */ + if (priv->display_state == OSSO_DISPLAY_ON) + modest_platform_remove_new_mail_notifications (TRUE, NULL); +} + +static gboolean +modest_hildon2_window_mgr_close_all_but_initial (ModestWindowMgr *self) +{ + ModestWindow *top; + + /* Exit if there are no windows */ + if (!modest_window_mgr_get_num_windows (self)) { + g_warning ("%s: unable to close, there are no windows", __FUNCTION__); + return FALSE; + } + + /* Close active modals */ + if (!_modest_window_mgr_close_active_modals (self)) { + g_debug ("%s: unable to close some dialogs", __FUNCTION__); + return FALSE; + } + + /* Close all but first */ + top = modest_window_mgr_get_current_top (self); + if (!MODEST_IS_ACCOUNTS_WINDOW (top)) + close_all_but_first (NULL); + + /* If some cannot be closed return */ + top = modest_window_mgr_get_current_top (self); + if (!MODEST_IS_ACCOUNTS_WINDOW (top)) { + g_debug ("%s: could not close some windows", __FUNCTION__); + return FALSE; + } + + return TRUE; +}