diff options
-rw-r--r-- | shell/ChangeLog | 15 | ||||
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-history.c | 238 | ||||
-rw-r--r-- | shell/e-history.h | 84 | ||||
-rw-r--r-- | shell/e-shell-view.c | 83 |
5 files changed, 416 insertions, 6 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index dd8a9384c1..eeef21d1c9 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,5 +1,20 @@ 2002-02-22 Ettore Perazzoli <ettore@ximian.com> + * e-shell-view.c: New member `history' in `EShellViewPrivate'. + (init): Initialize. + (destroy): Unref. + (e_shell_view_display_uri): Make it a no-op if the URI is the same + as the current one. Also, moved code into `display_uri' and use + it. + (back_clicked_callback): New, callback for the back button on the + folder title bar. + (forward_clicked_callback): Likewise for the forward button. + + * e-history.c: New. + * e-history.h: New. + +2002-02-22 Ettore Perazzoli <ettore@ximian.com> + * e-shell-view.c (e_shell_view_show_folder_bar): `e_shell_folder_title_bar_set_title_clickable()', not `e_shell_folder_title_bar_set_clickable()'. diff --git a/shell/Makefile.am b/shell/Makefile.am index 84cf6e59ec..b884150927 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -111,6 +111,8 @@ evolution_SOURCES = \ e-folder.h \ e-gray-bar.c \ e-gray-bar.h \ + e-history.c \ + e-history.h \ e-local-folder.c \ e-local-folder.h \ e-local-storage.c \ diff --git a/shell/e-history.c b/shell/e-history.c new file mode 100644 index 0000000000..99579871e1 --- /dev/null +++ b/shell/e-history.c @@ -0,0 +1,238 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-history.c + * + * Copyright (C) 2002 Ximian, 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. + * + * Author: Ettore Perazzoli <ettore@ximian.com> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-history.h" + +#include <gal/util/e-util.h> + + +#define PARENT_TYPE gtk_object_get_type () +static GtkObjectClass *parent_class = NULL; + +struct _EHistoryPrivate { + EHistoryItemFreeFunc item_free_function; + + GList *items; + GList *current_item; +}; + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + EHistory *history; + EHistoryPrivate *priv; + GList *p; + + history = E_HISTORY (object); + priv = history->priv; + + for (p = priv->items; p != NULL; p = p->next) + (* priv->item_free_function) (p->data); + + g_list_free (priv->items); + + g_free (priv); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (GtkObjectClass *object_class) +{ + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = impl_destroy; +} + +static void +init (EHistory *history) +{ + EHistoryPrivate *priv; + + priv = g_new (EHistoryPrivate, 1); + priv->items = NULL; + priv->current_item = NULL; + + history->priv = priv; + + GTK_OBJECT_UNSET_FLAGS (history, GTK_FLOATING); +} + + +void +e_history_construct (EHistory *history, + EHistoryItemFreeFunc item_free_function) +{ + EHistoryPrivate *priv; + + g_return_if_fail (history != NULL); + g_return_if_fail (E_IS_HISTORY (history)); + + priv = history->priv; + + priv->item_free_function = item_free_function; +} + +EHistory * +e_history_new (EHistoryItemFreeFunc item_free_function) +{ + EHistory *history; + + history = gtk_type_new (e_history_get_type ()); + e_history_construct (history, item_free_function); + + return history; +} + +void * +e_history_prev (EHistory *history) +{ + EHistoryPrivate *priv; + + g_return_val_if_fail (history != NULL, NULL); + g_return_val_if_fail (E_IS_HISTORY (history), NULL); + + priv = history->priv; + + if (! e_history_has_prev (history)) + return NULL; + + priv->current_item = priv->current_item->prev; + return e_history_get_current (history); +} + +gboolean +e_history_has_prev (EHistory *history) +{ + EHistoryPrivate *priv; + + g_return_val_if_fail (history != NULL, FALSE); + g_return_val_if_fail (E_IS_HISTORY (history), FALSE); + + priv = history->priv; + + if (priv->current_item == NULL) + return FALSE; + + if (priv->current_item->prev == NULL) + return FALSE; + else + return TRUE; +} + +void * +e_history_next (EHistory *history) +{ + EHistoryPrivate *priv; + + g_return_val_if_fail (history != NULL, NULL); + g_return_val_if_fail (E_IS_HISTORY (history), NULL); + + priv = history->priv; + + if (! e_history_has_next (history)) + return NULL; + + priv->current_item = priv->current_item->next; + return e_history_get_current (history); +} + +gboolean +e_history_has_next (EHistory *history) +{ + EHistoryPrivate *priv; + + g_return_val_if_fail (history != NULL, FALSE); + g_return_val_if_fail (E_IS_HISTORY (history), FALSE); + + priv = history->priv; + + if (priv->current_item == NULL) + return FALSE; + + if (priv->current_item->next == NULL) + return FALSE; + else + return TRUE; +} + +void * +e_history_get_current (EHistory *history) +{ + EHistoryPrivate *priv; + + g_return_val_if_fail (history != NULL, NULL); + g_return_val_if_fail (E_IS_HISTORY (history), NULL); + + priv = history->priv; + + if (priv->current_item == NULL) + return NULL; + + return priv->current_item->data; +} + +void +e_history_add (EHistory *history, + void *data) +{ + EHistoryPrivate *priv; + + g_return_if_fail (history != NULL); + g_return_if_fail (E_IS_HISTORY (history)); + + priv = history->priv; + + if (priv->current_item == NULL) { + priv->items = g_list_prepend (priv->items, data); + priv->current_item = priv->items; + + return; + } + + if (priv->current_item->next != NULL) { + GList *p; + + for (p = priv->current_item->next; p != NULL; p = p->next) + (* priv->item_free_function) (p->data); + + priv->current_item->next->prev = NULL; + g_list_free (priv->current_item->next); + + priv->current_item->next = NULL; + } + + g_list_append (priv->current_item, data); + priv->current_item = priv->current_item->next; +} + + +E_MAKE_TYPE (e_history, "EHistory", EHistory, class_init, init, GTK_TYPE_OBJECT) diff --git a/shell/e-history.h b/shell/e-history.h new file mode 100644 index 0000000000..f2d4efb1fa --- /dev/null +++ b/shell/e-history.h @@ -0,0 +1,84 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-history.h + * + * Copyright (C) 2002 Ximian, 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. + * + * Author: Ettore Perazzoli <ettore@ximian.com> + */ + +#ifndef _E_HISTORY_H_ +#define _E_HISTORY_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnome.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_HISTORY (e_history_get_type ()) +#define E_HISTORY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_HISTORY, EHistory)) +#define E_HISTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_HISTORY, EHistoryClass)) +#define E_IS_HISTORY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_HISTORY)) +#define E_IS_HISTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_HISTORY)) + + +typedef struct _EHistory EHistory; +typedef struct _EHistoryPrivate EHistoryPrivate; +typedef struct _EHistoryClass EHistoryClass; + +struct _EHistory { + GtkObject parent; + + EHistoryPrivate *priv; +}; + +struct _EHistoryClass { + GtkObjectClass parent_class; +}; + + +typedef void (* EHistoryItemFreeFunc) (void *data); + + +GtkType e_history_get_type (void); + +void e_history_construct (EHistory *history, + EHistoryItemFreeFunc item_free_function); +EHistory *e_history_new (EHistoryItemFreeFunc item_free_function); + +void *e_history_prev (EHistory *history); +gboolean e_history_has_prev (EHistory *history); + +void *e_history_next (EHistory *history); +gboolean e_history_has_next (EHistory *history); + +void *e_history_get_current (EHistory *history); + +void e_history_add (EHistory *history, + void *data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_HISTORY_H_ */ diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 3a5ce7c851..66fedd29b1 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -56,6 +56,7 @@ #include "evolution-shell-view.h" #include "e-gray-bar.h" +#include "e-history.h" #include "e-shell-constants.h" #include "e-shell-folder-title-bar.h" #include "e-shell-utils.h" @@ -89,6 +90,9 @@ struct _EShellViewPrivate { BonoboUIComponent *ui_component; BonoboUIContainer *ui_container; + /* History of visited (evolution:) URIs. */ + EHistory *history; + /* Currently displayed URI. */ char *uri; @@ -180,6 +184,7 @@ static const char *get_storage_set_path_from_uri (const char *uri); /* Boo. */ static void new_folder_cb (EStorageSet *storage_set, const char *path, void *data); +static gboolean display_uri (EShellView *shell_view, const char *uri, gboolean add_to_history); /* View handling. */ @@ -797,6 +802,47 @@ offline_toggle_clicked_cb (GtkButton *button, } +/* More callbacks: navigation buttons handling. */ + +static void +back_clicked_callback (EShellFolderTitleBar *title_bar, + void *data) +{ + EShellView *shell_view; + EShellViewPrivate *priv; + const char *new_uri; + + shell_view = E_SHELL_VIEW (data); + priv = shell_view->priv; + + if (! e_history_has_prev (priv->history)) + return; + + new_uri = (const char *) e_history_prev (priv->history); + + display_uri (shell_view, new_uri, FALSE); +} + +static void +forward_clicked_callback (EShellFolderTitleBar *title_bar, + void *data) +{ + EShellView *shell_view; + EShellViewPrivate *priv; + const char *new_uri; + + shell_view = E_SHELL_VIEW (data); + priv = shell_view->priv; + + if (! e_history_has_next (priv->history)) + return; + + new_uri = (const char *) e_history_next (priv->history); + + display_uri (shell_view, new_uri, FALSE); +} + + /* Widget setup. */ static void @@ -1019,6 +1065,10 @@ setup_widgets (EShellView *shell_view) priv->folder_title_bar = e_shell_folder_title_bar_new (); gtk_signal_connect (GTK_OBJECT (priv->folder_title_bar), "title_toggled", GTK_SIGNAL_FUNC (title_bar_toggled_cb), shell_view); + gtk_signal_connect (GTK_OBJECT (priv->folder_title_bar), "back_clicked", + GTK_SIGNAL_FUNC (back_clicked_callback), shell_view); + gtk_signal_connect (GTK_OBJECT (priv->folder_title_bar), "forward_clicked", + GTK_SIGNAL_FUNC (forward_clicked_callback), shell_view); priv->view_hpaned = e_hpaned_new (); e_paned_pack1 (E_PANED (priv->view_hpaned), priv->storage_set_view_box, FALSE, FALSE); @@ -1100,6 +1150,9 @@ destroy (GtkObject *object) gtk_object_unref (GTK_OBJECT (priv->tooltips)); + if (priv->history != NULL) + gtk_object_unref (GTK_OBJECT (priv->history)); + if (priv->shell != NULL) bonobo_object_unref (BONOBO_OBJECT (priv->shell)); @@ -1197,6 +1250,7 @@ init (EShellView *shell_view) priv->shell = NULL; priv->corba_interface = NULL; priv->ui_component = NULL; + priv->history = e_history_new ((EHistoryItemFreeFunc) g_free); priv->uri = NULL; priv->delayed_selection = NULL; @@ -1996,19 +2050,23 @@ create_new_view_for_uri (EShellView *shell_view, return TRUE; } -gboolean -e_shell_view_display_uri (EShellView *shell_view, - const char *uri) +static gboolean +display_uri (EShellView *shell_view, + const char *uri, + gboolean add_to_history) { EShellViewPrivate *priv; View *view; 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 && priv->uri == NULL) + return TRUE; + + if (priv->uri != NULL && uri != NULL && strcmp (priv->uri, uri) == 0) + return TRUE; + bonobo_window_freeze (BONOBO_WINDOW (shell_view)); if (uri == NULL) { @@ -2047,6 +2105,9 @@ e_shell_view_display_uri (EShellView *shell_view, retval = TRUE; end: + if (add_to_history && retval == TRUE && priv->uri != NULL) + e_history_add (priv->history, g_strdup (priv->uri)); + g_free (priv->set_folder_uri); priv->set_folder_uri = NULL; @@ -2068,6 +2129,16 @@ e_shell_view_display_uri (EShellView *shell_view, return retval; } +gboolean +e_shell_view_display_uri (EShellView *shell_view, + const char *uri) +{ + g_return_val_if_fail (shell_view != NULL, FALSE); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE); + + return display_uri (shell_view, uri, TRUE); +} + void e_shell_view_show_shortcut_bar (EShellView *shell_view, |