diff options
-rw-r--r-- | shell/ChangeLog | 11 | ||||
-rw-r--r-- | shell/e-shell-view.c | 101 |
2 files changed, 109 insertions, 3 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 7b1d425981..dedaf7188f 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,14 @@ +2000-10-06 Ettore Perazzoli <ettore@helixcode.com> + + * e-shell-view.c: New member `sockets. + (init): Init to NULL. + (destroy): Free. Also, disconnect the "destroy" signal from them + before the controls get destroyed. + (find_socket): New function. [Thanks Dan.] + (socket_destroy_cb): New callback for the destruction of a socket. + (get_control_for_uri): Get the socket through `find_socket()' and + connect the "destroy" signal to `socket_destroy_cb'. + 2000-10-06 Chris Toshok <toshok@helixcode.com> * e-storage-set-view.c (insert_storages): call diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index b748347a40..acd829def3 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -30,6 +30,7 @@ #include <gnome.h> #include <bonobo.h> +#include <bonobo/bonobo-socket.h> #include <libgnomeui/gnome-window-icon.h> #include "widgets/misc/e-clipped-label.h" @@ -101,6 +102,9 @@ struct _EShellViewPrivate { /* Status of the progress bar. */ int progress_bar_value; + + /* List of sockets we created. */ + GList *sockets; }; enum { @@ -547,10 +551,21 @@ destroy (GtkObject *object) { EShellView *shell_view; EShellViewPrivate *priv; + GList *p; shell_view = E_SHELL_VIEW (object); priv = shell_view->priv; + for (p = priv->sockets; p != NULL; p = p->next) { + GtkWidget *socket_widget; + int destroy_connection_id; + + socket_widget = GTK_WIDGET (p->data); + destroy_connection_id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (socket_widget), + "e_shell_view_destroy_connection_id")); + gtk_signal_disconnect (GTK_OBJECT (socket_widget), destroy_connection_id); + } + g_hash_table_foreach (priv->uri_to_control, hash_forall_destroy_control, NULL); g_hash_table_destroy (priv->uri_to_control); @@ -1058,6 +1073,73 @@ setup_evolution_shell_view_interface (EShellView *shell_view, BONOBO_OBJECT (shell_view_interface)); } + +/* Socket destruction handling. */ + +static GtkWidget * +find_socket (GtkContainer *container) +{ + GList *children, *tmp; + + children = gtk_container_children (container); + while (children) { + if (BONOBO_IS_SOCKET (children->data)) + return children->data; + else if (GTK_IS_CONTAINER (children->data)) { + GtkWidget *socket = find_socket (children->data); + if (socket) + return socket; + } + tmp = children->next; + g_list_free_1 (children); + children = tmp; + } + return NULL; +} + +static void +socket_destroy_cb (GtkWidget *socket_widget, gpointer data) +{ + EShellView *shell_view; + EShellViewPrivate *priv; + EFolder *folder; + GtkWidget *control; + const char *uri; + char *copy_of_uri; + + shell_view = E_SHELL_VIEW (data); + priv = shell_view->priv; + + uri = (const char *) gtk_object_get_data (GTK_OBJECT (socket_widget), "e_shell_view_folder_uri"); + + /* Strdup here as the string will be freed when the socket is destroyed. */ + copy_of_uri = g_strdup (uri); + + control = g_hash_table_lookup (priv->uri_to_control, uri); + if (control == NULL) { + g_warning ("What?! Destroyed socket for non-existing URI? -- %s", uri); + return; + } + + priv->sockets = g_list_remove (priv->sockets, socket_widget); + + gtk_widget_destroy (control); + g_hash_table_remove (priv->uri_to_control, uri); + + folder = e_storage_set_get_folder (e_shell_get_storage_set (priv->shell), + get_storage_set_path_from_uri (uri)); + + e_shell_view_display_uri (shell_view, NULL); + + e_notice (GTK_WINDOW (shell_view), GNOME_MESSAGE_BOX_ERROR, + _("Ooops! The view for `%s' has died unexpectedly. :-(\n" + "This probably means that the %s component has crashed."), + uri, e_folder_get_type_string (folder)); + + g_free (copy_of_uri); +} + + /* Create a new view for @uri with @control. It assumes a view for @uri does not exist yet. */ static GtkWidget * get_control_for_uri (EShellView *shell_view, @@ -1074,6 +1156,9 @@ get_control_for_uri (EShellView *shell_view, const char *folder_type; GtkWidget *control; CORBA_Environment ev; + Bonobo_UIContainer container; + GtkWidget *socket; + int destroy_connection_id; priv = shell_view->priv; @@ -1116,9 +1201,19 @@ get_control_for_uri (EShellView *shell_view, CORBA_exception_free (&ev); - control = bonobo_widget_new_control_from_objref ( - corba_control, - bonobo_ui_component_get_container (priv->ui_component)); + container = bonobo_ui_component_get_container (priv->ui_component); + control = bonobo_widget_new_control_from_objref (corba_control, container); + + socket = find_socket (GTK_CONTAINER (control)); + destroy_connection_id = gtk_signal_connect (GTK_OBJECT (socket), "destroy", + GTK_SIGNAL_FUNC (socket_destroy_cb), + shell_view); + gtk_object_set_data (GTK_OBJECT (socket), + "e_shell_view_destroy_connection_id", + GINT_TO_POINTER (destroy_connection_id)); + gtk_object_set_data_full (GTK_OBJECT (socket), "e_shell_view_folder_uri", g_strdup (uri), g_free); + + priv->sockets = g_list_prepend (priv->sockets, socket); setup_evolution_shell_view_interface (shell_view, control); |