From 534e5a1764bdbeb542cf3531c2575df451d8e572 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 9 Apr 2008 02:00:45 +0000 Subject: ** Fixes bug #523413 2008-04-08 Matthew Barnes ** Fixes bug #523413 * composer/e-msg-composer.c (msg_composer_dispose): Use the 'application_exiting' private flag to determine whether to tell e_composer_autosave_unregister() to delete the autosave file. * composer/e-msg-composer.c (msg_composer_class_init), (e_msg_composer_save_draft): Remove the 'quit' parameter from the 'save-draft' signal. * composer/e-msg-composer.c (e_msg_composer_request_close_all): Take an autosave snapshot before activating the CLOSE action, and set the private 'application_exiting' flag. This should avoid prompting the user before shutting down. * composer/e-composer-actions.c (action_close_cb): When electing to save a message before closing, hide the window immediately. The callback function can then check the window's visibility after the save is complete to know whether to destroy the window. * composer/e-composer-autosave.c (e_composer_autosave_unregister): Add a 'delete_file' boolean parameter to determine whether to delete the autosave file. * composer/e-composer-private.h: Add an 'application_exiting' flag. * mail/em-composer-utils.c (save_draft_done): Check the composer window's visibility to determine whether to destroy the window. See the corresponding composer/ChangeLog entry to get the full story. * mail/em-composer-utils.c (em_utils_composer_save_draft_cb): Remove the 'quit' parameter. svn path=/trunk/; revision=35346 --- composer/ChangeLog | 31 +++++++++++++++++++++++++++++++ composer/e-composer-actions.c | 9 ++++++--- composer/e-composer-autosave.c | 12 +++++++----- composer/e-composer-autosave.h | 3 ++- composer/e-composer-private.h | 3 +-- composer/e-msg-composer.c | 30 +++++++++++++++++++++++++----- mail/ChangeLog | 12 ++++++++++++ mail/em-composer-utils.c | 9 +++++---- mail/em-composer-utils.h | 2 +- 9 files changed, 90 insertions(+), 21 deletions(-) diff --git a/composer/ChangeLog b/composer/ChangeLog index cec3eff342..5fccf25965 100644 --- a/composer/ChangeLog +++ b/composer/ChangeLog @@ -1,3 +1,34 @@ +2008-04-08 Matthew Barnes + + ** Fixes bug #523413 + + * e-msg-composer.c (msg_composer_dispose): + Use the 'application_exiting' private flag to determine whether + to tell e_composer_autosave_unregister() to delete the autosave + file. + + * e-msg-composer.c (msg_composer_class_init), + (e_msg_composer_save_draft): + Remove the 'quit' parameter from the 'save-draft' signal. + + * e-msg-composer.c (e_msg_composer_request_close_all): + Take an autosave snapshot before activating the CLOSE action, + and set the private 'application_exiting' flag. This should + avoid prompting the user before shutting down. + + * e-composer-actions.c (action_close_cb): + When electing to save a message before closing, hide the window + immediately. The callback function can then check the window's + visibility after the save is complete to know whether to destroy + the window. + + * e-composer-autosave.c (e_composer_autosave_unregister): + Add a 'delete_file' boolean parameter to determine whether to + delete the autosave file. + + * e-composer-private.h: + Add an 'application_exiting' flag. + 2008-04-08 Matthew Barnes ** Fixes bug #525966 diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c index aeae508153..ecf7e84346 100644 --- a/composer/e-composer-actions.c +++ b/composer/e-composer-actions.c @@ -119,19 +119,21 @@ action_close_cb (GtkAction *action, { GtkhtmlEditor *editor; EComposerHeaderTable *table; + GtkWidget *widget; const gchar *subject; gint response; editor = GTKHTML_EDITOR (composer); + widget = GTK_WIDGET (composer); if (!gtkhtml_editor_get_changed (editor) && e_composer_autosave_get_saved (composer)) { - gtk_widget_destroy (GTK_WIDGET (composer)); + gtk_widget_destroy (widget); return; } - gdk_window_raise (GTK_WIDGET (composer)->window); + gdk_window_raise (widget->window); table = e_msg_composer_get_header_table (composer); subject = e_composer_header_table_get_subject (table); @@ -146,11 +148,12 @@ action_close_cb (GtkAction *action, switch (response) { case GTK_RESPONSE_YES: + gtk_widget_hide (widget); gtk_action_activate (ACTION (SAVE_DRAFT)); break; case GTK_RESPONSE_NO: - gtk_widget_destroy (GTK_WIDGET (composer)); + gtk_widget_destroy (widget); break; case GTK_RESPONSE_CANCEL: diff --git a/composer/e-composer-autosave.c b/composer/e-composer-autosave.c index eda3a033e2..23451685f3 100644 --- a/composer/e-composer-autosave.c +++ b/composer/e-composer-autosave.c @@ -230,9 +230,12 @@ e_composer_autosave_register (EMsgComposer *composer) } void -e_composer_autosave_unregister (EMsgComposer *composer) +e_composer_autosave_unregister (EMsgComposer *composer, + gboolean delete_file) { AutosaveState *state; + GtkWindow *parent; + gboolean delete_autosave_file = FALSE; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); @@ -240,11 +243,10 @@ e_composer_autosave_unregister (EMsgComposer *composer) if (state == NULL || state->filename == NULL) return; - if (e_composer_autosave_snapshot (composer)) { - close (state->fd); + close (state->fd); + + if (delete_file) g_unlink (state->filename); - } else - close (state->fd); g_object_set_data (G_OBJECT (composer), "autosave", NULL); } diff --git a/composer/e-composer-autosave.h b/composer/e-composer-autosave.h index b2db7b7dac..2f7181a4c8 100644 --- a/composer/e-composer-autosave.h +++ b/composer/e-composer-autosave.h @@ -28,7 +28,8 @@ G_BEGIN_DECLS GList * e_composer_autosave_find_orphans (GError **error); void e_composer_autosave_register (EMsgComposer *composer); -void e_composer_autosave_unregister (EMsgComposer *composer); +void e_composer_autosave_unregister (EMsgComposer *composer, + gboolean delete_file); gboolean e_composer_autosave_snapshot (EMsgComposer *composer); gint e_composer_autosave_get_fd (EMsgComposer *composer); const gchar * e_composer_autosave_get_filename (EMsgComposer *composer); diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h index c9f9174394..5cea10af89 100644 --- a/composer/e-composer-private.h +++ b/composer/e-composer-private.h @@ -120,10 +120,9 @@ struct _EMsgComposerPrivate { guint32 attachment_bar_visible : 1; guint32 is_alternative : 1; guint32 autosaved : 1; - guint32 mode_post : 1; - guint32 in_signature_insert : 1; + guint32 application_exiting : 1; CamelMimeMessage *redirect; diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 5b2d9526a7..ac9f452f07 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -2150,8 +2150,15 @@ static void msg_composer_dispose (GObject *object) { EMsgComposer *composer = E_MSG_COMPOSER (object); + gboolean delete_file; + + /* If the application is exiting, keep the autosave file so we can + * restore it later. Otherwise we're just closing this composer + * window, and the CLOSE action has already handled any unsaved + * changes, so we can safely delete the autosave file. */ + delete_file = !composer->priv->application_exiting; + e_composer_autosave_unregister (composer, delete_file); - e_composer_autosave_unregister (composer); e_composer_private_dispose (composer); /* Chain up to parent's dispose() method. */ @@ -2709,9 +2716,8 @@ msg_composer_class_init (EMsgComposerClass *class) E_TYPE_MSG_COMPOSER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -3744,7 +3750,7 @@ e_msg_composer_save_draft (EMsgComposer *composer) editor = GTKHTML_EDITOR (composer); - g_signal_emit (composer, signals[SAVE_DRAFT], 0, FALSE); + g_signal_emit (composer, signals[SAVE_DRAFT], 0); /* XXX This should be elsewhere. */ gtkhtml_editor_set_changed (editor, FALSE); @@ -4601,7 +4607,21 @@ e_msg_composer_request_close_all (void) for (iter = all_composers; iter != NULL; iter = next) { EMsgComposer *composer = iter->data; + + /* The CLOSE action will delete this list node, + * so grab the next one while we still can. */ next = iter->next; + + /* Try to autosave before closing. If it fails for + * some reason, the CLOSE action will still detect + * unsaved changes and prompt the user. + * + * FIXME If it /does/ prompt the user, the Cancel + * button will act the same as Discard Changes, + * which is misleading. + */ + composer->priv->application_exiting = TRUE; + e_composer_autosave_snapshot (composer); gtk_action_activate (ACTION (CLOSE)); } diff --git a/mail/ChangeLog b/mail/ChangeLog index 6818a4ca26..dde995a83f 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,15 @@ +2008-04-08 Matthew Barnes + + ** Fixes bug #523413 + + * em-composer-utils.c (save_draft_done): + Check the composer window's visibility to determine whether to + destroy the window. See the corresponding composer/ChangeLog + entry to get the full story. + + * em-composer-utils.c (em_utils_composer_save_draft_cb): + Remove the 'quit' parameter. + 2008-04-07 Takao Fujiwara reviewed by: Milan Crha diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index 089b3bfea7..f5a3a2ced0 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -459,7 +459,6 @@ struct _save_draft_info { struct emcs_t *emcs; EMsgComposer *composer; CamelMessageInfo *info; - int quit; }; static void @@ -511,7 +510,10 @@ save_draft_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *i emcs->drafts_uid = g_strdup (appended_uid); } - if (sdi->quit) + /* This is kind of a hack, but the composer's CLOSE action + * hides the window before emitting the "save-draft" signal. + * We use that to determine whether to destroy the composer. */ + if (!GTK_WIDGET_VISIBLE (sdi->composer)) gtk_widget_destroy (GTK_WIDGET (sdi->composer)); done: @@ -534,7 +536,7 @@ save_draft_folder (char *uri, CamelFolder *folder, gpointer data) } void -em_utils_composer_save_draft_cb (EMsgComposer *composer, int quit, gpointer user_data) +em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data) { const char *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS); CamelFolder *drafts_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS); @@ -559,7 +561,6 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, int quit, gpointer user sdi->emcs = user_data; if (sdi->emcs) emcs_ref(sdi->emcs); - sdi->quit = quit; if (account && account->drafts_folder_uri && strcmp (account->drafts_folder_uri, default_drafts_folder_uri) != 0) { diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h index bd7c9f404e..4af2c26f48 100644 --- a/mail/em-composer-utils.h +++ b/mail/em-composer-utils.h @@ -42,7 +42,7 @@ void em_composer_utils_setup_callbacks (struct _EMsgComposer *composer, struct _ #define em_composer_utils_setup_default_callbacks(composer) em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL) void em_utils_composer_send_cb(struct _EMsgComposer *composer, gpointer user_data); -void em_utils_composer_save_draft_cb(struct _EMsgComposer *composer, int quit, gpointer user_data); +void em_utils_composer_save_draft_cb(struct _EMsgComposer *composer, gpointer user_data); void em_utils_compose_new_message (const char *fromuri); -- cgit v1.2.3