Files
evolution/shell/e-shell-view.c
Federico Mena Quintero 84ba8642c5 As a quasi-hack, do a gdk_flush() when the shell view is unrealized so
2000-07-10  Federico Mena Quintero  <federico@helixcode.com>

	* e-shell-view.c (unrealize): As a quasi-hack, do a gdk_flush()
	when the shell view is unrealized so that the DeleteEvent gets
	sent to the remote plugs as soon as possible before we start
	making other CORBA calls.  The problem is that our CORBA pipe is
	synchronous while our X pipe is asynch.  We have to ensure
	ordering for certain operations.  This is NOT the correct and
	complete fix, which should go in Bonobo.

svn path=/trunk/; revision=4030
2000-07-10 09:30:28 +00:00

1086 lines
28 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-shell-view.c
*
* Copyright (C) 2000 Helix Code, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* 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.
*
* Authors:
* Ettore Perazzoli <ettore@helixcode.com>
* Miguel de Icaza <miguel@helixcode.com>
* Matt Loper <matt@helixcode.com>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gnome.h>
#include <bonobo.h>
#include <libgnomeui/gnome-window-icon.h>
#include "widgets/misc/e-clipped-label.h"
#include "e-util/e-util.h"
#include "e-util/e-gui-utils.h"
#include "e-shell-constants.h"
#include "e-shell-folder-title-bar.h"
#include "e-shell-utils.h"
#include "e-shell.h"
#include "e-shortcuts-view.h"
#include "e-storage-set-view.h"
#include "e-title-bar.h"
#include "e-shell-view.h"
#include "e-shell-view-menu.h"
#include <widgets/e-paned/e-hpaned.h>
#define PARENT_TYPE gnome_app_get_type () /* Losing GnomeApp does not define GNOME_TYPE_APP. */
static GnomeAppClass *parent_class = NULL;
struct _EShellViewPrivate {
/* The shell. */
EShell *shell;
/* The UI handler. */
BonoboUIHandler *uih;
/* Currently displayed URI. */
char *uri;
/* The widgetry. */
GtkWidget *appbar;
GtkWidget *hpaned;
GtkWidget *view_vbox;
GtkWidget *view_title_bar;
GtkWidget *view_hpaned;
GtkWidget *contents;
GtkWidget *notebook;
GtkWidget *shortcut_bar;
GtkWidget *storage_set_view;
GtkWidget *storage_set_view_box;
/* The view we have already open. */
GHashTable *uri_to_control;
/* Position of the handles in the paneds, to be restored when we show elements
after hiding them. */
unsigned int hpaned_position;
unsigned int view_hpaned_position;
/* Status of the shortcut and folder bars. */
EShellViewSubwindowMode shortcut_bar_mode;
EShellViewSubwindowMode folder_bar_mode;
};
enum {
SHORTCUT_BAR_MODE_CHANGED,
FOLDER_BAR_MODE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
#define DEFAULT_SHORTCUT_BAR_WIDTH 100
#define DEFAULT_TREE_WIDTH 130
#define DEFAULT_WIDTH 705
#define DEFAULT_HEIGHT 550
/* Utility functions. */
static GtkWidget *
create_label_for_empty_page (void)
{
GtkWidget *label;
label = e_clipped_label_new (_("(No folder displayed)"));
gtk_widget_show (label);
return label;
}
/* FIXME this is broken. */
static gboolean
bonobo_widget_is_dead (BonoboWidget *bonobo_widget)
{
BonoboControlFrame *control_frame;
CORBA_Object corba_object;
CORBA_Environment ev;
gboolean is_dead;
control_frame = bonobo_widget_get_control_frame (bonobo_widget);
corba_object = bonobo_control_frame_get_control (control_frame);
CORBA_exception_init (&ev);
is_dead = CORBA_Object_non_existent (corba_object, &ev);
CORBA_exception_free (&ev);
return is_dead;
}
/* Callbacks. */
/* Callback called when an icon on the shortcut bar gets clicked. */
static void
activate_shortcut_cb (EShortcutsView *shortcut_view,
EShortcuts *shortcuts,
const char *uri,
void *data)
{
EShellView *shell_view;
shell_view = E_SHELL_VIEW (data);
e_shell_view_display_uri (shell_view, uri);
}
/* Callback called when a folder on the tree view gets clicked. */
static void
folder_selected_cb (EStorageSetView *storage_set_view,
const char *path,
void *data)
{
EShellView *shell_view;
char *uri;
shell_view = E_SHELL_VIEW (data);
uri = g_strconcat (E_SHELL_URI_PREFIX, path, NULL);
e_shell_view_display_uri (shell_view, uri);
g_free (uri);
}
/* Callback called when the close button on the tree's title bar is clicked. */
static void
storage_set_view_close_button_clicked_cb (ETitleBar *title_bar,
void *data)
{
EShellView *shell_view;
shell_view = E_SHELL_VIEW (data);
e_shell_view_set_folder_bar_mode (shell_view, E_SHELL_VIEW_SUBWINDOW_HIDDEN);
}
/* Widget setup. */
static void
setup_storage_set_subwindow (EShellView *shell_view)
{
EShellViewPrivate *priv;
GtkWidget *storage_set_view;
GtkWidget *title_bar;
GtkWidget *vbox;
GtkWidget *scrolled_window;
priv = shell_view->priv;
storage_set_view = e_storage_set_view_new (e_shell_get_storage_set (priv->shell));
gtk_signal_connect (GTK_OBJECT (storage_set_view), "folder_selected",
GTK_SIGNAL_FUNC (folder_selected_cb), shell_view);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolled_window), storage_set_view);
vbox = gtk_vbox_new (FALSE, 0);
title_bar = e_title_bar_new (_("Folders"));
gtk_box_pack_start (GTK_BOX (vbox), title_bar, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (title_bar), "close_button_clicked",
GTK_SIGNAL_FUNC (storage_set_view_close_button_clicked_cb), shell_view);
gtk_widget_show (vbox);
gtk_widget_show (storage_set_view);
gtk_widget_show (title_bar);
gtk_widget_show (scrolled_window);
priv->storage_set_view_box = vbox;
priv->storage_set_view = storage_set_view;
}
static void
setup_widgets (EShellView *shell_view)
{
EShellViewPrivate *priv;
priv = shell_view->priv;
/* The application bar. */
priv->appbar = gnome_appbar_new (FALSE, TRUE, GNOME_PREFERENCES_NEVER);
gnome_app_set_statusbar (GNOME_APP (shell_view), priv->appbar);
/* The shortcut bar. */
priv->shortcut_bar = e_shortcuts_new_view (e_shell_get_shortcuts (priv->shell));
gtk_signal_connect (GTK_OBJECT (priv->shortcut_bar), "activate_shortcut",
GTK_SIGNAL_FUNC (activate_shortcut_cb), shell_view);
/* The storage set view. */
setup_storage_set_subwindow (shell_view);
/* The tabless notebook which we used to contain the views. */
priv->notebook = gtk_notebook_new ();
gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
/* Page for "No URL displayed" message. */
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), create_label_for_empty_page (), NULL);
/* Put things into a paned and the paned into the GnomeApp. */
priv->view_vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (priv->view_vbox), 2);
priv->view_title_bar = e_shell_folder_title_bar_new ();
priv->view_hpaned = e_hpaned_new ();
e_paned_add1 (E_PANED (priv->view_hpaned), priv->storage_set_view_box);
e_paned_add2 (E_PANED (priv->view_hpaned), priv->notebook);
e_paned_set_position (E_PANED (priv->view_hpaned), DEFAULT_TREE_WIDTH);
gtk_box_pack_start (GTK_BOX (priv->view_vbox), priv->view_title_bar,
FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (priv->view_vbox), priv->view_hpaned,
TRUE, TRUE, 2);
priv->hpaned = e_hpaned_new ();
e_paned_add1 (E_PANED (priv->hpaned), priv->shortcut_bar);
e_paned_add2 (E_PANED (priv->hpaned), priv->view_vbox);
e_paned_set_position (E_PANED (priv->hpaned), DEFAULT_SHORTCUT_BAR_WIDTH);
gnome_app_set_contents (GNOME_APP (shell_view), priv->hpaned);
/* Show stuff. */
gtk_widget_show (priv->shortcut_bar);
gtk_widget_show (priv->storage_set_view);
gtk_widget_show (priv->storage_set_view_box);
gtk_widget_show (priv->notebook);
gtk_widget_show (priv->hpaned);
gtk_widget_show (priv->view_hpaned);
gtk_widget_show (priv->view_vbox);
gtk_widget_show (priv->view_title_bar);
/* By default, both the folder bar and shortcut bar are visible. */
priv->shortcut_bar_mode = E_SHELL_VIEW_SUBWINDOW_STICKY;
priv->folder_bar_mode = E_SHELL_VIEW_SUBWINDOW_STICKY;
/* FIXME: Session management and stuff? */
gtk_window_set_default_size (GTK_WINDOW (shell_view), DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
/* BonoboUIHandler setup. */
static void
setup_bonobo_ui_handler (EShellView *shell_view)
{
BonoboUIHandler *uih;
EShellViewPrivate *priv;
priv = shell_view->priv;
uih = bonobo_ui_handler_new ();
bonobo_ui_handler_set_app (uih, GNOME_APP (shell_view));
bonobo_ui_handler_create_menubar (uih);
/* bonobo_ui_handler_create_toolbar (uih, "Toolbar"); */
bonobo_ui_handler_set_statusbar (uih, priv->appbar);
priv->uih = uih;
}
/* GtkObject methods. */
static void
hash_forall_destroy_control (void *name,
void *value,
void *data)
{
BonoboWidget *bonobo_widget;
bonobo_widget = BONOBO_WIDGET (value);
gtk_widget_destroy (GTK_WIDGET (bonobo_widget));
g_free (name);
}
static void
destroy (GtkObject *object)
{
EShellView *shell_view;
EShellViewPrivate *priv;
shell_view = E_SHELL_VIEW (object);
priv = shell_view->priv;
g_hash_table_foreach (priv->uri_to_control, hash_forall_destroy_control, NULL);
g_hash_table_destroy (priv->uri_to_control);
g_free (priv->uri);
g_free (priv);
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
/* Unrealize handler */
static void
unrealize (GtkWidget *widget)
{
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
/* We flush so that all the destroy window requests for foreign windows
* get sent over the X wire. Hopefully this will diminish the chance of
* hitting the CORBA (sync) vs. Xlib (async) race conditions. This is
* not the complete fix, which should actually be put in Bonobo and
* completed. FIXME.
*/
gdk_flush ();
}
/* Initialization. */
static void
class_init (EShellViewClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
object_class->destroy = destroy;
widget_class->unrealize = unrealize;
parent_class = gtk_type_class (gnome_app_get_type ());
signals[SHORTCUT_BAR_MODE_CHANGED]
= gtk_signal_new ("shortcut_bar_mode_changed",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (EShellViewClass, shortcut_bar_mode_changed),
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1,
GTK_TYPE_INT);
signals[FOLDER_BAR_MODE_CHANGED]
= gtk_signal_new ("folder_bar_mode_changed",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (EShellViewClass, folder_bar_mode_changed),
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1,
GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
init (EShellView *shell_view)
{
EShellViewPrivate *priv;
priv = g_new (EShellViewPrivate, 1);
priv->shell = NULL;
priv->uih = NULL;
priv->uri = NULL;
priv->appbar = NULL;
priv->hpaned = NULL;
priv->view_hpaned = NULL;
priv->contents = NULL;
priv->notebook = NULL;
priv->storage_set_view = NULL;
priv->storage_set_view_box = NULL;
priv->shortcut_bar = NULL;
priv->shortcut_bar_mode = E_SHELL_VIEW_SUBWINDOW_HIDDEN;
priv->folder_bar_mode = E_SHELL_VIEW_SUBWINDOW_HIDDEN;
priv->hpaned_position = 0;
priv->view_hpaned_position = 0;
priv->uri_to_control = g_hash_table_new (g_str_hash, g_str_equal);
shell_view->priv = priv;
}
void
e_shell_view_construct (EShellView *shell_view,
EShell *shell)
{
EShellViewPrivate *priv;
g_return_if_fail (shell_view != NULL);
g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell));
priv = shell_view->priv;
gnome_app_construct (GNOME_APP (shell_view), "evolution", "Evolution");
priv->shell = shell;
setup_widgets (shell_view);
setup_bonobo_ui_handler (shell_view);
e_shell_view_menu_setup (shell_view);
e_shell_view_set_folder_bar_mode (shell_view, E_SHELL_VIEW_SUBWINDOW_HIDDEN);
}
GtkWidget *
e_shell_view_new (EShell *shell)
{
GtkWidget *new;
g_return_val_if_fail (shell != NULL, NULL);
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
new = gtk_type_new (e_shell_view_get_type ());
e_shell_view_construct (E_SHELL_VIEW (new), shell);
return new;
}
static const char *
get_storage_set_path_from_uri (const char *uri)
{
const char *colon;
if (uri == NULL)
return NULL;
if (g_path_is_absolute (uri))
return NULL;
colon = strchr (uri, ':');
if (colon == NULL || colon == uri || colon[1] == '\0')
return NULL;
if (! g_path_is_absolute (colon + 1))
return NULL;
if (g_strncasecmp (uri, E_SHELL_URI_PREFIX, colon - uri) != 0)
return NULL;
return colon + 1;
}
static void
update_window_icon (EShellView *shell_view,
EFolder *folder)
{
EShellViewPrivate *priv;
const char *type;
const char *icon_name;
char *icon_path;
priv = shell_view->priv;
if (folder == NULL)
type = NULL;
else
type = e_folder_get_type_string (folder);
if (type == NULL) {
icon_path = NULL;
} else {
EFolderTypeRegistry *folder_type_registry;
folder_type_registry = e_shell_get_folder_type_registry (priv->shell);
icon_name = e_folder_type_registry_get_icon_name_for_type (folder_type_registry, type);
if (icon_name == NULL)
icon_path = NULL;
else
icon_path = e_shell_get_icon_path (icon_name, TRUE);
}
if (icon_path == NULL) {
gnome_window_icon_set_from_default (GTK_WINDOW (shell_view));
} else {
gnome_window_icon_set_from_file (GTK_WINDOW (shell_view), icon_path);
g_free (icon_path);
}
}
static void
update_folder_title_bar (EShellView *shell_view,
EFolder *folder)
{
EShellViewPrivate *priv;
EFolderTypeRegistry *folder_type_registry;
GdkPixbuf *folder_icon;
const char *folder_name;
const char *folder_type_name;
priv = shell_view->priv;
if (folder == NULL)
folder_type_name = NULL;
else
folder_type_name = e_folder_get_type_string (folder);
if (folder_type_name == NULL) {
folder_name = NULL;
folder_icon = NULL;
} else {
folder_type_registry = e_shell_get_folder_type_registry (priv->shell);
folder_icon = e_folder_type_registry_get_icon_for_type (folder_type_registry,
folder_type_name,
TRUE);
folder_name = e_folder_get_name (folder);
}
e_shell_folder_title_bar_set_icon (E_SHELL_FOLDER_TITLE_BAR (priv->view_title_bar), folder_icon);
e_shell_folder_title_bar_set_title (E_SHELL_FOLDER_TITLE_BAR (priv->view_title_bar), folder_name);
}
static void
update_for_current_uri (EShellView *shell_view)
{
EShellViewPrivate *priv;
EFolder *folder;
const char *folder_name;
const char *path;
char *window_title;
priv = shell_view->priv;
path = get_storage_set_path_from_uri (priv->uri);
if (path == NULL)
folder = NULL;
else
folder = e_storage_set_get_folder (e_shell_get_storage_set (priv->shell),
path);
if (folder == NULL)
folder_name = _("None");
else
folder_name = e_folder_get_name (folder);
window_title = g_strdup_printf (_("Evolution - %s"), folder_name);
gtk_window_set_title (GTK_WINDOW (shell_view), window_title);
g_free (window_title);
update_folder_title_bar (shell_view, folder);
update_window_icon (shell_view, folder);
gtk_signal_handler_block_by_func (GTK_OBJECT (priv->storage_set_view),
GTK_SIGNAL_FUNC (folder_selected_cb),
shell_view);
e_storage_set_view_set_current_folder (E_STORAGE_SET_VIEW (priv->storage_set_view),
path);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (priv->storage_set_view),
GTK_SIGNAL_FUNC (folder_selected_cb),
shell_view);
}
/* This displays the specified page, doing the appropriate Bonobo activation/deactivation
magic to make sure things work nicely. FIXME: Crappy way to solve the issue. */
static void
set_current_notebook_page (EShellView *shell_view,
int page_num)
{
EShellViewPrivate *priv;
GtkNotebook *notebook;
GtkWidget *current;
BonoboControlFrame *control_frame;
int current_page;
priv = shell_view->priv;
notebook = GTK_NOTEBOOK (priv->notebook);
current_page = gtk_notebook_get_current_page (notebook);
if (current_page == page_num)
return;
if (current_page != -1 && current_page != 0) {
current = gtk_notebook_get_nth_page (notebook, current_page);
control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (current));
bonobo_control_frame_set_autoactivate (control_frame, FALSE);
bonobo_control_frame_control_deactivate (control_frame);
}
gtk_notebook_set_page (notebook, page_num);
if (page_num == -1 || page_num == 0)
return;
current = gtk_notebook_get_nth_page (notebook, page_num);
control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (current));
bonobo_control_frame_set_autoactivate (control_frame, FALSE);
bonobo_control_frame_control_activate (control_frame);
}
/* 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,
const char *uri)
{
EShellViewPrivate *priv;
EFolderTypeRegistry *folder_type_registry;
EStorageSet *storage_set;
EFolder *folder;
Bonobo_UIHandler corba_uih;
EvolutionShellComponentClient *handler_client;
Bonobo_Control corba_control;
Evolution_ShellComponent handler;
const char *path;
const char *folder_type;
GtkWidget *control;
CORBA_Environment ev;
priv = shell_view->priv;
path = strchr (uri, ':');
if (path == NULL)
return NULL;
path++;
if (*path == '\0')
return NULL;
storage_set = e_shell_get_storage_set (priv->shell);
folder_type_registry = e_shell_get_folder_type_registry (priv->shell);
folder = e_storage_set_get_folder (storage_set, path);
if (folder == NULL)
return NULL;
folder_type = e_folder_get_type_string (folder);
if (folder_type == NULL)
return NULL;
handler_client = e_folder_type_registry_get_handler_for_type (folder_type_registry, folder_type);
if (handler_client == NULL)
return NULL;
handler = bonobo_object_corba_objref (BONOBO_OBJECT (handler_client));
if (handler_client == CORBA_OBJECT_NIL)
return NULL;
CORBA_exception_init (&ev);
corba_control = Evolution_ShellComponent_create_view (handler, e_folder_get_physical_uri (folder),
folder_type, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
CORBA_exception_free (&ev);
return NULL;
}
CORBA_exception_free (&ev);
corba_uih = bonobo_object_corba_objref (BONOBO_OBJECT (priv->uih));
control = bonobo_widget_new_control_from_objref (corba_control, corba_uih);
return control;
}
static gboolean
show_existing_view (EShellView *shell_view,
const char *uri,
GtkWidget *control)
{
EShellViewPrivate *priv;
int notebook_page;
g_print ("Already have view for %s\n", uri);
priv = shell_view->priv;
notebook_page = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), control);
g_assert (notebook_page != -1);
/* A BonoboWidget can be a "zombie" in the sense that its actual
control is dead; if it's zombie, we have to recreate it. */
if (bonobo_widget_is_dead (BONOBO_WIDGET (control))) {
GtkWidget *parent;
Bonobo_UIHandler uih;
parent = control->parent;
uih = bonobo_object_corba_objref (BONOBO_OBJECT (priv->uih));
/* Out with the old. */
gtk_container_remove (GTK_CONTAINER (parent), control);
g_hash_table_remove (priv->uri_to_control, uri);
/* In with the new. */
control = get_control_for_uri (shell_view, uri);
if (control == NULL)
return FALSE;
gtk_container_add (GTK_CONTAINER (parent), control);
g_hash_table_insert (priv->uri_to_control, g_strdup (uri), control);
/* Show. */
gtk_widget_show (control);
}
set_current_notebook_page (shell_view, notebook_page);
return TRUE;
}
static gboolean
create_new_view_for_uri (EShellView *shell_view,
const char *uri)
{
GtkWidget *control;
EShellViewPrivate *priv;
int page_num;
priv = shell_view->priv;
control = get_control_for_uri (shell_view, uri);
if (control == NULL)
return FALSE;
gtk_widget_show (control);
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), control, NULL);
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), control);
g_assert (page_num != -1);
set_current_notebook_page (shell_view, page_num);
g_hash_table_insert (priv->uri_to_control, g_strdup (uri), control);
return TRUE;
}
gboolean
e_shell_view_display_uri (EShellView *shell_view,
const char *uri)
{
EShellViewPrivate *priv;
GtkWidget *control;
gboolean retval;
g_return_val_if_fail (shell_view != NULL, FALSE);
g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
priv = shell_view->priv;
if (uri == NULL) {
gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), 0);
gtk_notebook_prepend_page (GTK_NOTEBOOK (priv->notebook),
create_label_for_empty_page (), NULL);
set_current_notebook_page (shell_view, 0);
if (priv->uri != NULL) {
g_free (priv->uri);
priv->uri = NULL;
}
retval = TRUE;
goto end;
}
if (strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) != 0) {
retval = FALSE;
goto end;
}
control = g_hash_table_lookup (priv->uri_to_control, uri);
if (control != NULL) {
g_assert (GTK_IS_WIDGET (control));
show_existing_view (shell_view, uri, control);
} else if (! create_new_view_for_uri (shell_view, uri)) {
retval = FALSE;
goto end;
}
g_free (priv->uri);
priv->uri = g_strdup (uri);
retval = TRUE;
end:
update_for_current_uri (shell_view);
return retval;
}
void
e_shell_view_set_shortcut_bar_mode (EShellView *shell_view,
EShellViewSubwindowMode mode)
{
EShellViewPrivate *priv;
g_return_if_fail (shell_view != NULL);
g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
g_return_if_fail (mode == E_SHELL_VIEW_SUBWINDOW_STICKY
|| mode == E_SHELL_VIEW_SUBWINDOW_HIDDEN);
priv = shell_view->priv;
if (priv->shortcut_bar_mode == mode)
return;
if (mode == E_SHELL_VIEW_SUBWINDOW_STICKY) {
if (! GTK_WIDGET_VISIBLE (priv->shortcut_bar)) {
gtk_widget_show (priv->shortcut_bar);
e_paned_set_position (E_PANED (priv->hpaned), priv->hpaned_position);
}
} else {
if (GTK_WIDGET_VISIBLE (priv->shortcut_bar)) {
gtk_widget_hide (priv->shortcut_bar);
/* FIXME this is a private field! */
priv->hpaned_position = E_PANED (priv->hpaned)->child1_size;
e_paned_set_position (E_PANED (priv->hpaned), 0);
}
}
priv->shortcut_bar_mode = mode;
gtk_signal_emit (GTK_OBJECT (shell_view), signals[SHORTCUT_BAR_MODE_CHANGED], mode);
}
void
e_shell_view_set_folder_bar_mode (EShellView *shell_view,
EShellViewSubwindowMode mode)
{
EShellViewPrivate *priv;
g_return_if_fail (shell_view != NULL);
g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
g_return_if_fail (mode == E_SHELL_VIEW_SUBWINDOW_STICKY
|| mode == E_SHELL_VIEW_SUBWINDOW_HIDDEN);
priv = shell_view->priv;
if (priv->folder_bar_mode == mode)
return;
if (mode == E_SHELL_VIEW_SUBWINDOW_STICKY) {
if (! GTK_WIDGET_VISIBLE (priv->storage_set_view_box)) {
gtk_widget_show (priv->storage_set_view_box);
e_paned_set_position (E_PANED (priv->view_hpaned), priv->view_hpaned_position);
}
} else {
if (GTK_WIDGET_VISIBLE (priv->storage_set_view_box)) {
gtk_widget_hide (priv->storage_set_view_box);
/* FIXME this is a private field! */
priv->view_hpaned_position = E_PANED (priv->view_hpaned)->child1_size;
e_paned_set_position (E_PANED (priv->view_hpaned), 0);
}
}
priv->folder_bar_mode = mode;
gtk_signal_emit (GTK_OBJECT (shell_view), signals[FOLDER_BAR_MODE_CHANGED], mode);
}
EShellViewSubwindowMode
e_shell_view_get_shortcut_bar_mode (EShellView *shell_view)
{
g_return_val_if_fail (shell_view != NULL, E_SHELL_VIEW_SUBWINDOW_HIDDEN);
g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), E_SHELL_VIEW_SUBWINDOW_HIDDEN);
return shell_view->priv->shortcut_bar_mode;
}
EShellViewSubwindowMode
e_shell_view_get_folder_bar_mode (EShellView *shell_view)
{
g_return_val_if_fail (shell_view != NULL, E_SHELL_VIEW_SUBWINDOW_HIDDEN);
g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), E_SHELL_VIEW_SUBWINDOW_HIDDEN);
return shell_view->priv->folder_bar_mode;
}
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;
}
BonoboUIHandler *
e_shell_view_get_bonobo_ui_handler (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->uih;
}
GtkWidget *
e_shell_view_get_appbar (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->appbar;
}
const char *
e_shell_view_get_current_uri (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->uri;
}
/**
* e_shell_view_save_settings:
* @shell_view:
* @gconf_client:
* @prefix:
*
* Save settings for @shell_view at the specified GConf @prefix through
* @gconf_client.
*
* Return value: TRUE if successful, FALSE if not.
**/
gboolean
e_shell_view_save_settings (EShellView *shell_view,
GConfClient *gconf_client,
const char *prefix)
{
GConfError *err = NULL;
const char *uri;
char *path;
g_return_val_if_fail (shell_view != NULL, FALSE);
g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
g_return_val_if_fail (gconf_client != NULL, FALSE);
g_return_val_if_fail (GCONF_IS_CLIENT (gconf_client), FALSE);
g_return_val_if_fail (prefix != NULL, FALSE);
g_return_val_if_fail (g_path_is_absolute (prefix), FALSE);
#define SET(type, key, value) \
path = g_strconcat (prefix, "/", (key), NULL); \
gconf_client_set_##type (gconf_client, path, (value), &err); \
g_free (path); \
if (err != NULL) { \
gconf_error_destroy (err); \
return FALSE; \
}
SET (int, "FolderBarMode", e_shell_view_get_folder_bar_mode (shell_view))
SET (int, "ShortcutBarMode", e_shell_view_get_shortcut_bar_mode (shell_view));
uri = e_shell_view_get_current_uri (shell_view);
if (uri != NULL) {
SET (string, "DisplayedURI", uri);
} else {
path = g_strconcat (prefix, "/", "DisplayedURI", NULL);
gconf_client_unset (gconf_client, path, &err);
g_free (path);
if (err != NULL) {
gconf_error_destroy (err);
return FALSE;
}
}
#undef SET
return TRUE;
}
/**
* e_shell_view_load_settings:
* @shell_view:
* @gconf_client:
* @prefix:
*
* Load settings for @shell_view at the specified GConf @prefix through
* @gconf_client.
*
* Return value:
**/
gboolean
e_shell_view_load_settings (EShellView *shell_view,
GConfClient *gconf_client,
const char *prefix)
{
gboolean val;
GConfError *err = NULL;
char *stringval;
char *path;
g_return_val_if_fail (shell_view != NULL, FALSE);
g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
g_return_val_if_fail (gconf_client != NULL, FALSE);
g_return_val_if_fail (GCONF_IS_CLIENT (gconf_client), FALSE);
g_return_val_if_fail (prefix != NULL, FALSE);
g_return_val_if_fail (g_path_is_absolute (prefix), FALSE);
#define GET(type, key, value) \
path = g_strconcat (prefix, "/", (key), NULL); \
(value) = gconf_client_get_##type (gconf_client, path, &err); \
g_free (path); \
if (err != NULL) { \
gconf_error_destroy (err); \
return FALSE; \
}
GET (int, "FolderBarMode", val);
e_shell_view_set_folder_bar_mode (shell_view, val);
GET (int, "ShortcutBarMode", val);
e_shell_view_set_shortcut_bar_mode (shell_view, val);
GET (string, "DisplayedURI", stringval);
e_shell_view_display_uri (shell_view, stringval);
g_free (stringval);
#undef GET
return TRUE;
}
E_MAKE_TYPE (e_shell_view, "EShellView", EShellView, class_init, init, PARENT_TYPE)