From dfb3b918b0dfe988cdf1e45dc129cb02fea59107 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 15 Jun 2010 15:10:05 +0200 Subject: Bug #617557 - Quits without asking user to save unfinished messages The second attempt. --- composer/e-composer-actions.c | 45 +---------------- composer/e-msg-composer.c | 113 ++++++++++++++++++++++++++++++++++++++++-- composer/e-msg-composer.h | 3 ++ 3 files changed, 114 insertions(+), 47 deletions(-) (limited to 'composer') diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c index e5c9372f59..d028beb56f 100644 --- a/composer/e-composer-actions.c +++ b/composer/e-composer-actions.c @@ -56,49 +56,8 @@ static void action_close_cb (GtkAction *action, EMsgComposer *composer) { - GtkhtmlEditor *editor; - EComposerHeaderTable *table; - GdkWindow *window; - GtkWidget *widget; - const gchar *subject; - gint response; - - editor = GTKHTML_EDITOR (composer); - widget = GTK_WIDGET (composer); - - if (!gtkhtml_editor_get_changed (editor)) { - gtk_widget_destroy (widget); - return; - } - - window = gtk_widget_get_window (widget); - gdk_window_raise (window); - - table = e_msg_composer_get_header_table (composer); - subject = e_composer_header_table_get_subject (table); - - if (subject == NULL || *subject == '\0') - subject = _("Untitled Message"); - - response = e_alert_run_dialog_for_args ( - GTK_WINDOW (composer), - "mail-composer:exit-unsaved", - subject, NULL); - - switch (response) { - case GTK_RESPONSE_YES: - gtk_widget_hide (widget); - e_msg_composer_request_close (composer); - gtk_action_activate (ACTION (SAVE_DRAFT)); - break; - - case GTK_RESPONSE_NO: - gtk_widget_destroy (widget); - break; - - case GTK_RESPONSE_CANCEL: - break; - } + if (e_msg_composer_can_close (composer, TRUE)) + gtk_widget_destroy (GTK_WIDGET (composer)); } static void diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index ba09088897..d2e60ccc1e 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -1689,12 +1689,50 @@ msg_composer_finalize (GObject *object) static gboolean msg_composer_delete_event_cb (GtkWidget *widget, gpointer user_data) { - /* This is needed for the ACTION macro. */ - EMsgComposer *composer = E_MSG_COMPOSER (widget); + EShell *shell; - gtk_action_activate (ACTION (CLOSE)); + shell = e_shell_get_default (); - return FALSE; + if (g_list_length (e_shell_get_watched_windows (shell)) == 1) { + /* This is the last watched window, use the quit + mechanism to have a draft saved properly */ + e_shell_quit (shell, E_SHELL_QUIT_ACTION); + } else { + /* This is needed for the ACTION macro. */ + EMsgComposer *composer = E_MSG_COMPOSER (widget); + + /* There are more watched windows opened, + invoke only a close action */ + gtk_action_activate (ACTION (CLOSE)); + } + + return TRUE; +} + +static void +msg_composer_prepare_for_quit_cb (EShell *shell, EActivity *activity, EMsgComposer *composer) +{ + if (e_msg_composer_is_exiting (composer)) { + /* needs save draft first */ + g_object_ref (activity); + g_object_weak_ref (G_OBJECT (composer), (GWeakNotify) g_object_unref, activity); + gtk_action_activate (ACTION (SAVE_DRAFT)); + } +} + +static void +msg_composer_quit_requested_cb (EShell *shell, EShellQuitReason reason, EMsgComposer *composer) +{ + if (e_msg_composer_is_exiting (composer)) { + EShell *shell; + + shell = e_shell_get_default (); + + g_signal_handlers_disconnect_by_func (shell, msg_composer_quit_requested_cb, composer); + g_signal_handlers_disconnect_by_func (shell, msg_composer_prepare_for_quit_cb, composer); + } else if (!e_msg_composer_can_close (composer, FALSE) && !e_msg_composer_is_exiting (composer)) { + e_shell_cancel_quit (shell); + } } static void @@ -1741,6 +1779,12 @@ msg_composer_constructed (GObject *object) e_shell_adapt_window_size (shell, GTK_WINDOW (composer)); e_shell_watch_window (shell, GTK_WINDOW (object)); + g_signal_connect (shell, "quit-requested", + G_CALLBACK (msg_composer_quit_requested_cb), composer); + + g_signal_connect (shell, "prepare-for-quit", + G_CALLBACK (msg_composer_prepare_for_quit_cb), composer); + /* Restore Persistent State */ array = composer->priv->gconf_bridge_binding_ids; @@ -1847,12 +1891,18 @@ static void msg_composer_destroy (GtkObject *object) { EMsgComposer *composer = E_MSG_COMPOSER (object); + EShell *shell; if (composer->priv->address_dialog != NULL) { gtk_widget_destroy (composer->priv->address_dialog); composer->priv->address_dialog = NULL; } + shell = e_shell_get_default (); + + g_signal_handlers_disconnect_by_func (shell, msg_composer_quit_requested_cb, composer); + g_signal_handlers_disconnect_by_func (shell, msg_composer_prepare_for_quit_cb, composer); + /* Chain up to parent's destroy() method. */ GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -4009,6 +4059,61 @@ e_msg_composer_request_close (EMsgComposer *composer) composer->priv->application_exiting = TRUE; } +/* Returns whether can close the composer immediately. It will return FALSE also when + saving to drafts, but the e_msg_composer_is_exiting will return TRUE for this case. + can_save_draft means whether can save draft immediately, or rather keep it on the + caller (when FALSE). If kept on the folder, then returns FALSE and sets interval + variable to return TRUE in e_msg_composer_is_exiting. */ +gboolean +e_msg_composer_can_close (EMsgComposer *composer, gboolean can_save_draft) +{ + gboolean res = FALSE; + GtkhtmlEditor *editor; + EComposerHeaderTable *table; + GdkWindow *window; + GtkWidget *widget; + const gchar *subject; + gint response; + + editor = GTKHTML_EDITOR (composer); + widget = GTK_WIDGET (composer); + + if (!gtkhtml_editor_get_changed (editor)) + return TRUE; + + window = gtk_widget_get_window (widget); + gdk_window_raise (window); + + table = e_msg_composer_get_header_table (composer); + subject = e_composer_header_table_get_subject (table); + + if (subject == NULL || *subject == '\0') + subject = _("Untitled Message"); + + response = e_alert_run_dialog_for_args ( + GTK_WINDOW (composer), + "mail-composer:exit-unsaved", + subject, NULL); + + switch (response) { + case GTK_RESPONSE_YES: + gtk_widget_hide (widget); + e_msg_composer_request_close (composer); + if (can_save_draft) + gtk_action_activate (ACTION (SAVE_DRAFT)); + break; + + case GTK_RESPONSE_NO: + res = TRUE; + break; + + case GTK_RESPONSE_CANCEL: + break; + } + + return res; +} + EMsgComposer * e_msg_composer_load_from_file (const gchar *filename) { diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index 25c78ced03..b10253d6eb 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -134,6 +134,9 @@ void e_msg_composer_add_message_attachments gboolean just_inlines); void e_msg_composer_request_close (EMsgComposer *composer); +gboolean e_msg_composer_can_close (EMsgComposer *composer, + gboolean can_save_draft); + EMsgComposer * e_msg_composer_load_from_file (const gchar *filename); void e_msg_composer_check_autosave (GtkWindow *parent); -- cgit v1.2.3