X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fwidgets%2Fmodest-window-mgr.c;h=9d10d8b4c631349a100e6ddc872e5d201de65a3e;hp=528fa335add5d7f72904de4c61ac31f6f1a3fd0d;hb=a8712a6b492bdc754ef169452802773ec89376cd;hpb=dde66f6a3aceb78ed40d8ae247bd613ab25b8fff diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index 528fa33..9d10d8b 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -30,6 +30,9 @@ #include #include "modest-window-mgr.h" #include "modest-runtime.h" +#include "modest-tny-folder.h" +#include "modest-ui-actions.h" +#include "modest-platform.h" #include "widgets/modest-main-window.h" #include "widgets/modest-msg-edit-window.h" #include "widgets/modest-msg-view-window.h" @@ -52,11 +55,14 @@ enum { typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate; struct _ModestWindowMgrPrivate { - GList *window_list; + GList *window_list; ModestWindow *main_window; - gboolean fullscreen_mode; - gboolean show_toolbars; - gboolean show_toolbars_fullscreen; + gboolean fullscreen_mode; + gboolean show_toolbars; + gboolean show_toolbars_fullscreen; + + GSList *windows_that_prevent_hibernation; + GHashTable *destroy_handlers; }; #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_WINDOW_MGR, \ @@ -117,6 +123,7 @@ modest_window_mgr_init (ModestWindowMgr *obj) ready yet */ priv->show_toolbars = FALSE; priv->show_toolbars_fullscreen = FALSE; + priv->destroy_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); } static void @@ -136,6 +143,12 @@ modest_window_mgr_finalize (GObject *obj) priv->window_list = NULL; } + /* Free the hash table with the handlers */ + if (priv->destroy_handlers) { + g_hash_table_destroy (priv->destroy_handlers); + priv->destroy_handlers = NULL; + } + /* Do not unref priv->main_window because it does not hold a new reference */ @@ -156,6 +169,7 @@ modest_window_mgr_register_window (ModestWindowMgr *self, GList *win; gboolean show; ModestWindowMgrPrivate *priv; + gint *handler_id; g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); g_return_if_fail (MODEST_IS_WINDOW (window)); @@ -183,7 +197,9 @@ modest_window_mgr_register_window (ModestWindowMgr *self, priv->window_list = g_list_prepend (priv->window_list, window); /* Listen to object destruction */ - g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), self); + handler_id = g_malloc0 (sizeof (gint)); + *handler_id = g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), self); + g_hash_table_insert (priv->destroy_handlers, window, handler_id); /* Put into fullscreen if needed */ if (priv->fullscreen_mode) @@ -235,8 +251,18 @@ on_window_destroy (ModestWindow *window, ModestWindowMgr *self) } } else { if (MODEST_IS_MSG_EDIT_WINDOW (window)) { - /* TODO: Save currently edited message to Drafts - folder */ + gboolean sent; + + 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))) { + gint response = + modest_platform_run_confirmation_dialog (GTK_WINDOW (self), + _("mcen_nc_no_email_message_modified_save_changes")); + if (response != GTK_RESPONSE_CANCEL) { + modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window)); + } + } } } @@ -250,6 +276,7 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, { GList *win; ModestWindowMgrPrivate *priv; + gint *tmp, handler_id; g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); g_return_if_fail (MODEST_IS_WINDOW (window)); @@ -262,9 +289,25 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, return; } - /* Remove from list. Remove the reference to the window */ - g_object_unref (win->data); + /* If it's the main window unset it */ + if (priv->main_window == window) + priv->main_window = NULL; + + /* Save state */ + modest_window_save_state (window); + + /* Remove from list & hash table */ priv->window_list = g_list_remove_link (priv->window_list, win); + tmp = g_hash_table_lookup (priv->destroy_handlers, window); + handler_id = *tmp; + g_hash_table_remove (priv->destroy_handlers, window); + + /* Remove the reference to the window. We need to block the + destroy event handler to avoid recursive calls */ + g_signal_handler_block (window, handler_id); + gtk_widget_destroy (win->data); + if (G_IS_OBJECT (window)) + g_signal_handler_unblock (window, handler_id); /* If there are no more windows registered then exit program */ if (priv->window_list == NULL) { @@ -292,30 +335,36 @@ compare_msguids (ModestWindow *win, /* Get message uid from msg window */ msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win)); - if (msg_uid && !strcmp (msg_uid, uid)) + + if (msg_uid && uid &&!strcmp (msg_uid, uid)) return 0; else return 1; } ModestWindow* -modest_window_mgr_find_window_by_msguid (ModestWindowMgr *self, - const gchar *msguid) +modest_window_mgr_find_window_by_header (ModestWindowMgr *self, + TnyHeader *header) { ModestWindowMgrPrivate *priv; GList *win = NULL; + gchar *msg_uid; g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL); - g_return_val_if_fail (msguid != NULL, NULL); + g_return_val_if_fail (TNY_IS_HEADER (header), NULL); priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + msg_uid = modest_tny_folder_get_header_unique_id (header); /* Look for the window */ if (priv->window_list) win = g_list_find_custom (priv->window_list, - msguid, + msg_uid, (GCompareFunc) compare_msguids); + /* Free */ + g_free (msg_uid); + /* Return the window */ if (win) return win->data; else @@ -419,3 +468,77 @@ modest_window_mgr_get_main_window (ModestWindowMgr *self) return priv->main_window; } + +static void +on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + + /* Forget this window, + * so hibernation will be allowed again if no windows are remembered: */ + priv->windows_that_prevent_hibernation = + g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget)); +} + +static void +on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + + GtkWindow *window = GTK_WINDOW (widget); + + priv->windows_that_prevent_hibernation = + g_slist_append (priv->windows_that_prevent_hibernation, window); + + /* Allow hibernation again when the window has been hidden: */ + g_signal_connect (window, "hide", + G_CALLBACK (on_nonhibernating_window_hide), self); +} + +void modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self, + GtkWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); + + if (GTK_WIDGET_VISIBLE(window)) { + on_nonhibernating_window_show (GTK_WIDGET (window), self); + } else { + /* Wait for it to be shown: */ + g_signal_connect (window, "show", + G_CALLBACK (on_nonhibernating_window_show), self); + } +} + +gboolean modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self) +{ + g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE); + + ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + + /* Prevent hibernation if any open windows are currently + * preventing hibernation: */ + return (g_slist_length (priv->windows_that_prevent_hibernation) > 0); +} + + +void modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self) +{ + g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); + + ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + + /* Iterate over all windows */ + GList *win = priv->window_list; + while (win) { + ModestWindow *window = MODEST_WINDOW (win->data); + if (window) { + /* This calls the vfunc, + * so each window can do its own thing: */ + modest_window_save_state (window); + } + + win = g_list_next (win); + } +}