aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/e-shell.c')
-rw-r--r--shell/e-shell.c93
1 files changed, 66 insertions, 27 deletions
diff --git a/shell/e-shell.c b/shell/e-shell.c
index c774285f0d..172939c387 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -95,6 +95,9 @@ struct _EShellPrivate {
/* Settings Dialog */
GtkWidget *settings_dialog;
+ /* If we're quitting and things are still busy, a timeout handler */
+ guint quit_timeout;
+
/* Whether the shell is succesfully initialized. This is needed during
the start-up sequence, to avoid CORBA calls to do make wrong things
to happen while the shell is initializing. */
@@ -354,6 +357,11 @@ impl_dispose (GObject *object)
priv->offline_handler = NULL;
}
+ if (priv->quit_timeout) {
+ g_source_remove(priv->quit_timeout);
+ priv->quit_timeout = 0;
+ }
+
for (p = priv->windows; p != NULL; p = p->next) {
EShellWindow *window;
@@ -756,21 +764,9 @@ e_shell_request_close_window (EShell *shell,
return TRUE;
}
- if (shell->priv->preparing_to_quit)
- return FALSE;
-
- /* If it's the last window, save settings and ask for confirmation before
- quitting. */
-
- e_shell_window_save_defaults (shell_window);
-
- if (e_shell_prepare_for_quit (shell))
- return TRUE;
- else
- return FALSE;
+ return e_shell_quit(shell);
}
-
#if 0 /* FIXME */
/**
* e_shell_peek_uri_schema_registry:
@@ -863,7 +859,6 @@ e_shell_close_all_windows (EShell *shell)
}
}
-
/**
* e_shell_get_line_status:
* @shell: A pointer to an EShell object.
@@ -1077,25 +1072,67 @@ e_shell_construct_result_to_string (EShellConstructResult result)
}
}
+/* timeout handler, so returns TRUE if we can't quit yet */
+static gboolean
+es_run_quit(EShell *shell)
+{
+ EShellPrivate *priv;
+ GSList *component_infos;
+ GSList *sp;
+ CORBA_boolean done_quit;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
+ priv = shell->priv;
+ priv->preparing_to_quit = TRUE;
+
+ component_infos = e_component_registry_peek_list (priv->component_registry);
+ done_quit = TRUE;
+ for (sp = component_infos; sp != NULL; sp = sp->next) {
+ EComponentInfo *info = sp->data;
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ done_quit = GNOME_Evolution_Component_quit(info->iface, &ev);
+ if (BONOBO_EX (&ev)) {
+ /* The component might not implement the interface, in which case we assume we can quit. */
+ done_quit = TRUE;
+ }
+
+ CORBA_exception_free (&ev);
+
+ if (!done_quit)
+ break;
+ }
+
+ if (done_quit) {
+ if (priv->quit_timeout) {
+ g_source_remove(priv->quit_timeout);
+ priv->quit_timeout = 0;
+ }
+ e_shell_close_all_windows(shell);
+ } else if (priv->quit_timeout == 0) {
+ priv->quit_timeout = g_timeout_add(500, (GSourceFunc)es_run_quit, shell);
+ }
+
+ return !done_quit;
+}
gboolean
-e_shell_prepare_for_quit (EShell *shell)
+e_shell_quit(EShell *shell)
{
+ if (shell->priv->preparing_to_quit)
+ return FALSE;
+
EShellPrivate *priv;
GSList *component_infos;
- GList *p;
GSList *sp;
CORBA_boolean can_quit;
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
priv = shell->priv;
- priv->preparing_to_quit = TRUE;
-
- /* Make all the windows insensitive so we have some modal-like
- behavior. */
- for (p = priv->windows; p != NULL; p = p->next)
- gtk_widget_set_sensitive (GTK_WIDGET (p->data), FALSE);
component_infos = e_component_registry_peek_list (priv->component_registry);
can_quit = TRUE;
@@ -1117,15 +1154,17 @@ e_shell_prepare_for_quit (EShell *shell)
break;
}
- /* Restore all the windows to be sensitive. */
- for (p = priv->windows; p != NULL; p = p->next)
- gtk_widget_set_sensitive (GTK_WIDGET (p->data), TRUE);
+ if (can_quit) {
+ GList *p = shell->priv->windows;
+
+ for (; p != NULL; p = p->next)
+ gtk_widget_set_sensitive (GTK_WIDGET (p->data), FALSE);
+ can_quit = !es_run_quit(shell);
+ }
- priv->preparing_to_quit = FALSE;
return can_quit;
}
-
EUserCreatableItemsHandler *
e_shell_peek_user_creatable_items_handler (EShell *shell)
{