From 83a766e5af1226d93d67476ea73bce921c681f0e Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Sun, 7 May 2000 06:47:44 +0000 Subject: Machinery for quitting and handling the relationship between a shell and its views. svn path=/trunk/; revision=2862 --- shell/ChangeLog | 39 ++++++++++++++++++++++ shell/e-shell-view-menu.c | 19 ++++++++++- shell/e-shell-view.c | 12 +++++++ shell/e-shell-view.h | 4 ++- shell/e-shell.c | 82 ++++++++++++++++++++++++++++++++++++++++++----- shell/e-shell.h | 4 +++ shell/e-shortcuts-view.c | 2 ++ shell/main.c | 17 ++++++++++ 8 files changed, 169 insertions(+), 10 deletions(-) diff --git a/shell/ChangeLog b/shell/ChangeLog index ec8efccb7e..508aee6be4 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,42 @@ +2000-05-07 Ettore Perazzoli + + * e-shell.c (e_shell_construct): Output a warning message if the + shortcut file is not found. + (setup_storages): Output a warning message if the local storage + cannot be initialized. + (destroy): Destroy all the views. + + * e-shell-view.c + (e_shell_view_construct): Ref the shell. + + * e-shortcuts-view.c + (e_shortcuts_view_construct): Ref the shortcuts. + + * e-shell.c: Create the "no_views_left" signal. New member + `views' in `EShellPrivate'. + (init): Initialize `views' to NULL. + (view_destroy_cb): Destroy handler for a view: remove the view + from `views', and emit the "no_views_left" signal if this was the + last view. + (e_shell_new_view): Add the new view to `views' and connect the + "destroy" signal to `view_destroy_cb'. + (destroy): Destroy the views. + + * e-shell.h: New signal "no_views_left". + + * e-shell-view-menu.c (command_quit): New function, implementation + of the "quit" command. + + * e-shell-view.c (e_shell_view_get_shell): New function. + + * e-shell.c (e_shell_quit): New function. + + * main.c (main): If it is not possible to create the shell for + some reason, pop up an error message. + (shell_destroy_cb): New function, signal handler for "destroy" on + the shell object. + (main): Connect it. + 2000-05-06 Ettore Perazzoli * e-shortcuts.c (destroy): Be safer about NULL objects. diff --git a/shell/e-shell-view-menu.c b/shell/e-shell-view-menu.c index d1fe6e959f..156b81ed30 100644 --- a/shell/e-shell-view-menu.c +++ b/shell/e-shell-view-menu.c @@ -29,6 +29,23 @@ #include "e-shell-view.h" #include "e-shell-view-menu.h" + +static void +command_quit (GtkWidget *widget, + gpointer data) +{ + EShellView *shell_view; + EShell *shell; + + shell_view = E_SHELL_VIEW (data); + + shell = e_shell_view_get_shell (shell_view); + e_shell_quit (shell); +} + + +/* Unimplemented commands. */ + #define DEFINE_UNIMPLEMENTED(func) \ static void \ func (GtkWidget *widget, gpointer data) \ @@ -47,11 +64,11 @@ DEFINE_UNIMPLEMENTED (command_new_journal_entry) DEFINE_UNIMPLEMENTED (command_new_note) DEFINE_UNIMPLEMENTED (command_open_selected_items) DEFINE_UNIMPLEMENTED (command_save_as) -DEFINE_UNIMPLEMENTED (command_quit) DEFINE_UNIMPLEMENTED (command_close_open_items) DEFINE_UNIMPLEMENTED (command_toggle_shortcut_bar) DEFINE_UNIMPLEMENTED (command_toggle_treeview) + /* * FIXME * diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 9651cce08c..8d83a9fca4 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -262,7 +262,9 @@ e_shell_view_construct (EShellView *shell_view, priv = shell_view->priv; + gtk_object_ref (GTK_OBJECT (shell)); priv->shell = shell; + priv->uri = g_strdup (uri); setup_widgets (shell_view); @@ -523,5 +525,15 @@ e_shell_view_display_uri (EShellView *shell_view, return TRUE; } + +EShell * +e_shell_view_get_shell (EShellView *shell_view) +{ + g_return_val_if_fail (shell_view != NULL, NULL); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->shell; +} + E_MAKE_TYPE (e_shell_view, "EShellView", EShellView, class_init, init, PARENT_TYPE) diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 0ca2f19eae..2cd39ebec9 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -65,9 +65,11 @@ void e_shell_view_construct (EShellView *shell_view, const char *uri); GtkWidget *e_shell_view_new (EShell *shell, const char *uri); -gboolean e_shell_view_display_uri (EShellView *shell, +gboolean e_shell_view_display_uri (EShellView *shell_view, const char *uri); +EShell *e_shell_view_get_shell (EShellView *shell_view); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/e-shell.c b/shell/e-shell.c index dbde28f890..3e5b9038f9 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -45,6 +45,8 @@ static GtkObjectClass *parent_class = NULL; struct _EShellPrivate { char *local_directory; + GList *views; + EStorageSet *storage_set; EShortcuts *shortcuts; EFolderTypeRepository *folder_type_repository; @@ -53,6 +55,13 @@ struct _EShellPrivate { #define SHORTCUTS_FILE_NAME "shortcuts.xml" #define LOCAL_STORAGE_DIRECTORY "local" +enum { + NO_VIEWS_LEFT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + /* Initialization of the storages. */ @@ -70,8 +79,10 @@ setup_storages (EShell *shell) local_storage = e_local_storage_open (local_storage_path); g_free (local_storage_path); - if (local_storage == NULL) + if (local_storage == NULL) { + g_warning (_("Cannot set up local storage -- %s"), local_storage_path); return FALSE; + } priv->storage_set = e_storage_set_new (); e_storage_set_add_storage (priv->storage_set, local_storage); @@ -79,6 +90,24 @@ setup_storages (EShell *shell) return TRUE; } + +/* EShellView destruction callback. */ + +static void +view_destroy_cb (GtkObject *object, + gpointer data) +{ + EShell *shell; + + g_assert (E_IS_SHELL_VIEW (object)); + + shell = E_SHELL (data); + shell->priv->views = g_list_remove (shell->priv->views, shell); + + if (shell->priv->views == NULL) + gtk_signal_emit (GTK_OBJECT (object), signals[NO_VIEWS_LEFT]); +} + /* GtkObject methods. */ @@ -87,6 +116,7 @@ destroy (GtkObject *object) { EShell *shell; EShellPrivate *priv; + GList *p; shell = E_SHELL (object); priv = shell->priv; @@ -100,6 +130,18 @@ destroy (GtkObject *object) if (priv->folder_type_repository != NULL) gtk_object_unref (GTK_OBJECT (priv->folder_type_repository)); + for (p = priv->views; p != NULL; p = p->next) { + EShellView *view; + + view = E_SHELL_VIEW (p->data); + + gtk_signal_disconnect_by_func (GTK_OBJECT (view), + GTK_SIGNAL_FUNC (view_destroy_cb), shell); + gtk_object_destroy (GTK_OBJECT (view)); + } + + g_list_free (priv->views); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -111,11 +153,20 @@ class_init (EShellClass *klass) { GtkObjectClass *object_class; + parent_class = gtk_type_class (gtk_object_get_type ()); + object_class = GTK_OBJECT_CLASS (klass); object_class->destroy = destroy; - parent_class = gtk_type_class (gtk_object_get_type ()); + signals[NO_VIEWS_LEFT] = + gtk_signal_new ("no_views_left", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EShellClass, no_views_left), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } static void @@ -125,6 +176,8 @@ init (EShell *shell) priv = g_new (EShellPrivate, 1); + priv->views = NULL; + priv->local_directory = NULL; priv->storage_set = NULL; priv->shortcuts = NULL; @@ -163,6 +216,8 @@ e_shell_construct (EShell *shell, if (! e_shortcuts_load (priv->shortcuts, shortcut_path)) { gtk_object_unref (GTK_OBJECT (priv->shortcuts)); priv->shortcuts = NULL; + + g_warning ("Cannot load shortcuts -- %s", shortcut_path); } g_free (shortcut_path); @@ -192,18 +247,19 @@ GtkWidget * e_shell_new_view (EShell *shell, const char *uri) { - GtkWidget *view_widget; - EShellView *shell_view; + GtkWidget *view; g_return_val_if_fail (shell != NULL, NULL); g_return_val_if_fail (E_IS_SHELL (shell), NULL); - view_widget = e_shell_view_new (shell, uri); - shell_view = E_SHELL_VIEW (view_widget); + view = e_shell_view_new (shell, uri); + + gtk_widget_show (view); + gtk_signal_connect (GTK_OBJECT (view), "destroy", GTK_SIGNAL_FUNC (view_destroy_cb), shell); - gtk_widget_show (view_widget); + shell->priv->views = g_list_prepend (shell->priv->views, view); - return view_widget; + return view; } @@ -234,5 +290,15 @@ e_shell_get_folder_type_repository (EShell *shell) return shell->priv->folder_type_repository; } + +void +e_shell_quit (EShell *shell) +{ + g_return_if_fail (shell != NULL); + g_return_if_fail (E_IS_SHELL (shell)); + + gtk_object_destroy (GTK_OBJECT (shell)); +} + E_MAKE_TYPE (e_shell, "EShell", EShell, class_init, init, PARENT_TYPE) diff --git a/shell/e-shell.h b/shell/e-shell.h index fd82b6b862..10b42f527d 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -56,6 +56,8 @@ struct _EShell { struct _EShellClass { GtkObjectClass parent_class; + + void (* no_views_left) (EShell *shell); }; @@ -71,6 +73,8 @@ EShortcuts *e_shell_get_shortcuts (EShell *shell); EStorageSet *e_shell_get_storage_set (EShell *shell); EFolderTypeRepository *e_shell_get_folder_type_repository (EShell *shell); +void e_shell_quit (EShell *shell); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/e-shortcuts-view.c b/shell/e-shortcuts-view.c index 8de29c49ce..a6f7f73fe1 100644 --- a/shell/e-shortcuts-view.c +++ b/shell/e-shortcuts-view.c @@ -134,6 +134,8 @@ e_shortcuts_view_construct (EShortcutsView *shortcuts_view, priv = shortcuts_view->priv; priv->shortcuts = shortcuts; + + gtk_object_ref (E_SHORTCUTS (shortcuts)); } GtkWidget * diff --git a/shell/main.c b/shell/main.c index 9c914c4dce..1bf97e8c74 100644 --- a/shell/main.c +++ b/shell/main.c @@ -29,6 +29,15 @@ #include "e-shell.h" + +static void +shell_destroy_cb (GtkObject *object, + gpointer data) +{ + gtk_main_quit (); +} + + #ifdef USING_OAF #include @@ -88,6 +97,14 @@ main (int argc, char **argv) } shell = e_shell_new (evolution_directory); + if (shell == NULL) { + e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, + _("Cannot initialize the Evolution shell.")); + exit (1); + } + + gtk_signal_connect (GTK_OBJECT (shell), "destroy", + GTK_SIGNAL_FUNC (shell_destroy_cb), NULL); e_shell_new_view (shell, NULL); -- cgit v1.2.3