aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-06-15 21:10:05 +0800
committerMilan Crha <mcrha@redhat.com>2010-06-15 21:10:05 +0800
commitdfb3b918b0dfe988cdf1e45dc129cb02fea59107 (patch)
treec278d2b659aedfc2d0d09cf88831fce0d6cb54e0
parenta55021bcef7eb082b48e56aac361bd35a3a77b64 (diff)
downloadgsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar.gz
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar.bz2
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar.lz
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar.xz
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.tar.zst
gsoc2013-evolution-dfb3b918b0dfe988cdf1e45dc129cb02fea59107.zip
Bug #617557 - Quits without asking user to save unfinished messages
The second attempt.
-rw-r--r--composer/e-composer-actions.c45
-rw-r--r--composer/e-msg-composer.c113
-rw-r--r--composer/e-msg-composer.h3
3 files changed, 114 insertions, 47 deletions
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);