diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ChangeLog | 20 | ||||
-rw-r--r-- | shell/Evolution-ShellComponent.idl | 8 | ||||
-rw-r--r-- | shell/e-shell-view-menu.c | 4 | ||||
-rw-r--r-- | shell/e-shell.c | 64 | ||||
-rw-r--r-- | shell/e-shell.h | 2 | ||||
-rw-r--r-- | shell/evolution-shell-component-client.c | 42 | ||||
-rw-r--r-- | shell/evolution-shell-component-client.h | 4 | ||||
-rw-r--r-- | shell/evolution-shell-component.c | 34 | ||||
-rw-r--r-- | shell/evolution-shell-component.h | 46 | ||||
-rw-r--r-- | shell/evolution-test-component.c | 26 |
10 files changed, 228 insertions, 22 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 11701f170e..421bd64a6b 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,23 @@ +2002-05-15 Ettore Perazzoli <ettore@ximian.com> + + * e-shell-view-menu.c (command_quit): Check with + e_shell_prepare_for_quit() before quitting. + + * e-shell.c (e_shell_prepare_for_quit): New. + + * evolution-test-component.c (request_quit_fn): New function + asking for confirmation to quit. + + * evolution-shell-component.c (evolution_shell_component_new): New + arg @request_quit_fn. + (impl_requestQuit): New, implementation for + EvolutionShellComponent::requestQuit. + (evolution_shell_component_result_to_string): Handle + EVOLUTION_SHELL_COMPONENT_CANCEL. + (evolution_shell_component_client_request_quit): New. + + * Evolution-ShellComponent.idl (requestQuit): New. + 2002-05-15 Iain <iain@ximian.com> * e-corba-storage-registry.c (impl_StorageRegistry_addStorage): Remove diff --git a/shell/Evolution-ShellComponent.idl b/shell/Evolution-ShellComponent.idl index 495553e8f7..e450aa719f 100644 --- a/shell/Evolution-ShellComponent.idl +++ b/shell/Evolution-ShellComponent.idl @@ -137,11 +137,19 @@ module Evolution { @show_dialog is true, display a progress dialog for the operation as well. */ void sendReceive (in boolean show_dialog); + + /* Request the component to quit. The component should report + through the listener (through OK or CANCEL) whether the + shell can quit safely. (This is meant to be used for + confirmations before quitting.) */ + oneway void requestQuit (in ShellComponentListener listener) + raises (Busy); }; interface ShellComponentListener { enum Result { OK, + CANCEL, UNSUPPORTED_OPERATION, UNSUPPORTED_TYPE, EXISTS, diff --git a/shell/e-shell-view-menu.c b/shell/e-shell-view-menu.c index eff7aa0817..efbb5898a5 100644 --- a/shell/e-shell-view-menu.c +++ b/shell/e-shell-view-menu.c @@ -147,7 +147,9 @@ command_quit (BonoboUIComponent *uih, shell_view = E_SHELL_VIEW (data); shell = e_shell_view_get_shell (shell_view); - e_shell_destroy_all_views (shell); + + if (e_shell_prepare_for_quit (shell)) + e_shell_destroy_all_views (shell); } static void diff --git a/shell/e-shell.c b/shell/e-shell.c index ff227dbb23..6353a45f55 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -70,6 +70,7 @@ #include "e-splash.h" #include "e-uri-schema-registry.h" +#include "evolution-shell-component-client.h" #include "evolution-shell-component-utils.h" #include "evolution-storage-set-view-factory.h" @@ -2145,6 +2146,69 @@ e_shell_construct_result_to_string (EShellConstructResult result) } +static void +prepare_for_quit_callback (EvolutionShellComponentClient *client, + EvolutionShellComponentResult result, + void *data) +{ + GNOME_Evolution_ShellComponentListener_Result *result_return; + + result_return = (GNOME_Evolution_ShellComponentListener_Result *) data; + *result_return = result; +} + +gboolean +e_shell_prepare_for_quit (EShell *shell) +{ + EShellPrivate *priv; + GList *component_ids; + GList *p; + gboolean retval; + + g_return_val_if_fail (E_IS_SHELL (shell), FALSE); + + priv = shell->priv; + + /* Make all the views insensitive so we have some modal-like + behavior. */ + for (p = priv->views; p != NULL; p = p->next) + gtk_widget_set_sensitive (GTK_WIDGET (p->data), FALSE); + + component_ids = e_component_registry_get_id_list (priv->component_registry); + + for (p = component_ids; p != NULL; p = p->next) { + EvolutionShellComponentClient *client; + const char *id; + GNOME_Evolution_ShellComponentListener_Result result; + + id = (const char *) p->data; + client = e_component_registry_get_component_by_id (priv->component_registry, id); + + result = (GNOME_Evolution_ShellComponentListener_Result) -1; + + evolution_shell_component_client_request_quit (client, prepare_for_quit_callback, &result); + + while (result == (GNOME_Evolution_ShellComponentListener_Result) -1) + gtk_main_iteration (); + + if (result != GNOME_Evolution_ShellComponentListener_OK) { + retval = FALSE; + goto end; + } + } + + retval = TRUE; + + end: + /* Restore all the views to be sensitive. */ + for (p = priv->views; p != NULL; p = p->next) + gtk_widget_set_sensitive (GTK_WIDGET (p->data), TRUE); + + e_free_string_list (component_ids); + return retval; +} + + E_MAKE_X_TYPE (e_shell, "EShell", EShell, class_init, init, PARENT_TYPE, POA_GNOME_Evolution_Shell__init, diff --git a/shell/e-shell.h b/shell/e-shell.h index bf211f886b..119cb87b14 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -150,6 +150,8 @@ Bonobo_ConfigDatabase e_shell_get_config_db (EShe EComponentRegistry *e_shell_get_component_registry (EShell *shell); EShellUserCreatableItemsHandler *e_shell_get_user_creatable_items_handler (EShell *shell); +gboolean e_shell_prepare_for_quit (EShell *shell); + const char *e_shell_construct_result_to_string (EShellConstructResult result); diff --git a/shell/evolution-shell-component-client.c b/shell/evolution-shell-component-client.c index 2a1b2e0a2d..7b8051e0c1 100644 --- a/shell/evolution-shell-component-client.c +++ b/shell/evolution-shell-component-client.c @@ -839,5 +839,47 @@ evolution_shell_component_client_populate_folder_context_menu (EvolutionShellCom } +void +evolution_shell_component_client_request_quit (EvolutionShellComponentClient *shell_component_client, + EvolutionShellComponentClientCallback callback, + void *data) +{ + EvolutionShellComponentClientPrivate *priv; + GNOME_Evolution_ShellComponent corba_shell_component; + CORBA_Environment ev; + + g_return_if_fail (EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component_client)); + g_return_if_fail (callback != NULL); + + priv = shell_component_client->priv; + + if (priv->callback != NULL) { + (* callback) (shell_component_client, EVOLUTION_SHELL_COMPONENT_BUSY, data); + return; + } + + create_listener_interface (shell_component_client); + + CORBA_exception_init (&ev); + + corba_shell_component = BONOBO_OBJREF (shell_component_client); + + priv->callback = callback; + priv->callback_data = data; + + GNOME_Evolution_ShellComponent_requestQuit (corba_shell_component, priv->listener_interface, &ev); + + if (ev._major != CORBA_NO_EXCEPTION && priv->callback != NULL) { + (* callback) (shell_component_client, + shell_component_result_from_corba_exception (&ev), + data); + priv->callback = NULL; + priv->callback_data = NULL; + } + + CORBA_exception_free (&ev); +} + + E_MAKE_TYPE (evolution_shell_component_client, "EvolutionShellComponentClient", EvolutionShellComponentClient, class_init, init, PARENT_TYPE) diff --git a/shell/evolution-shell-component-client.h b/shell/evolution-shell-component-client.h index 9973f9a931..fdb3650432 100644 --- a/shell/evolution-shell-component-client.h +++ b/shell/evolution-shell-component-client.h @@ -124,6 +124,10 @@ void evolution_shell_component_client_populate_folder_context_menu (EvolutionS const char *physical_uri, const char *type); +void evolution_shell_component_client_request_quit (EvolutionShellComponentClient *shell_component_client, + EvolutionShellComponentClientCallback callback, + void *data); + #ifdef cplusplus } #endif /* cplusplus */ diff --git a/shell/evolution-shell-component.c b/shell/evolution-shell-component.c index b1eab010de..b3383b742f 100644 --- a/shell/evolution-shell-component.c +++ b/shell/evolution-shell-component.c @@ -64,6 +64,7 @@ struct _EvolutionShellComponentPrivate { EvolutionShellComponentXferFolderFn xfer_folder_fn; EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn; EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn; + EvolutionShellComponentRequestQuitFn request_quit_fn; EvolutionShellClient *owner_client; @@ -670,6 +671,32 @@ impl_sendReceive (PortableServer_Servant servant, gtk_signal_emit (GTK_OBJECT (shell_component), signals[SEND_RECEIVE], show_dialog); } +static void +impl_requestQuit (PortableServer_Servant servant, + const GNOME_Evolution_ShellComponentListener listener, + CORBA_Environment *ev) +{ + EvolutionShellComponent *shell_component; + gboolean allow_quit; + + shell_component = EVOLUTION_SHELL_COMPONENT (bonobo_object_from_servant (servant)); + + if (shell_component->priv->request_quit_fn == NULL) + allow_quit = TRUE; + else + allow_quit = (* shell_component->priv->request_quit_fn) (shell_component, + shell_component->priv->closure); + + if (allow_quit) + GNOME_Evolution_ShellComponentListener_notifyResult (listener, + GNOME_Evolution_ShellComponentListener_OK, + ev); + else + GNOME_Evolution_ShellComponentListener_notifyResult (listener, + GNOME_Evolution_ShellComponentListener_CANCEL, + ev); +} + /* GtkObject methods. */ @@ -872,6 +899,7 @@ class_init (EvolutionShellComponentClass *klass) epv->populateFolderContextMenu = impl_populateFolderContextMenu; epv->userCreateNewItem = impl_userCreateNewItem; epv->sendReceive = impl_sendReceive; + epv->requestQuit = impl_requestQuit; shell_component_class = EVOLUTION_SHELL_COMPONENT_CLASS (object_class); shell_component_class->owner_died = impl_owner_died; @@ -914,6 +942,7 @@ evolution_shell_component_construct (EvolutionShellComponent *shell_component, EvolutionShellComponentXferFolderFn xfer_folder_fn, EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, + EvolutionShellComponentRequestQuitFn request_quit_fn, void *closure) { EvolutionShellComponentPrivate *priv; @@ -931,6 +960,7 @@ evolution_shell_component_construct (EvolutionShellComponent *shell_component, priv->xfer_folder_fn = xfer_folder_fn; priv->populate_folder_context_menu_fn = populate_folder_context_menu_fn; priv->get_dnd_selection_fn = get_dnd_selection_fn; + priv->request_quit_fn = request_quit_fn; priv->closure = closure; @@ -976,6 +1006,7 @@ evolution_shell_component_new (const EvolutionShellComponentFolderType folder_ty EvolutionShellComponentXferFolderFn xfer_folder_fn, EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, + EvolutionShellComponentRequestQuitFn request_quit_fn, void *closure) { EvolutionShellComponent *new; @@ -993,6 +1024,7 @@ evolution_shell_component_new (const EvolutionShellComponentFolderType folder_ty xfer_folder_fn, populate_folder_context_menu_fn, get_dnd_selection_fn, + request_quit_fn, closure); return new; @@ -1041,6 +1073,8 @@ evolution_shell_component_result_to_string (EvolutionShellComponentResult result switch (result) { case EVOLUTION_SHELL_COMPONENT_OK: return _("Success"); + case EVOLUTION_SHELL_COMPONENT_CANCEL: + return _("Cancel"); case EVOLUTION_SHELL_COMPONENT_CORBAERROR: return _("CORBA error"); case EVOLUTION_SHELL_COMPONENT_INTERRUPTED: diff --git a/shell/evolution-shell-component.h b/shell/evolution-shell-component.h index b10613cb34..8cd1f98d96 100644 --- a/shell/evolution-shell-component.h +++ b/shell/evolution-shell-component.h @@ -52,6 +52,7 @@ typedef struct _EvolutionShellComponentClass EvolutionShellComponentClass; enum _EvolutionShellComponentResult { EVOLUTION_SHELL_COMPONENT_OK, + EVOLUTION_SHELL_COMPONENT_CANCEL, EVOLUTION_SHELL_COMPONENT_CORBAERROR, EVOLUTION_SHELL_COMPONENT_INTERRUPTED, EVOLUTION_SHELL_COMPONENT_INVALIDARG, @@ -110,6 +111,9 @@ typedef char * (* EvolutionShellComponentGetDndSelectionFn) (EvolutionShellCompo int *selection_length_return, void *closure); +typedef gboolean (* EvolutionShellComponentRequestQuitFn) (EvolutionShellComponent *shell_component, + void *closure); + struct _EvolutionShellComponentFolderType { char *name; char *icon_name; @@ -161,26 +165,28 @@ struct _EvolutionShellComponentClass { }; -GtkType evolution_shell_component_get_type (void); -void evolution_shell_component_construct (EvolutionShellComponent *shell_component, - const EvolutionShellComponentFolderType folder_types[], - const char *external_uri_schemas[], - EvolutionShellComponentCreateViewFn create_view_fn, - EvolutionShellComponentCreateFolderFn create_folder_fn, - EvolutionShellComponentRemoveFolderFn remove_folder_fn, - EvolutionShellComponentXferFolderFn xfer_folder_fn, - EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, - EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, - void *closure); -EvolutionShellComponent *evolution_shell_component_new (const EvolutionShellComponentFolderType folder_types[], - const char *external_uri_schemas[], - EvolutionShellComponentCreateViewFn create_view_fn, - EvolutionShellComponentCreateFolderFn create_folder_fn, - EvolutionShellComponentRemoveFolderFn remove_folder_fn, - EvolutionShellComponentXferFolderFn xfer_folder_fn, - EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, - EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, - void *closure); +GtkType evolution_shell_component_get_type (void); +void evolution_shell_component_construct (EvolutionShellComponent *shell_component, + const EvolutionShellComponentFolderType folder_types[], + const char *external_uri_schemas[], + EvolutionShellComponentCreateViewFn create_view_fn, + EvolutionShellComponentCreateFolderFn create_folder_fn, + EvolutionShellComponentRemoveFolderFn remove_folder_fn, + EvolutionShellComponentXferFolderFn xfer_folder_fn, + EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, + EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, + EvolutionShellComponentRequestQuitFn request_quit_fn, + void *closure); +EvolutionShellComponent *evolution_shell_component_new (const EvolutionShellComponentFolderType folder_types[], + const char *external_uri_schemas[], + EvolutionShellComponentCreateViewFn create_view_fn, + EvolutionShellComponentCreateFolderFn create_folder_fn, + EvolutionShellComponentRemoveFolderFn remove_folder_fn, + EvolutionShellComponentXferFolderFn xfer_folder_fn, + EvolutionShellComponentPopulateFolderContextMenuFn populate_folder_context_menu_fn, + EvolutionShellComponentGetDndSelectionFn get_dnd_selection_fn, + EvolutionShellComponentRequestQuitFn request_quit_fn, + void *closure); EvolutionShellClient *evolution_shell_component_get_owner (EvolutionShellComponent *shell_component); void evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *shell_component, diff --git a/shell/evolution-test-component.c b/shell/evolution-test-component.c index 7dc991fcf3..5c2d36b16e 100644 --- a/shell/evolution-test-component.c +++ b/shell/evolution-test-component.c @@ -488,6 +488,28 @@ create_view_fn (EvolutionShellComponent *shell_component, return EVOLUTION_SHELL_COMPONENT_OK; } +static gboolean +request_quit_fn (EvolutionShellComponent *shell_component, + void *closure) +{ + GtkWidget *confirm_dialog; + GtkWidget *label; + int button; + + confirm_dialog = gnome_dialog_new ("Quit?", GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL); + label = gtk_label_new ("Please confirm that you want to quit now."); + gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (confirm_dialog)->vbox), label); + gtk_widget_show_all (confirm_dialog); + + button = gnome_dialog_run (GNOME_DIALOG (confirm_dialog)); + gtk_widget_destroy (confirm_dialog); + + if (button == 0) + return TRUE; /* OK */ + else + return FALSE; /* Cancel */ +} + /* Callbacks. */ @@ -547,7 +569,9 @@ register_component (void) shell_component = evolution_shell_component_new (folder_types, NULL, create_view_fn, - NULL, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, + request_quit_fn, + NULL); gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set", GTK_SIGNAL_FUNC (owner_set_callback), NULL); |