aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-shell-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/e-shell-view.c')
-rw-r--r--shell/e-shell-view.c101
1 files changed, 98 insertions, 3 deletions
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);