aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog22
-rw-r--r--shell/Evolution-Component.idl13
-rw-r--r--shell/e-shell-window-commands.c4
-rw-r--r--shell/e-shell.c93
-rw-r--r--shell/e-shell.h2
-rw-r--r--shell/main.c58
6 files changed, 99 insertions, 93 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index f9051b87cd..1268414dfb 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,25 @@
+2004-02-04 Not Zed <NotZed@Ximian.com>
+
+ ** See bug #53683.
+
+ * Evolution-Component.idl: added EvolutionComponent::quit() call.
+
+ * main.c (quit_box_new): removed, dont show quit box anymore at
+ the end, we've already shutdown by now with the new shutdown
+ sequence.
+
+ * e-shell-window-commands.c (command_quit): call e_shell_quit to
+ quit.
+
+ * e-shell.c (e_shell_prepare_for_quit): renamed es_run_quit, now
+ internal, and a gtktimeout function, so return code inverted.
+ (e_shell_quit): new public entry, find out if we can shutdown, if
+ so, then trigger a shutdown.
+ (e_shell_request_close_window): just call e_shell_quit to exit
+ when we've run out of windows.
+ (e_shell_quit): desensitise all of the app windows before running
+ shutdown. looks a bit weird, but not doing so looks worse.
+
2004-02-03 Dan Winship <danw@ximian.com>
* e-activity-handler.c:
diff --git a/shell/Evolution-Component.idl b/shell/Evolution-Component.idl
index dc23fc40be..873cd6b7d0 100644
--- a/shell/Evolution-Component.idl
+++ b/shell/Evolution-Component.idl
@@ -12,7 +12,6 @@
module GNOME {
module Evolution {
-
/* A type of item that the component can create when asked by the user,
e.g. a mail message or an appointment. */
struct CreatableItemType {
@@ -29,7 +28,6 @@ module Evolution {
exception Failed {};
exception UnknownType {};
-
/*** Upgrade path. ***/
boolean upgradeFromVersion (in short major, in short minor, in short revision);
@@ -43,10 +41,17 @@ module Evolution {
out Bonobo::Control statusbar_control)
raises (Failed);
- /* Request the component to quit. The component will return TRUE
- if it agrees to quit and FALSE if it doesn't want to. */
+ /* Check if the component can quit.
+ Do not perform any quit-related tasks however.
+ May be called multiple times, depending on user interaction. */
boolean requestQuit ();
+ /* Ask the component to quit. Returns TRUE when the
+ component has completed any closing-down tasks, and
+ is ready to exit(). This will be called repeatedly
+ at intervals until it returns TRUE. */
+ boolean quit ();
+
/* Notify the component of whether the shell is currently
running in interactive mode or not. (I.e. basically,
whether there are any Evolution windows on the screen.)
diff --git a/shell/e-shell-window-commands.c b/shell/e-shell-window-commands.c
index fa45f34fb0..9640d86a0d 100644
--- a/shell/e-shell-window-commands.c
+++ b/shell/e-shell-window-commands.c
@@ -97,9 +97,7 @@ command_quit (BonoboUIComponent *uih,
EShell *shell = e_shell_window_peek_shell (window);
e_shell_window_save_defaults (window);
-
- if (e_shell_prepare_for_quit (shell))
- e_shell_close_all_windows (shell);
+ e_shell_quit(shell);
}
static void
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)
{
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 2dcac9fc6d..976016da97 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -133,7 +133,7 @@ void e_shell_show_settings (EShell *shell,
const char *type,
EShellWindow *shell_window);
-gboolean e_shell_prepare_for_quit (EShell *shell);
+gboolean e_shell_quit (EShell *shell);
const char *e_shell_construct_result_to_string (EShellConstructResult result);
diff --git a/shell/main.c b/shell/main.c
index eb0af46f70..18762df621 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -97,68 +97,10 @@ static gboolean force_migrate = FALSE;
static char *default_component_id = NULL;
static char *evolution_debug_log = NULL;
-
-static GtkWidget *
-quit_box_new (void)
-{
- GtkWidget *window;
- GtkWidget *label;
- GtkWidget *frame;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
- gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
-
- /* (Just to prevent smart-ass window managers like Sawfish from setting
- the make the dialog as big as the standard Evolution window). */
- gtk_window_set_wmclass (GTK_WINDOW (window), "evolution-quit", "Evolution:quit");
-
- e_make_widget_backing_stored (window);
-
- gtk_window_set_title (GTK_WINDOW (window), _("Evolution"));
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (window), frame);
-
- label = gtk_label_new (_("Evolution is now exiting ..."));
- gtk_misc_set_padding (GTK_MISC (label), 30, 25);
-
- gtk_container_add (GTK_CONTAINER (frame), label);
-
- gtk_widget_show_now (frame);
- gtk_widget_show_now (label);
- gtk_widget_show_now (window);
-
- /* For some reason, the window fails to update without this
- sometimes. */
- gtk_widget_queue_draw (window);
- gtk_widget_queue_draw (label);
- gtk_widget_queue_draw (frame);
-
- gdk_flush ();
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- gdk_flush ();
-
- return window;
-}
-
static void
no_windows_left_cb (EShell *shell, gpointer data)
{
- GtkWidget *quit_box;
-
- quit_box = quit_box_new ();
- g_object_add_weak_pointer (G_OBJECT (quit_box), (void **) &quit_box);
-
bonobo_object_unref (BONOBO_OBJECT (shell));
-
- if (quit_box != NULL)
- gtk_widget_destroy (quit_box);
-
bonobo_main_quit ();
}