From 3a96d74c2bcd6c646c8176d88e82836aeab5d9bf Mon Sep 17 00:00:00 2001 From: Not Zed Date: Wed, 4 Feb 2004 10:55:25 +0000 Subject: ** See bug #53683. 2004-02-04 Not Zed ** 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. svn path=/trunk/; revision=24609 --- shell/ChangeLog | 22 ++++++++++ shell/Evolution-Component.idl | 13 ++++-- shell/e-shell-window-commands.c | 4 +- shell/e-shell.c | 93 +++++++++++++++++++++++++++++------------ shell/e-shell.h | 2 +- shell/main.c | 58 ------------------------- 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 + + ** 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 * 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 (); } -- cgit v1.2.3