aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2003-07-24 05:58:28 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2003-07-24 05:58:28 +0800
commita238c463ddea2a3ddb3a530c75a3a7e1083c9c2d (patch)
tree2b53e3235c7067bf8ab94dd3ede84f54cf811809
parent0dd1d18f1ab6609c1c38f9e97a0702cc71ce2705 (diff)
downloadgsoc2013-evolution-a238c463ddea2a3ddb3a530c75a3a7e1083c9c2d.tar.gz
gsoc2013-evolution-a238c463ddea2a3ddb3a530c75a3a7e1083c9c2d.tar.zst
gsoc2013-evolution-a238c463ddea2a3ddb3a530c75a3a7e1083c9c2d.zip
Create a new EShellWindow and show it.
* main.c (idle_cb): Create a new EShellWindow and show it. * e-storage.c: New signal "async_open_folder". (impl_async_open_folder): Removed. (class_init): Declare new signal. * e-shell.c (setup_components): Don't actually activate any components. * e-storage-browser.c, e-storage-browser.h: New. * e-shell-window.c, e-shell-window.h: New. * e-shell-marshal.list: Add an entry for NONE:STRING,POINTER,POINTER. * Evolution.idl: Include Evolution-Component.idl. * Evolution-Component.idl: New interface for Evolution components. svn path=/trunk/; revision=21925
-rw-r--r--shell/ChangeLog22
-rw-r--r--shell/Evolution-Component.idl23
-rw-r--r--shell/Evolution-ShellComponent.idl2
-rw-r--r--shell/Evolution.idl1
-rw-r--r--shell/Makefile.am43
-rw-r--r--shell/e-folder.c1
-rw-r--r--shell/e-shell-marshal.list1
-rw-r--r--shell/e-shell-window.c381
-rw-r--r--shell/e-shell-window.h58
-rw-r--r--shell/e-shell.c3
-rw-r--r--shell/e-storage-browser.c310
-rw-r--r--shell/e-storage-browser.h79
-rw-r--r--shell/e-storage.c27
-rw-r--r--shell/e-storage.h15
-rw-r--r--shell/main.c9
15 files changed, 934 insertions, 41 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 1836661ca9..93fd01791b 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,25 @@
+2003-07-23 Ettore Perazzoli <ettore@ximian.com>
+
+ * main.c (idle_cb): Create a new EShellWindow and show it.
+
+ * e-storage.c: New signal "async_open_folder".
+ (impl_async_open_folder): Removed.
+ (class_init): Declare new signal.
+
+ * e-shell.c (setup_components): Don't actually activate any
+ components.
+
+ * e-storage-browser.c, e-storage-browser.h: New.
+
+ * e-shell-window.c, e-shell-window.h: New.
+
+ * e-shell-marshal.list: Add an entry for
+ NONE:STRING,POINTER,POINTER.
+
+ * Evolution.idl: Include Evolution-Component.idl.
+
+ * Evolution-Component.idl: New interface for Evolution components.
+
2003-07-23 Dan Winship <danw@ximian.com>
* Makefile.am: Use EVO_MARSHAL_RULE
diff --git a/shell/Evolution-Component.idl b/shell/Evolution-Component.idl
new file mode 100644
index 0000000000..665fa213b1
--- /dev/null
+++ b/shell/Evolution-Component.idl
@@ -0,0 +1,23 @@
+/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Interface for the Evolution components.
+ *
+ * Authors:
+ * Ettore Perazzoli <ettore@ximian.com>
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ */
+
+#include <Bonobo.idl>
+
+module GNOME {
+module Evolution {
+
+ interface Component : Bonobo::Unknown {
+ /* Create the controls for embedding in the shell. */
+ void createControls (out Bonobo::Control sidebar_control,
+ out Bonobo::Control view_control);
+ };
+
+};
+};
diff --git a/shell/Evolution-ShellComponent.idl b/shell/Evolution-ShellComponent.idl
index 90cd6fa57d..88a594853d 100644
--- a/shell/Evolution-ShellComponent.idl
+++ b/shell/Evolution-ShellComponent.idl
@@ -97,7 +97,7 @@ module Evolution {
/* Send debugging output to the file specified. */
void debug (in string log_path);
- /* Create a view for the specified @physical URI. */
+ /* Create a view for the specified @physical URI. FIXME */
Bonobo::Control createView (in string physical_uri,
in string type,
in string view_info)
diff --git a/shell/Evolution.idl b/shell/Evolution.idl
index 6692bd028d..01ce673724 100644
--- a/shell/Evolution.idl
+++ b/shell/Evolution.idl
@@ -13,6 +13,7 @@
#include <Evolution-common.idl>
#include <Evolution-Activity.idl>
+#include <Evolution-Component.idl>
#include <Evolution-ConfigControl.idl>
#include <Evolution-Session.idl>
#include <Evolution-ShellComponent.idl>
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 1631ccdef0..27430babee 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -29,6 +29,7 @@ noinst_PROGRAMS = evolution evolution-test-component
IDLS = \
Evolution-Activity.idl \
Evolution-ConfigControl.idl \
+ Evolution-Component.idl \
Evolution-Offline.idl \
Evolution-Session.idl \
Evolution-Shell.idl \
@@ -113,19 +114,28 @@ eshellincludedir = $(privincludedir)/shell
eshellinclude_HEADERS = \
Evolution.h \
- e-folder.h \
+ e-corba-storage.h \
+ e-folder-dnd-bridge.h \
e-folder-list.h \
e-folder-tree.h \
+ e-folder-type-registry.h \
+ e-folder.h \
+ e-icon-factory.h \
e-shell-corba-icon-utils.h \
+ e-shell-utils.h \
+ e-storage-browser.h \
+ e-storage-set-view.h \
+ e-storage-set.h \
+ e-storage.h \
evolution-activity-client.h \
evolution-config-control.h \
evolution-folder-selector-button.h \
evolution-session.h \
evolution-shell-client.h \
evolution-shell-component-client.h \
- evolution-shell-component.h \
evolution-shell-component-dnd.h \
evolution-shell-component-utils.h \
+ evolution-shell-component.h \
evolution-shell-view.h \
evolution-storage-listener.h \
evolution-storage-set-view-listener.h \
@@ -134,25 +144,34 @@ eshellinclude_HEADERS = \
libeshell_la_SOURCES = \
$(IDL_GENERATED) \
- e-folder.c \
+ e-corba-storage.c \
+ e-folder-dnd-bridge.c \
e-folder-list.c \
e-folder-tree.c \
+ e-folder-type-registry.c \
+ e-folder.c \
+ e-icon-factory.c \
e-shell-corba-icon-utils.c \
+ e-shell-marshal.c \
+ e-shell-utils.c \
+ e-storage-browser.c \
+ e-storage-set-view.c \
+ e-storage-set.c \
+ e-storage.c \
evolution-activity-client.c \
evolution-config-control.c \
evolution-folder-selector-button.c \
evolution-session.c \
evolution-shell-client.c \
evolution-shell-component-client.c \
- evolution-shell-component.c \
evolution-shell-component-dnd.c \
evolution-shell-component-utils.c \
+ evolution-shell-component.c \
evolution-shell-view.c \
evolution-storage-listener.c \
evolution-storage-set-view-listener.c \
evolution-storage.c \
evolution-wizard.c \
- e-shell-marshal.c \
$(eshellinclude_HEADERS)
libeshell_la_LIBADD = \
@@ -179,14 +198,8 @@ evolution_SOURCES = \
e-corba-storage-registry.h \
e-corba-storage.c \
e-corba-storage.h \
- e-folder-dnd-bridge.c \
- e-folder-dnd-bridge.h \
- e-folder-type-registry.c \
- e-folder-type-registry.h \
e-history.c \
e-history.h \
- e-icon-factory.c \
- e-icon-factory.h \
e-local-folder.c \
e-local-folder.h \
e-local-storage.c \
@@ -234,6 +247,8 @@ evolution_SOURCES = \
e-shell-view-menu.h \
e-shell-view.c \
e-shell-view.h \
+ e-shell-window.c \
+ e-shell-window.h \
e-shell.c \
e-shell.h \
e-shortcuts-view-model.c \
@@ -244,12 +259,6 @@ evolution_SOURCES = \
e-shortcuts.h \
e-splash.c \
e-splash.h \
- e-storage-set-view.c \
- e-storage-set-view.h \
- e-storage-set.c \
- e-storage-set.h \
- e-storage.c \
- e-storage.h \
e-task-bar.c \
e-task-bar.h \
e-task-widget.c \
diff --git a/shell/e-folder.c b/shell/e-folder.c
index 8226170e92..adaa31f465 100644
--- a/shell/e-folder.c
+++ b/shell/e-folder.c
@@ -220,7 +220,6 @@ e_folder_new (const char *name,
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (type != NULL, NULL);
- g_return_val_if_fail (description != NULL, NULL);
folder = g_object_new (E_TYPE_FOLDER, NULL);
diff --git a/shell/e-shell-marshal.list b/shell/e-shell-marshal.list
index f1ae29622d..d4076e2a6c 100644
--- a/shell/e-shell-marshal.list
+++ b/shell/e-shell-marshal.list
@@ -23,6 +23,7 @@ NONE:STRING,BOOL
NONE:STRING,INT
NONE:STRING,INT,INT
NONE:STRING,POINTER
+NONE:STRING,POINTER,POINTER
NONE:STRING,STRING
NONE:STRING,STRING,STRING
NONE:STRING,STRING,STRING,STRING
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
new file mode 100644
index 0000000000..5074668f92
--- /dev/null
+++ b/shell/e-shell-window.c
@@ -0,0 +1,381 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-shell-window.c
+ *
+ * Copyright (C) 2003 Ettore Perazzoli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#include <config.h>
+
+#include "Evolution.h"
+
+#include <gal/util/e-util.h>
+
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkhpaned.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkvbox.h>
+
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-object.h>
+#include <bonobo/bonobo-ui-util.h>
+#include <bonobo/bonobo-widget.h>
+
+#include <string.h>
+
+#include "e-shell-window.h"
+
+
+#define PARENT_TYPE gtk_window_get_type ()
+static GtkWindowClass *parent_class = NULL;
+
+
+/* A view for each component. These are all created when EShellWindow is
+ instantiated, but with the widget pointers to NULL and the page number set
+ to -1. When the views are created the first time, the widget pointers as
+ well as the notebook page value get set. */
+struct _ComponentView {
+ char *component_id;
+
+ GNOME_Evolution_Component component_iface;
+
+ GtkWidget *sidebar_widget;
+ GtkWidget *view_widget;
+
+ int notebook_page_num;
+};
+typedef struct _ComponentView ComponentView;
+
+
+struct _EShellWindowPrivate {
+ EShell *shell;
+
+ /* All the ComponentViews. */
+ GSList *component_views;
+
+ /* Notebooks used to switch between components. */
+ GtkWidget *sidebar_notebook;
+ GtkWidget *view_notebook;
+
+ /* Bonobo foo. */
+ BonoboUIComponent *ui_component;
+ BonoboUIContainer *ui_container;
+};
+
+
+/* ComponentView handling. */
+
+static ComponentView *
+component_view_new (const char *id)
+{
+ ComponentView *view = g_new0 (ComponentView, 1);
+
+ view->component_id = g_strdup (id);
+ view->notebook_page_num = -1;
+
+ return view;
+}
+
+static void
+component_view_free (ComponentView *view)
+{
+ g_free (view->component_id);
+ bonobo_object_release_unref (view->component_iface, NULL);
+ g_free (view);
+}
+
+
+/* Utility functions. */
+
+static void
+init_view (EShellWindow *window,
+ ComponentView *view)
+{
+ EShellWindowPrivate *priv = window->priv;
+ Bonobo_UIContainer container;
+ Bonobo_Control sidebar_control;
+ Bonobo_Control view_control;
+ CORBA_Environment ev;
+ int sidebar_notebook_page_num;
+ int view_notebook_page_num;
+
+ g_assert (view->component_iface == CORBA_OBJECT_NIL);
+ g_assert (view->view_widget == NULL);
+ g_assert (view->sidebar_widget == NULL);
+ g_assert (view->notebook_page_num == -1);
+
+ CORBA_exception_init (&ev);
+
+ /* 1. Activate component. (FIXME: Shouldn't do this here.) */
+
+ view->component_iface = bonobo_activation_activate_from_id (view->component_id, 0, NULL, &ev);
+ if (BONOBO_EX (&ev) || view->component_iface == CORBA_OBJECT_NIL) {
+ char *ex_text = bonobo_exception_get_text (&ev);
+ g_warning ("Cannot activate component %s: %s", view->component_id, ex_text);
+ g_free (ex_text);
+
+ view->component_iface = CORBA_OBJECT_NIL;
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ /* 2. Set up view. */
+
+ GNOME_Evolution_Component_createControls (view->component_iface, &sidebar_control, &view_control, &ev);
+ if (BONOBO_EX (&ev)) {
+ g_warning ("Cannot create view for %s", view->component_id);
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ CORBA_exception_free (&ev);
+
+ container = bonobo_ui_component_get_container (priv->ui_component);
+
+ view->sidebar_widget = bonobo_widget_new_control_from_objref (sidebar_control, container);
+ gtk_widget_show (view->sidebar_widget);
+ bonobo_object_release_unref (sidebar_control, NULL);
+
+ view->view_widget = bonobo_widget_new_control_from_objref (view_control, container);
+ gtk_widget_show (view->view_widget);
+ bonobo_object_release_unref (view_control, NULL);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget, NULL);
+ gtk_notebook_append_page (GTK_NOTEBOOK (priv->view_notebook), view->view_widget, NULL);
+
+ sidebar_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget);
+ view_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->view_notebook), view->view_widget);
+
+ /* Since we always add a view page and a sidebar page at the same time... */
+ g_assert (sidebar_notebook_page_num == view_notebook_page_num);
+
+ view->notebook_page_num = view_notebook_page_num;
+}
+
+
+/* Callbacks. */
+
+static void
+component_button_clicked_callback (GtkButton *button,
+ EShellWindow *window)
+{
+ ComponentView *component_view = g_object_get_data (G_OBJECT (button), "ComponentView");
+ EShellWindowPrivate *priv = window->priv;
+
+ g_assert (component_view != NULL);
+
+ if (component_view->sidebar_widget == NULL) {
+ init_view (window, component_view);
+ } else {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->view_notebook), component_view->notebook_page_num);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->sidebar_notebook), component_view->notebook_page_num);
+ }
+}
+
+
+/* Widget layout. */
+
+static GtkWidget *
+create_component_button (EShellWindow *window,
+ ComponentView *component_view)
+{
+ GtkWidget *button;
+ const char *id = component_view->component_id;
+ const char *p, *q;
+ char *label;
+
+ /* FIXME: Need a "name" property on the component or somesuch. */
+
+ p = strrchr (id, '_');
+ if (p == NULL || p == id) {
+ label = g_strdup (id);
+ } else {
+ for (q = p - 1; q != id; q--) {
+ if (*q == '_')
+ break;
+ }
+
+ if (*q != '_') {
+ label = g_strdup (id);
+ } else {
+ label = g_strndup (q + 1, p - q - 1);
+ }
+ }
+
+ button = gtk_button_new_with_label (label);
+
+ g_object_set_data (G_OBJECT (button), "ComponentView", component_view);
+ g_signal_connect (button, "clicked", G_CALLBACK (component_button_clicked_callback), window);
+
+ g_free (label);
+
+ return button;
+}
+
+static void
+setup_widgets (EShellWindow *window)
+{
+ EShellWindowPrivate *priv = window->priv;
+ Bonobo_ServerInfoList *info_list;
+ CORBA_Environment ev;
+ GtkWidget *paned;
+ GtkWidget *sidebar_vbox;
+ GtkWidget *button_box;
+ int i;
+
+ paned = gtk_hpaned_new ();
+ bonobo_window_set_contents (BONOBO_WINDOW (window), paned);
+
+ sidebar_vbox = gtk_vbox_new (FALSE, 6);
+ gtk_paned_pack1 (GTK_PANED (paned), sidebar_vbox, FALSE, FALSE);
+
+ priv->sidebar_notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->sidebar_notebook), FALSE);
+ gtk_box_pack_start (GTK_BOX (sidebar_vbox), priv->sidebar_notebook, TRUE, TRUE, 0);
+
+ priv->view_notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->view_notebook), FALSE);
+ gtk_paned_pack2 (GTK_PANED (paned), priv->view_notebook, FALSE, FALSE);
+
+ button_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (sidebar_vbox), button_box, FALSE, FALSE, 0);
+
+ CORBA_exception_init (&ev);
+
+ /* FIXME: Shouldn't be doing this here. */
+
+ info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Component:1.0')", NULL, &ev);
+ if (BONOBO_EX (&ev)) {
+ char *ex_text = bonobo_exception_get_text (&ev);
+ g_warning ("Cannot query for components: %s\n", ex_text);
+ g_free (ex_text);
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ for (i = 0; i < info_list->_length; i++) {
+ ComponentView *component_view = component_view_new (info_list->_buffer[i].iid);
+ GtkWidget *component_button = create_component_button (window, component_view);
+
+ priv->component_views = g_slist_prepend (priv->component_views, component_view);
+
+ gtk_box_pack_start (GTK_BOX (button_box), component_button, FALSE, FALSE, 0);
+ }
+
+ CORBA_free (info_list);
+ CORBA_exception_free (&ev);
+
+ gtk_widget_show_all (paned);
+}
+
+
+/* GObject methods. */
+
+static void
+impl_dispose (GObject *object)
+{
+ EShellWindowPrivate *priv = E_SHELL_WINDOW (object)->priv;
+
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (G_OBJECT (priv->shell), (void **) &priv->shell);
+ priv->shell = NULL;
+ }
+
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+}
+
+static void
+impl_finalize (GObject *object)
+{
+ EShellWindowPrivate *priv = E_SHELL_WINDOW (object)->priv;
+
+ g_slist_foreach (priv->component_views, (GFunc) component_view_free, NULL);
+ g_slist_free (priv->component_views);
+
+ g_free (priv);
+
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+/* Initialization. */
+
+static void
+class_init (EShellWindowClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->dispose = impl_dispose;
+ object_class->finalize = impl_finalize;
+
+ parent_class = g_type_class_peek_parent (class);
+}
+
+static void
+init (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv;
+
+ priv = g_new0 (EShellWindowPrivate, 1);
+
+ shell_window->priv = priv;
+}
+
+
+/* Instantiation. */
+
+GtkWidget *
+e_shell_window_new (EShell *shell)
+{
+ EShellWindow *window = g_object_new (e_shell_window_get_type (), NULL);
+ EShellWindowPrivate *priv = window->priv;
+
+ if (bonobo_window_construct (BONOBO_WINDOW (window),
+ bonobo_ui_container_new (),
+ "evolution", "Ximian Evolution") == NULL) {
+ g_object_unref (window);
+ return NULL;
+ }
+
+ /* FIXME TODO: Add system_exception signal handling and all the other
+ stuff from e_shell_view_construct(). */
+
+ priv->ui_container = bonobo_window_get_ui_container (BONOBO_WINDOW (window));
+
+ priv->ui_component = bonobo_ui_component_new ("evolution");
+ bonobo_ui_component_set_container (priv->ui_component,
+ bonobo_object_corba_objref (BONOBO_OBJECT (priv->ui_container)),
+ NULL);
+
+ bonobo_ui_util_set_ui (priv->ui_component,
+ PREFIX,
+ EVOLUTION_UIDIR "/evolution.xml",
+ "evolution-1.4", NULL);
+
+ window->priv->shell = shell;
+ g_object_add_weak_pointer (G_OBJECT (shell), (void **) &window->priv->shell);
+
+ setup_widgets (window);
+
+ gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
+
+ return GTK_WIDGET (window);
+}
+
+
+E_MAKE_TYPE (e_shell_window, "EShellWindow", EShellWindow, class_init, init, BONOBO_TYPE_WINDOW)
diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h
new file mode 100644
index 0000000000..602b030283
--- /dev/null
+++ b/shell/e-shell-window.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-shell-window.h
+ *
+ * Copyright (C) 2003 Ettore Perazzoli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifndef _E_SHELL_WINDOW_H_
+#define _E_SHELL_WINDOW_H_
+
+#include <bonobo/bonobo-window.h>
+
+#define E_TYPE_SHELL_WINDOW (e_shell_window_get_type ())
+#define E_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_WINDOW, EShellWindow))
+#define E_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_WINDOW, EShellWindowClass))
+#define E_IS_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_WINDOW))
+#define E_IS_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_WINDOW))
+
+
+typedef struct _EShellWindow EShellWindow;
+typedef struct _EShellWindowPrivate EShellWindowPrivate;
+typedef struct _EShellWindowClass EShellWindowClass;
+
+struct _EShellWindow {
+ BonoboWindow parent;
+
+ EShellWindowPrivate *priv;
+};
+
+struct _EShellWindowClass {
+ BonoboWindowClass parent_class;
+};
+
+
+#include "e-shell.h"
+
+
+GType e_shell_window_get_type (void);
+
+GtkWidget *e_shell_window_new (EShell *shell);
+
+
+#endif /* _E_SHELL_WINDOW_H_ */
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 5dbf9f8666..8462042279 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -797,6 +797,7 @@ setup_components (EShell *shell,
priv = shell->priv;
priv->component_registry = e_component_registry_new (shell);
+#if 0 /* FIXME */
info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/ShellComponent:1.0')", selection_order, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
@@ -852,8 +853,8 @@ setup_components (EShell *shell,
while (gtk_events_pending ())
gtk_main_iteration ();
}
-
CORBA_free (info_list);
+#endif
CORBA_exception_free (&ev);
}
diff --git a/shell/e-storage-browser.c b/shell/e-storage-browser.c
new file mode 100644
index 0000000000..e1baf6bae9
--- /dev/null
+++ b/shell/e-storage-browser.c
@@ -0,0 +1,310 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-browser.c
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+/* TODO:
+
+ - Currently it assumes that the starting path always exists, and you
+ can't remove it. It might be a limitation, but it makes the logic
+ very simple and robust.
+
+ - Doesn't save expansion state for nodes.
+
+ - Context menu handling?
+
+*/
+
+#include <config.h>
+
+#include "e-storage-browser.h"
+
+#include "e-shell-marshal.h"
+#include "e-storage-set-view.h"
+
+#include <gal/util/e-util.h>
+
+#include <gtk/gtknotebook.h>
+#include <string.h>
+
+
+#define PARENT_TYPE G_TYPE_OBJECT
+static GObjectClass *parent_class = NULL;
+
+
+struct _EStorageBrowserPrivate {
+ char *starting_path;
+ char *current_path;
+
+ GtkWidget *view_notebook;
+ GtkWidget *storage_set_view;
+
+ GHashTable *path_to_view; /* (char *, GtkWidget *) */
+
+ EStorageBrowserCreateViewCallback create_view_callback;
+ void *create_view_callback_data;
+};
+
+
+enum {
+ WIDGETS_GONE,
+ NUM_SIGNALS
+};
+
+static unsigned int signals[NUM_SIGNALS] = { 0 };
+
+
+/* Callbacks. */
+
+static void
+storage_set_view_folder_selected_callback (EStorageSetView *storage_set_view,
+ const char *path,
+ EStorageBrowser *browser)
+{
+ if (! e_storage_browser_show_path (browser, path)) {
+ /* Make the selection go back to where it was. */
+ e_storage_browser_show_path (browser, browser->priv->current_path);
+ }
+}
+
+static void
+storage_set_removed_folder_callback (EStorageSet *storage_set,
+ const char *path,
+ EStorageBrowser *browser)
+{
+ if (g_hash_table_lookup (browser->priv->path_to_view, path) != NULL)
+ e_storage_browser_remove_view_for_path (browser, path);
+}
+
+static void
+view_notebook_weak_notify (EStorageBrowser *browser)
+{
+ browser->priv->view_notebook = NULL;
+
+ if (browser->priv->storage_set_view == NULL)
+ g_signal_emit (browser, signals[WIDGETS_GONE], 0);
+}
+
+static void
+storage_set_view_weak_notify (EStorageBrowser *browser)
+{
+ browser->priv->storage_set_view = NULL;
+
+ if (browser->priv->view_notebook == NULL)
+ g_signal_emit (browser, signals[WIDGETS_GONE], 0);
+}
+
+
+/* GObject methods. */
+
+static void
+impl_dispose (GObject *object)
+{
+ EStorageBrowserPrivate *priv = E_STORAGE_BROWSER (object)->priv;
+
+ if (priv->view_notebook != NULL) {
+ g_object_weak_unref (G_OBJECT (priv->view_notebook),
+ (GWeakNotify) view_notebook_weak_notify,
+ object);
+ priv->view_notebook = NULL;
+ }
+
+ if (priv->storage_set_view != NULL) {
+ g_object_weak_unref (G_OBJECT (priv->storage_set_view),
+ (GWeakNotify) storage_set_view_weak_notify,
+ object);
+ priv->storage_set_view = NULL;
+ }
+
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+}
+
+static void
+impl_finalize (GObject *object)
+{
+ EStorageBrowserPrivate *priv = E_STORAGE_BROWSER (object)->priv;
+
+ g_free (priv->starting_path);
+ g_free (priv->current_path);
+
+ g_hash_table_destroy (priv->path_to_view);
+
+ g_free (priv);
+
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+/* Initialization. */
+
+static void
+class_init (EStorageBrowserClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->dispose = impl_dispose;
+ object_class->finalize = impl_finalize;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ signals[WIDGETS_GONE]
+ = g_signal_new ("widgets_gone",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EStorageBrowserClass, widgets_gone),
+ NULL, NULL,
+ e_shell_marshal_NONE__NONE,
+ G_TYPE_NONE, 0);
+}
+
+static void
+init (EStorageBrowser *browser)
+{
+ EStorageBrowserPrivate *priv;
+
+ priv = g_new0 (EStorageBrowserPrivate, 1);
+
+ priv->path_to_view = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ priv->view_notebook = gtk_notebook_new ();
+ g_object_weak_ref (G_OBJECT (priv->view_notebook), (GWeakNotify) view_notebook_weak_notify, browser);
+
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->view_notebook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->view_notebook), FALSE);
+
+ browser->priv = priv;
+}
+
+
+EStorageBrowser *
+e_storage_browser_new (EStorageSet *storage_set,
+ const char *starting_path,
+ EStorageBrowserCreateViewCallback create_view_callback,
+ void *callback_data)
+{
+ EStorageBrowser *new;
+
+ g_return_val_if_fail (create_view_callback != NULL, NULL);
+
+ new = g_object_new (e_storage_browser_get_type (), NULL);
+
+ new->priv->create_view_callback = create_view_callback;
+ new->priv->create_view_callback_data = callback_data;
+ new->priv->starting_path = g_strdup (starting_path);
+ new->priv->storage_set_view = e_storage_set_create_new_view (storage_set, NULL);
+
+ g_object_weak_ref (G_OBJECT (new->priv->storage_set_view), (GWeakNotify) storage_set_view_weak_notify, new);
+
+ g_signal_connect_object (new->priv->storage_set_view,
+ "folder_selected", G_CALLBACK (storage_set_view_folder_selected_callback),
+ G_OBJECT (new), 0);
+ g_signal_connect_object (e_storage_set_view_get_storage_set (E_STORAGE_SET_VIEW (new->priv->storage_set_view)),
+ "removed_folder", G_CALLBACK (storage_set_removed_folder_callback),
+ G_OBJECT (new), 0);
+
+ if (! e_storage_browser_show_path (new, starting_path)) {
+ g_object_unref (new);
+ return NULL;
+ }
+
+ return new;
+}
+
+
+GtkWidget *
+e_storage_browser_peek_tree_widget (EStorageBrowser *browser)
+{
+ return browser->priv->storage_set_view;
+}
+
+GtkWidget *
+e_storage_browser_peek_view_widget (EStorageBrowser *browser)
+{
+ return browser->priv->view_notebook;
+}
+
+EStorageSet *
+e_storage_browser_peek_storage_set (EStorageBrowser *browser)
+{
+ return e_storage_set_view_get_storage_set (E_STORAGE_SET_VIEW (browser->priv->storage_set_view));
+}
+
+gboolean
+e_storage_browser_show_path (EStorageBrowser *browser,
+ const char *path)
+{
+ EStorageBrowserPrivate *priv = browser->priv;
+ GtkWidget *existing_view;
+ GtkWidget *new_view;
+ GtkNotebook *notebook;
+
+ notebook = GTK_NOTEBOOK (priv->view_notebook);
+
+ existing_view = g_hash_table_lookup (priv->path_to_view, path);
+ if (existing_view != NULL) {
+ gtk_notebook_set_current_page (notebook, gtk_notebook_page_num (notebook, existing_view));
+ return TRUE;
+ }
+
+ new_view = (* priv->create_view_callback) (browser, path, priv->create_view_callback_data);
+ if (new_view == NULL)
+ return FALSE;
+
+ gtk_widget_show (new_view);
+ gtk_notebook_append_page (notebook, new_view, NULL);
+ gtk_notebook_set_current_page (notebook, gtk_notebook_page_num (notebook, new_view));
+
+ g_hash_table_insert (priv->path_to_view, g_strdup (path), new_view);
+
+ g_free (priv->current_path);
+ priv->current_path = g_strdup (path);
+
+ e_storage_set_view_set_current_folder (E_STORAGE_SET_VIEW (priv->storage_set_view), path);
+
+ return TRUE;
+}
+
+void
+e_storage_browser_remove_view_for_path (EStorageBrowser *browser,
+ const char *path)
+{
+ GtkWidget *view;
+
+ if (strcmp (path, browser->priv->starting_path) == 0) {
+ g_warning (G_GNUC_FUNCTION ": cannot remove starting view");
+ return;
+ }
+
+ view = g_hash_table_lookup (browser->priv->path_to_view, path);
+ if (view == NULL) {
+ g_warning (G_GNUC_FUNCTION ": no view for %s", path);
+ return;
+ }
+
+ g_hash_table_remove (browser->priv->path_to_view, path);
+ gtk_widget_destroy (view);
+
+ e_storage_browser_show_path (browser, browser->priv->starting_path);
+}
+
+
+E_MAKE_TYPE (e_storage_browser, "EStorageBrowser", EStorageBrowser, class_init, init, PARENT_TYPE)
diff --git a/shell/e-storage-browser.h b/shell/e-storage-browser.h
new file mode 100644
index 0000000000..ddc0430ca9
--- /dev/null
+++ b/shell/e-storage-browser.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-storage-browser.h
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifndef _E_STORAGE_BROWSER_H_
+#define _E_STORAGE_BROWSER_H_
+
+#include "e-storage-set.h"
+
+#include <glib-object.h>
+#include <gtk/gtkwidget.h>
+
+
+#define E_TYPE_STORAGE_BROWSER (e_storage_browser_get_type ())
+#define E_STORAGE_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_STORAGE_BROWSER, EStorageBrowser))
+#define E_STORAGE_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_STORAGE_BROWSER, EStorageBrowserClass))
+#define E_IS_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_STORAGE_BROWSER))
+#define E_IS_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_STORAGE_BROWSER))
+
+
+typedef struct _EStorageBrowser EStorageBrowser;
+typedef struct _EStorageBrowserPrivate EStorageBrowserPrivate;
+typedef struct _EStorageBrowserClass EStorageBrowserClass;
+
+/* FIXME: Use a GClosure instead of void *? */
+typedef GtkWidget * (* EStorageBrowserCreateViewCallback) (EStorageBrowser *browser,
+ const char *path,
+ void *data);
+
+
+struct _EStorageBrowser {
+ GObject parent;
+
+ EStorageBrowserPrivate *priv;
+};
+
+struct _EStorageBrowserClass {
+ GObjectClass parent_class;
+
+ void (* widgets_gone) (EStorageBrowser *browser);
+};
+
+
+GType e_storage_browser_get_type (void);
+
+EStorageBrowser *e_storage_browser_new (EStorageSet *storage_set,
+ const char *starting_path,
+ EStorageBrowserCreateViewCallback create_view_callback,
+ void *create_view_callback_data);
+
+GtkWidget *e_storage_browser_peek_tree_widget (EStorageBrowser *browser);
+GtkWidget *e_storage_browser_peek_view_widget (EStorageBrowser *browser);
+EStorageSet *e_storage_browser_peek_storage_set (EStorageBrowser *browser);
+
+gboolean e_storage_browser_show_path (EStorageBrowser *browser,
+ const char *path);
+void e_storage_browser_remove_view_for_path (EStorageBrowser *browser,
+ const char *path);
+
+
+#endif /* _E_STORAGE_BROWSER_H_ */
diff --git a/shell/e-storage.c b/shell/e-storage.c
index f4a8e5ff26..0a56e3569f 100644
--- a/shell/e-storage.c
+++ b/shell/e-storage.c
@@ -61,6 +61,7 @@ enum {
NEW_FOLDER,
UPDATED_FOLDER,
REMOVED_FOLDER,
+ ASYNC_OPEN_FOLDER,
LAST_SIGNAL
};
@@ -212,15 +213,6 @@ impl_async_xfer_folder (EStorage *storage,
(* callback) (storage, E_STORAGE_NOTIMPLEMENTED, data);
}
-static void
-impl_async_open_folder (EStorage *storage,
- const char *path,
- EStorageDiscoveryCallback callback,
- void *data)
-{
- (*callback) (storage, E_STORAGE_NOTIMPLEMENTED, path, data);
-}
-
static gboolean
impl_supports_shared_folders (EStorage *storage)
{
@@ -265,7 +257,6 @@ class_init (EStorageClass *class)
class->async_create_folder = impl_async_create_folder;
class->async_remove_folder = impl_async_remove_folder;
class->async_xfer_folder = impl_async_xfer_folder;
- class->async_open_folder = impl_async_open_folder;
class->supports_shared_folders = impl_supports_shared_folders;
class->async_discover_shared_folder = impl_async_discover_shared_folder;
@@ -298,6 +289,17 @@ class_init (EStorageClass *class)
e_shell_marshal_NONE__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING);
+ signals[ASYNC_OPEN_FOLDER] =
+ g_signal_new ("async_open_folder",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EStorageClass, async_open_folder),
+ NULL, NULL,
+ e_shell_marshal_NONE__STRING_POINTER_POINTER,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
}
static void
@@ -328,7 +330,7 @@ e_storage_construct (EStorage *storage,
priv = storage->priv;
- priv->name = g_strdup (name);
+ priv->name = g_strdup (name);
e_storage_new_folder (storage, "/", root_folder);
@@ -500,7 +502,8 @@ e_storage_async_open_folder (EStorage *storage,
return;
}
- (* ES_CLASS (storage)->async_open_folder) (storage, path, callback, data);
+ g_signal_emit (storage, signals[ASYNC_OPEN_FOLDER], 0,
+ path, callback, data);
}
diff --git a/shell/e-storage.h b/shell/e-storage.h
index bd0cc5da22..1015290b6a 100644
--- a/shell/e-storage.h
+++ b/shell/e-storage.h
@@ -82,7 +82,12 @@ struct _EStorageClass {
void (* new_folder) (EStorage *storage, const char *path);
void (* updated_folder) (EStorage *storage, const char *path);
void (* removed_folder) (EStorage *storage, const char *path);
- void (* close_folder) (EStorage *storage, const char *path);
+
+ /* FIXME: This should NOT be a signal. */
+ void (* async_open_folder) (EStorage *storage,
+ const char *path,
+ EStorageDiscoveryCallback callback,
+ void *data);
/* Virtual methods. */
@@ -111,11 +116,6 @@ struct _EStorageClass {
EStorageResultCallback callback,
void *data);
- void (* async_open_folder) (EStorage *storage,
- const char *path,
- EStorageDiscoveryCallback callback,
- void *data);
-
gboolean (* supports_shared_folders) (EStorage *storage);
void (* async_discover_shared_folder) (EStorage *storage,
const char *owner,
@@ -194,7 +194,8 @@ void e_storage_async_remove_shared_folder (EStorage *s
char *e_storage_get_path_for_physical_uri (EStorage *storage,
const char *physical_uri);
-/* Protected. C++ anyone? */
+/* FIXME: Need to rename these. */
+
gboolean e_storage_new_folder (EStorage *storage,
const char *path,
EFolder *folder);
diff --git a/shell/main.c b/shell/main.c
index 740eb091ca..8a729822da 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -29,6 +29,7 @@
#include "e-icon-factory.h"
#include "e-shell-constants.h"
#include "e-shell-config.h"
+#include "e-shell-window.h" /* FIXME */
#include "e-setup.h"
#include "e-shell.h"
@@ -439,7 +440,7 @@ idle_cb (void *data)
view, AND we can't load the user's previous settings, then show the default
URI. */
if (! have_evolution_uri) {
- e_shell_create_view (shell, NULL, NULL);
+ /* e_shell_create_view (shell, NULL, NULL); FIXME */
display_default = TRUE;
displayed_any = TRUE;
} else {
@@ -476,8 +477,12 @@ idle_cb (void *data)
CORBA_exception_free (&ev);
- if (shell == NULL)
+ if (shell == NULL) {
bonobo_main_quit ();
+ } else {
+ /* FIXME */
+ gtk_widget_show (e_shell_window_new (shell));
+ }
return FALSE;
}